net: wireless: rockchip_wlan: bcmdhd: Update to 101.10.591.x
This commit is contained in:
parent
c598125738
commit
0a60f6cf89
Binary file not shown.
|
|
@ -1,6 +1,27 @@
|
|||
# SPDX-License-Identifier: GPL-2.0
|
||||
#
|
||||
# Copyright (C) 2023, Broadcom.
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
#
|
||||
# <<Broadcom-WL-IPTag/Open:>>
|
||||
#
|
||||
|
||||
config BCMDHD
|
||||
tristate "Broadcom FullMAC wireless cards support"
|
||||
default m
|
||||
help
|
||||
This module adds support for wireless adapters based on
|
||||
Broadcom FullMAC chipset.
|
||||
|
|
@ -51,7 +72,6 @@ choice
|
|||
config BCMDHD_OOB
|
||||
depends on BCMDHD && BCMDHD_SDIO
|
||||
bool "Out-of-Band Interrupt"
|
||||
default y
|
||||
help
|
||||
Interrupt from WL_HOST_WAKE.
|
||||
config BCMDHD_SDIO_IRQ
|
||||
|
|
|
|||
|
|
@ -1,8 +1,27 @@
|
|||
# SPDX-License-Identifier: GPL-2.0
|
||||
# bcmdhd
|
||||
#
|
||||
# Copyright (C) 2023, Broadcom.
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
#
|
||||
# <<Broadcom-WL-IPTag/Open:>>
|
||||
#
|
||||
|
||||
MODULE_NAME := bcmdhd
|
||||
CONFIG_BCMDHD ?= m
|
||||
CONFIG_AP6XXX ?= m
|
||||
|
||||
#CONFIG_BCMDHD_SDIO := y
|
||||
#CONFIG_BCMDHD_PCIE := y
|
||||
|
|
@ -14,47 +33,52 @@ CONFIG_BCMDHD_OOB := y
|
|||
CONFIG_BCMDHD_PROPTXSTATUS := y
|
||||
CONFIG_BCMDHD_AG := y
|
||||
CONFIG_DHD_USE_STATIC_BUF := y
|
||||
#CONFIG_BCMDHD_STATIC_BUF_IN_DHD := y
|
||||
CONFIG_BCMDHD_ANDROID_VERSION := 12
|
||||
CONFIG_BCMDHD_STATIC_BUF_IN_DHD := y
|
||||
CONFIG_BCMDHD_ANDROID_VERSION := 14
|
||||
CONFIG_BCMDHD_AUTO_SELECT := y
|
||||
CONFIG_BCMDHD_DEBUG := y
|
||||
#CONFIG_BCMDHD_RECONNECT := y
|
||||
#CONFIG_BCMDHD_TIMESTAMP := y
|
||||
#CONFIG_BCMDHD_WAPI := y
|
||||
#CONFIG_BCMDHD_RANDOM_MAC := y
|
||||
CONFIG_BCMDHD_REQUEST_FW := y
|
||||
#CONFIG_BCMDHD_MULTIPLE_DRIVER := y
|
||||
#CONFIG_BCMDHD_FW_SIGNATURE := y
|
||||
#CONFIG_BCMDHD_DWDS := y
|
||||
CONFIG_BCMDHD_TPUT := y
|
||||
|
||||
#CONFIG_BCMDHD_MULTIPLE_DRIVER := y
|
||||
#CONFIG_BCMDHD_ADAPTER_INDEX := 0
|
||||
|
||||
CONFIG_MACH_PLATFORM := y
|
||||
#CONFIG_BCMDHD_DTS := y
|
||||
|
||||
DHDCFLAGS = -Wall -Wstrict-prototypes -Wno-date-time \
|
||||
-Wno-implicit-fallthrough -Wno-declaration-after-statement \
|
||||
-Wno-vla -Wno-vla-extension \
|
||||
-Dlinux -DLINUX -DBCMDRIVER \
|
||||
DHDCFLAGS = -Wall -Wstrict-prototypes -Wno-date-time -Wno-strict-prototypes \
|
||||
-Wno-uninitialized -Wno-unused-but-set-variable -Wno-address \
|
||||
-Dlinux -DLINUX -DBCMDRIVER -DBCMUTILS_ERR_CODES \
|
||||
-DBCMDONGLEHOST -DBCMDMA32 -DBCMFILEIMAGE \
|
||||
-DDHDTHREAD -DDHD_DEBUG -DSHOW_EVENTS -DGET_OTP_MAC_ENABLE \
|
||||
-DWIFI_ACT_FRAME -DARP_OFFLOAD_SUPPORT -DSUPPORT_PM2_ONLY \
|
||||
-DPKTPRIO_OVERRIDE \
|
||||
-DKEEP_ALIVE -DPKT_FILTER_SUPPORT -DDHDTCPACK_SUPPRESS \
|
||||
-DDHD_DONOT_FORWARD_BCMEVENT_AS_NETWORK_PKT -DOEM_ANDROID \
|
||||
-DMULTIPLE_SUPPLICANT -DTSQ_MULTIPLIER -DMFP -DDHD_8021X_DUMP \
|
||||
-DPOWERUP_MAX_RETRY=0 -DIFACE_HANG_FORCE_DEV_CLOSE -DWAIT_DEQUEUE \
|
||||
-DUSE_NEW_RSPEC_DEFS -DBCM_USE_PLATFORM_STRLCPY \
|
||||
-DUSE_NEW_RSPEC_DEFS \
|
||||
-DWL_EXT_IAPSTA -DWL_ESCAN -DCCODE_LIST -DSUSPEND_EVENT \
|
||||
-DEAPOL_RESEND -DEAPOL_DYNAMATIC_RESEND -DWL_SCHED_SCAN \
|
||||
-DENABLE_INSMOD_NO_FW_LOAD -Wframe-larger-than=2048 \
|
||||
-DSCHED_SCAN_DELAYED_WORK -DDHD_PNO_FLAG
|
||||
-DKEY_INSTALL_CHECK \
|
||||
-DENABLE_INSMOD_NO_FW_LOAD
|
||||
|
||||
DHDOFILES = aiutils.o siutils.o sbutils.o bcmutils.o bcmwifi_channels.o \
|
||||
DHDOFILES = aiutils.o siutils.o sbutils.o \
|
||||
bcmutils.o bcmwifi_channels.o bcmxtlv.o bcm_app_utils.o bcmstdlib_s.o \
|
||||
dhd_linux.o dhd_linux_platdev.o dhd_linux_sched.o dhd_pno.o \
|
||||
dhd_common.o dhd_ip.o dhd_linux_wq.o dhd_custom_gpio.o \
|
||||
bcmevent.o hndpmu.o linux_osl.o wldev_common.o wl_android.o \
|
||||
dhd_debug_linux.o dhd_debug.o dhd_mschdbg.o dhd_dbg_ring.o \
|
||||
hnd_pktq.o hnd_pktpool.o bcmxtlv.o linux_pkt.o bcmstdlib_s.o frag.o \
|
||||
dhd_linux_exportfs.o dhd_linux_pktdump.o dhd_mschdbg.o \
|
||||
hnd_pktq.o hnd_pktpool.o linux_pkt.o frag.o \
|
||||
dhd_linux_exportfs.o dhd_linux_pktdump.o dhd_mschdbg.o linuxerrmap.o \
|
||||
dhd_linux_tx.o dhd_linux_rx.o fwpkg_utils.o \
|
||||
dhd_config.o dhd_ccode.o wl_event.o wl_android_ext.o \
|
||||
wl_iapsta.o wl_escan.o
|
||||
wl_iapsta.o wl_escan.o wl_timer.o
|
||||
|
||||
ifneq ($(CONFIG_WIRELESS_EXT),)
|
||||
DHDOFILES += wl_iw.o
|
||||
|
|
@ -63,39 +87,49 @@ endif
|
|||
ifneq ($(CONFIG_CFG80211),)
|
||||
DHDOFILES += wl_cfg80211.o wl_cfgscan.o wl_cfgp2p.o
|
||||
DHDOFILES += wl_linux_mon.o wl_cfg_btcoex.o wl_cfgvendor.o
|
||||
DHDOFILES += dhd_cfg80211.o wl_cfgvif.o
|
||||
DHDOFILES += dhd_cfg80211.o wl_cfgvif.o wl_roam.o
|
||||
DHDCFLAGS += -DWL_CFG80211 -DWLP2P -DWL_CFG80211_STA_EVENT
|
||||
# DHDCFLAGS += -DWL_IFACE_COMB_NUM_CHANNELS
|
||||
DHDCFLAGS += -DWL_CFG80211_GON_COLLISION
|
||||
DHDCFLAGS += -DWL_CAP_HE -DWL_6G_BAND -DWL_5P9G
|
||||
# DHDCFLAGS += -DCONFIG_6GHZ_BKPORT
|
||||
DHDCFLAGS += -DWL_IFACE_COMB_NUM_CHANNELS
|
||||
DHDCFLAGS += -DCUSTOM_PNO_EVENT_LOCK_xTIME=10
|
||||
DHDCFLAGS += -DWL_SUPPORT_AUTO_CHANNEL
|
||||
DHDCFLAGS += -DWL_SUPPORT_BACKPORTED_KPATCHES
|
||||
DHDCFLAGS += -DESCAN_RESULT_PATCH -DESCAN_BUF_OVERFLOW_MGMT
|
||||
DHDCFLAGS += -DVSDB -DWL_CFG80211_VSDB_PRIORITIZE_SCAN_REQUEST
|
||||
DHDCFLAGS += -DWLTDLS -DMIRACAST_AMPDU_SIZE=8
|
||||
DHDCFLAGS += -DWL_VIRTUAL_APSTA
|
||||
DHDCFLAGS += -DPNO_SUPPORT -DEXPLICIT_DISCIF_CLEANUP
|
||||
# DHDCFLAGS += -DHOSTAPD_BW_SUPPORT
|
||||
DHDCFLAGS += -DWL_VIRTUAL_APSTA -DSTA_MGMT -DSOFTAP_UAPSD_OFF
|
||||
DHDCFLAGS += -DWL_SOFTAP_ACS
|
||||
DHDCFLAGS += -DNUM_SCB_MAX_PROBE=3
|
||||
DHDCFLAGS += -DWL_SCB_TIMEOUT=10
|
||||
DHDCFLAGS += -DEXPLICIT_DISCIF_CLEANUP
|
||||
DHDCFLAGS += -DDHD_USE_SCAN_WAKELOCK
|
||||
DHDCFLAGS += -DSPECIFIC_MAC_GEN_SCHEME
|
||||
DHDCFLAGS += -DWL_IFACE_MGMT
|
||||
DHDCFLAGS += -DWLFBT -DWL_GCMP_SUPPORT
|
||||
DHDCFLAGS += -DWL_EXT_RECONNECT
|
||||
DHDCFLAGS += -DDHD_LOSSLESS_ROAMING
|
||||
DHDCFLAGS += -DSUPPORT_RSSI_SUM_REPORT
|
||||
DHDCFLAGS += -DWLFBT -DWL_GCMP_SUPPORT -DWL_OWE -DWL_SAE_FT
|
||||
DHDCFLAGS += -DROAM_CHANNEL_CACHE -DDHD_LOSSLESS_ROAMING
|
||||
# DHDCFLAGS += -DWL_CFGVENDOR_SEND_HANG_EVENT
|
||||
DHDCFLAGS += -DGTK_OFFLOAD_SUPPORT
|
||||
DHDCFLAGS += -DRESTART_AP_WAR
|
||||
# DHDCFLAGS += -DWL_STATIC_IF
|
||||
DHDCFLAGS += -DWL_CLIENT_SAE -DWL_OWE
|
||||
#DHDCFLAGS += -DWL_STATIC_IF #-DDHD_MAX_STATIC_IFS=2
|
||||
DHDCFLAGS += -DWL_CLIENT_SAE
|
||||
DHDCFLAGS += -DCONNECT_INFO_WAR -DWL_ROAM_WAR
|
||||
DHDCFLAGS += -DVNDR_IE_WAR
|
||||
DHDCFLAGS += -DRESTART_AP_WAR -DRXF0OVFL_REINIT_WAR
|
||||
endif
|
||||
|
||||
#BCMDHD_SDIO
|
||||
ifneq ($(CONFIG_BCMDHD_SDIO),)
|
||||
BUS_TYPE := "sdio"
|
||||
DHDCFLAGS += -DBCMSDIO -DMMC_SDIO_ABORT -DMMC_SW_RESET -DBCMLXSDMMC \
|
||||
-DUSE_SDIOFIFO_IOVAR -DSDTEST \
|
||||
-DBDC -DDHD_USE_IDLECOUNT -DCUSTOM_SDIO_F2_BLKSIZE=256 \
|
||||
-DBCMSDIOH_TXGLOM -DBCMSDIOH_TXGLOM_EXT -DRXFRAME_THREAD \
|
||||
-DDHDENABLE_TAILPAD -DSUPPORT_P2P_GO_PS \
|
||||
BUS_TYPE := sdio
|
||||
DHDCFLAGS += -DBCMSDIO -DMMC_SDIO_ABORT -DUSE_SDIOFIFO_IOVAR -DBCMLXSDMMC \
|
||||
-DSDTEST -DBDC -DDHD_USE_IDLECOUNT -DCUSTOM_SDIO_F2_BLKSIZE=256 \
|
||||
-DBCMSDIOH_TXGLOM -DBCMSDIOH_TXGLOM_EXT -DBCMSDIOH_STATIC_COPY_BUF \
|
||||
-DRXFRAME_THREAD -DDHDENABLE_TAILPAD -DSUPPORT_P2P_GO_PS \
|
||||
-DBCMSDIO_RXLIM_POST -DBCMSDIO_TXSEQ_SYNC -DCONSOLE_DPC \
|
||||
-DBCMSDIO_INTSTATUS_WAR
|
||||
DHDCFLAGS += -DMMC_HW_RESET #-DMMC_SW_RESET #-DBUS_POWER_RESTORE
|
||||
ifeq ($(CONFIG_BCMDHD_OOB),y)
|
||||
DHDCFLAGS += -DOOB_INTR_ONLY -DCUSTOMER_OOB -DHW_OOB
|
||||
ifeq ($(CONFIG_BCMDHD_DISABLE_WOWLAN),y)
|
||||
|
|
@ -110,15 +144,24 @@ endif
|
|||
|
||||
#BCMDHD_PCIE
|
||||
ifneq ($(CONFIG_BCMDHD_PCIE),)
|
||||
BUS_TYPE := "pcie"
|
||||
DHDCFLAGS += -DPCIE_FULL_DONGLE -DBCMPCIE -DCUSTOM_DPC_PRIO_SETTING=-1 \
|
||||
-DDONGLE_ENABLE_ISOLATION
|
||||
DHDCFLAGS += -DDHD_LB -DDHD_LB_RXP -DDHD_LB_STATS -DDHD_LB_TXP
|
||||
#DHDCFLAGS += -DDHD_PKTID_AUDIT_ENABLED
|
||||
DHDCFLAGS += -DINSMOD_FW_LOAD
|
||||
DHDCFLAGS += -DCHIP_INTR_CONTROL
|
||||
#DHDCFLAGS += -DDHD_PCIE_RUNTIMEPM -DMAX_IDLE_COUNT=11 -DCUSTOM_DHD_RUNTIME_MS=100
|
||||
DHDCFLAGS += -DDHD_CONTROL_PCIE_ASPM_WIFI_TURNON
|
||||
BUS_TYPE := pcie
|
||||
DHDCFLAGS += -DPCIE_FULL_DONGLE -DBCMPCIE -DCUSTOM_DPC_PRIO_SETTING=-1
|
||||
DHDCFLAGS += -DDONGLE_ENABLE_ISOLATION
|
||||
DHDCFLAGS += -DDHD_LB -DDHD_LB_RXP -DDHD_LB_STATS -DDHD_LB_TXP
|
||||
DHDCFLAGS += -DDHD_LB_PRIMARY_CPUS=0xF0 -DDHD_LB_SECONDARY_CPUS=0x0E
|
||||
# DHDCFLAGS += -DDHD_PKTID_AUDIT_ENABLED
|
||||
DHDCFLAGS += -DEAPOL_PKT_PRIO -DENABLE_DHD_GRO
|
||||
DHDCFLAGS += -DDHD_SKIP_DONGLE_RESET_IN_ATTACH
|
||||
DHDCFLAGS += -DDHD_DONGLE_TRAP_IN_DETACH
|
||||
DHDCFLAGS += -DFORCE_DONGLE_RESET_IN_DEVRESET_ON
|
||||
DHDCFLAGS += -DDHD_USE_COHERENT_MEM_FOR_RING
|
||||
DHDCFLAGS += -DCHECK_TRAP_ROT
|
||||
DHDCFLAGS += -DINSMOD_FW_LOAD
|
||||
DHDCFLAGS += -DCONFIG_HAS_WAKELOCK #-DDHD_DEBUG_WAKE_LOCK
|
||||
DHDCFLAGS += -DDHD_PACKET_TIMEOUT_MS=50 -DMAX_TX_TIMEOUT=50
|
||||
ifeq ($(CONFIG_AP6XXX),y)
|
||||
DHDCFLAGS += -DWAKEUP_KSOFTIRQD_POST_NAPI_SCHEDULE
|
||||
endif
|
||||
ifeq ($(CONFIG_BCMDHD_OOB),y)
|
||||
DHDCFLAGS += -DCUSTOMER_OOB -DBCMPCIE_OOB_HOST_WAKE -DHW_OOB
|
||||
endif
|
||||
|
|
@ -131,10 +174,16 @@ endif
|
|||
|
||||
#BCMDHD_USB
|
||||
ifneq ($(CONFIG_BCMDHD_USB),)
|
||||
BUS_TYPE := "usb"
|
||||
BUS_TYPE := usb
|
||||
DHDCFLAGS += -DUSBOS_TX_THREAD -DBCMDBUS -DBCMTRXV2 -DDBUS_USB_LOOPBACK \
|
||||
-DBDC
|
||||
DHDCFLAGS += -DBCM_REQUEST_FW -DEXTERNAL_FW_PATH
|
||||
DHDCFLAGS += -DINSMOD_FW_LOAD
|
||||
DHDCFLAGS += -DBCM_REQUEST_FW
|
||||
DHDCFLAGS += -DSHOW_LOGTRACE
|
||||
DHDCFLAGS += -DWL_EXT_WOWL
|
||||
ifneq ($(CONFIG_BCMDHD_REQUEST_FW),y)
|
||||
DHDCFLAGS += -DEXTERNAL_FW_PATH
|
||||
endif
|
||||
ifneq ($(CONFIG_BCMDHD_CUSB),)
|
||||
DHDCFLAGS += -DBCMUSBDEV_COMPOSITE
|
||||
CONFIG_BCMDHD_NO_POWER_OFF := y
|
||||
|
|
@ -149,9 +198,17 @@ endif
|
|||
|
||||
ifeq ($(CONFIG_BCMDHD_MULTIPLE_DRIVER),y)
|
||||
DHDCFLAGS += -DBCMDHD_MDRIVER
|
||||
ifneq ($(CONFIG_BCMDHD_ADAPTER_INDEX),)
|
||||
CONFIG_BCMDHD_STATIC_BUF_IN_DHD := y
|
||||
MODULE_NAME := dhd$(BUS_TYPE)_$(CONFIG_BCMDHD_ADAPTER_INDEX)
|
||||
DHDCFLAGS += -DADAPTER_IDX=$(CONFIG_BCMDHD_ADAPTER_INDEX)
|
||||
DHDCFLAGS += -DBUS_TYPE=\"-$(BUS_TYPE)-$(CONFIG_BCMDHD_ADAPTER_INDEX)\"
|
||||
DHDCFLAGS += -DDHD_LOG_PREFIX=\"[dhd-$(BUS_TYPE)-$(CONFIG_BCMDHD_ADAPTER_INDEX)]\"
|
||||
else
|
||||
MODULE_NAME := dhd$(BUS_TYPE)
|
||||
DHDCFLAGS += -DBUS_TYPE=\"-$(BUS_TYPE)\"
|
||||
DHDCFLAGS += -DDHD_LOG_PREFIX=\"[dhd-$(BUS_TYPE)]\"
|
||||
MODULE_NAME := dhd$(BUS_TYPE)
|
||||
endif
|
||||
else
|
||||
DHDCFLAGS += -DBUS_TYPE=\"\"
|
||||
endif
|
||||
|
|
@ -165,9 +222,11 @@ endif
|
|||
ifeq ($(CONFIG_BCMDHD_PROPTXSTATUS),y)
|
||||
ifneq ($(CONFIG_BCMDHD_USB),)
|
||||
DHDCFLAGS += -DPROP_TXSTATUS
|
||||
DHDCFLAGS += -DLIMIT_BORROW -DBULK_DEQUEUE
|
||||
endif
|
||||
ifneq ($(CONFIG_BCMDHD_SDIO),)
|
||||
DHDCFLAGS += -DPROP_TXSTATUS -DPROPTX_MAXCOUNT
|
||||
DHDCFLAGS += -DLIMIT_BORROW -DBULK_DEQUEUE
|
||||
endif
|
||||
ifneq ($(CONFIG_CFG80211),)
|
||||
DHDCFLAGS += -DPROP_TXSTATUS_VSDB
|
||||
|
|
@ -183,18 +242,22 @@ endif
|
|||
ifneq ($(CONFIG_BCMDHD_ANDROID_VERSION),)
|
||||
DHDCFLAGS += -DANDROID_VERSION=$(CONFIG_BCMDHD_ANDROID_VERSION)
|
||||
DHDCFLAGS += -DDHD_NOTIFY_MAC_CHANGED
|
||||
DHDCFLAGS += -DANDROID_BKPORT
|
||||
ifneq ($(CONFIG_CFG80211),)
|
||||
DHDCFLAGS += -DGSCAN_SUPPORT -DRTT_SUPPORT
|
||||
DHDCFLAGS += -DWL_SAR_TX_POWER
|
||||
# DHDCFLAGS += -DLINKSTAT_SUPPORT
|
||||
DHDCFLAGS += -DCUSTOM_COUNTRY_CODE -DDHD_GET_VALID_CHANNELS
|
||||
DHDCFLAGS += -DDEBUGABILITY -DDBG_PKT_MON
|
||||
# DHDCFLAGS += -DDHD_LOG_DUMP
|
||||
DHDCFLAGS += -DDHD_FW_COREDUMP
|
||||
DHDCFLAGS += -DPNO_SUPPORT
|
||||
DHDCFLAGS += -DWL_SCHED_SCAN
|
||||
DHDCFLAGS += -DWL_P2P_RAND
|
||||
DHDCFLAGS += -DGSCAN_SUPPORT -DRTT_SUPPORT
|
||||
DHDCFLAGS += -DLINKSTAT_SUPPORT -DLINKSTAT_EXT_SUPPORT
|
||||
DHDCFLAGS += -DCUSTOM_COUNTRY_CODE -DDHD_GET_VALID_CHANNELS
|
||||
DHDCFLAGS += -DDEBUGABILITY -DDEBUGABILITY_DISABLE_MEMDUMP -DDBG_PKT_MON
|
||||
DHDCFLAGS += -DDHD_LOG_DUMP -DDHD_FW_COREDUMP
|
||||
# DHDCFLAGS += -DDHD_PKT_LOGGING_DBGRING
|
||||
DHDCFLAGS += -DAPF -DNDO_CONFIG_SUPPORT -DRSSI_MONITOR_SUPPORT
|
||||
DHDCFLAGS += -DDHD_WAKE_STATUS -DWL_LATENCY_MODE
|
||||
DHDOFILES += dhd_rtt.o bcm_app_utils.o
|
||||
DHDCFLAGS += -DDHD_WAKE_STATUS
|
||||
DHDCFLAGS += -DWL_LATENCY_MODE
|
||||
DHDOFILES += dhd_rtt.o
|
||||
DHDOFILES += dhd_log_dump.o
|
||||
endif
|
||||
else
|
||||
DHDCFLAGS += -DANDROID_VERSION=0
|
||||
|
|
@ -210,6 +273,7 @@ ifeq ($(CONFIG_BCMDHD_DEBUG),y)
|
|||
DHDCFLAGS += -DPKT_STATICS
|
||||
DHDCFLAGS += -DKSO_DEBUG
|
||||
# DHDCFLAGS += -DDHD_PKTDUMP_TOFW
|
||||
# DHDCFLAGS += -DDHD_DUMP_FILE_WRITE_FROM_KERNEL
|
||||
endif
|
||||
|
||||
# For Debug2
|
||||
|
|
@ -221,11 +285,15 @@ ifneq ($(CONFIG_BCMDHD_PCIE),)
|
|||
DHDCFLAGS += -DEWP_EDL
|
||||
DHDCFLAGS += -DDNGL_EVENT_SUPPORT
|
||||
DHDCFLAGS += -DDHD_SSSR_DUMP
|
||||
DHDCFLAGS += -DDHD_MEM_STATS
|
||||
DHDCFLAGS += -DDHD_FLOW_RING_STATUS_TRACE
|
||||
DHDCFLAGS += -DDNGL_AXI_ERROR_LOGGING
|
||||
endif
|
||||
DHDOFILES += dhd_log_dump.o
|
||||
endif
|
||||
|
||||
# MESH support for kernel 3.10 later
|
||||
ifeq ($(CONFIG_WL_MESH),y)
|
||||
ifeq ($(CONFIG_BCMDHD_WLMESH),y)
|
||||
DHDCFLAGS += -DWLMESH
|
||||
ifneq ($(CONFIG_CFG80211),)
|
||||
DHDCFLAGS += -DWLMESH_CFG80211
|
||||
|
|
@ -253,7 +321,7 @@ ifneq ($(CONFIG_CFG80211),)
|
|||
ifneq ($(CONFIG_BCMDHD_SDIO),)
|
||||
DHDCFLAGS += -DRXF_DEQUEUE_ON_BUSY
|
||||
endif
|
||||
DHDCFLAGS += -DWL_STATIC_IF
|
||||
#DHDCFLAGS += -DWL_STATIC_IF
|
||||
endif
|
||||
endif
|
||||
|
||||
|
|
@ -263,10 +331,19 @@ ifeq ($(CONFIG_CSI_SUPPORT),y)
|
|||
DHDOFILES += dhd_csi.o
|
||||
endif
|
||||
|
||||
# For CONNECTION_IMPROVE
|
||||
ifeq ($(CONFIG_BCMDHD_RECONNECT),y)
|
||||
DHDCFLAGS += -DEAPOL_RESEND -DEAPOL_RESEND_M4
|
||||
ifneq ($(CONFIG_CFG80211),)
|
||||
DHDCFLAGS += -DWL_EXT_RECONNECT -DWL_REASSOC_BCAST
|
||||
DHDCFLAGS += -DWL_EXT_DISCONNECT_RECONNECT
|
||||
endif
|
||||
endif
|
||||
|
||||
# For TPUT_IMPROVE
|
||||
ifeq ($(CONFIG_BCMDHD_TPUT),y)
|
||||
DHDCFLAGS += -DDHD_TPUT_PATCH
|
||||
DHDCFLAGS += -DTCPACK_INFO_MAXNUM=10 -DTCPDATA_INFO_MAXNUM=10
|
||||
DHDCFLAGS += -DTCPACK_INFO_MAXNUM=40 -DTCPDATA_INFO_MAXNUM=40
|
||||
ifneq ($(CONFIG_BCMDHD_SDIO),)
|
||||
DHDCFLAGS += -DDYNAMIC_MAX_HDR_READ
|
||||
DHDCFLAGS :=$(filter-out -DSDTEST,$(DHDCFLAGS))
|
||||
|
|
@ -301,20 +378,29 @@ endif
|
|||
|
||||
# For NAN
|
||||
ifneq ($(CONFIG_BCMDHD_NAN),)
|
||||
DHDCFLAGS += -DWL_NAN -DWL_NAN_DISC_CACHE
|
||||
DHDCFLAGS += -DWL_NAN -DWL_NAN_DISC_CACHE -DWL_NANP2P -DWL_NAN_ENABLE_MERGE
|
||||
DHDOFILES += wl_cfgnan.o bcmbloom.o
|
||||
endif
|
||||
|
||||
# For Module auto-selection
|
||||
ifeq ($(CONFIG_BCMDHD_AUTO_SELECT),y)
|
||||
DHDCFLAGS += -DUPDATE_MODULE_NAME
|
||||
ifeq ($(CONFIG_BCMDHD_REQUEST_FW),y)
|
||||
# DHDCFLAGS += -DFW_AMPAK_PATH="\"ampak\""
|
||||
# DHDCFLAGS += -DMODULE_PATH
|
||||
endif
|
||||
ifneq ($(CONFIG_BCMDHD_SDIO),)
|
||||
DHDCFLAGS += -DGET_OTP_MODULE_NAME -DCOMPAT_OLD_MODULE
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_AP6XXX),y)
|
||||
DHDCFLAGS += -DUSE_LATE_INITCALL_SYNC
|
||||
DHDCFLAGS += -DBCM_USE_PLATFORM_STRLCPY
|
||||
endif
|
||||
ifeq ($(CONFIG_AP6XXX),m)
|
||||
DHDCFLAGS += -DBCMDHD_MODULAR
|
||||
DHDCFLAGS += -DBOARD_MODULAR_INIT
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_MACH_PLATFORM),y)
|
||||
|
|
@ -324,19 +410,36 @@ ifeq ($(CONFIG_BCMDHD_DTS),y)
|
|||
endif
|
||||
DHDCFLAGS += -DCUSTOMER_HW -DDHD_OF_SUPPORT
|
||||
DHDCFLAGS += -DCUSTOMER_HW_ROCKCHIP
|
||||
# DHDCFLAGS += -DCUSTOMER_HW_ROCKCHIP_RK3588
|
||||
DHDCFLAGS += -DBCM_USE_PLATFORM_STRLCPY
|
||||
endif
|
||||
|
||||
ifneq ($(CONFIG_BCMDHD_PCIE),)
|
||||
ifneq ($(filter -DCUSTOMER_HW_ROCKCHIP_RK3588, $(DHDCFLAGS)),)
|
||||
DHDCFLAGS += -DDHD_CONTROL_PCIE_ASPM_WIFI_TURNON
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_BCMDHD_REQUEST_FW),y)
|
||||
DHDCFLAGS += -DDHD_LINUX_STD_FW_API
|
||||
DHDCFLAGS += -DDHD_REQUEST_FW_PATH
|
||||
DHDCFLAGS += -DDHD_FW_NAME="\"fw_bcmdhd.bin\""
|
||||
DHDCFLAGS += -DDHD_NVRAM_NAME="\"nvram.txt\""
|
||||
DHDCFLAGS += -DDHD_CLM_NAME="\"clm_bcmdhd.blob\""
|
||||
DHDCFLAGS += -DDHD_CONFIG_NAME="\"config.txt\""
|
||||
else
|
||||
DHDCFLAGS += -DDHD_SUPPORT_VFS_CALL
|
||||
ifeq ($(CONFIG_BCMDHD_FW_PATH),)
|
||||
DHDCFLAGS += -DCONFIG_BCMDHD_FW_PATH="\"/system/etc/firmware/fw_bcmdhd.bin\""
|
||||
DHDCFLAGS += -DCONFIG_BCMDHD_NVRAM_PATH="\"/system/etc/firmware/nvram.txt\""
|
||||
DHDCFLAGS += -DCONFIG_BCMDHD_CLM_PATH="\"/system/etc/firmware/clm_bcmdhd.blob\""
|
||||
DHDCFLAGS += -DCONFIG_BCMDHD_FW_PATH="\"/vendor/etc/firmware/fw_bcmdhd.bin\""
|
||||
DHDCFLAGS += -DCONFIG_BCMDHD_NVRAM_PATH="\"/vendor/etc/firmware/nvram.txt\""
|
||||
DHDCFLAGS += -DCONFIG_BCMDHD_CLM_PATH="\"/vendor/etc/firmware/clm_bcmdhd.blob\""
|
||||
endif
|
||||
DHDCFLAGS += -DCONFIG_BCMDHD_CONFIG_PATH="\"/vendor/etc/firmware/config.txt\""
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_BCMDHD_FW_SIGNATURE),y)
|
||||
DHDCFLAGS += -DFW_SIGNATURE
|
||||
DHDCFLAGS += -DBL_HEAP_START_GAP_SIZE=0x1000 -DBL_HEAP_SIZE=0x10000
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_BCMDHD_AG),y)
|
||||
|
|
@ -352,7 +455,12 @@ else
|
|||
endif
|
||||
DHDCFLAGS += -DSTATIC_WL_PRIV_STRUCT -DENHANCED_STATIC_BUF
|
||||
DHDCFLAGS += -DCONFIG_DHD_USE_STATIC_BUF
|
||||
ifneq ($(filter -DDHD_LOG_DUMP, $(DHDCFLAGS)),)
|
||||
DHDCFLAGS += -DDHD_USE_STATIC_MEMDUMP
|
||||
endif
|
||||
ifneq ($(filter -DDHD_FW_COREDUMP, $(DHDCFLAGS)),)
|
||||
DHDCFLAGS += -DDHD_USE_STATIC_MEMDUMP
|
||||
endif
|
||||
ifneq ($(CONFIG_BCMDHD_PCIE),)
|
||||
DHDCFLAGS += -DDHD_USE_STATIC_CTRLBUF
|
||||
endif
|
||||
|
|
@ -363,8 +471,7 @@ BCMDHD_ROOT = $(src)
|
|||
#$(warning "BCMDHD_ROOT=$(BCMDHD_ROOT)")
|
||||
EXTRA_CFLAGS = $(DHDCFLAGS)
|
||||
EXTRA_CFLAGS += -DDHD_COMPILED=\"$(BCMDHD_ROOT)\"
|
||||
EXTRA_CFLAGS += -I$(srctree)/$(BCMDHD_ROOT)/include/ -I$(srctree)/$(BCMDHD_ROOT)/
|
||||
EXTRA_CFLAGS += $(call cc-disable-warning, unused-but-set-variable)
|
||||
EXTRA_CFLAGS += -I$(BCMDHD_ROOT)/include/ -I$(BCMDHD_ROOT)/
|
||||
ifeq ($(CONFIG_AP6XXX),m)
|
||||
EXTRA_LDFLAGS += --strip-debug
|
||||
endif
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
* Misc utility routines for accessing chip-specific features
|
||||
* of the SiliconBackplane-based Broadcom chips.
|
||||
*
|
||||
* Copyright (C) 2020, Broadcom.
|
||||
* Copyright (C) 2022, Broadcom.
|
||||
*
|
||||
* Unless you and Broadcom execute a separate written software license
|
||||
* agreement governing use of this software, this software is licensed to you
|
||||
|
|
@ -52,7 +52,7 @@ static bool ai_get_apb_bridge(const si_t *sih, uint32 coreidx, uint32 *apb_id,
|
|||
uint32 *apb_coreunit);
|
||||
#endif /* AXI_TIMEOUTS_NIC */
|
||||
|
||||
#if defined (AXI_TIMEOUTS) || defined (AXI_TIMEOUTS_NIC)
|
||||
#if defined(AXI_TIMEOUTS) || defined(AXI_TIMEOUTS_NIC)
|
||||
static void ai_reset_axi_to(const si_info_t *sii, aidmp_t *ai);
|
||||
#endif /* defined (AXI_TIMEOUTS) || defined (AXI_TIMEOUTS_NIC) */
|
||||
|
||||
|
|
@ -169,7 +169,7 @@ get_asd(const si_t *sih, uint32 **eromptr, uint sp, uint ad, uint st, uint32 *ad
|
|||
|
||||
/* Parse the enumeration rom to identify all cores */
|
||||
void
|
||||
BCMATTACHFN(ai_scan)(si_t *sih, void *regs, uint devid)
|
||||
ai_scan(si_t *sih, void *regs, uint devid)
|
||||
{
|
||||
si_info_t *sii = SI_INFO(sih);
|
||||
si_cores_info_t *cores_info = (si_cores_info_t *)sii->cores_info;
|
||||
|
|
@ -177,6 +177,7 @@ BCMATTACHFN(ai_scan)(si_t *sih, void *regs, uint devid)
|
|||
uint32 erombase, *eromptr, *eromlim;
|
||||
axi_wrapper_t * axi_wrapper = sii->axi_wrapper;
|
||||
|
||||
SI_MSG_DBG_REG(("%s: Enter\n", __FUNCTION__));
|
||||
BCM_REFERENCE(devid);
|
||||
|
||||
erombase = R_REG(sii->osh, &cc->eromptr);
|
||||
|
|
@ -225,6 +226,7 @@ BCMATTACHFN(ai_scan)(si_t *sih, void *regs, uint devid)
|
|||
cia = get_erom_ent(sih, &eromptr, ER_TAG, ER_CI);
|
||||
if (cia == (ER_END | ER_VALID)) {
|
||||
SI_VMSG(("Found END of erom after %d cores\n", sii->numcores));
|
||||
SI_MSG_DBG_REG(("%s: Exit\n", __FUNCTION__));
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -423,6 +425,11 @@ BCMATTACHFN(ai_scan)(si_t *sih, void *regs, uint devid)
|
|||
/* cache APB bridge wrapper address for set/clear timeout */
|
||||
if ((mfg == MFGID_ARM) && (cid == APB_BRIDGE_ID)) {
|
||||
ASSERT(sii->num_br < SI_MAXBR);
|
||||
if (sii->num_br >= SI_MAXBR) {
|
||||
SI_ERROR(("bridge number %d is overflowed\n", sii->num_br));
|
||||
goto error;
|
||||
}
|
||||
|
||||
sii->br_wrapba[sii->num_br++] = addrl;
|
||||
}
|
||||
|
||||
|
|
@ -474,6 +481,7 @@ BCMATTACHFN(ai_scan)(si_t *sih, void *regs, uint devid)
|
|||
|
||||
error:
|
||||
sii->numcores = 0;
|
||||
SI_MSG_DBG_REG(("%s: Exit\n", __FUNCTION__));
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -612,8 +620,10 @@ BCMPOSTTRAPFN(_ai_setcoreidx)(si_t *sih, uint coreidx, uint use_wrapn)
|
|||
sii->curwrap = (void *)((uintptr)regs + SI_CORE_SIZE);
|
||||
|
||||
/* point bar0 window */
|
||||
ai_corereg(sih, sih->buscoreidx, PCIE_TER_BAR0_WIN, ~0, addr);
|
||||
ai_corereg(sih, sih->buscoreidx, PCIE_TER_BAR0_WRAPPER, ~0, wrap);
|
||||
ai_corereg(sih, sih->buscoreidx,
|
||||
PCIE_TER_BAR0_WIN_REG(sih->buscorerev), ~0, addr);
|
||||
ai_corereg(sih, sih->buscoreidx,
|
||||
PCIE_TER_BAR0_WRAPPER_REG(sih->buscorerev), ~0, wrap);
|
||||
break;
|
||||
|
||||
default: /* other slices */
|
||||
|
|
@ -643,6 +653,10 @@ BCMPOSTTRAPFN(_ai_setcoreidx)(si_t *sih, uint coreidx, uint use_wrapn)
|
|||
|
||||
sii->curidx = coreidx;
|
||||
|
||||
if (regs) {
|
||||
SI_MSG_DBG_REG(("%s: %d\n", __FUNCTION__, coreidx));
|
||||
}
|
||||
|
||||
return regs;
|
||||
}
|
||||
|
||||
|
|
@ -1755,7 +1769,7 @@ ai_update_backplane_timeouts(const si_t *sih, bool enable, uint32 timeout_exp, u
|
|||
#endif /* AXI_TIMEOUTS || AXI_TIMEOUTS_NIC */
|
||||
}
|
||||
|
||||
#if defined (AXI_TIMEOUTS) || defined (AXI_TIMEOUTS_NIC)
|
||||
#if defined(AXI_TIMEOUTS) || defined(AXI_TIMEOUTS_NIC)
|
||||
|
||||
/* slave error is ignored, so account for those cases */
|
||||
static uint32 si_ignore_errlog_cnt = 0;
|
||||
|
|
@ -1824,12 +1838,6 @@ BCMPOSTTRAPFN(ai_ignore_errlog)(const si_info_t *sii, const aidmp_t *ai,
|
|||
extd_axi_id_mask = TRUE;
|
||||
ignore_errsts_2 = AIELS_DECODE;
|
||||
break;
|
||||
#ifdef USE_HOSTMEM
|
||||
case BCM43602_CHIP_ID:
|
||||
axi_id = BCM43602_BT_AXI_ID;
|
||||
address_check = FALSE;
|
||||
break;
|
||||
#endif /* USE_HOSTMEM */
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
|
|
@ -1946,7 +1954,7 @@ ai_clear_backplane_to_fast(si_t *sih, void *addr)
|
|||
}
|
||||
#endif /* AXI_TIMEOUTS_NIC */
|
||||
|
||||
#if defined (AXI_TIMEOUTS) || defined (AXI_TIMEOUTS_NIC)
|
||||
#if defined(AXI_TIMEOUTS) || defined(AXI_TIMEOUTS_NIC)
|
||||
static bool g_disable_backplane_logs = FALSE;
|
||||
|
||||
static uint32 last_axi_error = AXI_WRAP_STS_NONE;
|
||||
|
|
@ -2086,11 +2094,6 @@ BCMPOSTTRAPFN(ai_clear_backplane_to_per_core)(si_t *sih, uint coreid, uint coreu
|
|||
|
||||
case AIELS_DECODE:
|
||||
SI_PRINT(("AXI decode error\n"));
|
||||
#ifdef USE_HOSTMEM
|
||||
/* Ignore known cases of CR4 prefetch abort bugs */
|
||||
if ((errlog_id & (BCM_AXI_ID_MASK | BCM_AXI_ACCESS_TYPE_MASK)) !=
|
||||
(BCM43xx_AXI_ACCESS_TYPE_PREFETCH | BCM43xx_CR4_AXI_ID))
|
||||
#endif
|
||||
{
|
||||
ret |= AXI_WRAP_STS_DECODE_ERR;
|
||||
}
|
||||
|
|
@ -2236,7 +2239,7 @@ uint32
|
|||
BCMPOSTTRAPFN(ai_clear_backplane_to)(si_t *sih)
|
||||
{
|
||||
uint32 ret = 0;
|
||||
#if defined (AXI_TIMEOUTS) || defined (AXI_TIMEOUTS_NIC)
|
||||
#if defined(AXI_TIMEOUTS) || defined(AXI_TIMEOUTS_NIC)
|
||||
const si_info_t *sii = SI_INFO(sih);
|
||||
aidmp_t *ai;
|
||||
uint32 i;
|
||||
|
|
@ -2490,7 +2493,7 @@ BCMPOSTTRAPRAMFN(ai_get_wrapper_base_addr)(uint32 **offset)
|
|||
}
|
||||
|
||||
uint32
|
||||
BCMATTACHFN(ai_wrapper_dump_buf_size)(const si_t *sih)
|
||||
ai_wrapper_dump_buf_size(const si_t *sih)
|
||||
{
|
||||
uint32 buf_size = 0;
|
||||
uint32 wrapper_count = 0;
|
||||
|
|
@ -2539,7 +2542,7 @@ uint32
|
|||
BCMPOSTTRAPFN(ai_wrapper_dump_last_timeout)(const si_t *sih, uint32 *error, uint32 *core,
|
||||
uint32 *ba, uchar *p)
|
||||
{
|
||||
#if defined (AXI_TIMEOUTS) || defined (AXI_TIMEOUTS_NIC)
|
||||
#if defined(AXI_TIMEOUTS) || defined(AXI_TIMEOUTS_NIC)
|
||||
uint32 *p32;
|
||||
uint32 wrap_ba = last_axi_error_wrap;
|
||||
uint i;
|
||||
|
|
@ -2590,7 +2593,7 @@ BCMPOSTTRAPFN(ai_wrapper_dump_binary)(const si_t *sih, uchar *p)
|
|||
bool
|
||||
BCMPOSTTRAPFN(ai_check_enable_backplane_log)(const si_t *sih)
|
||||
{
|
||||
#if defined (AXI_TIMEOUTS) || defined (AXI_TIMEOUTS_NIC)
|
||||
#if defined(AXI_TIMEOUTS) || defined(AXI_TIMEOUTS_NIC)
|
||||
if (g_disable_backplane_logs) {
|
||||
return FALSE;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
* Contents are wifi-specific, used by any kernel or app-level
|
||||
* software that might want wifi things as it grows.
|
||||
*
|
||||
* Copyright (C) 2020, Broadcom.
|
||||
* Copyright (C) 2022, Broadcom.
|
||||
*
|
||||
* Unless you and Broadcom execute a separate written software license
|
||||
* agreement governing use of this software, this software is licensed to you
|
||||
|
|
@ -28,7 +28,9 @@
|
|||
#ifdef BCMDRIVER
|
||||
#include <osl.h>
|
||||
#define strtoul(nptr, endptr, base) bcm_strtoul((nptr), (endptr), (base))
|
||||
#ifndef tolower
|
||||
#define tolower(c) (bcm_isupper((c)) ? ((c) + 'a' - 'A') : (c))
|
||||
#endif /* tolower */
|
||||
#else /* BCMDRIVER */
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
|
@ -40,7 +42,7 @@
|
|||
#endif /* BCMDRIVER */
|
||||
#include <bcmwifi_channels.h>
|
||||
|
||||
#if defined(WIN32) && (defined(BCMDLL) || defined(WLMDLL))
|
||||
#if defined(WIN32) && (defined(BCMDLL) || defined(WLMDLL) || defined(_CONSOLE))
|
||||
#include <bcmstdlib.h> /* For wlexe/Makefile.wlm_dll */
|
||||
#endif
|
||||
|
||||
|
|
@ -109,33 +111,7 @@ cca_info(uint8 *bitmap, int num_bits, int *left, int *bit_pos)
|
|||
static uint8
|
||||
spec_to_chan(chanspec_t chspec)
|
||||
{
|
||||
uint8 center_ch, edge, primary, sb;
|
||||
|
||||
center_ch = CHSPEC_CHANNEL(chspec);
|
||||
|
||||
if (CHSPEC_IS20(chspec)) {
|
||||
return center_ch;
|
||||
} else {
|
||||
/* the lower edge of the wide channel is half the bw from
|
||||
* the center channel.
|
||||
*/
|
||||
if (CHSPEC_IS40(chspec)) {
|
||||
edge = center_ch - CH_20MHZ_APART;
|
||||
} else {
|
||||
/* must be 80MHz (until we support more) */
|
||||
ASSERT(CHSPEC_IS80(chspec));
|
||||
edge = center_ch - CH_40MHZ_APART;
|
||||
}
|
||||
|
||||
/* find the channel number of the lowest 20MHz primary channel */
|
||||
primary = edge + CH_10MHZ_APART;
|
||||
|
||||
/* select the actual subband */
|
||||
sb = (chspec & WL_CHANSPEC_CTL_SB_MASK) >> WL_CHANSPEC_CTL_SB_SHIFT;
|
||||
primary = primary + sb * CH_20MHZ_APART;
|
||||
|
||||
return primary;
|
||||
}
|
||||
return wf_chspec_primary20_chan(chspec);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -161,7 +137,7 @@ cca_analyze(cca_congest_channel_req_t *input[], int num_chans, uint flags, chans
|
|||
return BCME_NOMEM;
|
||||
}
|
||||
|
||||
memset(bitmap, 0, bitmap_sz);
|
||||
bzero(bitmap, bitmap_sz);
|
||||
/* Initially, all channels are up for consideration */
|
||||
for (i = 0; i < num_chans; i++) {
|
||||
if (input[i]->chanspec)
|
||||
|
|
@ -1180,8 +1156,8 @@ wl_cntbuf_to_xtlv_format(void *ctx, void *cntbuf, int buflen, uint32 corerev)
|
|||
}
|
||||
|
||||
#ifdef BCMDRIVER
|
||||
wlccnt = MALLOC(osh, sizeof(*wlccnt));
|
||||
macstat = MALLOC(osh, WL_CNT_MCST_STRUCT_SZ);
|
||||
wlccnt = MALLOCZ(osh, sizeof(*wlccnt));
|
||||
macstat = MALLOCZ(osh, WL_CNT_MCST_STRUCT_SZ);
|
||||
#else
|
||||
wlccnt = (wl_cnt_wlc_t *)malloc(sizeof(*wlccnt));
|
||||
macstat = (uint32 *)malloc(WL_CNT_MCST_STRUCT_SZ);
|
||||
|
|
@ -1251,7 +1227,7 @@ wl_cntbuf_to_xtlv_format(void *ctx, void *cntbuf, int buflen, uint32 corerev)
|
|||
xtlv_desc[2].len = 0;
|
||||
xtlv_desc[2].ptr = NULL;
|
||||
|
||||
memset(cntbuf, 0, buflen);
|
||||
bzero(cntbuf, buflen);
|
||||
|
||||
res = bcm_pack_xtlv_buf_from_mem(&xtlvbuf_p, &xtlvbuflen,
|
||||
xtlv_desc, BCM_XTLV_OPTION_ALIGN32);
|
||||
|
|
|
|||
|
|
@ -1,766 +0,0 @@
|
|||
/*
|
||||
* L2 Filter handling functions
|
||||
*
|
||||
* Copyright (C) 2020, Broadcom.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*
|
||||
* <<Broadcom-WL-IPTag/Dual:>>
|
||||
*
|
||||
*/
|
||||
#include <bcmutils.h>
|
||||
#include <bcmendian.h>
|
||||
#include <bcmdefs.h>
|
||||
#include <bcmdevs.h>
|
||||
#include <ethernet.h>
|
||||
#include <bcmip.h>
|
||||
#include <bcmipv6.h>
|
||||
#include <bcmudp.h>
|
||||
#include <bcmarp.h>
|
||||
#include <bcmicmp.h>
|
||||
#include <bcmproto.h>
|
||||
#include <bcmdhcp.h>
|
||||
#include <802.11.h>
|
||||
#include <bcm_l2_filter.h>
|
||||
|
||||
#ifdef BCMDBG_ERR
|
||||
#define L2_FILTER_ERROR(args) printf args
|
||||
#else
|
||||
#define L2_FILTER_ERROR(args)
|
||||
#endif /* BCMDBG_ERR */
|
||||
|
||||
#ifdef BCMDBG_MSG
|
||||
#define L2_FILTER_MSG(args) printf args
|
||||
#else
|
||||
#define L2_FILTER_MSG(args)
|
||||
#endif /* BCMDBG_msg */
|
||||
|
||||
struct arp_table {
|
||||
parp_entry_t *parp_table[BCM_PARP_TABLE_SIZE]; /* proxyarp entries in cache table */
|
||||
parp_entry_t *parp_candidate_list; /* proxyarp entries in candidate list */
|
||||
uint8 parp_smac[ETHER_ADDR_LEN]; /* L2 SMAC from DHCP Req */
|
||||
uint8 parp_cmac[ETHER_ADDR_LEN]; /* Bootp Client MAC from DHCP Req */
|
||||
};
|
||||
#ifdef DHD_DUMP_ARPTABLE
|
||||
void bcm_l2_parp_dump_table(arp_table_t* arp_tbl);
|
||||
|
||||
void
|
||||
bcm_l2_parp_dump_table(arp_table_t* arp_tbl)
|
||||
{
|
||||
parp_entry_t *entry;
|
||||
uint16 idx, ip_len;
|
||||
arp_table_t *ptable;
|
||||
ip_len = IPV4_ADDR_LEN;
|
||||
ptable = arp_tbl;
|
||||
for (idx = 0; idx < BCM_PARP_TABLE_SIZE; idx++) {
|
||||
entry = ptable->parp_table[idx];
|
||||
while (entry) {
|
||||
printf("Cached entries..\n");
|
||||
printf("%d: %d.%d.%d.%d", idx, entry->ip.data[0], entry->ip.data[1],
|
||||
entry->ip.data[2], entry->ip.data[3]);
|
||||
printf("%02x:%02x:%02x:%02x:%02x:%02x", entry->ea.octet[0],
|
||||
entry->ea.octet[1], entry->ea.octet[2], entry->ea.octet[3],
|
||||
entry->ea.octet[4], entry->ea.octet[5]);
|
||||
printf("\n");
|
||||
entry = entry->next;
|
||||
}
|
||||
}
|
||||
entry = ptable->parp_candidate_list;
|
||||
while (entry) {
|
||||
printf("Candidate entries..\n");
|
||||
printf("%d.%d.%d.%d", entry->ip.data[0], entry->ip.data[1],
|
||||
entry->ip.data[2], entry->ip.data[3]);
|
||||
printf("%02x:%02x:%02x:%02x:%02x:%02x", entry->ea.octet[0],
|
||||
entry->ea.octet[1], entry->ea.octet[2], entry->ea.octet[3],
|
||||
entry->ea.octet[4], entry->ea.octet[5]);
|
||||
|
||||
printf("\n");
|
||||
entry = entry->next;
|
||||
}
|
||||
}
|
||||
#endif /* DHD_DUMP_ARPTABLE */
|
||||
|
||||
arp_table_t* init_l2_filter_arp_table(osl_t* osh)
|
||||
{
|
||||
return ((arp_table_t*)MALLOCZ(osh, sizeof(arp_table_t)));
|
||||
}
|
||||
|
||||
void deinit_l2_filter_arp_table(osl_t* osh, arp_table_t* ptable)
|
||||
{
|
||||
MFREE(osh, ptable, sizeof(arp_table_t));
|
||||
}
|
||||
/* returns 0 if gratuitous ARP or unsolicited neighbour advertisement */
|
||||
int
|
||||
bcm_l2_filter_gratuitous_arp(osl_t *osh, void *pktbuf)
|
||||
{
|
||||
uint8 *frame = PKTDATA(osh, pktbuf);
|
||||
uint16 ethertype;
|
||||
int send_ip_offset, target_ip_offset;
|
||||
int iplen;
|
||||
int minlen;
|
||||
uint8 *data;
|
||||
int datalen;
|
||||
bool snap;
|
||||
|
||||
if (get_pkt_ether_type(osh, pktbuf, &data, &datalen, ðertype, &snap) != BCME_OK)
|
||||
return BCME_ERROR;
|
||||
|
||||
if (!ETHER_ISBCAST(frame + ETHER_DEST_OFFSET) &&
|
||||
bcmp(ðer_ipv6_mcast, frame + ETHER_DEST_OFFSET, sizeof(ether_ipv6_mcast))) {
|
||||
return BCME_ERROR;
|
||||
}
|
||||
|
||||
if (ethertype == ETHER_TYPE_ARP) {
|
||||
L2_FILTER_MSG(("bcm_l2_filter_gratuitous_arp: ARP RX data : %p: datalen : %d\n",
|
||||
data, datalen));
|
||||
send_ip_offset = ARP_SRC_IP_OFFSET;
|
||||
target_ip_offset = ARP_TGT_IP_OFFSET;
|
||||
iplen = IPV4_ADDR_LEN;
|
||||
minlen = ARP_DATA_LEN;
|
||||
} else if (ethertype == ETHER_TYPE_IPV6) {
|
||||
send_ip_offset = NEIGHBOR_ADVERTISE_SRC_IPV6_OFFSET;
|
||||
target_ip_offset = NEIGHBOR_ADVERTISE_TGT_IPV6_OFFSET;
|
||||
iplen = IPV6_ADDR_LEN;
|
||||
minlen = target_ip_offset + iplen;
|
||||
|
||||
/* check for neighbour advertisement */
|
||||
if (datalen >= minlen && (data[IPV6_NEXT_HDR_OFFSET] != IP_PROT_ICMP6 ||
|
||||
data[NEIGHBOR_ADVERTISE_TYPE_OFFSET] != NEIGHBOR_ADVERTISE_TYPE))
|
||||
return BCME_ERROR;
|
||||
|
||||
/* Dont drop Unsolicitated NA fm AP with allnode mcast dest addr (HS2-4.5.E) */
|
||||
if (datalen >= minlen &&
|
||||
(data[IPV6_NEXT_HDR_OFFSET] == IP_PROT_ICMP6) &&
|
||||
(data[NEIGHBOR_ADVERTISE_TYPE_OFFSET] == NEIGHBOR_ADVERTISE_TYPE) &&
|
||||
(data[NEIGHBOR_ADVERTISE_OPTION_OFFSET] == OPT_TYPE_TGT_LINK_ADDR)) {
|
||||
L2_FILTER_MSG(("Unsolicitated Neighbour Advertisement from AP "
|
||||
"with allnode mcast dest addr tx'ed (%d)\n", datalen));
|
||||
return -1;
|
||||
}
|
||||
|
||||
} else {
|
||||
return BCME_ERROR;
|
||||
}
|
||||
|
||||
if (datalen < minlen) {
|
||||
L2_FILTER_MSG(("BCM: dhd_gratuitous_arp: truncated packet (%d)\n", datalen));
|
||||
return BCME_ERROR;
|
||||
}
|
||||
|
||||
if (bcmp(data + send_ip_offset, data + target_ip_offset, iplen) == 0) {
|
||||
L2_FILTER_MSG((" returning BCME_OK in bcm_l2_filter_gratuitous_arp\n"));
|
||||
return BCME_OK;
|
||||
}
|
||||
|
||||
return BCME_ERROR;
|
||||
}
|
||||
int
|
||||
get_pkt_ether_type(osl_t *osh, void *pktbuf,
|
||||
uint8 **data_ptr, int *len_ptr, uint16 *et_ptr, bool *snap_ptr)
|
||||
{
|
||||
uint8 *frame = PKTDATA(osh, pktbuf);
|
||||
int length = PKTLEN(osh, pktbuf);
|
||||
uint8 *pt; /* Pointer to type field */
|
||||
uint16 ethertype;
|
||||
bool snap = FALSE;
|
||||
/* Process Ethernet II or SNAP-encapsulated 802.3 frames */
|
||||
if (length < ETHER_HDR_LEN) {
|
||||
L2_FILTER_MSG(("BCM: get_pkt_ether_type: short eth frame (%d)\n",
|
||||
length));
|
||||
return BCME_ERROR;
|
||||
} else if (ntoh16_ua(frame + ETHER_TYPE_OFFSET) >= ETHER_TYPE_MIN) {
|
||||
/* Frame is Ethernet II */
|
||||
pt = frame + ETHER_TYPE_OFFSET;
|
||||
} else if (length >= ETHER_HDR_LEN + SNAP_HDR_LEN + ETHER_TYPE_LEN &&
|
||||
!bcmp(llc_snap_hdr, frame + ETHER_HDR_LEN, SNAP_HDR_LEN)) {
|
||||
pt = frame + ETHER_HDR_LEN + SNAP_HDR_LEN;
|
||||
snap = TRUE;
|
||||
} else {
|
||||
L2_FILTER_MSG((" get_pkt_ether_type: non-SNAP 802.3 frame\n"));
|
||||
return BCME_ERROR;
|
||||
}
|
||||
|
||||
ethertype = ntoh16_ua(pt);
|
||||
|
||||
/* Skip VLAN tag, if any */
|
||||
if (ethertype == ETHER_TYPE_8021Q) {
|
||||
pt += VLAN_TAG_LEN;
|
||||
|
||||
if ((pt + ETHER_TYPE_LEN) > (frame + length)) {
|
||||
L2_FILTER_MSG(("BCM: get_pkt_ether_type: short VLAN frame (%d)\n",
|
||||
length));
|
||||
return BCME_ERROR;
|
||||
}
|
||||
ethertype = ntoh16_ua(pt);
|
||||
}
|
||||
*data_ptr = pt + ETHER_TYPE_LEN;
|
||||
*len_ptr = length - (int32)(pt + ETHER_TYPE_LEN - frame);
|
||||
*et_ptr = ethertype;
|
||||
*snap_ptr = snap;
|
||||
return BCME_OK;
|
||||
}
|
||||
|
||||
int
|
||||
get_pkt_ip_type(osl_t *osh, void *pktbuf,
|
||||
uint8 **data_ptr, int *len_ptr, uint8 *prot_ptr)
|
||||
{
|
||||
struct ipv4_hdr *iph; /* IP frame pointer */
|
||||
int iplen; /* IP frame length */
|
||||
uint16 ethertype, iphdrlen, ippktlen;
|
||||
uint16 iph_frag;
|
||||
uint8 prot;
|
||||
bool snap;
|
||||
|
||||
if (get_pkt_ether_type(osh, pktbuf, (uint8 **)&iph,
|
||||
&iplen, ðertype, &snap) != 0)
|
||||
return BCME_ERROR;
|
||||
|
||||
if (ethertype != ETHER_TYPE_IP) {
|
||||
return BCME_ERROR;
|
||||
}
|
||||
|
||||
/* We support IPv4 only */
|
||||
if (iplen < IPV4_OPTIONS_OFFSET || (IP_VER(iph) != IP_VER_4)) {
|
||||
return BCME_ERROR;
|
||||
}
|
||||
|
||||
/* Header length sanity */
|
||||
iphdrlen = IPV4_HLEN(iph);
|
||||
|
||||
/*
|
||||
* Packet length sanity; sometimes we receive eth-frame size bigger
|
||||
* than the IP content, which results in a bad tcp chksum
|
||||
*/
|
||||
ippktlen = ntoh16(iph->tot_len);
|
||||
if (ippktlen < iplen) {
|
||||
L2_FILTER_MSG(("get_pkt_ip_type: extra frame length ignored\n"));
|
||||
iplen = ippktlen;
|
||||
} else if (ippktlen > iplen) {
|
||||
L2_FILTER_MSG(("get_pkt_ip_type: truncated IP packet (%d)\n",
|
||||
ippktlen - iplen));
|
||||
return BCME_ERROR;
|
||||
}
|
||||
|
||||
if (iphdrlen < IPV4_OPTIONS_OFFSET || iphdrlen > iplen) {
|
||||
L2_FILTER_ERROR((" get_pkt_ip_type: IP-header-len (%d) out of range (%d-%d)\n",
|
||||
iphdrlen, IPV4_OPTIONS_OFFSET, iplen));
|
||||
return BCME_ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
* We don't handle fragmented IP packets. A first frag is indicated by the MF
|
||||
* (more frag) bit and a subsequent frag is indicated by a non-zero frag offset.
|
||||
*/
|
||||
iph_frag = ntoh16(iph->frag);
|
||||
|
||||
if ((iph_frag & IPV4_FRAG_MORE) || (iph_frag & IPV4_FRAG_OFFSET_MASK) != 0) {
|
||||
L2_FILTER_ERROR(("get_pkt_ip_type: IP fragment not handled\n"));
|
||||
return BCME_ERROR;
|
||||
}
|
||||
prot = IPV4_PROT(iph);
|
||||
*data_ptr = (((uint8 *)iph) + iphdrlen);
|
||||
*len_ptr = iplen - iphdrlen;
|
||||
*prot_ptr = prot;
|
||||
return BCME_OK;
|
||||
}
|
||||
|
||||
/* Check if packet type is ICMP ECHO */
|
||||
int bcm_l2_filter_block_ping(osl_t *osh, void *pktbuf)
|
||||
{
|
||||
struct bcmicmp_hdr *icmph;
|
||||
int udpl;
|
||||
uint8 prot;
|
||||
|
||||
if (get_pkt_ip_type(osh, pktbuf, (uint8 **)&icmph, &udpl, &prot) != 0)
|
||||
return BCME_ERROR;
|
||||
if (prot == IP_PROT_ICMP) {
|
||||
if (icmph->type == ICMP_TYPE_ECHO_REQUEST)
|
||||
return BCME_OK;
|
||||
}
|
||||
return BCME_ERROR;
|
||||
}
|
||||
|
||||
int bcm_l2_filter_get_mac_addr_dhcp_pkt(osl_t *osh, void *pktbuf,
|
||||
int ifidx, uint8** mac_addr)
|
||||
{
|
||||
uint8 *eh = PKTDATA(osh, pktbuf);
|
||||
uint8 *udph;
|
||||
uint8 *dhcp;
|
||||
int udpl;
|
||||
int dhcpl;
|
||||
uint16 port;
|
||||
uint8 prot;
|
||||
|
||||
if (!ETHER_ISMULTI(eh + ETHER_DEST_OFFSET))
|
||||
return BCME_ERROR;
|
||||
if (get_pkt_ip_type(osh, pktbuf, &udph, &udpl, &prot) != 0)
|
||||
return BCME_ERROR;
|
||||
if (prot != IP_PROT_UDP)
|
||||
return BCME_ERROR;
|
||||
/* check frame length, at least UDP_HDR_LEN */
|
||||
if (udpl < UDP_HDR_LEN) {
|
||||
L2_FILTER_MSG(("BCM: bcm_l2_filter_get_mac_addr_dhcp_pkt: short UDP frame,"
|
||||
" ignored\n"));
|
||||
return BCME_ERROR;
|
||||
}
|
||||
port = ntoh16_ua(udph + UDP_DEST_PORT_OFFSET);
|
||||
/* only process DHCP packets from server to client */
|
||||
if (port != DHCP_PORT_CLIENT)
|
||||
return BCME_ERROR;
|
||||
|
||||
dhcp = udph + UDP_HDR_LEN;
|
||||
dhcpl = udpl - UDP_HDR_LEN;
|
||||
|
||||
if (dhcpl < DHCP_CHADDR_OFFSET + ETHER_ADDR_LEN) {
|
||||
L2_FILTER_MSG(("BCM: bcm_l2_filter_get_mac_addr_dhcp_pkt: short DHCP frame,"
|
||||
" ignored\n"));
|
||||
return BCME_ERROR;
|
||||
}
|
||||
/* only process DHCP reply(offer/ack) packets */
|
||||
if (*(dhcp + DHCP_TYPE_OFFSET) != DHCP_TYPE_REPLY)
|
||||
return BCME_ERROR;
|
||||
/* chaddr = dhcp + DHCP_CHADDR_OFFSET; */
|
||||
*mac_addr = dhcp + DHCP_CHADDR_OFFSET;
|
||||
return BCME_OK;
|
||||
}
|
||||
/* modify the mac address for IP, in arp table */
|
||||
int
|
||||
bcm_l2_filter_parp_modifyentry(arp_table_t* arp_tbl, struct ether_addr *ea,
|
||||
uint8 *ip, uint8 ip_ver, bool cached, unsigned int entry_tickcnt)
|
||||
{
|
||||
parp_entry_t *entry;
|
||||
uint8 idx, ip_len;
|
||||
arp_table_t *ptable;
|
||||
|
||||
if (ip_ver == IP_VER_4 && !IPV4_ADDR_NULL(ip) && !IPV4_ADDR_BCAST(ip)) {
|
||||
idx = BCM_PARP_TABLE_INDEX(ip[IPV4_ADDR_LEN - 1]);
|
||||
ip_len = IPV4_ADDR_LEN;
|
||||
}
|
||||
else if (ip_ver == IP_VER_6 && !IPV6_ADDR_NULL(ip)) {
|
||||
idx = BCM_PARP_TABLE_INDEX(ip[IPV6_ADDR_LEN - 1]);
|
||||
ip_len = IPV6_ADDR_LEN;
|
||||
}
|
||||
else {
|
||||
return BCME_ERROR;
|
||||
}
|
||||
|
||||
ptable = arp_tbl;
|
||||
if (cached) {
|
||||
entry = ptable->parp_table[idx];
|
||||
} else {
|
||||
entry = ptable->parp_candidate_list;
|
||||
}
|
||||
while (entry) {
|
||||
if (bcmp(entry->ip.data, ip, ip_len) == 0) {
|
||||
/* entry matches, overwrite mac content and return */
|
||||
bcopy((void *)ea, (void *)&entry->ea, ETHER_ADDR_LEN);
|
||||
entry->used = entry_tickcnt;
|
||||
#ifdef DHD_DUMP_ARPTABLE
|
||||
bcm_l2_parp_dump_table(arp_tbl);
|
||||
#endif
|
||||
return BCME_OK;
|
||||
}
|
||||
entry = entry->next;
|
||||
}
|
||||
#ifdef DHD_DUMP_ARPTABLE
|
||||
bcm_l2_parp_dump_table(arp_tbl);
|
||||
#endif
|
||||
return BCME_ERROR;
|
||||
}
|
||||
|
||||
/* Add the IP entry in ARP table based on Cached argument, if cached argument is
|
||||
* non zero positive value: it adds to parp_table, else adds to
|
||||
* parp_candidate_list
|
||||
*/
|
||||
int
|
||||
bcm_l2_filter_parp_addentry(osl_t *osh, arp_table_t* arp_tbl, struct ether_addr *ea,
|
||||
uint8 *ip, uint8 ip_ver, bool cached, unsigned int entry_tickcnt)
|
||||
{
|
||||
parp_entry_t *entry;
|
||||
uint8 idx, ip_len;
|
||||
arp_table_t *ptable;
|
||||
|
||||
if (ip_ver == IP_VER_4 && !IPV4_ADDR_NULL(ip) && !IPV4_ADDR_BCAST(ip)) {
|
||||
idx = BCM_PARP_TABLE_INDEX(ip[IPV4_ADDR_LEN - 1]);
|
||||
ip_len = IPV4_ADDR_LEN;
|
||||
}
|
||||
else if (ip_ver == IP_VER_6 && !IPV6_ADDR_NULL(ip)) {
|
||||
idx = BCM_PARP_TABLE_INDEX(ip[IPV6_ADDR_LEN - 1]);
|
||||
ip_len = IPV6_ADDR_LEN;
|
||||
}
|
||||
else {
|
||||
return BCME_ERROR;
|
||||
}
|
||||
|
||||
if ((entry = MALLOCZ(osh, sizeof(parp_entry_t) + ip_len)) == NULL) {
|
||||
L2_FILTER_MSG(("Allocating new parp_entry for IPv%d failed!!\n", ip_ver));
|
||||
return BCME_NOMEM;
|
||||
}
|
||||
|
||||
bcopy((void *)ea, (void *)&entry->ea, ETHER_ADDR_LEN);
|
||||
entry->used = entry_tickcnt;
|
||||
entry->ip.id = ip_ver;
|
||||
entry->ip.len = ip_len;
|
||||
bcopy(ip, entry->ip.data, ip_len);
|
||||
ptable = arp_tbl;
|
||||
if (cached) {
|
||||
entry->next = ptable->parp_table[idx];
|
||||
ptable->parp_table[idx] = entry;
|
||||
} else {
|
||||
entry->next = ptable->parp_candidate_list;
|
||||
ptable->parp_candidate_list = entry;
|
||||
}
|
||||
#ifdef DHD_DUMP_ARPTABLE
|
||||
bcm_l2_parp_dump_table(arp_tbl);
|
||||
#endif
|
||||
return BCME_OK;
|
||||
}
|
||||
|
||||
/* Delete the IP entry in ARP table based on Cached argument, if cached argument is
|
||||
* non zero positive value: it delete from parp_table, else delete from
|
||||
* parp_candidate_list
|
||||
*/
|
||||
int
|
||||
bcm_l2_filter_parp_delentry(osl_t* osh, arp_table_t *arp_tbl, struct ether_addr *ea,
|
||||
uint8 *ip, uint8 ip_ver, bool cached)
|
||||
{
|
||||
parp_entry_t *entry, *prev = NULL;
|
||||
uint8 idx, ip_len;
|
||||
arp_table_t *ptable;
|
||||
|
||||
if (ip_ver == IP_VER_4) {
|
||||
idx = BCM_PARP_TABLE_INDEX(ip[IPV4_ADDR_LEN - 1]);
|
||||
ip_len = IPV4_ADDR_LEN;
|
||||
}
|
||||
else if (ip_ver == IP_VER_6) {
|
||||
idx = BCM_PARP_TABLE_INDEX(ip[IPV6_ADDR_LEN - 1]);
|
||||
ip_len = IPV6_ADDR_LEN;
|
||||
}
|
||||
else {
|
||||
return BCME_ERROR;
|
||||
}
|
||||
ptable = arp_tbl;
|
||||
if (cached) {
|
||||
entry = ptable->parp_table[idx];
|
||||
} else {
|
||||
entry = ptable->parp_candidate_list;
|
||||
}
|
||||
while (entry) {
|
||||
if (entry->ip.id == ip_ver &&
|
||||
bcmp(entry->ip.data, ip, ip_len) == 0 &&
|
||||
bcmp(&entry->ea, ea, ETHER_ADDR_LEN) == 0) {
|
||||
if (prev == NULL) {
|
||||
if (cached) {
|
||||
ptable->parp_table[idx] = entry->next;
|
||||
} else {
|
||||
ptable->parp_candidate_list = entry->next;
|
||||
}
|
||||
} else {
|
||||
prev->next = entry->next;
|
||||
}
|
||||
break;
|
||||
}
|
||||
prev = entry;
|
||||
entry = entry->next;
|
||||
}
|
||||
if (entry != NULL)
|
||||
MFREE(osh, entry, sizeof(parp_entry_t) + ip_len);
|
||||
#ifdef DHD_DUMP_ARPTABLE
|
||||
bcm_l2_parp_dump_table(arp_tbl);
|
||||
#endif
|
||||
return BCME_OK;
|
||||
}
|
||||
|
||||
/* search the IP entry in ARP table based on Cached argument, if cached argument is
|
||||
* non zero positive value: it searches from parp_table, else search from
|
||||
* parp_candidate_list
|
||||
*/
|
||||
parp_entry_t *
|
||||
bcm_l2_filter_parp_findentry(arp_table_t* arp_tbl, uint8 *ip, uint8 ip_ver, bool cached,
|
||||
unsigned int entry_tickcnt)
|
||||
{
|
||||
parp_entry_t *entry;
|
||||
uint8 idx, ip_len;
|
||||
arp_table_t *ptable;
|
||||
|
||||
if (ip_ver == IP_VER_4) {
|
||||
idx = BCM_PARP_TABLE_INDEX(ip[IPV4_ADDR_LEN - 1]);
|
||||
ip_len = IPV4_ADDR_LEN;
|
||||
} else if (ip_ver == IP_VER_6) {
|
||||
idx = BCM_PARP_TABLE_INDEX(ip[IPV6_ADDR_LEN - 1]);
|
||||
ip_len = IPV6_ADDR_LEN;
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
ptable = arp_tbl;
|
||||
if (cached) {
|
||||
entry = ptable->parp_table[idx];
|
||||
} else {
|
||||
entry = ptable->parp_candidate_list;
|
||||
}
|
||||
while (entry) {
|
||||
if (entry->ip.id == ip_ver && bcmp(entry->ip.data, ip, ip_len) == 0) {
|
||||
/* time stamp of adding the station entry to arp table for ifp */
|
||||
entry->used = entry_tickcnt;
|
||||
break;
|
||||
}
|
||||
entry = entry->next;
|
||||
}
|
||||
return entry;
|
||||
}
|
||||
|
||||
/* update arp table entries for every proxy arp enable interface */
|
||||
void
|
||||
bcm_l2_filter_arp_table_update(osl_t *osh, arp_table_t* arp_tbl, bool all, uint8 *del_ea,
|
||||
bool periodic, unsigned int tickcnt)
|
||||
{
|
||||
parp_entry_t *prev, *entry, *delentry;
|
||||
uint8 idx, ip_ver;
|
||||
struct ether_addr ea;
|
||||
uint8 ip[IPV6_ADDR_LEN];
|
||||
arp_table_t *ptable;
|
||||
|
||||
ptable = arp_tbl;
|
||||
for (idx = 0; idx < BCM_PARP_TABLE_SIZE; idx++) {
|
||||
entry = ptable->parp_table[idx];
|
||||
while (entry) {
|
||||
/* check if the entry need to be removed */
|
||||
if (all || (periodic && BCM_PARP_IS_TIMEOUT(tickcnt, entry)) ||
|
||||
(del_ea != NULL && !bcmp(del_ea, &entry->ea, ETHER_ADDR_LEN))) {
|
||||
/* copy frame here */
|
||||
ip_ver = entry->ip.id;
|
||||
bcopy(entry->ip.data, ip, entry->ip.len);
|
||||
bcopy(&entry->ea, &ea, ETHER_ADDR_LEN);
|
||||
entry = entry->next;
|
||||
bcm_l2_filter_parp_delentry(osh, ptable, &ea, ip, ip_ver, TRUE);
|
||||
}
|
||||
else {
|
||||
entry = entry->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* remove candidate or promote to real entry */
|
||||
prev = delentry = NULL;
|
||||
entry = ptable->parp_candidate_list;
|
||||
while (entry) {
|
||||
/* remove candidate */
|
||||
if (all || (periodic && BCM_PARP_ANNOUNCE_WAIT_REACH(tickcnt, entry)) ||
|
||||
(del_ea != NULL && !bcmp(del_ea, (uint8 *)&entry->ea, ETHER_ADDR_LEN))) {
|
||||
bool promote = (periodic && BCM_PARP_ANNOUNCE_WAIT_REACH(tickcnt, entry)) ?
|
||||
TRUE: FALSE;
|
||||
parp_entry_t *node = NULL;
|
||||
|
||||
ip_ver = entry->ip.id;
|
||||
|
||||
if (prev == NULL)
|
||||
ptable->parp_candidate_list = entry->next;
|
||||
else
|
||||
prev->next = entry->next;
|
||||
|
||||
node = bcm_l2_filter_parp_findentry(ptable,
|
||||
entry->ip.data, IP_VER_6, TRUE, tickcnt);
|
||||
if (promote && node == NULL) {
|
||||
bcm_l2_filter_parp_addentry(osh, ptable, &entry->ea,
|
||||
entry->ip.data, entry->ip.id, TRUE, tickcnt);
|
||||
}
|
||||
MFREE(osh, entry, sizeof(parp_entry_t) + entry->ip.len);
|
||||
if (prev == NULL) {
|
||||
entry = ptable->parp_candidate_list;
|
||||
} else {
|
||||
entry = prev->next;
|
||||
}
|
||||
}
|
||||
else {
|
||||
prev = entry;
|
||||
entry = entry->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* create 42 byte ARP packet for ARP response, aligned the Buffer */
|
||||
void *
|
||||
bcm_l2_filter_proxyarp_alloc_reply(osl_t* osh, uint16 pktlen, struct ether_addr *src_ea,
|
||||
struct ether_addr *dst_ea, uint16 ea_type, bool snap, void **p)
|
||||
{
|
||||
void *pkt;
|
||||
uint8 *frame;
|
||||
|
||||
/* adjust pktlen since skb->data is aligned to 2 */
|
||||
pktlen += ALIGN_ADJ_BUFLEN;
|
||||
|
||||
if ((pkt = PKTGET(osh, pktlen, FALSE)) == NULL) {
|
||||
L2_FILTER_ERROR(("bcm_l2_filter_proxyarp_alloc_reply: PKTGET failed\n"));
|
||||
return NULL;
|
||||
}
|
||||
/* adjust for pkt->data aligned */
|
||||
PKTPULL(osh, pkt, ALIGN_ADJ_BUFLEN);
|
||||
frame = PKTDATA(osh, pkt);
|
||||
|
||||
/* Create 14-byte eth header, plus snap header if applicable */
|
||||
bcopy(src_ea, frame + ETHER_SRC_OFFSET, ETHER_ADDR_LEN);
|
||||
bcopy(dst_ea, frame + ETHER_DEST_OFFSET, ETHER_ADDR_LEN);
|
||||
if (snap) {
|
||||
hton16_ua_store(pktlen, frame + ETHER_TYPE_OFFSET);
|
||||
bcopy(llc_snap_hdr, frame + ETHER_HDR_LEN, SNAP_HDR_LEN);
|
||||
hton16_ua_store(ea_type, frame + ETHER_HDR_LEN + SNAP_HDR_LEN);
|
||||
} else
|
||||
hton16_ua_store(ea_type, frame + ETHER_TYPE_OFFSET);
|
||||
|
||||
*p = (void *)(frame + ETHER_HDR_LEN + (snap ? SNAP_HDR_LEN + ETHER_TYPE_LEN : 0));
|
||||
return pkt;
|
||||
}
|
||||
/* copy the smac entry from parp_table */
|
||||
void bcm_l2_filter_parp_get_smac(arp_table_t* ptable, void* smac)
|
||||
{
|
||||
bcopy(ptable->parp_smac, smac, ETHER_ADDR_LEN);
|
||||
}
|
||||
/* copy the cmac entry from parp_table */
|
||||
void bcm_l2_filter_parp_get_cmac(arp_table_t* ptable, void* cmac)
|
||||
{
|
||||
bcopy(ptable->parp_cmac, cmac, ETHER_ADDR_LEN);
|
||||
}
|
||||
/* copy the smac entry to smac entry in parp_table */
|
||||
void bcm_l2_filter_parp_set_smac(arp_table_t* ptable, void* smac)
|
||||
{
|
||||
bcopy(smac, ptable->parp_smac, ETHER_ADDR_LEN);
|
||||
}
|
||||
/* copy the cmac entry to cmac entry in parp_table */
|
||||
void bcm_l2_filter_parp_set_cmac(arp_table_t* ptable, void* cmac)
|
||||
{
|
||||
bcopy(cmac, ptable->parp_cmac, ETHER_ADDR_LEN);
|
||||
}
|
||||
|
||||
uint16
|
||||
calc_checksum(uint8 *src_ipa, uint8 *dst_ipa, uint32 ul_len, uint8 prot, uint8 *ul_data)
|
||||
{
|
||||
uint16 *startpos;
|
||||
uint32 sum = 0;
|
||||
int i;
|
||||
uint16 answer = 0;
|
||||
|
||||
if (src_ipa) {
|
||||
uint8 ph[8] = {0, };
|
||||
for (i = 0; i < (IPV6_ADDR_LEN / 2); i++) {
|
||||
sum += *((uint16 *)src_ipa);
|
||||
src_ipa += 2;
|
||||
}
|
||||
|
||||
for (i = 0; i < (IPV6_ADDR_LEN / 2); i++) {
|
||||
sum += *((uint16 *)dst_ipa);
|
||||
dst_ipa += 2;
|
||||
}
|
||||
|
||||
*((uint32 *)ph) = hton32(ul_len);
|
||||
*((uint32 *)(ph+4)) = 0;
|
||||
ph[7] = prot;
|
||||
startpos = (uint16 *)ph;
|
||||
for (i = 0; i < 4; i++) {
|
||||
sum += *startpos++;
|
||||
}
|
||||
}
|
||||
|
||||
startpos = (uint16 *)ul_data;
|
||||
while (ul_len > 1) {
|
||||
sum += *startpos++;
|
||||
ul_len -= 2;
|
||||
}
|
||||
|
||||
if (ul_len == 1) {
|
||||
*((uint8 *)(&answer)) = *((uint8 *)startpos);
|
||||
sum += answer;
|
||||
}
|
||||
|
||||
sum = (sum >> 16) + (sum & 0xffff);
|
||||
sum += (sum >> 16);
|
||||
answer = ~sum;
|
||||
|
||||
return answer;
|
||||
}
|
||||
/*
|
||||
* The length of the option including
|
||||
* the type and length fields in units of 8 octets
|
||||
*/
|
||||
bcm_tlv_t *
|
||||
parse_nd_options(void *buf, int buflen, uint key)
|
||||
{
|
||||
bcm_tlv_t *elt;
|
||||
int totlen;
|
||||
|
||||
elt = (bcm_tlv_t*)buf;
|
||||
totlen = buflen;
|
||||
|
||||
/* find tagged parameter */
|
||||
while (totlen >= TLV_HDR_LEN) {
|
||||
int len = elt->len * 8;
|
||||
|
||||
/* validate remaining totlen */
|
||||
if ((elt->id == key) &&
|
||||
(totlen >= len))
|
||||
return (elt);
|
||||
|
||||
elt = (bcm_tlv_t*)((uint8*)elt + len);
|
||||
totlen -= len;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* returns 0 if tdls set up request or tdls discovery request */
|
||||
int
|
||||
bcm_l2_filter_block_tdls(osl_t *osh, void *pktbuf)
|
||||
{
|
||||
uint16 ethertype;
|
||||
uint8 *data;
|
||||
int datalen;
|
||||
bool snap;
|
||||
uint8 action_field;
|
||||
|
||||
if (get_pkt_ether_type(osh, pktbuf, &data, &datalen, ðertype, &snap) != BCME_OK)
|
||||
return BCME_ERROR;
|
||||
|
||||
if (ethertype != ETHER_TYPE_89_0D)
|
||||
return BCME_ERROR;
|
||||
|
||||
/* validate payload type */
|
||||
if (datalen < TDLS_PAYLOAD_TYPE_LEN + 2) {
|
||||
L2_FILTER_ERROR(("bcm_l2_filter_block_tdls: wrong length for 89-0d eth frame %d\n",
|
||||
datalen));
|
||||
return BCME_ERROR;
|
||||
}
|
||||
|
||||
/* validate payload type */
|
||||
if (*data != TDLS_PAYLOAD_TYPE) {
|
||||
L2_FILTER_ERROR(("bcm_l2_filter_block_tdls: wrong payload type for 89-0d"
|
||||
" eth frame %d\n",
|
||||
*data));
|
||||
return BCME_ERROR;
|
||||
}
|
||||
data += TDLS_PAYLOAD_TYPE_LEN;
|
||||
|
||||
/* validate TDLS action category */
|
||||
if (*data != TDLS_ACTION_CATEGORY_CODE) {
|
||||
L2_FILTER_ERROR(("bcm_l2_filter_block_tdls: wrong TDLS Category %d\n", *data));
|
||||
return BCME_ERROR;
|
||||
}
|
||||
data++;
|
||||
|
||||
action_field = *data;
|
||||
|
||||
if ((action_field == TDLS_SETUP_REQ) || (action_field == TDLS_DISCOVERY_REQ))
|
||||
return BCME_OK;
|
||||
|
||||
return BCME_ERROR;
|
||||
}
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* Bloom filter support
|
||||
*
|
||||
* Copyright (C) 2020, Broadcom.
|
||||
* Copyright (C) 2022, Broadcom.
|
||||
*
|
||||
* Unless you and Broadcom execute a separate written software license
|
||||
* agreement governing use of this software, this software is licensed to you
|
||||
|
|
@ -24,16 +24,13 @@
|
|||
#include <typedefs.h>
|
||||
#include <bcmdefs.h>
|
||||
|
||||
#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 16, 0))
|
||||
#include <stdarg.h>
|
||||
#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(5, 16, 0) */
|
||||
|
||||
#ifdef BCMDRIVER
|
||||
#include <osl.h>
|
||||
#include <bcmutils.h>
|
||||
#else /* !BCMDRIVER */
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#ifndef ASSERT
|
||||
#define ASSERT(exp)
|
||||
#endif
|
||||
|
|
@ -71,7 +68,7 @@ bcm_bloom_create(bcm_bloom_alloc_t alloc_cb,
|
|||
err = BCME_NOMEM;
|
||||
goto done;
|
||||
}
|
||||
memset(bp, 0, sizeof(*bp));
|
||||
bzero(bp, sizeof(*bp));
|
||||
|
||||
bp->cb_ctx = cb_ctx;
|
||||
bp->max_hash = max_hash;
|
||||
|
|
@ -80,7 +77,7 @@ bcm_bloom_create(bcm_bloom_alloc_t alloc_cb,
|
|||
err = BCME_NOMEM;
|
||||
goto done;
|
||||
}
|
||||
memset(bp->hash, 0, sizeof(*bp->hash) * max_hash);
|
||||
bzero(bp->hash, sizeof(*bp->hash) * max_hash);
|
||||
|
||||
if (filter_size > 0) {
|
||||
bp->filter = (*alloc_cb)(cb_ctx, filter_size);
|
||||
|
|
@ -89,7 +86,7 @@ bcm_bloom_create(bcm_bloom_alloc_t alloc_cb,
|
|||
goto done;
|
||||
}
|
||||
bp->filter_size = filter_size;
|
||||
memset(bp->filter, 0, filter_size);
|
||||
bzero(bp->filter, filter_size);
|
||||
}
|
||||
|
||||
*bloom = bp;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* bcmevent read-only data shared by kernel or app layers
|
||||
*
|
||||
* Copyright (C) 2020, Broadcom.
|
||||
* Copyright (C) 2022, Broadcom.
|
||||
*
|
||||
* Unless you and Broadcom execute a separate written software license
|
||||
* agreement governing use of this software, this software is licensed to you
|
||||
|
|
@ -28,6 +28,7 @@
|
|||
#include <bcmeth.h>
|
||||
#include <bcmevent.h>
|
||||
#include <802.11.h>
|
||||
#include <802.11brcm.h>
|
||||
|
||||
/* Table of event name strings for UIs and debugging dumps */
|
||||
typedef struct {
|
||||
|
|
@ -179,9 +180,6 @@ static const bcmevent_name_str_t bcmevent_names[] = {
|
|||
#endif
|
||||
BCMEVENT_NAME(WLC_E_PSTA_PRIMARY_INTF_IND),
|
||||
BCMEVENT_NAME(WLC_E_TXFAIL_THRESH),
|
||||
#ifdef WLAIBSS
|
||||
BCMEVENT_NAME(WLC_E_AIBSS_TXFAIL),
|
||||
#endif /* WLAIBSS */
|
||||
#ifdef GSCAN_SUPPORT
|
||||
BCMEVENT_NAME(WLC_E_PFN_GSCAN_FULL_RESULT),
|
||||
BCMEVENT_NAME(WLC_E_PFN_SSID_EXT),
|
||||
|
|
@ -189,21 +187,12 @@ static const bcmevent_name_str_t bcmevent_names[] = {
|
|||
#ifdef WLBSSLOAD_REPORT
|
||||
BCMEVENT_NAME(WLC_E_BSS_LOAD),
|
||||
#endif
|
||||
#if defined(BT_WIFI_HANDOVER) || defined(WL_TBOW)
|
||||
BCMEVENT_NAME(WLC_E_BT_WIFI_HANDOVER_REQ),
|
||||
#endif
|
||||
#ifdef WLFBT
|
||||
BCMEVENT_NAME(WLC_E_FBT),
|
||||
#endif /* WLFBT */
|
||||
BCMEVENT_NAME(WLC_E_AUTHORIZED),
|
||||
BCMEVENT_NAME(WLC_E_PROBREQ_MSG_RX),
|
||||
|
||||
#ifdef WLAWDL
|
||||
BCMEVENT_NAME(WLC_E_AWDL_AW),
|
||||
BCMEVENT_NAME(WLC_E_AWDL_ROLE),
|
||||
BCMEVENT_NAME(WLC_E_AWDL_EVENT),
|
||||
#endif /* WLAWDL */
|
||||
|
||||
BCMEVENT_NAME(WLC_E_CSA_START_IND),
|
||||
BCMEVENT_NAME(WLC_E_CSA_DONE_IND),
|
||||
BCMEVENT_NAME(WLC_E_CSA_FAILURE_IND),
|
||||
|
|
@ -237,14 +226,27 @@ static const bcmevent_name_str_t bcmevent_names[] = {
|
|||
BCMEVENT_NAME(WLC_E_ROAM_CACHE_UPDATE),
|
||||
BCMEVENT_NAME(WLC_E_AP_BCN_DRIFT),
|
||||
BCMEVENT_NAME(WLC_E_PFN_SCAN_ALLGONE_EXT),
|
||||
#ifdef WL_CLIENT_SAE
|
||||
BCMEVENT_NAME(WLC_E_AUTH_START),
|
||||
#endif /* WL_CLIENT_SAE */
|
||||
#ifdef WL_TWT
|
||||
BCMEVENT_NAME(WLC_E_TWT_SETUP),
|
||||
BCMEVENT_NAME(WLC_E_TWT_TEARDOWN),
|
||||
BCMEVENT_NAME(WLC_E_TWT_INFO_FRM)
|
||||
BCMEVENT_NAME(WLC_E_TWT),
|
||||
#endif /* WL_TWT */
|
||||
BCMEVENT_NAME(WLC_E_AMT),
|
||||
BCMEVENT_NAME(WLC_E_ROAM_SCAN_RESULT),
|
||||
#if defined(XRAPI)
|
||||
BCMEVENT_NAME(WLC_E_XR_SOFTAP_PSMODE),
|
||||
#endif /* XRAPI */
|
||||
#ifdef WL_SIB_COEX
|
||||
BCMEVENT_NAME(WLC_E_SIB),
|
||||
#endif /* WL_SIB_COEX */
|
||||
BCMEVENT_NAME(WLC_E_MSCS),
|
||||
BCMEVENT_NAME(WLC_E_RXDMA_RECOVERY_ATMPT),
|
||||
#ifdef WL_SCHED_SCAN
|
||||
BCMEVENT_NAME(WLC_E_PFN_PARTIAL_RESULT),
|
||||
#endif /* WL_SCHED_SCAN */
|
||||
BCMEVENT_NAME(WLC_E_MLO_LINK_INFO),
|
||||
BCMEVENT_NAME(WLC_E_C2C),
|
||||
BCMEVENT_NAME(WLC_E_BCN_TSF),
|
||||
BCMEVENT_NAME(WLC_E_OWE_INFO),
|
||||
BCMEVENT_NAME(WLC_E_ULMU_DISABLED_REASON_UPD),
|
||||
};
|
||||
|
||||
const char *bcmevent_get_name(uint event_type)
|
||||
|
|
@ -396,7 +398,8 @@ is_wlc_event_frame(void *pktdata, uint pktlen, uint16 exp_usr_subtype,
|
|||
|
||||
if (out_event) {
|
||||
/* ensure BRCM event pkt aligned */
|
||||
memcpy(&out_event->event, &bcm_event->event, sizeof(wl_event_msg_t));
|
||||
(void)memcpy_s(&out_event->event, sizeof(out_event->event),
|
||||
&bcm_event->event, sizeof(out_event->event));
|
||||
}
|
||||
|
||||
break;
|
||||
|
|
@ -424,8 +427,9 @@ is_wlc_event_frame(void *pktdata, uint pktlen, uint16 exp_usr_subtype,
|
|||
|
||||
if (out_event) {
|
||||
/* ensure BRCM dngl event pkt aligned */
|
||||
memcpy(&out_event->dngl_event, &((bcm_dngl_event_t *)pktdata)->dngl_event,
|
||||
sizeof(bcm_dngl_event_msg_t));
|
||||
(void)memcpy_s(&out_event->dngl_event, sizeof(out_event->dngl_event),
|
||||
&((bcm_dngl_event_t *)pktdata)->dngl_event,
|
||||
sizeof(out_event->dngl_event));
|
||||
}
|
||||
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -1,88 +0,0 @@
|
|||
#
|
||||
# Broadcom Proprietary and Confidential. Copyright (C) 2020,
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# This is UNPUBLISHED PROPRIETARY SOURCE CODE of Broadcom;
|
||||
# the contents of this file may not be disclosed to third parties,
|
||||
# copied or duplicated in any form, in whole or in part, without
|
||||
# the prior written permission of Broadcom.
|
||||
#
|
||||
#
|
||||
# <<Broadcom-WL-IPTag/Secret:>>
|
||||
|
||||
# This file should be seen only by internal builds because it will
|
||||
# be mentioned only in internal filelists like brcm.flist.
|
||||
# See extended comment bcminternal.mk for details.
|
||||
|
||||
BCMINTERNAL := 1
|
||||
|
||||
BCMINTERNAL_DFLAGS += -DDHD_NO_MOG
|
||||
|
||||
ifneq ($(CONFIG_BCMDHD_PCIE),)
|
||||
# Enable Register access via dhd IOVAR
|
||||
BCMINTERNAL_DFLAGS += -DDHD_PCIE_REG_ACCESS
|
||||
# latency timestamping
|
||||
BCMINTERNAL_DFLAGS += -DDHD_PKTTS
|
||||
# Traffic Pattern Analysis on Socket Flow
|
||||
BCMINTERNAL_DFLAGS += -DDHD_QOS_ON_SOCK_FLOW
|
||||
# QoS unit testing support
|
||||
BCMINTERNAL_DFLAGS += -DDHD_QOS_ON_SOCK_FLOW_UT
|
||||
# Auto QOS
|
||||
BCMINTERNAL_DFLAGS += -DWL_AUTO_QOS
|
||||
|
||||
ifneq ($(filter -DCUSTOMER_HW4, $(DHDCFLAGS)),)
|
||||
# These will be moved to hw4 Makefile for 4389b0
|
||||
BCMINTERNAL_DFLAGS += -DWBRC
|
||||
BCMINTERNAL_DFLAGS += -DWLAN_ACCEL_BOOT
|
||||
BCMINTERNAL_DFLAGS += -DDHD_HTPUT_TUNABLES
|
||||
# BCMINTERNAL_DFLAGS += -DDHD_FIS_DUMP
|
||||
# SCAN TYPES, if kernel < 4.17 ..back port support required
|
||||
ifneq ($(CONFIG_CFG80211_SCANTYPE_BKPORT),)
|
||||
DHDCFLAGS += -DWL_SCAN_TYPE
|
||||
endif
|
||||
# Jig builds
|
||||
# No reset during dhd attach
|
||||
BCMINTERNAL_DFLAGS += -DDHD_SKIP_DONGLE_RESET_IN_ATTACH
|
||||
# Dongle Isolation will ensure no resets devreset ON/OFF
|
||||
BCMINTERNAL_DFLAGS += -DDONGLE_ENABLE_ISOLATION
|
||||
# Quiesce dongle using DB7 trap
|
||||
BCMINTERNAL_DFLAGS += -DDHD_DONGLE_TRAP_IN_DETACH
|
||||
# Collect socram during dongle init failurs for internal builds
|
||||
BCMINTERNAL_DFLAGS += -DDEBUG_DNGL_INIT_FAIL
|
||||
# Dongle reset during Wifi ON to keep in sane state
|
||||
BCMINTERNAL_DFLAGS += -DFORCE_DONGLE_RESET_IN_DEVRESET_ON
|
||||
# Perform Backplane Reset else FLR will happen
|
||||
# BCMINTERNAL_DFLAGS += -DDHD_USE_BP_RESET_SS_CTRL
|
||||
BCMINTERNAL_DFLAGS += -DWIFI_TURNOFF_DELAY=10
|
||||
|
||||
endif
|
||||
|
||||
# NCI_BUS support
|
||||
BCMINTERNAL_DFLAGS += -DSOCI_NCI_BUS
|
||||
endif
|
||||
|
||||
|
||||
BCMINTERNAL_DFLAGS += -DDHD_BUS_MEM_ACCESS
|
||||
|
||||
# Support multiple chips
|
||||
BCMINTERNAL_DFLAGS += -DSUPPORT_MULTIPLE_CHIPS
|
||||
|
||||
# Support unreleased chips
|
||||
BCMINTERNAL_DFLAGS += -DUNRELEASEDCHIP
|
||||
|
||||
# Collect socram if readshared fails
|
||||
BCMINTERNAL_DFLAGS += -DDEBUG_DNGL_INIT_FAIL
|
||||
|
||||
# Force enable memdump value to DUMP_MEMFILE if it is disabled
|
||||
BCMINTERNAL_DFLAGS += -DDHD_INIT_DEFAULT_MEMDUMP
|
||||
|
||||
ifneq ($(filter -DDHD_QOS_ON_SOCK_FLOW,$(BCMINTERNAL_DFLAGS)),)
|
||||
BCMINTERNAL_DHDOFILES += dhd_linux_sock_qos.o
|
||||
endif
|
||||
ifneq ($(filter -DSOCI_NCI_BUS,$(BCMINTERNAL_DFLAGS)),)
|
||||
BCMINTERNAL_DHDOFILES += nciutils.o
|
||||
endif
|
||||
ifneq ($(filter -DWBRC,$(BCMINTERNAL_DFLAGS)),)
|
||||
BCMINTERNAL_DHDOFILES += wb_regon_coordinator.o
|
||||
endif
|
||||
# vim: filetype=make shiftwidth=2
|
||||
|
|
@ -1,60 +0,0 @@
|
|||
#
|
||||
# Broadcom Proprietary and Confidential. Copyright (C) 2020,
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# This is UNPUBLISHED PROPRIETARY SOURCE CODE of Broadcom;
|
||||
# the contents of this file may not be disclosed to third parties,
|
||||
# copied or duplicated in any form, in whole or in part, without
|
||||
# the prior written permission of Broadcom.
|
||||
#
|
||||
#
|
||||
# <<Broadcom-WL-IPTag/Secret:>>
|
||||
|
||||
# This file should be seen only by internal builds because it will
|
||||
# be mentioned only in internal filelists like brcm.flist. The idea
|
||||
# is that it will be conditionally included by makefiles using the
|
||||
# "-include" syntax, with the result that internal builds will see
|
||||
# this file and set BCMINTERNAL which will eventually result in a
|
||||
# -DBCMINTERNAL option passed to the compiler along with possible
|
||||
# other effects. External builds will never see it and it will be
|
||||
# silently ignored.
|
||||
#
|
||||
# Any settings which should not be exposed to customers may be
|
||||
# placed here. For instance, if we were working on a super-secret
|
||||
# new feature in supersecret.c we could set a variable here like
|
||||
# BCMINTERNAL_OBJECTS := supersecret.o
|
||||
# and later say
|
||||
# OBJECTS += $(BCMINTERNAL_OBJECTS)
|
||||
# within the main makefile.
|
||||
#
|
||||
# The key point is that this file is never shipped to customers
|
||||
# because it's present only in internal filelists so anything
|
||||
# here is private.
|
||||
|
||||
BCMINTERNAL := 1
|
||||
|
||||
BCMINTERNAL_DFLAGS += -DBCMINTERNAL
|
||||
BCMINTERNAL_DFLAGS += -DDHD_NO_MOG
|
||||
|
||||
# Support unreleased chips
|
||||
BCMINTERNAL_DFLAGS += -DUNRELEASEDCHIP
|
||||
|
||||
ifneq ($(findstring -fwtrace,-$(TARGET)-),)
|
||||
BCMINTERNAL_DFLAGS += -DDHD_FWTRACE
|
||||
BCMINTERNAL_CFILES += dhd_fwtrace.c
|
||||
endif
|
||||
|
||||
# support only for SDIO MFG Fedora builds
|
||||
ifneq ($(findstring -sdstd-,-$(TARGET)-),)
|
||||
ifneq ($(findstring -mfgtest-,-$(TARGET)-),)
|
||||
BCMINTERNAL_DFLAGS += -DDHD_SPROM
|
||||
BCMINTERNAL_CFILES += bcmsrom.c bcmotp.c
|
||||
endif
|
||||
endif
|
||||
|
||||
ifneq ($(findstring -pciefd-,$(TARGET)-),)
|
||||
# NCI_BUS support
|
||||
BCMINTERNAL_DFLAGS += -DSOCI_NCI_BUS -DBOOKER_NIC400_INF
|
||||
BCMINTERNAL_CFILES += nciutils.c
|
||||
endif
|
||||
# vim: filetype=make shiftwidth=2
|
||||
|
|
@ -2,7 +2,7 @@
|
|||
* BCMSDH interface glue
|
||||
* implement bcmsdh API for SDIOH driver
|
||||
*
|
||||
* Copyright (C) 2020, Broadcom.
|
||||
* Copyright (C) 2022, Broadcom.
|
||||
*
|
||||
* Unless you and Broadcom execute a separate written software license
|
||||
* agreement governing use of this software, this software is licensed to you
|
||||
|
|
@ -46,7 +46,7 @@
|
|||
#include <sbsdio.h> /* SDIO device core hardware definitions. */
|
||||
#include <sdio.h> /* SDIO Device and Protocol Specs */
|
||||
|
||||
#if defined (BT_OVER_SDIO)
|
||||
#if defined(BT_OVER_SDIO)
|
||||
#include <dhd_bt_interface.h>
|
||||
#endif /* defined (BT_OVER_SDIO) */
|
||||
|
||||
|
|
@ -56,7 +56,7 @@ const uint bcmsdh_msglevel = BCMSDH_ERROR_VAL;
|
|||
/* local copy of bcm sd handler */
|
||||
bcmsdh_info_t * l_bcmsdh = NULL;
|
||||
|
||||
#if defined (BT_OVER_SDIO)
|
||||
#if defined(BT_OVER_SDIO)
|
||||
struct sdio_func *func_f3 = NULL;
|
||||
static f3intr_handler processf3intr = NULL;
|
||||
static dhd_hang_notification process_dhd_hang_notification = NULL;
|
||||
|
|
@ -78,7 +78,7 @@ bcmsdh_enable_hw_oob_intr(bcmsdh_info_t *sdh, bool enable)
|
|||
}
|
||||
#endif
|
||||
|
||||
#if defined (BT_OVER_SDIO)
|
||||
#if defined(BT_OVER_SDIO)
|
||||
void bcmsdh_btsdio_process_hang_state(dhd_hang_state_t new_state)
|
||||
{
|
||||
bool state_change = false;
|
||||
|
|
@ -358,9 +358,6 @@ bcmsdh_cfg_read(void *sdh, uint fnc_num, uint32 addr, int *err)
|
|||
|
||||
return data;
|
||||
}
|
||||
#ifdef BCMSDH_MODULE
|
||||
EXPORT_SYMBOL(bcmsdh_cfg_read);
|
||||
#endif
|
||||
|
||||
void
|
||||
bcmsdh_cfg_write(void *sdh, uint fnc_num, uint32 addr, uint8 data, int *err)
|
||||
|
|
@ -391,9 +388,6 @@ bcmsdh_cfg_write(void *sdh, uint fnc_num, uint32 addr, uint8 data, int *err)
|
|||
BCMSDH_INFO(("%s:fun = %d, addr = 0x%x, uint8data = 0x%x\n", __FUNCTION__,
|
||||
fnc_num, addr, data));
|
||||
}
|
||||
#ifdef BCMSDH_MODULE
|
||||
EXPORT_SYMBOL(bcmsdh_cfg_write);
|
||||
#endif
|
||||
|
||||
uint32
|
||||
bcmsdh_cfg_read_word(void *sdh, uint fnc_num, uint32 addr, int *err)
|
||||
|
|
@ -498,7 +492,6 @@ bcmsdh_cisaddr_read(void *sdh, uint func, uint8 *cisd, uint32 offset)
|
|||
return (SDIOH_API_SUCCESS(status) ? 0 : BCME_ERROR);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
bcmsdhsdio_set_sbaddr_window(void *sdh, uint32 address, bool force_set)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* SDIO access interface for drivers - linux specific (pci only)
|
||||
*
|
||||
* Copyright (C) 2020, Broadcom.
|
||||
* Copyright (C) 2022, Broadcom.
|
||||
*
|
||||
* Unless you and Broadcom execute a separate written software license
|
||||
* agreement governing use of this software, this software is licensed to you
|
||||
|
|
@ -95,23 +95,6 @@ bool
|
|||
bcmsdh_chipmatch(uint16 vendor, uint16 device)
|
||||
{
|
||||
/* Add other vendors and devices as required */
|
||||
#ifdef BCMINTERNAL
|
||||
#ifdef BCMSDIOH_BCM
|
||||
if (device == SDIOH_FPGA_ID && vendor == VENDOR_BROADCOM) {
|
||||
return (TRUE);
|
||||
}
|
||||
if (device == BCM_SDIOH_ID && vendor == VENDOR_BROADCOM) {
|
||||
return (TRUE);
|
||||
}
|
||||
if (device == BCM4710_DEVICE_ID && vendor == VENDOR_BROADCOM) {
|
||||
return (TRUE);
|
||||
}
|
||||
/* For now still accept the old devid */
|
||||
if (device == 0x4380 && vendor == VENDOR_BROADCOM) {
|
||||
return (TRUE);
|
||||
}
|
||||
#endif /* BCMSDIOH_BCM */
|
||||
#endif /* BCMINTERNAL */
|
||||
|
||||
#ifdef BCMSDIOH_STD
|
||||
/* Check for Arasan host controller */
|
||||
|
|
@ -142,12 +125,6 @@ bcmsdh_chipmatch(uint16 vendor, uint16 device)
|
|||
return (TRUE);
|
||||
}
|
||||
|
||||
#ifdef BCMINTERNAL
|
||||
/* Check for Jinvani (C-Guys) host controller */
|
||||
if (device == JINVANI_SDIOH_ID && vendor == VENDOR_JINVANI) {
|
||||
return (TRUE);
|
||||
}
|
||||
#endif /* BCMINTERNAL */
|
||||
#endif /* BCMSDIOH_STD */
|
||||
#ifdef BCMSDIOH_SPI
|
||||
/* This is the PciSpiHost. */
|
||||
|
|
@ -156,28 +133,8 @@ bcmsdh_chipmatch(uint16 vendor, uint16 device)
|
|||
return (TRUE);
|
||||
}
|
||||
|
||||
#ifdef BCMINTERNAL
|
||||
/* This is the SPI Host for QT. */
|
||||
if (device == BCM_SPIH_ID && vendor == VENDOR_BROADCOM) {
|
||||
printf("Found SPI Host Controller\n");
|
||||
return (TRUE);
|
||||
}
|
||||
#endif /* BCMINTERNAL */
|
||||
#endif /* BCMSDIOH_SPI */
|
||||
|
||||
#ifdef BCMINTERNAL
|
||||
/*
|
||||
* XXX - This is a hack to get the GPL SdioLinux driver to load on Arasan/x86
|
||||
* This is accomplished by installing a PciSpiHost into the system alongside the
|
||||
* Arasan controller. The PciSpiHost is just used to get BCMSDH loaded.
|
||||
*/
|
||||
#ifdef BCMSDH_FD
|
||||
if (device == SPIH_FPGA_ID && vendor == VENDOR_BROADCOM) {
|
||||
printf("Found SdioLinux Host Controller\n");
|
||||
return (TRUE);
|
||||
}
|
||||
#endif /* BCMSDH_FD */
|
||||
#endif /* BCMINTERNAL */
|
||||
return (FALSE);
|
||||
}
|
||||
|
||||
|
|
@ -271,15 +228,37 @@ int bcmsdh_set_get_wake(bcmsdh_info_t *bcmsdh, int flag)
|
|||
bcmsdh_os_info_t *bcmsdh_osinfo = bcmsdh->os_cxt;
|
||||
unsigned long flags;
|
||||
#endif
|
||||
int ret = 0;
|
||||
int ret;
|
||||
|
||||
#if defined(OOB_INTR_ONLY)
|
||||
spin_lock_irqsave(&bcmsdh_osinfo->oob_irq_spinlock, flags);
|
||||
#endif
|
||||
|
||||
ret = bcmsdh->pkt_wake;
|
||||
bcmsdh->total_wake_count += flag;
|
||||
bcmsdh->pkt_wake = flag;
|
||||
|
||||
#if defined(OOB_INTR_ONLY)
|
||||
spin_unlock_irqrestore(&bcmsdh_osinfo->oob_irq_spinlock, flags);
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
int bcmsdh_get_wake(bcmsdh_info_t *bcmsdh)
|
||||
{
|
||||
#if defined(OOB_INTR_ONLY)
|
||||
bcmsdh_os_info_t *bcmsdh_osinfo = bcmsdh->os_cxt;
|
||||
unsigned long flags;
|
||||
#endif
|
||||
int ret;
|
||||
|
||||
#if defined(OOB_INTR_ONLY)
|
||||
spin_lock_irqsave(&bcmsdh_osinfo->oob_irq_spinlock, flags);
|
||||
#endif
|
||||
|
||||
ret = bcmsdh->pkt_wake;
|
||||
|
||||
#if defined(OOB_INTR_ONLY)
|
||||
spin_unlock_irqrestore(&bcmsdh_osinfo->oob_irq_spinlock, flags);
|
||||
#endif
|
||||
return ret;
|
||||
|
|
@ -566,7 +545,7 @@ EXPORT_SYMBOL(bcmsdh_intr_dereg);
|
|||
EXPORT_SYMBOL(bcmsdh_intr_pending);
|
||||
#endif
|
||||
|
||||
#if defined (BT_OVER_SDIO)
|
||||
#if defined(BT_OVER_SDIO)
|
||||
EXPORT_SYMBOL(bcmsdh_btsdio_interface_init);
|
||||
#endif /* defined (BT_OVER_SDIO) */
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* BCMSDH Function Driver for the native SDIO/MMC driver in the Linux Kernel
|
||||
*
|
||||
* Copyright (C) 2020, Broadcom.
|
||||
* Copyright (C) 2022, Broadcom.
|
||||
*
|
||||
* Unless you and Broadcom execute a separate written software license
|
||||
* agreement governing use of this software, this software is licensed to you
|
||||
|
|
@ -43,7 +43,7 @@
|
|||
#include <dhd.h>
|
||||
#include <dhd_dbg.h>
|
||||
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && defined (CONFIG_PM_SLEEP)
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && defined(CONFIG_PM_SLEEP)
|
||||
#include <linux/suspend.h>
|
||||
extern volatile bool dhd_mmc_suspend;
|
||||
#endif
|
||||
|
|
@ -82,9 +82,23 @@ static void IRQHandler(struct sdio_func *func);
|
|||
static void IRQHandlerF2(struct sdio_func *func);
|
||||
#endif /* !defined(OOB_INTR_ONLY) */
|
||||
static int sdioh_sdmmc_get_cisaddr(sdioh_info_t *sd, uint32 regaddr);
|
||||
#if defined(ENABLE_INSMOD_NO_FW_LOAD) && !defined(BUS_POWER_RESTORE)
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 18, 0) && defined(MMC_SW_RESET)
|
||||
#if defined(ENABLE_INSMOD_NO_FW_LOAD)
|
||||
#if defined(MMC_SW_RESET) && LINUX_VERSION_CODE >= KERNEL_VERSION(4, 18, 0)
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 0)
|
||||
extern int mmc_sw_reset(struct mmc_card *card);
|
||||
#else
|
||||
extern int mmc_sw_reset(struct mmc_host *host);
|
||||
#endif
|
||||
#elif defined(MMC_HW_RESET) && LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0)
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 18, 0)
|
||||
extern int mmc_hw_reset(struct mmc_card *card);
|
||||
#else
|
||||
extern int mmc_hw_reset(struct mmc_host *host);
|
||||
#endif
|
||||
#elif defined(BUS_POWER_RESTORE) && \
|
||||
LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 32) && LINUX_VERSION_CODE < KERNEL_VERSION(4, 19, 0)
|
||||
#undef MMC_SW_RESET
|
||||
#undef MMC_HW_RESET
|
||||
#else
|
||||
extern int sdio_reset_comm(struct mmc_card *card);
|
||||
#endif
|
||||
|
|
@ -103,13 +117,15 @@ extern PBCMSDH_SDMMC_INSTANCE gInstance;
|
|||
#define CUSTOM_SDIO_F1_BLKSIZE DEFAULT_SDIO_F1_BLKSIZE
|
||||
#endif
|
||||
|
||||
#define COPY_BUF_SIZE (SDPCM_MAXGLOM_SIZE * 1600)
|
||||
|
||||
#define MAX_IO_RW_EXTENDED_BLK 511
|
||||
|
||||
uint sd_sdmode = SDIOH_MODE_SD4; /* Use SD4 mode by default */
|
||||
uint sd_f2_blocksize = CUSTOM_SDIO_F2_BLKSIZE;
|
||||
uint sd_f1_blocksize = CUSTOM_SDIO_F1_BLKSIZE;
|
||||
|
||||
#if defined (BT_OVER_SDIO)
|
||||
#if defined(BT_OVER_SDIO)
|
||||
uint sd_f3_blocksize = 64;
|
||||
#endif /* defined (BT_OVER_SDIO) */
|
||||
|
||||
|
|
@ -139,7 +155,7 @@ static int
|
|||
sdioh_sdmmc_card_regwrite(sdioh_info_t *sd, int func, uint32 regaddr, int regsize, uint32 data);
|
||||
#endif /* NOTYET */
|
||||
|
||||
#if defined (BT_OVER_SDIO)
|
||||
#if defined(BT_OVER_SDIO)
|
||||
extern
|
||||
void sdioh_sdmmc_card_enable_func_f3(sdioh_info_t *sd, struct sdio_func *func)
|
||||
{
|
||||
|
|
@ -148,6 +164,8 @@ void sdioh_sdmmc_card_enable_func_f3(sdioh_info_t *sd, struct sdio_func *func)
|
|||
}
|
||||
#endif /* defined (BT_OVER_SDIO) */
|
||||
|
||||
void sdmmc_set_timing(sdioh_info_t *sd, uint8 timing);
|
||||
uint8 sdmmc_get_timing(sdioh_info_t *sd);
|
||||
void sdmmc_set_clock_rate(sdioh_info_t *sd, uint hz);
|
||||
uint sdmmc_get_clock_rate(sdioh_info_t *sd);
|
||||
void sdmmc_set_clock_divisor(sdioh_info_t *sd, uint sd_div);
|
||||
|
|
@ -182,12 +200,49 @@ sdioh_sdmmc_card_enablefuncs(sdioh_info_t *sd)
|
|||
err_ret = sdio_enable_func(sd->func[1]);
|
||||
sdio_release_host(sd->func[1]);
|
||||
if (err_ret) {
|
||||
sd_err(("bcmsdh_sdmmc: Failed to enable F1 Err: 0x%08x\n", err_ret));
|
||||
sd_err(("bcmsdh_sdmmc: Failed to enable F1 Err: %d\n", err_ret));
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set standard CCCR driver strength. Default value is type B.
|
||||
* Type: Value, driver strength
|
||||
* A: 0x10, x1.5
|
||||
* B: 0x00, x1
|
||||
* C: 0x20, x0.75
|
||||
* D: 0x30, x0.5
|
||||
*/
|
||||
int
|
||||
sdioh_set_driver_strength(struct sdio_func *func, uint8 level)
|
||||
{
|
||||
int reg;
|
||||
int err = 0;
|
||||
|
||||
sdio_claim_host(func);
|
||||
reg = sdio_readb(func, SDIOD_CCCR_DRIVER_STRENGTH, &err);
|
||||
if (err) {
|
||||
sd_err(("sd_ds error for read SDIOD_CCCR_DRIVER_STRENGTH : 0x%x\n", err));
|
||||
goto done;
|
||||
} else {
|
||||
sd_info(("SYNA: sd_ds get cccr driver strength 0x%x\n", reg));
|
||||
}
|
||||
|
||||
reg = ((reg & 0xf) | level);
|
||||
sdio_writeb(func, reg, SDIOD_CCCR_DRIVER_STRENGTH, &err);
|
||||
|
||||
if (err) {
|
||||
sd_err(("sd_ds error for write SDIOD_CCCR_DRIVER_STRENGTH : 0x%x\n", err));
|
||||
goto done;
|
||||
} else {
|
||||
sd_info(("SYNA: sd_ds set cccr driver strength 0x%x\n", reg));
|
||||
}
|
||||
done:
|
||||
sdio_release_host(func);
|
||||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
* Public entry points & extern's
|
||||
*/
|
||||
|
|
@ -209,6 +264,14 @@ sdioh_attach(osl_t *osh, struct sdio_func *func)
|
|||
return NULL;
|
||||
}
|
||||
bzero((char *)sd, sizeof(sdioh_info_t));
|
||||
#if defined(BCMSDIOH_TXGLOM) && defined(BCMSDIOH_STATIC_COPY_BUF)
|
||||
sd->copy_buf = MALLOC(osh, COPY_BUF_SIZE);
|
||||
if (sd->copy_buf == NULL) {
|
||||
sd_err(("%s: MALLOC of %d-byte copy_buf failed\n",
|
||||
__FUNCTION__, COPY_BUF_SIZE));
|
||||
goto fail;
|
||||
}
|
||||
#endif
|
||||
sd->osh = osh;
|
||||
sd->fake_func0.num = 0;
|
||||
sd->fake_func0.card = func->card;
|
||||
|
|
@ -224,7 +287,7 @@ sdioh_attach(osl_t *osh, struct sdio_func *func)
|
|||
sd->func[func->num] = func;
|
||||
#endif
|
||||
|
||||
#if defined (BT_OVER_SDIO)
|
||||
#if defined(BT_OVER_SDIO)
|
||||
sd->func[3] = NULL;
|
||||
#endif /* defined (BT_OVER_SDIO) */
|
||||
|
||||
|
|
@ -273,6 +336,9 @@ sdioh_attach(osl_t *osh, struct sdio_func *func)
|
|||
return sd;
|
||||
|
||||
fail:
|
||||
#if defined(BCMSDIOH_TXGLOM) && defined(BCMSDIOH_STATIC_COPY_BUF)
|
||||
MFREE(sd->osh, sd->copy_buf, COPY_BUF_SIZE);
|
||||
#endif
|
||||
MFREE(sd->osh, sd, sizeof(sdioh_info_t));
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -301,6 +367,9 @@ sdioh_detach(osl_t *osh, sdioh_info_t *sd)
|
|||
sd->func[1] = NULL;
|
||||
sd->func[2] = NULL;
|
||||
|
||||
#if defined(BCMSDIOH_TXGLOM) && defined(BCMSDIOH_STATIC_COPY_BUF)
|
||||
MFREE(sd->osh, sd->copy_buf, COPY_BUF_SIZE);
|
||||
#endif
|
||||
MFREE(sd->osh, sd, sizeof(sdioh_info_t));
|
||||
}
|
||||
return SDIOH_API_RC_SUCCESS;
|
||||
|
|
@ -329,7 +398,7 @@ sdioh_enable_func_intr(sdioh_info_t *sd)
|
|||
/* Enable F1 and F2 interrupts, clear master enable */
|
||||
reg &= ~INTR_CTL_MASTER_EN;
|
||||
reg |= (INTR_CTL_FUNC1_EN | INTR_CTL_FUNC2_EN);
|
||||
#if defined (BT_OVER_SDIO)
|
||||
#if defined(BT_OVER_SDIO)
|
||||
reg |= (INTR_CTL_FUNC3_EN);
|
||||
#endif /* defined (BT_OVER_SDIO) */
|
||||
sdio_writeb(sd->func[0], reg, SDIOD_CCCR_INTEN, &err);
|
||||
|
|
@ -357,7 +426,8 @@ sdioh_disable_func_intr(sdioh_info_t *sd)
|
|||
sdio_claim_host(sd->func[0]);
|
||||
reg = sdio_readb(sd->func[0], SDIOD_CCCR_INTEN, &err);
|
||||
if (err) {
|
||||
sd_err(("%s: error for read SDIO_CCCR_IENx : 0x%x\n", __FUNCTION__, err));
|
||||
sd_err(("%s: error for read SDIO_CCCR_IENx : 0x%x (ignore when remove)\n",
|
||||
__FUNCTION__, err));
|
||||
sdio_release_host(sd->func[0]);
|
||||
return SDIOH_API_RC_FAIL;
|
||||
}
|
||||
|
|
@ -483,7 +553,8 @@ enum {
|
|||
IOV_HCIREGS,
|
||||
IOV_POWER,
|
||||
IOV_CLOCK,
|
||||
IOV_RXCHAIN
|
||||
IOV_RXCHAIN,
|
||||
IOV_DS
|
||||
};
|
||||
|
||||
const bcm_iovar_t sdioh_iovars[] = {
|
||||
|
|
@ -494,10 +565,6 @@ const bcm_iovar_t sdioh_iovars[] = {
|
|||
{"sd_ints", IOV_USEINTS, 0, 0, IOVT_BOOL, 0 },
|
||||
{"sd_numints", IOV_NUMINTS, 0, 0, IOVT_UINT32, 0 },
|
||||
{"sd_numlocalints", IOV_NUMLOCALINTS, 0, 0, IOVT_UINT32, 0 },
|
||||
#ifdef BCMINTERNAL
|
||||
{"sd_hostreg", IOV_HOSTREG, 0, 0, IOVT_BUFFER, sizeof(sdreg_t) },
|
||||
{"sd_devreg", IOV_DEVREG, 0, 0, IOVT_BUFFER, sizeof(sdreg_t) },
|
||||
#endif /* BCMINTERNAL */
|
||||
{"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 },
|
||||
|
|
@ -507,6 +574,7 @@ const bcm_iovar_t sdioh_iovars[] = {
|
|||
#ifdef BCMDBG
|
||||
{"sd_hciregs", IOV_HCIREGS, 0, 0, IOVT_BUFFER, 0 },
|
||||
#endif
|
||||
{"sd_ds", IOV_DS, 0, 0, IOVT_UINT32, 0 },
|
||||
{NULL, 0, 0, 0, 0, 0 }
|
||||
};
|
||||
|
||||
|
|
@ -721,88 +789,52 @@ sdioh_iovar_op(sdioh_info_t *si, const char *name,
|
|||
int_val = (int32)0;
|
||||
bcopy(&int_val, arg, val_size);
|
||||
break;
|
||||
#ifdef BCMINTERNAL
|
||||
case IOV_GVAL(IOV_HOSTREG):
|
||||
|
||||
case IOV_GVAL(IOV_DS):
|
||||
{
|
||||
/* XXX Should copy for alignment reasons */
|
||||
sdreg_t *sd_ptr = (sdreg_t *)params;
|
||||
uint8 reg2;
|
||||
int err;
|
||||
|
||||
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;
|
||||
sdio_claim_host(si->func[0]);
|
||||
reg2 = sdio_readb(si->func[0], SDIOD_CCCR_DRIVER_STRENGTH, &err);
|
||||
if (err) {
|
||||
sd_err(("sd_ds error for read SDIOD_CCCR_DRIVER_STRENGTH : 0x%x\n", err));
|
||||
bcmerror = BCME_SDIO_ERROR;
|
||||
} else {
|
||||
sd_trace(("sd_ds get cccr driver strength 0x%x\n", reg2));
|
||||
}
|
||||
sdio_release_host(si->func[0]);
|
||||
|
||||
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); */
|
||||
|
||||
int_val = (int)reg2;
|
||||
bcopy(&int_val, arg, sizeof(int_val));
|
||||
break;
|
||||
}
|
||||
|
||||
case IOV_SVAL(IOV_HOSTREG):
|
||||
case IOV_SVAL(IOV_DS):
|
||||
{
|
||||
/* XXX Should copy for alignment reasons */
|
||||
sdreg_t *sd_ptr = (sdreg_t *)params;
|
||||
uint8 type;
|
||||
int err;
|
||||
|
||||
if (sd_ptr->offset < SD_SysAddr || sd_ptr->offset > SD_MaxCurCap) {
|
||||
sd_err(("%s: bad offset 0x%x\n", __FUNCTION__, sd_ptr->offset));
|
||||
if (int_val == 0) {
|
||||
type = 0x0;
|
||||
} else if (int_val == 1) {
|
||||
type = 0x10;
|
||||
} else if (int_val == 2) {
|
||||
type = 0x20;
|
||||
} else if (int_val == 3) {
|
||||
type = 0x30;
|
||||
} else {
|
||||
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):
|
||||
{
|
||||
/* XXX Should copy for alignment reasons */
|
||||
sdreg_t *sd_ptr = (sdreg_t *)params;
|
||||
uint8 data = 0;
|
||||
|
||||
if ((uint)sd_ptr->func > si->num_funcs) {
|
||||
bcmerror = BCME_BADARG;
|
||||
break;
|
||||
}
|
||||
|
||||
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):
|
||||
{
|
||||
/* XXX Should copy for alignment reasons */
|
||||
sdreg_t *sd_ptr = (sdreg_t *)params;
|
||||
uint8 data = (uint8)sd_ptr->value;
|
||||
|
||||
if ((uint)sd_ptr->func > si->num_funcs) {
|
||||
bcmerror = BCME_BADARG;
|
||||
break;
|
||||
}
|
||||
|
||||
if (sdioh_cfg_write(si, sd_ptr->func, sd_ptr->offset, &data)) {
|
||||
bcmerror = BCME_SDIO_ERROR;
|
||||
break;
|
||||
err = sdioh_set_driver_strength(si->func[0], type);
|
||||
if (err) {
|
||||
sd_err(("sd_ds error write SDIOD_CCCR_DRIVER_STRENGTH : 0x%x\n", err));
|
||||
}
|
||||
break;
|
||||
}
|
||||
#endif /* BCMINTERNAL */
|
||||
|
||||
default:
|
||||
bcmerror = BCME_UNSUPPORTED;
|
||||
break;
|
||||
|
|
@ -949,7 +981,7 @@ sdioh_request_byte(sdioh_info_t *sd, uint rw, uint func, uint regaddr, uint8 *by
|
|||
* as a special case.
|
||||
*/
|
||||
if (regaddr == SDIOD_CCCR_IOEN) {
|
||||
#if defined (BT_OVER_SDIO)
|
||||
#if defined(BT_OVER_SDIO)
|
||||
do {
|
||||
if (sd->func[3]) {
|
||||
sd_info(("bcmsdh_sdmmc F3: *byte 0x%x\n", *byte));
|
||||
|
|
@ -1014,7 +1046,7 @@ sdioh_request_byte(sdioh_info_t *sd, uint rw, uint func, uint regaddr, uint8 *by
|
|||
}
|
||||
sdio_release_host(sd->func[2]);
|
||||
}
|
||||
#if defined (BT_OVER_SDIO)
|
||||
#if defined(BT_OVER_SDIO)
|
||||
} while (0);
|
||||
#endif /* defined (BT_OVER_SDIO) */
|
||||
}
|
||||
|
|
@ -1206,7 +1238,7 @@ sdioh_request_word(sdioh_info_t *sd, uint cmd_type, uint rw, uint func, uint add
|
|||
if (err_ret)
|
||||
#endif /* MMC_SDIO_ABORT */
|
||||
{
|
||||
sd_err(("bcmsdh_sdmmc: Failed to %s word F%d:@0x%05x=%02x, Err: 0x%08x\n",
|
||||
sd_err(("bcmsdh_sdmmc: Failed to %s word F%d:@0x%05x=%02x, Err: %d\n",
|
||||
rw ? "Write" : "Read", func, addr, *word, err_ret));
|
||||
}
|
||||
}
|
||||
|
|
@ -1356,7 +1388,8 @@ sdioh_request_packet_chain(sdioh_info_t *sd, uint fix_inc, uint write, uint func
|
|||
return SDIOH_API_RC_FAIL;
|
||||
}
|
||||
}
|
||||
} else if(sd->txglom_mode == SDPCM_TXGLOM_CPY) {
|
||||
}
|
||||
else if(sd->txglom_mode == SDPCM_TXGLOM_CPY) {
|
||||
for (pnext = pkt; pnext; pnext = PKTNEXT(sd->osh, pnext)) {
|
||||
ttl_len += PKTLEN(sd->osh, pnext);
|
||||
}
|
||||
|
|
@ -1365,16 +1398,20 @@ sdioh_request_packet_chain(sdioh_info_t *sd, uint fix_inc, uint write, uint func
|
|||
for (pnext = pkt; pnext; pnext = PKTNEXT(sd->osh, pnext)) {
|
||||
uint8 *buf = (uint8*)PKTDATA(sd->osh, pnext);
|
||||
pkt_len = PKTLEN(sd->osh, pnext);
|
||||
|
||||
if (!localbuf) {
|
||||
#ifdef BCMSDIOH_STATIC_COPY_BUF
|
||||
if (ttl_len <= COPY_BUF_SIZE)
|
||||
localbuf = sd->copy_buf;
|
||||
#else
|
||||
localbuf = (uint8 *)MALLOC(sd->osh, ttl_len);
|
||||
#endif
|
||||
if (localbuf == NULL) {
|
||||
sd_err(("%s: %s TXGLOM: localbuf malloc FAILED\n",
|
||||
__FUNCTION__, (write) ? "TX" : "RX"));
|
||||
sd_err(("%s: %s localbuf malloc FAILED ttl_len=%d\n",
|
||||
__FUNCTION__, (write) ? "TX" : "RX", ttl_len));
|
||||
ttl_len -= pkt_len;
|
||||
goto txglomfail;
|
||||
}
|
||||
}
|
||||
|
||||
bcopy(buf, (localbuf + local_plen), pkt_len);
|
||||
local_plen += pkt_len;
|
||||
if (PKTNEXT(sd->osh, pnext))
|
||||
|
|
@ -1419,8 +1456,10 @@ txglomfail:
|
|||
return SDIOH_API_RC_FAIL;
|
||||
}
|
||||
|
||||
#ifndef BCMSDIOH_STATIC_COPY_BUF
|
||||
if (localbuf)
|
||||
MFREE(sd->osh, localbuf, ttl_len);
|
||||
#endif
|
||||
|
||||
#ifndef PKT_STATICS
|
||||
if (sd_msglevel & SDH_COST_VAL)
|
||||
|
|
@ -1746,21 +1785,44 @@ sdioh_sdmmc_card_regwrite(sdioh_info_t *sd, int func, uint32 regaddr, int regsiz
|
|||
}
|
||||
#endif /* NOTUSED */
|
||||
|
||||
#if defined(ENABLE_INSMOD_NO_FW_LOAD) && !defined(BUS_POWER_RESTORE)
|
||||
#if defined(ENABLE_INSMOD_NO_FW_LOAD)
|
||||
static int sdio_sw_reset(sdioh_info_t *sd)
|
||||
{
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 18, 0) && defined(MMC_SW_RESET)
|
||||
struct mmc_host *host = sd->func[0]->card->host;
|
||||
#endif
|
||||
struct mmc_card *card = sd->func[0]->card;
|
||||
int err = 0;
|
||||
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 18, 0) && defined(MMC_SW_RESET)
|
||||
printf("%s: Enter\n", __FUNCTION__);
|
||||
#if defined(MMC_SW_RESET) && LINUX_VERSION_CODE >= KERNEL_VERSION(4, 18, 0)
|
||||
/* MMC_SW_RESET */
|
||||
printf("%s: call mmc_sw_reset\n", __FUNCTION__);
|
||||
sdio_claim_host(sd->func[0]);
|
||||
err = mmc_sw_reset(host);
|
||||
sdio_release_host(sd->func[0]);
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 0)
|
||||
err = mmc_sw_reset(card);
|
||||
#else
|
||||
err = sdio_reset_comm(sd->func[0]->card);
|
||||
err = mmc_sw_reset(card->host);
|
||||
#endif
|
||||
sdio_release_host(sd->func[0]);
|
||||
#elif defined(MMC_HW_RESET) && LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0)
|
||||
/* MMC_HW_RESET */
|
||||
printf("%s: call mmc_hw_reset\n", __FUNCTION__);
|
||||
sdio_claim_host(sd->func[0]);
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0)
|
||||
while (atomic_read(&card->sdio_funcs_probed) > 1) {
|
||||
atomic_dec(&card->sdio_funcs_probed);
|
||||
}
|
||||
#endif
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 18, 0)
|
||||
err = mmc_hw_reset(card);
|
||||
#else
|
||||
err = mmc_hw_reset(card->host);
|
||||
#endif
|
||||
sdio_release_host(sd->func[0]);
|
||||
#elif defined(BUS_POWER_RESTORE) && \
|
||||
LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 32) && LINUX_VERSION_CODE < KERNEL_VERSION(4, 19, 0)
|
||||
printf("%s: call mmc_power_restore_host\n", __FUNCTION__);
|
||||
mmc_power_restore_host(card->host);
|
||||
#else
|
||||
/* sdio_reset_comm */
|
||||
err = sdio_reset_comm(card);
|
||||
#endif
|
||||
|
||||
if (err)
|
||||
|
|
@ -1786,60 +1848,60 @@ sdioh_start(sdioh_info_t *sd, int stage)
|
|||
sdio access will come in way
|
||||
*/
|
||||
if (sd->func[0]) {
|
||||
if (stage == 0) {
|
||||
/* Since the power to the chip is killed, we will have
|
||||
re enumerate the device again. Set the block size
|
||||
and enable the fucntion 1 for in preparation for
|
||||
downloading the code
|
||||
*/
|
||||
/* sdio_reset_comm() - has been fixed in latest kernel/msm.git for Linux
|
||||
2.6.27. The implementation prior to that is buggy, and needs broadcom's
|
||||
patch for it
|
||||
*/
|
||||
#if defined(ENABLE_INSMOD_NO_FW_LOAD) && !defined(BUS_POWER_RESTORE)
|
||||
if ((ret = sdio_sw_reset(sd))) {
|
||||
sd_err(("%s Failed, error = %d\n", __FUNCTION__, ret));
|
||||
return ret;
|
||||
} else
|
||||
if (stage == 0) {
|
||||
/* Since the power to the chip is killed, we will have
|
||||
re enumerate the device again. Set the block size
|
||||
and enable the fucntion 1 for in preparation for
|
||||
downloading the code
|
||||
*/
|
||||
/* sdio_reset_comm() - has been fixed in latest kernel/msm.git for Linux
|
||||
2.6.27. The implementation prior to that is buggy, and needs broadcom's
|
||||
patch for it
|
||||
*/
|
||||
#if defined(ENABLE_INSMOD_NO_FW_LOAD)
|
||||
if ((ret = sdio_sw_reset(sd))) {
|
||||
sd_err(("%s Failed, error = %d\n", __FUNCTION__, ret));
|
||||
return ret;
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
sd->num_funcs = 2;
|
||||
sd->sd_blockmode = TRUE;
|
||||
sd->use_client_ints = TRUE;
|
||||
sd->client_block_size[0] = 64;
|
||||
{
|
||||
sd->num_funcs = 2;
|
||||
sd->sd_blockmode = TRUE;
|
||||
sd->use_client_ints = TRUE;
|
||||
sd->client_block_size[0] = 64;
|
||||
|
||||
if (sd->func[1]) {
|
||||
/* Claim host controller */
|
||||
sdio_claim_host(sd->func[1]);
|
||||
if (sd->func[1]) {
|
||||
/* Claim host controller */
|
||||
sdio_claim_host(sd->func[1]);
|
||||
|
||||
sd->client_block_size[1] = 64;
|
||||
ret = sdio_set_block_size(sd->func[1], 64);
|
||||
if (ret) {
|
||||
sd_err(("bcmsdh_sdmmc: Failed to set F1 "
|
||||
"blocksize(%d)\n", ret));
|
||||
sd->client_block_size[1] = 64;
|
||||
ret = sdio_set_block_size(sd->func[1], 64);
|
||||
if (ret) {
|
||||
sd_err(("bcmsdh_sdmmc: Failed to set F1 "
|
||||
"blocksize(%d)\n", ret));
|
||||
}
|
||||
|
||||
/* Release host controller F1 */
|
||||
sdio_release_host(sd->func[1]);
|
||||
}
|
||||
|
||||
/* Release host controller F1 */
|
||||
sdio_release_host(sd->func[1]);
|
||||
}
|
||||
if (sd->func[2]) {
|
||||
/* Claim host controller F2 */
|
||||
sdio_claim_host(sd->func[2]);
|
||||
|
||||
if (sd->func[2]) {
|
||||
/* Claim host controller F2 */
|
||||
sdio_claim_host(sd->func[2]);
|
||||
sd->client_block_size[2] = sd_f2_blocksize;
|
||||
printf("%s: set sd_f2_blocksize %d\n", __FUNCTION__, sd_f2_blocksize);
|
||||
ret = sdio_set_block_size(sd->func[2], sd_f2_blocksize);
|
||||
if (ret) {
|
||||
sd_err(("bcmsdh_sdmmc: Failed to set F2 blocksize"
|
||||
" to %d(%d)\n", sd_f2_blocksize, ret));
|
||||
}
|
||||
|
||||
sd->client_block_size[2] = sd_f2_blocksize;
|
||||
printf("%s: set sd_f2_blocksize %d\n", __FUNCTION__, sd_f2_blocksize);
|
||||
ret = sdio_set_block_size(sd->func[2], sd_f2_blocksize);
|
||||
if (ret) {
|
||||
sd_err(("bcmsdh_sdmmc: Failed to set F2 "
|
||||
"blocksize to %d(%d)\n", sd_f2_blocksize, ret));
|
||||
/* Release host controller F2 */
|
||||
sdio_release_host(sd->func[2]);
|
||||
}
|
||||
|
||||
/* Release host controller F2 */
|
||||
sdio_release_host(sd->func[2]);
|
||||
}
|
||||
|
||||
sdioh_sdmmc_card_enablefuncs(sd);
|
||||
sdioh_sdmmc_card_enablefuncs(sd);
|
||||
}
|
||||
} else {
|
||||
#if !defined(OOB_INTR_ONLY)
|
||||
|
|
@ -1856,8 +1918,7 @@ sdioh_start(sdioh_info_t *sd, int stage)
|
|||
bcmsdh_oob_intr_set(sd->bcmsdh, TRUE);
|
||||
#endif /* !defined(OOB_INTR_ONLY) */
|
||||
}
|
||||
}
|
||||
else
|
||||
} else
|
||||
sd_err(("%s Failed\n", __FUNCTION__));
|
||||
#endif /* defined(OEM_ANDROID) */
|
||||
|
||||
|
|
@ -1894,10 +1955,20 @@ sdioh_stop(sdioh_info_t *sd)
|
|||
}
|
||||
else
|
||||
sd_err(("%s Failed\n", __FUNCTION__));
|
||||
#endif /* defined(OEM_ANDROID) */
|
||||
#if !defined(MMC_SW_RESET) && !defined(MMC_HW_RESET)
|
||||
#if defined(BUS_POWER_RESTORE) && \
|
||||
LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 32) && LINUX_VERSION_CODE < KERNEL_VERSION(4, 19, 0)
|
||||
if (sd->func[0]) {
|
||||
struct mmc_card *card = sd->func[0]->card;
|
||||
printf("%s: call mmc_power_save_host\n", __FUNCTION__);
|
||||
mmc_power_save_host(card->host);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
#if !defined(OOB_INTR_ONLY)
|
||||
sdio_claim_host_unlock_local(sd);
|
||||
#endif
|
||||
#endif /* defined(OEM_ANDROID) */
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
|
@ -1907,16 +1978,6 @@ sdioh_waitlockfree(sdioh_info_t *sd)
|
|||
return (1);
|
||||
}
|
||||
|
||||
#ifdef BCMINTERNAL
|
||||
extern SDIOH_API_RC
|
||||
sdioh_test_diag(sdioh_info_t *sd)
|
||||
{
|
||||
sd_trace(("%s: Enter\n", __FUNCTION__));
|
||||
sd_trace(("%s: Exit\n", __FUNCTION__));
|
||||
return (0);
|
||||
}
|
||||
#endif /* BCMINTERNAL */
|
||||
|
||||
SDIOH_API_RC
|
||||
sdioh_gpioouten(sdioh_info_t *sd, uint32 gpio)
|
||||
{
|
||||
|
|
@ -1941,6 +2002,29 @@ sdioh_gpio_init(sdioh_info_t *sd)
|
|||
return SDIOH_API_RC_FAIL;
|
||||
}
|
||||
|
||||
uint8
|
||||
sdmmc_get_timing(sdioh_info_t *sd)
|
||||
{
|
||||
struct sdio_func *sdio_func = sd->func[0];
|
||||
struct mmc_host *host = sdio_func->card->host;
|
||||
return host->ios.timing;
|
||||
}
|
||||
|
||||
void
|
||||
sdmmc_set_timing(sdioh_info_t *sd, uint8 timing)
|
||||
{
|
||||
struct sdio_func *sdio_func = sd->func[0];
|
||||
struct mmc_host *host = sdio_func->card->host;
|
||||
struct mmc_ios *ios = &host->ios;
|
||||
|
||||
mmc_host_clk_hold(host);
|
||||
DHD_INFO(("%s: Before change: sd current timing is %u\n", __FUNCTION__, ios->timing));
|
||||
ios->timing = timing;
|
||||
host->ops->set_ios(host, ios);
|
||||
DHD_ERROR(("%s: After change: sd timing is %u\n", __FUNCTION__, ios->timing));
|
||||
mmc_host_clk_release(host);
|
||||
}
|
||||
|
||||
uint
|
||||
sdmmc_get_clock_rate(sdioh_info_t *sd)
|
||||
{
|
||||
|
|
|
|||
12
drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/bcmsdh_sdmmc_linux.c
Executable file → Normal file
12
drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/bcmsdh_sdmmc_linux.c
Executable file → Normal file
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* BCMSDH Function Driver for the native SDIO/MMC driver in the Linux Kernel
|
||||
*
|
||||
* Copyright (C) 2020, Broadcom.
|
||||
* Copyright (C) 2022, Broadcom.
|
||||
*
|
||||
* Unless you and Broadcom execute a separate written software license
|
||||
* agreement governing use of this software, this software is licensed to you
|
||||
|
|
@ -91,8 +91,12 @@ static int sdioh_probe(struct sdio_func *func)
|
|||
adapter->bus_num = host_idx;
|
||||
adapter->slot_num = rca;
|
||||
adapter->sdio_func = func;
|
||||
} else
|
||||
} else {
|
||||
sd_err(("can't find adapter info for this chip\n"));
|
||||
#ifdef ADAPTER_IDX
|
||||
goto fail;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef WL_CFG80211
|
||||
wl_cfg80211_set_parent_dev(&func->dev);
|
||||
|
|
@ -198,6 +202,7 @@ static const struct sdio_device_id bcmsdh_sdmmc_ids[] = {
|
|||
{ SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, BCM4362_CHIP_ID) },
|
||||
{ SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, BCM43751_CHIP_ID) },
|
||||
{ SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, BCM43752_CHIP_ID) },
|
||||
{ SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, BCM43756_CHIP_ID) },
|
||||
{ SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, BCM43012_CHIP_ID) },
|
||||
{ SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, BCM43014_CHIP_ID) },
|
||||
{ SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, BCM43014_D11N_ID) },
|
||||
|
|
@ -207,6 +212,9 @@ static const struct sdio_device_id bcmsdh_sdmmc_ids[] = {
|
|||
{ SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, BCM43013_D11N_ID) },
|
||||
{ SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, BCM43013_D11N2G_ID) },
|
||||
{ SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, BCM43013_D11N5G_ID) },
|
||||
{ SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_ANY_ID) },
|
||||
{ SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, BCM4381_CHIP_ID) },
|
||||
{ SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, BCM4382_CHIP_ID) },
|
||||
{ SDIO_DEVICE_CLASS(SDIO_CLASS_NONE) },
|
||||
{ 0, 0, 0, 0 /* end: all zeroes */
|
||||
},
|
||||
|
|
|
|||
|
|
@ -1,147 +0,0 @@
|
|||
/*
|
||||
* SD-SPI Protocol Conversion - BCMSDH->SPI Translation Layer
|
||||
*
|
||||
* Copyright (C) 2020, Broadcom.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*
|
||||
* <<Broadcom-WL-IPTag/Open:>>
|
||||
*
|
||||
* $Id: bcmsdspi.h 833013 2019-08-02 16:26:31Z jl904071 $
|
||||
*/
|
||||
#ifndef _BCM_SD_SPI_H
|
||||
#define _BCM_SD_SPI_H
|
||||
|
||||
/* global msglevel for debug messages - bitvals come from sdiovar.h */
|
||||
|
||||
#ifdef BCMDBG
|
||||
#define sd_err(x) do { if (sd_msglevel & SDH_ERROR_VAL) printf x; } while (0)
|
||||
#define sd_trace(x) do { if (sd_msglevel & SDH_TRACE_VAL) printf x; } while (0)
|
||||
#define sd_info(x) do { if (sd_msglevel & SDH_INFO_VAL) printf x; } while (0)
|
||||
#define sd_debug(x) do { if (sd_msglevel & SDH_DEBUG_VAL) printf x; } while (0)
|
||||
#define sd_data(x) do { if (sd_msglevel & SDH_DATA_VAL) printf x; } while (0)
|
||||
#define sd_ctrl(x) do { if (sd_msglevel & SDH_CTRL_VAL) printf x; } while (0)
|
||||
#else
|
||||
#define sd_err(x)
|
||||
#define sd_trace(x)
|
||||
#define sd_info(x)
|
||||
#define sd_debug(x)
|
||||
#define sd_data(x)
|
||||
#define sd_ctrl(x)
|
||||
#endif
|
||||
|
||||
#ifdef BCMPERFSTATS
|
||||
#define sd_log(x) do { if (sd_msglevel & SDH_LOG_VAL) bcmlog x; } while (0)
|
||||
#else
|
||||
#define sd_log(x)
|
||||
#endif
|
||||
|
||||
#define SDIOH_ASSERT(exp) \
|
||||
do { if (!(exp)) \
|
||||
printf("!!!ASSERT fail: file %s lines %d", __FILE__, __LINE__); \
|
||||
} while (0)
|
||||
|
||||
#define BLOCK_SIZE_4318 64
|
||||
#define BLOCK_SIZE_4328 512
|
||||
|
||||
/* internal return code */
|
||||
#define SUCCESS 0
|
||||
#undef ERROR
|
||||
#define ERROR 1
|
||||
|
||||
/* private bus modes */
|
||||
#define SDIOH_MODE_SPI 0
|
||||
|
||||
#define USE_BLOCKMODE 0x2 /* Block mode can be single block or multi */
|
||||
#define USE_MULTIBLOCK 0x4
|
||||
|
||||
struct sdioh_info {
|
||||
uint cfg_bar; /* pci cfg address for bar */
|
||||
uint32 caps; /* cached value of capabilities reg */
|
||||
uint bar0; /* BAR0 for PCI Device */
|
||||
osl_t *osh; /* osh handler */
|
||||
void *controller; /* Pointer to SPI Controller's private data struct */
|
||||
|
||||
uint lockcount; /* nest count of sdspi_lock() calls */
|
||||
bool client_intr_enabled; /* interrupt connnected flag */
|
||||
bool intr_handler_valid; /* client driver interrupt handler valid */
|
||||
sdioh_cb_fn_t intr_handler; /* registered interrupt handler */
|
||||
void *intr_handler_arg; /* argument to call interrupt handler */
|
||||
bool initialized; /* card initialized */
|
||||
uint32 target_dev; /* Target device ID */
|
||||
uint32 intmask; /* Current active interrupts */
|
||||
void *sdos_info; /* Pointer to per-OS private data */
|
||||
|
||||
uint32 controller_type; /* Host controller type */
|
||||
uint8 version; /* Host Controller Spec Compliance Version */
|
||||
uint irq; /* Client irq */
|
||||
uint32 intrcount; /* Client interrupts */
|
||||
uint32 local_intrcount; /* Controller interrupts */
|
||||
bool host_init_done; /* Controller initted */
|
||||
bool card_init_done; /* Client SDIO interface initted */
|
||||
bool polled_mode; /* polling for command completion */
|
||||
|
||||
bool sd_use_dma; /* DMA on CMD53 */
|
||||
bool sd_blockmode; /* sd_blockmode == FALSE => 64 Byte Cmd 53s. */
|
||||
/* Must be on for sd_multiblock to be effective */
|
||||
bool use_client_ints; /* If this is false, make sure to restore */
|
||||
bool got_hcint; /* Host Controller interrupt. */
|
||||
/* polling hack in wl_linux.c:wl_timer() */
|
||||
int adapter_slot; /* Maybe dealing with multiple slots/controllers */
|
||||
int sd_mode; /* SD1/SD4/SPI */
|
||||
int client_block_size[SDIOD_MAX_IOFUNCS]; /* Blocksize */
|
||||
uint32 data_xfer_count; /* Current register transfer size */
|
||||
uint32 cmd53_wr_data; /* Used to pass CMD53 write data */
|
||||
uint32 card_response; /* Used to pass back response status byte */
|
||||
uint32 card_rsp_data; /* Used to pass back response data word */
|
||||
uint16 card_rca; /* Current Address */
|
||||
uint8 num_funcs; /* Supported funcs on client */
|
||||
uint32 com_cis_ptr;
|
||||
uint32 func_cis_ptr[SDIOD_MAX_IOFUNCS];
|
||||
void *dma_buf;
|
||||
ulong dma_phys;
|
||||
int r_cnt; /* rx count */
|
||||
int t_cnt; /* tx_count */
|
||||
};
|
||||
|
||||
/************************************************************
|
||||
* Internal interfaces: per-port references into bcmsdspi.c
|
||||
*/
|
||||
|
||||
/* Global message bits */
|
||||
extern uint sd_msglevel;
|
||||
|
||||
/**************************************************************
|
||||
* Internal interfaces: bcmsdspi.c references to per-port code
|
||||
*/
|
||||
|
||||
/* Register mapping routines */
|
||||
extern uint32 *spi_reg_map(osl_t *osh, uintptr addr, int size);
|
||||
extern void spi_reg_unmap(osl_t *osh, uintptr addr, int size);
|
||||
|
||||
/* Interrupt (de)registration routines */
|
||||
extern int spi_register_irq(sdioh_info_t *sd, uint irq);
|
||||
extern void spi_free_irq(uint irq, sdioh_info_t *sd);
|
||||
|
||||
/* OS-specific interrupt wrappers (atomic interrupt enable/disable) */
|
||||
extern void spi_lock(sdioh_info_t *sd);
|
||||
extern void spi_unlock(sdioh_info_t *sd);
|
||||
|
||||
/* Allocate/init/free per-OS private data */
|
||||
extern int spi_osinit(sdioh_info_t *sd);
|
||||
extern void spi_osfree(sdioh_info_t *sd);
|
||||
|
||||
#endif /* _BCM_SD_SPI_H */
|
||||
|
|
@ -1,433 +0,0 @@
|
|||
/*
|
||||
* Broadcom SPI Host Controller Driver - Linux Per-port
|
||||
*
|
||||
* Copyright (C) 2020, Broadcom.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*
|
||||
* <<Broadcom-WL-IPTag/Open:>>
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include <typedefs.h>
|
||||
#include <bcmutils.h>
|
||||
|
||||
#include <bcmsdbus.h> /* bcmsdh to/from specific controller APIs */
|
||||
#include <sdiovar.h> /* to get msglevel bit values */
|
||||
|
||||
#ifdef BCMSPI_ANDROID
|
||||
#include <bcmsdh.h>
|
||||
#include <bcmspibrcm.h>
|
||||
#include <linux/spi/spi.h>
|
||||
#else
|
||||
#include <pcicfg.h>
|
||||
#include <sdio.h> /* SDIO Device and Protocol Specs */
|
||||
#include <linux/sched.h> /* request_irq(), free_irq() */
|
||||
#include <bcmsdspi.h>
|
||||
#include <bcmspi.h>
|
||||
#endif /* BCMSPI_ANDROID */
|
||||
|
||||
#ifndef BCMSPI_ANDROID
|
||||
extern uint sd_crc;
|
||||
module_param(sd_crc, uint, 0);
|
||||
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0))
|
||||
#define KERNEL26
|
||||
#endif
|
||||
#endif /* !BCMSPI_ANDROID */
|
||||
|
||||
struct sdos_info {
|
||||
sdioh_info_t *sd;
|
||||
spinlock_t lock;
|
||||
#ifndef BCMSPI_ANDROID
|
||||
wait_queue_head_t intr_wait_queue;
|
||||
#endif /* !BCMSPI_ANDROID */
|
||||
};
|
||||
|
||||
#ifndef BCMSPI_ANDROID
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0))
|
||||
#define BLOCKABLE() (!in_atomic())
|
||||
#else
|
||||
#define BLOCKABLE() (!in_interrupt()) /* XXX Doesn't handle CONFIG_PREEMPT? */
|
||||
#endif
|
||||
|
||||
/* Interrupt handler */
|
||||
static irqreturn_t
|
||||
sdspi_isr(int irq, void *dev_id
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20)
|
||||
, struct pt_regs *ptregs
|
||||
#endif
|
||||
)
|
||||
{
|
||||
sdioh_info_t *sd;
|
||||
struct sdos_info *sdos;
|
||||
bool ours;
|
||||
|
||||
sd = (sdioh_info_t *)dev_id;
|
||||
sd->local_intrcount++;
|
||||
|
||||
if (!sd->card_init_done) {
|
||||
sd_err(("%s: Hey Bogus intr...not even initted: irq %d\n", __FUNCTION__, irq));
|
||||
return IRQ_RETVAL(FALSE);
|
||||
} else {
|
||||
ours = spi_check_client_intr(sd, NULL);
|
||||
|
||||
/* For local interrupts, wake the waiting process */
|
||||
if (ours && sd->got_hcint) {
|
||||
sdos = (struct sdos_info *)sd->sdos_info;
|
||||
wake_up_interruptible(&sdos->intr_wait_queue);
|
||||
}
|
||||
|
||||
return IRQ_RETVAL(ours);
|
||||
}
|
||||
}
|
||||
#endif /* !BCMSPI_ANDROID */
|
||||
|
||||
#ifdef BCMSPI_ANDROID
|
||||
static struct spi_device *gBCMSPI = NULL;
|
||||
|
||||
extern int bcmsdh_probe(struct device *dev);
|
||||
extern int bcmsdh_remove(struct device *dev);
|
||||
|
||||
static int bcmsdh_spi_probe(struct spi_device *spi_dev)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
gBCMSPI = spi_dev;
|
||||
|
||||
#ifdef SPI_PIO_32BIT_RW
|
||||
spi_dev->bits_per_word = 32;
|
||||
#else
|
||||
spi_dev->bits_per_word = 8;
|
||||
#endif /* SPI_PIO_32BIT_RW */
|
||||
ret = spi_setup(spi_dev);
|
||||
|
||||
if (ret) {
|
||||
sd_err(("bcmsdh_spi_probe: spi_setup fail with %d\n", ret));
|
||||
}
|
||||
sd_err(("bcmsdh_spi_probe: spi_setup with %d, bits_per_word=%d\n",
|
||||
ret, spi_dev->bits_per_word));
|
||||
ret = bcmsdh_probe(&spi_dev->dev);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int bcmsdh_spi_remove(struct spi_device *spi_dev)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
ret = bcmsdh_remove(&spi_dev->dev);
|
||||
gBCMSPI = NULL;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct spi_driver bcmsdh_spi_driver = {
|
||||
.probe = bcmsdh_spi_probe,
|
||||
.remove = bcmsdh_spi_remove,
|
||||
.driver = {
|
||||
.name = "wlan_spi",
|
||||
.bus = &spi_bus_type,
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
};
|
||||
|
||||
/*
|
||||
* module init
|
||||
*/
|
||||
int bcmsdh_register_client_driver(void)
|
||||
{
|
||||
int error = 0;
|
||||
sd_trace(("bcmsdh_gspi: %s Enter\n", __FUNCTION__));
|
||||
|
||||
error = spi_register_driver(&bcmsdh_spi_driver);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
/*
|
||||
* module cleanup
|
||||
*/
|
||||
void bcmsdh_unregister_client_driver(void)
|
||||
{
|
||||
sd_trace(("%s Enter\n", __FUNCTION__));
|
||||
spi_unregister_driver(&bcmsdh_spi_driver);
|
||||
}
|
||||
#endif /* BCMSPI_ANDROID */
|
||||
|
||||
/* Register with Linux for interrupts */
|
||||
int
|
||||
spi_register_irq(sdioh_info_t *sd, uint irq)
|
||||
{
|
||||
#ifndef BCMSPI_ANDROID
|
||||
sd_trace(("Entering %s: irq == %d\n", __FUNCTION__, irq));
|
||||
if (request_irq(irq, sdspi_isr, IRQF_SHARED, "bcmsdspi", sd) < 0) {
|
||||
sd_err(("%s: request_irq() failed\n", __FUNCTION__));
|
||||
return ERROR;
|
||||
}
|
||||
#endif /* !BCMSPI_ANDROID */
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/* Free Linux irq */
|
||||
void
|
||||
spi_free_irq(uint irq, sdioh_info_t *sd)
|
||||
{
|
||||
#ifndef BCMSPI_ANDROID
|
||||
free_irq(irq, sd);
|
||||
#endif /* !BCMSPI_ANDROID */
|
||||
}
|
||||
|
||||
/* Map Host controller registers */
|
||||
#ifndef BCMSPI_ANDROID
|
||||
uint32 *
|
||||
spi_reg_map(osl_t *osh, uintptr addr, int size)
|
||||
{
|
||||
return (uint32 *)REG_MAP(addr, size);
|
||||
}
|
||||
|
||||
void
|
||||
spi_reg_unmap(osl_t *osh, uintptr addr, int size)
|
||||
{
|
||||
REG_UNMAP((void*)(uintptr)addr);
|
||||
}
|
||||
#endif /* !BCMSPI_ANDROID */
|
||||
|
||||
int
|
||||
spi_osinit(sdioh_info_t *sd)
|
||||
{
|
||||
struct sdos_info *sdos;
|
||||
|
||||
sdos = (struct sdos_info*)MALLOC(sd->osh, sizeof(struct sdos_info));
|
||||
sd->sdos_info = (void*)sdos;
|
||||
if (sdos == NULL)
|
||||
return BCME_NOMEM;
|
||||
|
||||
sdos->sd = sd;
|
||||
spin_lock_init(&sdos->lock);
|
||||
#ifndef BCMSPI_ANDROID
|
||||
init_waitqueue_head(&sdos->intr_wait_queue);
|
||||
#endif /* !BCMSPI_ANDROID */
|
||||
return BCME_OK;
|
||||
}
|
||||
|
||||
void
|
||||
spi_osfree(sdioh_info_t *sd)
|
||||
{
|
||||
struct sdos_info *sdos;
|
||||
ASSERT(sd && sd->sdos_info);
|
||||
|
||||
sdos = (struct sdos_info *)sd->sdos_info;
|
||||
MFREE(sd->osh, sdos, sizeof(struct sdos_info));
|
||||
}
|
||||
|
||||
/* Interrupt enable/disable */
|
||||
SDIOH_API_RC
|
||||
sdioh_interrupt_set(sdioh_info_t *sd, bool enable)
|
||||
{
|
||||
ulong flags;
|
||||
struct sdos_info *sdos;
|
||||
|
||||
sd_trace(("%s: %s\n", __FUNCTION__, enable ? "Enabling" : "Disabling"));
|
||||
|
||||
sdos = (struct sdos_info *)sd->sdos_info;
|
||||
ASSERT(sdos);
|
||||
|
||||
if (!(sd->host_init_done && sd->card_init_done)) {
|
||||
sd_err(("%s: Card & Host are not initted - bailing\n", __FUNCTION__));
|
||||
return SDIOH_API_RC_FAIL;
|
||||
}
|
||||
|
||||
#ifndef BCMSPI_ANDROID
|
||||
if (enable && !(sd->intr_handler && sd->intr_handler_arg)) {
|
||||
sd_err(("%s: no handler registered, will not enable\n", __FUNCTION__));
|
||||
return SDIOH_API_RC_FAIL;
|
||||
}
|
||||
#endif /* !BCMSPI_ANDROID */
|
||||
|
||||
/* Ensure atomicity for enable/disable calls */
|
||||
spin_lock_irqsave(&sdos->lock, flags);
|
||||
|
||||
sd->client_intr_enabled = enable;
|
||||
#ifndef BCMSPI_ANDROID
|
||||
if (enable && !sd->lockcount)
|
||||
spi_devintr_on(sd);
|
||||
else
|
||||
spi_devintr_off(sd);
|
||||
#endif /* !BCMSPI_ANDROID */
|
||||
|
||||
spin_unlock_irqrestore(&sdos->lock, flags);
|
||||
|
||||
return SDIOH_API_RC_SUCCESS;
|
||||
}
|
||||
|
||||
/* Protect against reentrancy (disable device interrupts while executing) */
|
||||
void
|
||||
spi_lock(sdioh_info_t *sd)
|
||||
{
|
||||
ulong flags;
|
||||
struct sdos_info *sdos;
|
||||
|
||||
sdos = (struct sdos_info *)sd->sdos_info;
|
||||
ASSERT(sdos);
|
||||
|
||||
sd_trace(("%s: %d\n", __FUNCTION__, sd->lockcount));
|
||||
|
||||
spin_lock_irqsave(&sdos->lock, flags);
|
||||
if (sd->lockcount) {
|
||||
sd_err(("%s: Already locked!\n", __FUNCTION__));
|
||||
ASSERT(sd->lockcount == 0);
|
||||
}
|
||||
#ifdef BCMSPI_ANDROID
|
||||
if (sd->client_intr_enabled)
|
||||
bcmsdh_oob_intr_set(0);
|
||||
#else
|
||||
spi_devintr_off(sd);
|
||||
#endif /* BCMSPI_ANDROID */
|
||||
sd->lockcount++;
|
||||
spin_unlock_irqrestore(&sdos->lock, flags);
|
||||
}
|
||||
|
||||
/* Enable client interrupt */
|
||||
void
|
||||
spi_unlock(sdioh_info_t *sd)
|
||||
{
|
||||
ulong flags;
|
||||
struct sdos_info *sdos;
|
||||
|
||||
sd_trace(("%s: %d, %d\n", __FUNCTION__, sd->lockcount, sd->client_intr_enabled));
|
||||
ASSERT(sd->lockcount > 0);
|
||||
|
||||
sdos = (struct sdos_info *)sd->sdos_info;
|
||||
ASSERT(sdos);
|
||||
|
||||
spin_lock_irqsave(&sdos->lock, flags);
|
||||
if (--sd->lockcount == 0 && sd->client_intr_enabled) {
|
||||
#ifdef BCMSPI_ANDROID
|
||||
bcmsdh_oob_intr_set(1);
|
||||
#else
|
||||
spi_devintr_on(sd);
|
||||
#endif /* BCMSPI_ANDROID */
|
||||
}
|
||||
spin_unlock_irqrestore(&sdos->lock, flags);
|
||||
}
|
||||
|
||||
#ifndef BCMSPI_ANDROID
|
||||
void spi_waitbits(sdioh_info_t *sd, bool yield)
|
||||
{
|
||||
#ifndef BCMSDYIELD
|
||||
ASSERT(!yield);
|
||||
#endif
|
||||
sd_trace(("%s: yield %d canblock %d\n",
|
||||
__FUNCTION__, yield, BLOCKABLE()));
|
||||
|
||||
/* Clear the "interrupt happened" flag and last intrstatus */
|
||||
sd->got_hcint = FALSE;
|
||||
|
||||
#ifdef BCMSDYIELD
|
||||
if (yield && BLOCKABLE()) {
|
||||
struct sdos_info *sdos;
|
||||
sdos = (struct sdos_info *)sd->sdos_info;
|
||||
/* Wait for the indication, the interrupt will be masked when the ISR fires. */
|
||||
wait_event_interruptible(sdos->intr_wait_queue, (sd->got_hcint));
|
||||
} else
|
||||
#endif /* BCMSDYIELD */
|
||||
{
|
||||
spi_spinbits(sd);
|
||||
}
|
||||
|
||||
}
|
||||
#else /* !BCMSPI_ANDROID */
|
||||
int bcmgspi_dump = 0; /* Set to dump complete trace of all SPI bus transactions */
|
||||
|
||||
static void
|
||||
hexdump(char *pfx, unsigned char *msg, int msglen)
|
||||
{
|
||||
int i, col;
|
||||
char buf[80];
|
||||
|
||||
ASSERT(strlen(pfx) + 49 <= sizeof(buf));
|
||||
|
||||
col = 0;
|
||||
|
||||
for (i = 0; i < msglen; i++, col++) {
|
||||
if (col % 16 == 0)
|
||||
strcpy(buf, pfx);
|
||||
sprintf(buf + strlen(buf), "%02x", msg[i]);
|
||||
if ((col + 1) % 16 == 0)
|
||||
printf("%s\n", buf);
|
||||
else
|
||||
sprintf(buf + strlen(buf), " ");
|
||||
}
|
||||
|
||||
if (col % 16 != 0)
|
||||
printf("%s\n", buf);
|
||||
}
|
||||
|
||||
/* Send/Receive an SPI Packet */
|
||||
void
|
||||
spi_sendrecv(sdioh_info_t *sd, uint8 *msg_out, uint8 *msg_in, int msglen)
|
||||
{
|
||||
int write = 0;
|
||||
int tx_len = 0;
|
||||
struct spi_message msg;
|
||||
struct spi_transfer t[2];
|
||||
|
||||
spi_message_init(&msg);
|
||||
memset(t, 0, 2*sizeof(struct spi_transfer));
|
||||
|
||||
if (sd->wordlen == 2)
|
||||
#if !(defined(SPI_PIO_RW_BIGENDIAN) && defined(SPI_PIO_32BIT_RW))
|
||||
write = msg_out[2] & 0x80; /* XXX bit 7: read:0, write :1 */
|
||||
#else
|
||||
write = msg_out[1] & 0x80; /* XXX bit 7: read:0, write :1 */
|
||||
#endif /* !(defined(SPI_PIO_RW_BIGENDIAN) && defined(SPI_PIO_32BIT_RW)) */
|
||||
if (sd->wordlen == 4)
|
||||
#if !(defined(SPI_PIO_RW_BIGENDIAN) && defined(SPI_PIO_32BIT_RW))
|
||||
write = msg_out[0] & 0x80; /* XXX bit 7: read:0, write :1 */
|
||||
#else
|
||||
write = msg_out[3] & 0x80; /* XXX bit 7: read:0, write :1 */
|
||||
#endif /* !(defined(SPI_PIO_RW_BIGENDIAN) && defined(SPI_PIO_32BIT_RW)) */
|
||||
|
||||
if (bcmgspi_dump) {
|
||||
hexdump(" OUT: ", msg_out, msglen);
|
||||
}
|
||||
|
||||
tx_len = write ? msglen-4 : 4;
|
||||
|
||||
sd_trace(("spi_sendrecv: %s, wordlen %d, cmd : 0x%02x 0x%02x 0x%02x 0x%02x\n",
|
||||
write ? "WR" : "RD", sd->wordlen,
|
||||
msg_out[0], msg_out[1], msg_out[2], msg_out[3]));
|
||||
|
||||
t[0].tx_buf = (char *)&msg_out[0];
|
||||
t[0].rx_buf = 0;
|
||||
t[0].len = tx_len;
|
||||
|
||||
spi_message_add_tail(&t[0], &msg);
|
||||
|
||||
t[1].rx_buf = (char *)&msg_in[tx_len];
|
||||
t[1].tx_buf = 0;
|
||||
t[1].len = msglen-tx_len;
|
||||
|
||||
spi_message_add_tail(&t[1], &msg);
|
||||
spi_sync(gBCMSPI, &msg);
|
||||
|
||||
if (bcmgspi_dump) {
|
||||
hexdump(" IN : ", msg_in, msglen);
|
||||
}
|
||||
}
|
||||
#endif /* !BCMSPI_ANDROID */
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* 'Standard' SDIO HOST CONTROLLER driver
|
||||
*
|
||||
* Copyright (C) 2020, Broadcom.
|
||||
* Copyright (C) 2022, Broadcom.
|
||||
*
|
||||
* Unless you and Broadcom execute a separate written software license
|
||||
* agreement governing use of this software, this software is licensed to you
|
||||
|
|
@ -134,38 +134,46 @@ uint32 sd3_autoselect_uhsi_max = 0;
|
|||
* All has DrvStr as 'B' [val:0] and CLKGEN as 0.
|
||||
*/
|
||||
static unsigned short presetval_sw_table[] = {
|
||||
0x0520, /* initialization: DrvStr:'B' [0]; CLKGen:0;
|
||||
0x0520, /* initialization: DrvStr:'B' [0]; CLKGen:0;
|
||||
* SDCLKFreqSel: 520 [division: 320*2 = 640: ~400 KHz]
|
||||
*/
|
||||
0x0008, /* default speed:DrvStr:'B' [0]; CLKGen:0;
|
||||
* SDCLKFreqSel: 8 [division: 6*2 = 12: ~25 MHz]
|
||||
*/
|
||||
0x0004, /* High speed: DrvStr:'B' [0]; CLKGen:0;
|
||||
0x0004, /* High speed: DrvStr:'B' [0]; CLKGen:0;
|
||||
* SDCLKFreqSel: 4 [division: 3*2 = 6: ~50 MHz]
|
||||
*/
|
||||
0x0008, /* SDR12: DrvStr:'B' [0]; CLKGen:0;
|
||||
0x0008, /* SDR12: DrvStr:'B' [0]; CLKGen:0;
|
||||
* SDCLKFreqSel: 8 [division: 6*2 = 12: ~25 MHz]
|
||||
*/
|
||||
0x0004, /* SDR25: DrvStr:'B' [0]; CLKGen:0;
|
||||
0x0004, /* SDR25: DrvStr:'B' [0]; CLKGen:0;
|
||||
* SDCLKFreqSel: 4 [division: 3*2 = 6: ~50 MHz]
|
||||
*/
|
||||
0x0001, /* SDR50: DrvStr:'B' [0]; CLKGen:0;
|
||||
0x0001, /* SDR50: DrvStr:'B' [0]; CLKGen:0;
|
||||
* SDCLKFreqSel: 2 [division: 1*2 = 2: ~100 MHz]
|
||||
*/
|
||||
0x0001, /* SDR104: DrvStr:'B' [0]; CLKGen:0;
|
||||
0x0001, /* SDR104: DrvStr:'B' [0]; CLKGen:0;
|
||||
SDCLKFreqSel: 1 [no division: ~255/~208 MHz]
|
||||
*/
|
||||
0x0002 /* DDR50: DrvStr:'B' [0]; CLKGen:0;
|
||||
0x0002 /* DDR50: DrvStr:'B' [0]; CLKGen:0;
|
||||
SDCLKFreqSel: 4 [division: 3*2 = 6: ~50 MHz]
|
||||
*/
|
||||
};
|
||||
|
||||
#ifdef BCMFPGA_HW
|
||||
/*
|
||||
* Voltage switch, clock tuning and preset are not supported in
|
||||
* FPGA which operates at 6.25Mhz.
|
||||
*/
|
||||
bool sd3_sw_override1 = TRUE;
|
||||
#else
|
||||
/* This is to have software overrides to the hardware. Info follows:
|
||||
For override [1]: Preset registers: not supported
|
||||
For override [1]: Preset registers: not supported
|
||||
Voltage switch: not supported
|
||||
Clock Tuning: not supported
|
||||
*/
|
||||
bool sd3_sw_override1 = FALSE;
|
||||
#endif /* BCMFPGA_HW */
|
||||
bool sd3_sw_read_magic_bytes = FALSE;
|
||||
|
||||
#define SD3_TUNING_REQD(sd, sd_uhsimode) ((sd_uhsimode != SD3CLKMODE_DISABLED) && \
|
||||
|
|
@ -248,14 +256,6 @@ static bool sdstd_3_get_matching_drvstrn(sdioh_info_t *sd,
|
|||
static int sdstd_3_clock_wrapper(sdioh_info_t *sd);
|
||||
static int sdstd_clock_wrapper(sdioh_info_t *sd);
|
||||
|
||||
#ifdef BCMINTERNAL
|
||||
#ifdef NOTUSED
|
||||
static int parse_caps(uint32 caps_reg, char *buf, int len);
|
||||
static int parse_state(uint32 state_reg, char *buf, int len);
|
||||
static void cis_fetch(sdioh_info_t *sd, int func, char *data, int len);
|
||||
#endif /* NOTUSED */
|
||||
#endif /* BCMINTERNAL */
|
||||
|
||||
#ifdef BCMDBG
|
||||
static void print_regs(sdioh_info_t *sd);
|
||||
#endif
|
||||
|
|
@ -321,25 +321,6 @@ sdstd_wreg(sdioh_info_t *sd, uint reg, uint32 data)
|
|||
sd_ctrl(("32: W Reg 0x%02x, Data 0x%x\n", reg, data));
|
||||
|
||||
}
|
||||
#ifdef BCMINTERNAL
|
||||
#ifdef NOTUSED
|
||||
static void
|
||||
sdstd_or_reg(sdioh_info_t *sd, uint reg, uint32 val)
|
||||
{
|
||||
volatile uint32 data = *(volatile uint32 *)(sd->mem_space + reg);
|
||||
data |= val;
|
||||
*(volatile uint32 *)(sd->mem_space + reg) = (volatile uint32)data;
|
||||
}
|
||||
static void
|
||||
sdstd_mod_reg(sdioh_info_t *sd, uint reg, uint32 mask, uint32 val)
|
||||
{
|
||||
volatile uint32 data = *(volatile uint32 *)(sd->mem_space + reg);
|
||||
data &= ~mask;
|
||||
data |= (val & mask);
|
||||
*(volatile uint32 *)(sd->mem_space + reg) = (volatile uint32)data;
|
||||
}
|
||||
#endif /* NOTUSED */
|
||||
#endif /* BCMINTERNAL */
|
||||
|
||||
/* 8 bit PCI regs */
|
||||
static inline void
|
||||
|
|
@ -545,7 +526,8 @@ enum {
|
|||
IOV_CLOCK,
|
||||
IOV_UHSIMOD,
|
||||
IOV_TUNEMOD,
|
||||
IOV_TUNEDIS
|
||||
IOV_TUNEDIS,
|
||||
IOV_DS
|
||||
};
|
||||
|
||||
const bcm_iovar_t sdioh_iovars[] = {
|
||||
|
|
@ -575,6 +557,7 @@ const bcm_iovar_t sdioh_iovars[] = {
|
|||
#endif
|
||||
{"tuning_mode", IOV_TUNEMOD, 0, 0, IOVT_UINT32, 0},
|
||||
{"sd3_tuning_disable", IOV_TUNEDIS, 0, 0, IOVT_BOOL, 0},
|
||||
{"sd_ds", IOV_DS, 0, 0, IOVT_UINT32, 0},
|
||||
|
||||
{NULL, 0, 0, 0, 0, 0 }
|
||||
};
|
||||
|
|
@ -1024,6 +1007,58 @@ sdioh_iovar_op(sdioh_info_t *si, const char *name,
|
|||
si->sd3_tuning_disable = (bool)int_val;
|
||||
break;
|
||||
|
||||
case IOV_GVAL(IOV_DS):
|
||||
{
|
||||
uint32 drvstrn;
|
||||
int status;
|
||||
|
||||
status = sdstd_card_regread(si, 0, SDIOD_CCCR_DRIVER_STRENGTH, 1, &drvstrn);
|
||||
if (status != BCME_OK) {
|
||||
sd_err(("sd_ds error for read SDIOD_CCCR_DRIVER_STRENGTH : 0x%x\n",
|
||||
status));
|
||||
bcmerror = BCME_SDIO_ERROR;
|
||||
} else {
|
||||
sd_err(("sd_ds get cccr driver strength 0x%x\n", drvstrn));
|
||||
}
|
||||
int_val = (uint32)drvstrn;
|
||||
bcopy(&int_val, arg, val_size);
|
||||
break;
|
||||
}
|
||||
|
||||
case IOV_SVAL(IOV_DS):
|
||||
{
|
||||
uint32 drvstrn;
|
||||
int status;
|
||||
|
||||
status = sdstd_card_regread(si, 0, SDIOD_CCCR_DRIVER_STRENGTH, 1, &drvstrn);
|
||||
if (status != BCME_OK) {
|
||||
sd_err(("sd_ds error for read SDIOD_CCCR_DRIVER_STRENGTH : 0x%x\n",
|
||||
status));
|
||||
bcmerror = BCME_SDIO_ERROR;
|
||||
} else {
|
||||
sd_err(("sd_ds get cccr driver strength 0x%x\n", drvstrn));
|
||||
}
|
||||
|
||||
if (int_val == 0) {
|
||||
drvstrn = ((drvstrn & 0xf) | 0x0);
|
||||
} else if (int_val == 1) {
|
||||
drvstrn = ((drvstrn & 0xf) | 0x10);
|
||||
} else if (int_val == 2) {
|
||||
drvstrn = ((drvstrn & 0xf) | 0x20);
|
||||
} else if (int_val == 3) {
|
||||
drvstrn = ((drvstrn & 0xf) | 0x30);
|
||||
} else {
|
||||
bcmerror = BCME_BADARG;
|
||||
break;
|
||||
}
|
||||
|
||||
status = sdstd_card_regwrite(si, 0, SDIOD_CCCR_DRIVER_STRENGTH, 1, drvstrn);
|
||||
if (status != BCME_OK) {
|
||||
sd_err(("sd_ds error write SDIOD_CCCR_DRIVER_STRENGTH : 0x%x\n", status));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
bcmerror = BCME_UNSUPPORTED;
|
||||
break;
|
||||
|
|
@ -1834,15 +1869,6 @@ sdstd_check_errs(sdioh_info_t *sdioh_info, uint32 cmd, uint32 arg)
|
|||
return ERROR;
|
||||
}
|
||||
|
||||
#ifdef BCMINTERNAL
|
||||
extern SDIOH_API_RC
|
||||
sdioh_test_diag(sdioh_info_t *sd)
|
||||
{
|
||||
sd_err(("%s: Implement me\n", __FUNCTION__));
|
||||
return (0);
|
||||
}
|
||||
#endif /* BCMINTERNAL */
|
||||
|
||||
/*
|
||||
* Private/Static work routines
|
||||
*/
|
||||
|
|
@ -1988,12 +2014,6 @@ sdstd_host_init(sdioh_info_t *sd)
|
|||
__FUNCTION__));
|
||||
sd->controller_type = SDIOH_TYPE_JMICRON;
|
||||
detect_slots = TRUE;
|
||||
#ifdef BCMINTERNAL
|
||||
} else if ((OSL_PCI_READ_CONFIG(sd->osh, PCI_CFG_VID, 4) & 0xFFFF) == VENDOR_JINVANI) {
|
||||
sd_info(("%s: Found Jinvani Standard SDIO Host Controller\n", __FUNCTION__));
|
||||
detect_slots = FALSE;
|
||||
sd->controller_type = SDIOH_TYPE_JINVANI_GOLD;
|
||||
#endif /* BCMINTERNAL */
|
||||
} else {
|
||||
return ERROR;
|
||||
}
|
||||
|
|
@ -2127,46 +2147,6 @@ sdstd_host_init(sdioh_info_t *sd)
|
|||
|
||||
sdstd_set_dma_mode(sd, sd->sd_dma_mode);
|
||||
|
||||
#if defined(BCMINTERNAL)
|
||||
if (OSL_PCI_READ_CONFIG(sd->osh, PCI_CFG_VID, 4) ==
|
||||
((SDIOH_FPGA_ID << 16) | VENDOR_BROADCOM)) {
|
||||
sd_err(("* * * SDIO20H FPGA Build Date: 0x%04x\n", sdstd_rreg(sd, 0x110)));
|
||||
}
|
||||
|
||||
if (GFIELD(sd->caps, CAP_MAXBLOCK) == 0x3) {
|
||||
sd_info(("SD HOST CAPS: Max block size is INVALID\n"));
|
||||
} else {
|
||||
sd_info(("SD HOST CAPS: Max block size is %d bytes\n",
|
||||
512 << GFIELD(sd->caps, CAP_MAXBLOCK)));
|
||||
}
|
||||
|
||||
sd_info(("SD HOST CAPS: 64-bit DMA is %ssupported.\n",
|
||||
GFIELD(sd->caps, CAP_64BIT_HOST) ? "" : "not "));
|
||||
sd_info(("SD HOST CAPS: Suspend/Resume is %ssupported.\n",
|
||||
GFIELD(sd->caps, CAP_SUSPEND) ? "" : "not "));
|
||||
|
||||
sd_err(("SD HOST CAPS: SD Host supports "));
|
||||
if (GFIELD(sd->caps, CAP_VOLT_3_3)) {
|
||||
sd_err(("3.3V"));
|
||||
if (GFIELD(sd->curr_caps, CAP_CURR_3_3)) {
|
||||
sd_err(("@%dmA\n", 4*GFIELD(sd->curr_caps, CAP_CURR_3_3)));
|
||||
}
|
||||
}
|
||||
if (GFIELD(sd->caps, CAP_VOLT_3_0)) {
|
||||
sd_err((", 3.0V"));
|
||||
if (GFIELD(sd->curr_caps, CAP_CURR_3_0)) {
|
||||
sd_err(("@%dmA\n", 4*GFIELD(sd->curr_caps, CAP_CURR_3_0)));
|
||||
}
|
||||
}
|
||||
if (GFIELD(sd->caps, CAP_VOLT_1_8)) {
|
||||
sd_err((", 1.8V"));
|
||||
if (GFIELD(sd->curr_caps, CAP_CURR_1_8)) {
|
||||
sd_err(("@%dmA\n", 4*GFIELD(sd->curr_caps, CAP_CURR_1_8)));
|
||||
}
|
||||
}
|
||||
sd_err(("\n"));
|
||||
#endif /* defined(BCMINTERNAL) */
|
||||
|
||||
sdstd_reset(sd, 1, 0);
|
||||
|
||||
/* Read SD4/SD1 mode */
|
||||
|
|
@ -2257,15 +2237,6 @@ sdstd_client_init(sdioh_info_t *sd)
|
|||
uint32 regdata;
|
||||
uint16 powerstat = 0;
|
||||
|
||||
#ifdef BCMINTERNAL
|
||||
#ifdef NOTUSED
|
||||
/* Handy routine to dump capabilities. */
|
||||
static char caps_buf[500];
|
||||
parse_caps(sd->caps, caps_buf, 500);
|
||||
sd_err((caps_buf));
|
||||
#endif /* NOTUSED */
|
||||
#endif /* BCMINTERNAL */
|
||||
|
||||
sd_trace(("%s: Powering up slot %d\n", __FUNCTION__, sd->adapter_slot));
|
||||
|
||||
/* Clear any pending ints */
|
||||
|
|
@ -2433,11 +2404,24 @@ sdstd_client_init(sdioh_info_t *sd)
|
|||
static int
|
||||
sdstd_clock_wrapper(sdioh_info_t *sd)
|
||||
{
|
||||
uint ret = 0;
|
||||
sd_trace(("%s:Enter\n", __FUNCTION__));
|
||||
/* After configuring for High-Speed mode, set the desired clock rate. */
|
||||
sdstd_set_highspeed_mode(sd, (bool)sd_hiok);
|
||||
|
||||
if (FALSE == sdstd_start_clock(sd, (uint16)sd_divisor)) {
|
||||
#ifdef BCMFPGA_HW
|
||||
/*
|
||||
* To make the SDIO clock 6.25Mhz for FPGA divide the
|
||||
* standard clock with 8 insted of default 2. 50Mhz/8 = 6.25Mhz
|
||||
* sdstd_clock_wrapper() is used to start clock for default and
|
||||
* high speed only.
|
||||
*/
|
||||
sd_err(("%s set 6.25Mhz clock speed for FPGA default or high speed\n", __FUNCTION__));
|
||||
ret = sdstd_start_clock(sd, ((uint16)sd_divisor * 4));
|
||||
#else
|
||||
ret = sdstd_start_clock(sd, (uint16)sd_divisor);
|
||||
#endif /* BCMFPGA_HW */
|
||||
if (ret != TRUE) {
|
||||
sd_err(("sdstd_start_clock failed\n"));
|
||||
return ERROR;
|
||||
}
|
||||
|
|
@ -2693,6 +2677,7 @@ sdstd_3_set_highspeed_uhsi_mode(sdioh_info_t *sd, int sd3ClkMode)
|
|||
uint8 hc_reg8;
|
||||
uint16 val1 = 0, presetval = 0;
|
||||
uint32 regdata;
|
||||
uint32 ret = 0;
|
||||
|
||||
sd3_trace(("sd3: %s:enter:clkmode:%d\n", __FUNCTION__, sd3ClkMode));
|
||||
|
||||
|
|
@ -2780,9 +2765,19 @@ sdstd_3_set_highspeed_uhsi_mode(sdioh_info_t *sd, int sd3ClkMode)
|
|||
sdstd_wreg16(sd, SD3_HostCntrl2, val1);
|
||||
|
||||
sd_err(("%s:HostCtrl2 final value:0x%x\n", __FUNCTION__, val1));
|
||||
|
||||
#ifdef BCMFPGA_HW
|
||||
/*
|
||||
* To make the SDIO clock 6.25Mhz for FPGA divide the
|
||||
* standard clock with 0x20. 208Mhz/32 = 6.25Mhz
|
||||
* this function is invoked to start clock for UHSI mode only
|
||||
*/
|
||||
sd_err(("%s set 6.25Mhz clock speed for UHSI speed\n", __FUNCTION__));
|
||||
ret = sdstd_start_clock(sd, 0x20);
|
||||
#else
|
||||
ret = sdstd_start_clock(sd, GFIELD(presetval, PRESET_CLK_DIV));
|
||||
#endif /* BCMFPGA_HW */
|
||||
if (ret != TRUE) {
|
||||
/* start clock : clk will be enabled inside. */
|
||||
if (FALSE == sdstd_start_clock(sd, GFIELD(presetval, PRESET_CLK_DIV))) {
|
||||
sd_err(("sdstd_start_clock failed\n"));
|
||||
return ERROR;
|
||||
}
|
||||
|
|
@ -3143,16 +3138,6 @@ sdstd_set_highspeed_mode(sdioh_info_t *sd, bool HSMode)
|
|||
|
||||
reg8 = sdstd_rreg8(sd, SD_HostCntrl);
|
||||
|
||||
#ifdef BCMINTERNAL
|
||||
/* The Jinvani SD Gold Host forces the highest clock rate in high-speed mode */
|
||||
/* Only enable high-speed mode if the SD clock divisor is 1. */
|
||||
if (sd->controller_type == SDIOH_TYPE_JINVANI_GOLD) {
|
||||
if (sd_divisor != 1) {
|
||||
HSMode = FALSE;
|
||||
}
|
||||
}
|
||||
#endif /* BCMINTERNAL */
|
||||
|
||||
if (HSMode == TRUE) {
|
||||
if (sd_hiok && (GFIELD(sd->caps, CAP_HIGHSPEED)) == 0) {
|
||||
sd_err(("Host Controller does not support hi-speed mode.\n"));
|
||||
|
|
@ -3409,61 +3394,6 @@ print_regs(sdioh_info_t *sd)
|
|||
}
|
||||
#endif /* BCMDBG */
|
||||
|
||||
#ifdef BCMINTERNAL
|
||||
#ifdef NOTUSED
|
||||
static int
|
||||
parse_state(uint32 state, char *buf, int len)
|
||||
{
|
||||
char *data = buf;
|
||||
|
||||
sd_err(("Parsing state 0x%x\n", state));
|
||||
if (!len) {
|
||||
return (0);
|
||||
}
|
||||
|
||||
data += sprintf(data, "cmd_inhibit %d\n", GFIELD(state, PRES_CMD_INHIBIT));
|
||||
data += sprintf(data, "dat_inhibit %d\n", GFIELD(state, PRES_DAT_INHIBIT));
|
||||
data += sprintf(data, "dat_busy %d\n", GFIELD(state, PRES_DAT_BUSY));
|
||||
data += sprintf(data, "write_active %d\n", GFIELD(state, PRES_WRITE_ACTIVE));
|
||||
data += sprintf(data, "read_active %d\n", GFIELD(state, PRES_READ_ACTIVE));
|
||||
data += sprintf(data, "write_data_rdy %d\n", GFIELD(state, PRES_WRITE_DATA_RDY));
|
||||
data += sprintf(data, "read_data_rdy %d\n", GFIELD(state, PRES_READ_DATA_RDY));
|
||||
data += sprintf(data, "card_present %d\n", GFIELD(state, PRES_CARD_PRESENT));
|
||||
data += sprintf(data, "card_stable %d\n", GFIELD(state, PRES_CARD_STABLE));
|
||||
data += sprintf(data, "card_present_raw %d\n", GFIELD(state, PRES_CARD_PRESENT_RAW));
|
||||
data += sprintf(data, "write_enabled %d\n", GFIELD(state, PRES_WRITE_ENABLED));
|
||||
data += sprintf(data, "cmd_signal %d\n", GFIELD(state, PRES_CMD_SIGNAL));
|
||||
|
||||
return (data - buf);
|
||||
}
|
||||
|
||||
static int
|
||||
parse_caps(uint32 cap, char *buf, int len)
|
||||
{
|
||||
int block = 0xbeef;
|
||||
char *data = buf;
|
||||
|
||||
data += sprintf(data, "TimeOut Clock Freq:\t%d\n", GFIELD(cap, CAP_TO_CLKFREQ));
|
||||
data += sprintf(data, "TimeOut Clock Unit:\t%d\n", GFIELD(cap, CAP_TO_CLKUNIT));
|
||||
data += sprintf(data, "Base Clock:\t\t%d\n", GFIELD(cap, CAP_BASECLK));
|
||||
switch (GFIELD(cap, CAP_MAXBLOCK)) {
|
||||
case 0: block = 512; break;
|
||||
case 1: block = 1024; break;
|
||||
case 2: block = 2048; break;
|
||||
case 3: block = 0; break;
|
||||
}
|
||||
data += sprintf(data, "Max Block Size:\t\t%d\n", block);
|
||||
data += sprintf(data, "Support High Speed:\t%d\n", GFIELD(cap, CAP_HIGHSPEED));
|
||||
data += sprintf(data, "Support DMA:\t\t%d\n", GFIELD(cap, CAP_DMA));
|
||||
data += sprintf(data, "Support Suspend:\t%d\n", GFIELD(cap, CAP_SUSPEND));
|
||||
data += sprintf(data, "Support 3.3 Volts:\t%d\n", GFIELD(cap, CAP_VOLT_3_3));
|
||||
data += sprintf(data, "Support 3.0 Volts:\t%d\n", GFIELD(cap, CAP_VOLT_3_0));
|
||||
data += sprintf(data, "Support 1.8 Volts:\t%d\n", GFIELD(cap, CAP_VOLT_1_8));
|
||||
return (data - buf);
|
||||
}
|
||||
#endif /* NOTUSED */
|
||||
#endif /* BCMINTERNAL */
|
||||
|
||||
/* XXX Per SDIO Host Controller Spec section 3.2.1
|
||||
Note: for 2.x HC, new_sd_divisor should be a power of 2, but for 3.0
|
||||
HC, new_sd_divisor should be a multiple of 2.
|
||||
|
|
@ -3507,11 +3437,6 @@ sdstd_start_clock(sdioh_info_t *sd, uint16 new_sd_divisor)
|
|||
new_sd_divisor = 256;
|
||||
divisor = (new_sd_divisor >> 1) << 8;
|
||||
}
|
||||
#ifdef BCMINTERNAL
|
||||
if (sd->controller_type == SDIOH_TYPE_JINVANI_GOLD) {
|
||||
divisor = (new_sd_divisor >> 2) << 8;
|
||||
}
|
||||
#endif /* BCMINTERNAL */
|
||||
|
||||
sd_info(("Clock control is 0x%x\n", sdstd_rreg16(sd, SD_ClockCntrl)));
|
||||
if (sd->host_UHSISupported) {
|
||||
|
|
@ -3848,6 +3773,7 @@ voltsel:
|
|||
* val1 = SFIELD(val1, HOSTCtrl2_1_8SIG_EN, 1);
|
||||
* sdstd_wreg16(sd, SD3_HostCntrl2, val1);
|
||||
*/
|
||||
|
||||
sd_info(("%s: Not sdio3.0: host_UHSISupported: %d; HC volts=%d\n",
|
||||
__FUNCTION__, sd->host_UHSISupported, volts));
|
||||
}
|
||||
|
|
@ -5143,30 +5069,6 @@ sdioh_sdio_reset(sdioh_info_t *si)
|
|||
return sdstd_client_init(si);
|
||||
}
|
||||
|
||||
#ifdef BCMINTERNAL
|
||||
#ifdef NOTUSED
|
||||
static void
|
||||
cis_fetch(sdioh_info_t *sd, int func, char *data, int len)
|
||||
{
|
||||
int count;
|
||||
int offset;
|
||||
char *end = data + len;
|
||||
uint32 foo;
|
||||
|
||||
for (count = 0; count < 512 && data < end; count++) {
|
||||
offset = sd->func_cis_ptr[func] + count;
|
||||
if (sdstd_card_regread (sd, func, offset, 1, &foo) < 0) {
|
||||
sd_err(("%s: regread failed\n", __FUNCTION__));
|
||||
return;
|
||||
}
|
||||
data += sprintf(data, "%.2x ", foo & 0xff);
|
||||
if (((count+1) % 16) == 0)
|
||||
data += sprintf(data, "\n");
|
||||
}
|
||||
}
|
||||
#endif /* NOTUSED */
|
||||
#endif /* BCMINTERNAL */
|
||||
|
||||
static void
|
||||
sd_map_dma(sdioh_info_t * sd)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* 'Standard' SDIO HOST CONTROLLER driver
|
||||
*
|
||||
* Copyright (C) 2020, Broadcom.
|
||||
* Copyright (C) 2022, Broadcom.
|
||||
*
|
||||
* Unless you and Broadcom execute a separate written software license
|
||||
* agreement governing use of this software, this software is licensed to you
|
||||
|
|
@ -20,7 +20,7 @@
|
|||
*
|
||||
* <<Broadcom-WL-IPTag/Open:>>
|
||||
*
|
||||
* $Id: bcmsdstd.h 833030 2019-08-02 17:22:42Z jl904071 $
|
||||
* $Id: bcmsdstd.h 833030 2019-08-02 17:22:42Z $
|
||||
*/
|
||||
#ifndef _BCM_SD_STD_H
|
||||
#define _BCM_SD_STD_H
|
||||
|
|
@ -80,9 +80,6 @@ extern void sdstd_osfree(sdioh_info_t *sd);
|
|||
|
||||
#define SDIOH_TYPE_ARASAN_HDK 1
|
||||
#define SDIOH_TYPE_BCM27XX 2
|
||||
#ifdef BCMINTERNAL
|
||||
#define SDIOH_TYPE_JINVANI_GOLD 3
|
||||
#endif
|
||||
#define SDIOH_TYPE_TI_PCIXX21 4 /* TI PCIxx21 Standard Host Controller */
|
||||
#define SDIOH_TYPE_RICOH_R5C822 5 /* Ricoh Co Ltd R5C822 SD/SDIO/MMC/MS/MSPro Host Adapter */
|
||||
#define SDIOH_TYPE_JMICRON 6 /* JMicron Standard SDIO Host Controller */
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* 'Standard' SDIO HOST CONTROLLER driver - linux portion
|
||||
*
|
||||
* Copyright (C) 2020, Broadcom.
|
||||
* Copyright (C) 2022, Broadcom.
|
||||
*
|
||||
* Unless you and Broadcom execute a separate written software license
|
||||
* agreement governing use of this software, this software is licensed to you
|
||||
|
|
@ -515,8 +515,15 @@ static struct pci_device_id bcmsdh_pci_devid[] __devinitdata = {
|
|||
class: 0,
|
||||
class_mask: 0,
|
||||
driver_data: 0,
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 3, 0))
|
||||
override_only: 0,
|
||||
#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 3, 0)) */
|
||||
},
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 3, 0))
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 0}
|
||||
#else
|
||||
{ 0, 0, 0, 0, 0, 0, 0}
|
||||
#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 3, 0)) */
|
||||
};
|
||||
MODULE_DEVICE_TABLE(pci, bcmsdh_pci_devid);
|
||||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* Broadcom Secure Standard Library.
|
||||
*
|
||||
* Copyright (C) 2020, Broadcom.
|
||||
* Copyright (C) 2022, Broadcom.
|
||||
*
|
||||
* Unless you and Broadcom execute a separate written software license
|
||||
* agreement governing use of this software, this software is licensed to you
|
||||
|
|
@ -28,6 +28,7 @@
|
|||
#else /* BCMDRIVER */
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#endif /* else BCMDRIVER */
|
||||
|
||||
#include <bcmstdlib_s.h>
|
||||
|
|
@ -60,8 +61,8 @@
|
|||
#endif /* SIZE_MAX */
|
||||
#define RSIZE_MAX (SIZE_MAX >> 1u)
|
||||
|
||||
#if !defined(__STDC_WANT_SECURE_LIB__) && \
|
||||
!(defined(__STDC_LIB_EXT1__) && defined(__STDC_WANT_LIB_EXT1__))
|
||||
#if !defined(__STDC_WANT_SECURE_LIB__) && !(defined(__STDC_LIB_EXT1__) && \
|
||||
defined(__STDC_WANT_LIB_EXT1__))
|
||||
/*
|
||||
* memmove_s - secure memmove
|
||||
* dest : pointer to the object to copy to
|
||||
|
|
@ -73,7 +74,7 @@
|
|||
* than RSIZE_MAX, writes destsz zero bytes into the dest object.
|
||||
*/
|
||||
int
|
||||
memmove_s(void *dest, size_t destsz, const void *src, size_t n)
|
||||
BCMPOSTTRAPFN(memmove_s)(void *dest, size_t destsz, const void *src, size_t n)
|
||||
{
|
||||
int err = BCME_OK;
|
||||
|
||||
|
|
@ -88,13 +89,13 @@ memmove_s(void *dest, size_t destsz, const void *src, size_t n)
|
|||
}
|
||||
|
||||
if (destsz < n) {
|
||||
memset(dest, 0, destsz);
|
||||
bzero(dest, destsz);
|
||||
err = BCME_BADLEN;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if ((!src) || (((const char *)src + n) < (const char *)src)) {
|
||||
memset(dest, 0, destsz);
|
||||
bzero(dest, destsz);
|
||||
err = BCME_BADARG;
|
||||
goto exit;
|
||||
}
|
||||
|
|
@ -132,20 +133,20 @@ BCMPOSTTRAPFN(memcpy_s)(void *dest, size_t destsz, const void *src, size_t n)
|
|||
}
|
||||
|
||||
if (destsz < n) {
|
||||
memset(dest, 0, destsz);
|
||||
bzero(dest, destsz);
|
||||
err = BCME_BADLEN;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if ((!s) || ((s + n) < s)) {
|
||||
memset(dest, 0, destsz);
|
||||
bzero(dest, destsz);
|
||||
err = BCME_BADARG;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* overlap checking between dest and src */
|
||||
if (!(((d + destsz) <= s) || (d >= (s + n)))) {
|
||||
memset(dest, 0, destsz);
|
||||
bzero(dest, destsz);
|
||||
err = BCME_BADARG;
|
||||
goto exit;
|
||||
}
|
||||
|
|
@ -204,7 +205,7 @@ exit:
|
|||
* of course, the buffer size is zero). It does not pad
|
||||
* out the result like strncpy() does.
|
||||
*/
|
||||
size_t strlcpy(char *dest, const char *src, size_t size)
|
||||
size_t BCMPOSTTRAPFN(strlcpy)(char *dest, const char *src, size_t size)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
357
drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/bcmwifi_channels.c
Executable file → Normal file
357
drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/bcmwifi_channels.c
Executable file → Normal file
|
|
@ -3,7 +3,7 @@
|
|||
* Contents are wifi-specific, used by any kernel or app-level
|
||||
* software that might want wifi things as it grows.
|
||||
*
|
||||
* Copyright (C) 2020, Broadcom.
|
||||
* Copyright (C) 2022, Broadcom.
|
||||
*
|
||||
* Unless you and Broadcom execute a separate written software license
|
||||
* agreement governing use of this software, this software is licensed to you
|
||||
|
|
@ -29,7 +29,9 @@
|
|||
#ifdef BCMDRIVER
|
||||
#include <osl.h>
|
||||
#define strtoul(nptr, endptr, base) bcm_strtoul((nptr), (endptr), (base))
|
||||
#ifndef tolower
|
||||
#define tolower(c) (bcm_isupper((c)) ? ((c) + 'a' - 'A') : (c))
|
||||
#endif
|
||||
#else
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
|
@ -47,6 +49,7 @@
|
|||
#endif
|
||||
|
||||
#include <802.11.h>
|
||||
#include <802.11ac.h>
|
||||
|
||||
/* Definitions for D11AC capable (80MHz+) Chanspec type */
|
||||
|
||||
|
|
@ -184,6 +187,13 @@ static const uint8 wf_5g_160m_chans[] = {
|
|||
#define WFC_BW_EQ(bw, val) (FALSE)
|
||||
#endif
|
||||
|
||||
/* compare bandwidth based on WFC_NON_CONT_CHAN */
|
||||
#ifdef WFC_NON_CONT_CHAN
|
||||
#define WFC_NCBW_EQ(bw, val) WFC_2VALS_EQ(bw, val)
|
||||
#else
|
||||
#define WFC_NCBW_EQ(bw, val) (FALSE)
|
||||
#endif
|
||||
|
||||
static void wf_chanspec_iter_firstchan(wf_chanspec_iter_t *iter);
|
||||
static chanspec_bw_t wf_iter_next_bw(chanspec_bw_t bw);
|
||||
static bool wf_chanspec_iter_next_2g(wf_chanspec_iter_t *iter);
|
||||
|
|
@ -383,6 +393,88 @@ channel_6g_320mhz_to_id(uint ch)
|
|||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function returns the the 5GHz 80MHz center channel for the given chanspec 80MHz ID
|
||||
*
|
||||
* @param chan_80MHz_id 80MHz chanspec ID
|
||||
*
|
||||
* @return Return the center channel number, or 0 on error.
|
||||
*
|
||||
*/
|
||||
static uint8
|
||||
wf_chspec_5G_id80_to_ch(uint8 chan_80MHz_id)
|
||||
{
|
||||
if (chan_80MHz_id < WF_NUM_5G_80M_CHANS) {
|
||||
return wf_5g_80m_chans[chan_80MHz_id];
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function returns the the 6GHz 80MHz center channel for the given chanspec 80MHz ID
|
||||
*
|
||||
* @param chan_80MHz_id 80MHz chanspec ID
|
||||
*
|
||||
* @return Return the center channel number, or 0 on error.
|
||||
*
|
||||
*/
|
||||
static uint8
|
||||
wf_chspec_6G_id80_to_ch(uint8 chan_80MHz_id)
|
||||
{
|
||||
uint8 ch = 0;
|
||||
|
||||
if (chan_80MHz_id < WF_NUM_6G_80M_CHANS) {
|
||||
/* The 6GHz center channels have a spacing of 16
|
||||
* starting from the first 80MHz center
|
||||
*/
|
||||
ch = CH_MIN_6G_80M_CHANNEL + (chan_80MHz_id * 16);
|
||||
}
|
||||
|
||||
return ch;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function returns the the 5GHz 160MHz center channel for the given chanspec 160MHz ID
|
||||
*
|
||||
* @param chan_160MHz_id 160MHz chanspec ID
|
||||
*
|
||||
* @return Return the center channel number, or 0 on error.
|
||||
*
|
||||
*/
|
||||
static uint8
|
||||
wf_chspec_5G_id160_to_ch(uint8 chan_160MHz_id)
|
||||
{
|
||||
if (chan_160MHz_id < WF_NUM_5G_160M_CHANS) {
|
||||
return wf_5g_160m_chans[chan_160MHz_id];
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function returns the the 6GHz 160MHz center channel for the given chanspec 160MHz ID
|
||||
*
|
||||
* @param chan_160MHz_id 160MHz chanspec ID
|
||||
*
|
||||
* @return Return the center channel number, or 0 on error.
|
||||
*
|
||||
*/
|
||||
static uint8
|
||||
wf_chspec_6G_id160_to_ch(uint8 chan_160MHz_id)
|
||||
{
|
||||
uint8 ch = 0;
|
||||
|
||||
if (chan_160MHz_id < WF_NUM_6G_160M_CHANS) {
|
||||
/* The 6GHz center channels have a spacing of 32
|
||||
* starting from the first 160MHz center
|
||||
*/
|
||||
ch = CH_MIN_6G_160M_CHANNEL + (chan_160MHz_id * 32);
|
||||
}
|
||||
|
||||
return ch;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function returns the the 6GHz 240MHz center channel for the given chanspec 240MHz ID
|
||||
*
|
||||
|
|
@ -521,6 +613,24 @@ wf_chspec_ntoa(chanspec_t chspec, char *buf)
|
|||
/* bandwidth and primary20 sideband */
|
||||
if (CHSPEC_IS20(chspec)) {
|
||||
snprintf(buf, CHANSPEC_STR_LEN, "%s%d", band, pri_chan);
|
||||
} else if (CHSPEC_IS8080(chspec)) {
|
||||
/* 80+80 */
|
||||
uint ch0;
|
||||
uint ch1;
|
||||
|
||||
/* get the center channels for each frequency segment */
|
||||
if (CHSPEC_IS5G(chspec)) {
|
||||
ch0 = wf_chspec_5G_id80_to_ch(CHSPEC_CHAN0(chspec));
|
||||
ch1 = wf_chspec_5G_id80_to_ch(CHSPEC_CHAN1(chspec));
|
||||
} else if (CHSPEC_IS6G(chspec)) {
|
||||
ch0 = wf_chspec_6G_id80_to_ch(CHSPEC_CHAN0(chspec));
|
||||
ch1 = wf_chspec_6G_id80_to_ch(CHSPEC_CHAN1(chspec));
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Outputs a max of CHANSPEC_STR_LEN chars including '\0' */
|
||||
snprintf(buf, CHANSPEC_STR_LEN, "%s%d/80+80/%d-%d", band, pri_chan, ch0, ch1);
|
||||
} else if (CHSPEC_IS240(chspec)) {
|
||||
/* 240 */
|
||||
const char *bw;
|
||||
|
|
@ -535,6 +645,24 @@ wf_chspec_ntoa(chanspec_t chspec, char *buf)
|
|||
bw = wf_chspec_to_bw_str(chspec);
|
||||
|
||||
snprintf(buf, CHANSPEC_STR_LEN, "%s%d/%s", band, pri_chan, bw);
|
||||
} else if (CHSPEC_IS160160(chspec)) {
|
||||
/* 160+160 */
|
||||
uint ch0;
|
||||
uint ch1;
|
||||
|
||||
/* get the center channels for each frequency segment */
|
||||
if (CHSPEC_IS5G(chspec)) {
|
||||
ch0 = wf_chspec_5G_id160_to_ch(CHSPEC_CHAN0(chspec));
|
||||
ch1 = wf_chspec_5G_id160_to_ch(CHSPEC_CHAN1(chspec));
|
||||
} else if (CHSPEC_IS6G(chspec)) {
|
||||
ch0 = wf_chspec_6G_id160_to_ch(CHSPEC_CHAN0(chspec));
|
||||
ch1 = wf_chspec_6G_id160_to_ch(CHSPEC_CHAN1(chspec));
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Outputs a max of CHANSPEC_STR_LEN chars including '\0' */
|
||||
snprintf(buf, CHANSPEC_STR_LEN, "%s%d/160+160/%d-%d", band, pri_chan, ch0, ch1);
|
||||
} else {
|
||||
const char *bw;
|
||||
const char *sb = "";
|
||||
|
|
@ -796,6 +924,40 @@ wf_chspec_malformed(chanspec_t chanspec)
|
|||
} else {
|
||||
return TRUE;
|
||||
}
|
||||
} else if (WFC_NCBW_EQ(chspec_bw, WL_CHANSPEC_BW_160160)) {
|
||||
uint ch0_id, ch1_id;
|
||||
|
||||
ch0_id = CHSPEC_CHAN0(chanspec);
|
||||
ch1_id = CHSPEC_CHAN1(chanspec);
|
||||
|
||||
/* channel IDs in 160+160 must be in range */
|
||||
if (CHSPEC_IS5G(chanspec) &&
|
||||
(ch0_id >= WF_NUM_5G_160M_CHANS || ch1_id >= WF_NUM_5G_160M_CHANS)) {
|
||||
/* bad 160MHz channel ID for the band */
|
||||
return TRUE;
|
||||
}
|
||||
if (CHSPEC_IS6G(chanspec) &&
|
||||
(ch0_id >= WF_NUM_6G_160M_CHANS || ch1_id >= WF_NUM_6G_160M_CHANS)) {
|
||||
/* bad 160MHz channel ID for the band */
|
||||
return TRUE;
|
||||
}
|
||||
} else if (WFC_NCBW_EQ(chspec_bw, WL_CHANSPEC_BW_8080)) {
|
||||
uint ch0_id, ch1_id;
|
||||
|
||||
ch0_id = CHSPEC_CHAN0(chanspec);
|
||||
ch1_id = CHSPEC_CHAN1(chanspec);
|
||||
|
||||
/* channel IDs in 80+80 must be in range */
|
||||
if (CHSPEC_IS5G(chanspec) &&
|
||||
(ch0_id >= WF_NUM_5G_80M_CHANS || ch1_id >= WF_NUM_5G_80M_CHANS)) {
|
||||
/* bad 80MHz channel ID for the band */
|
||||
return TRUE;
|
||||
}
|
||||
if (CHSPEC_IS6G(chanspec) &&
|
||||
(ch0_id >= WF_NUM_6G_80M_CHANS || ch1_id >= WF_NUM_6G_80M_CHANS)) {
|
||||
/* bad 80MHz channel ID for the band */
|
||||
return TRUE;
|
||||
}
|
||||
} else if (chspec_bw == WL_CHANSPEC_BW_20 || chspec_bw == WL_CHANSPEC_BW_40 ||
|
||||
chspec_bw == WL_CHANSPEC_BW_80 || chspec_bw == WL_CHANSPEC_BW_160) {
|
||||
|
||||
|
|
@ -827,13 +989,15 @@ wf_chspec_malformed(chanspec_t chanspec)
|
|||
} else if (chspec_bw == WL_CHANSPEC_BW_40) {
|
||||
if (chspec_sb > WL_CHANSPEC_CTL_SB_LLU)
|
||||
return TRUE;
|
||||
} else if (chspec_bw == WL_CHANSPEC_BW_80) {
|
||||
} else if (chspec_bw == WL_CHANSPEC_BW_80 ||
|
||||
WFC_NCBW_EQ(chspec_bw, WL_CHANSPEC_BW_8080)) {
|
||||
/* both 80MHz and 80+80MHz use 80MHz side bands.
|
||||
* 80+80 SB info is relative to the primary 80MHz sub-band.
|
||||
*/
|
||||
if (chspec_sb > WL_CHANSPEC_CTL_SB_LUU)
|
||||
return TRUE;
|
||||
} else if (chspec_bw == WL_CHANSPEC_BW_160) {
|
||||
} else if (chspec_bw == WL_CHANSPEC_BW_160 ||
|
||||
WFC_NCBW_EQ(chspec_bw, WL_CHANSPEC_BW_160160)) {
|
||||
ASSERT(chspec_sb <= WL_CHANSPEC_CTL_SB_UUU);
|
||||
} else if (WFC_BW_EQ(chspec_bw, WL_CHANSPEC_BW_240)) {
|
||||
/* FIXME: define the max sideband index */
|
||||
|
|
@ -918,6 +1082,45 @@ wf_chspec_valid(chanspec_t chanspec)
|
|||
|
||||
return wf_valid_320MHz_center_chan(chspec_ch, chspec_band);
|
||||
|
||||
} else if (WFC_NCBW_EQ(chspec_bw, WL_CHANSPEC_BW_8080)) {
|
||||
uint16 ch0 = 0;
|
||||
uint16 ch1 = 0;
|
||||
|
||||
/* get the center channels for each frequency segment */
|
||||
if (CHSPEC_IS5G(chanspec)) {
|
||||
ch0 = wf_chspec_5G_id80_to_ch(CHSPEC_CHAN0(chanspec));
|
||||
ch1 = wf_chspec_5G_id80_to_ch(CHSPEC_CHAN1(chanspec));
|
||||
} else if (CHSPEC_IS6G(chanspec)) {
|
||||
ch0 = wf_chspec_6G_id80_to_ch(CHSPEC_CHAN0(chanspec));
|
||||
ch1 = wf_chspec_6G_id80_to_ch(CHSPEC_CHAN1(chanspec));
|
||||
} else {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* the two channels must be separated by more than 80MHz by VHT req */
|
||||
if ((ch1 > ch0 + CH_80MHZ_APART) ||
|
||||
(ch0 > ch1 + CH_80MHZ_APART))
|
||||
return TRUE;
|
||||
} else if (WFC_NCBW_EQ(chspec_bw, WL_CHANSPEC_BW_160160)) {
|
||||
uint16 ch0 = 0;
|
||||
uint16 ch1 = 0;
|
||||
|
||||
/* get the center channels for each frequency segment */
|
||||
if (CHSPEC_IS5G(chanspec)) {
|
||||
ch0 = wf_chspec_5G_id160_to_ch(CHSPEC_CHAN0(chanspec));
|
||||
ch1 = wf_chspec_5G_id160_to_ch(CHSPEC_CHAN1(chanspec));
|
||||
} else if (CHSPEC_IS6G(chanspec)) {
|
||||
ch0 = wf_chspec_6G_id160_to_ch(CHSPEC_CHAN0(chanspec));
|
||||
ch1 = wf_chspec_6G_id160_to_ch(CHSPEC_CHAN1(chanspec));
|
||||
} else {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* the two channels must be separated by more than 160MHz by EHT req */
|
||||
if ((ch1 > ch0 + CH_160MHZ_APART) ||
|
||||
(ch0 > ch1 + CH_160MHZ_APART)) {
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
|
|
@ -2197,7 +2400,35 @@ wf_chspec_primary20_chan(chanspec_t chspec)
|
|||
sb = CHSPEC_CTL_SB(chspec) >> WL_CHANSPEC_CTL_SB_SHIFT;
|
||||
}
|
||||
|
||||
if (CHSPEC_IS240(chspec)) {
|
||||
if (CHSPEC_IS8080(chspec)) {
|
||||
/* For an 80+80 MHz channel, the sideband 'sb' field is an 80 MHz sideband
|
||||
* (LL, LU, UL, LU) for the 80 MHz frequency segment 0.
|
||||
*/
|
||||
|
||||
/* use bw 80MHz for the primary channel lookup */
|
||||
bw = WL_CHANSPEC_BW_80;
|
||||
|
||||
/* convert from channel index to channel number */
|
||||
if (CHSPEC_IS5G(chspec)) {
|
||||
center_chan = wf_chspec_5G_id80_to_ch(CHSPEC_CHAN0(chspec));
|
||||
} else if (CHSPEC_IS6G(chspec)) {
|
||||
center_chan = wf_chspec_6G_id80_to_ch(CHSPEC_CHAN0(chspec));
|
||||
}
|
||||
} else if (CHSPEC_IS160160(chspec)) {
|
||||
/* For an 160+160 MHz channel, the sideband 'sb' field is an 160MHz sideband
|
||||
* for the 160 MHz frequency segment 0.
|
||||
*/
|
||||
|
||||
/* use bw 160MHz for the primary channel lookup */
|
||||
bw = WL_CHANSPEC_BW_160;
|
||||
|
||||
/* convert from channel index to channel number */
|
||||
if (CHSPEC_IS5G(chspec)) {
|
||||
center_chan = wf_chspec_5G_id160_to_ch(CHSPEC_CHAN0(chspec));
|
||||
} else if (CHSPEC_IS6G(chspec)) {
|
||||
center_chan = wf_chspec_6G_id160_to_ch(CHSPEC_CHAN0(chspec));
|
||||
}
|
||||
} else if (CHSPEC_IS240(chspec)) {
|
||||
/* use bw 240MHz for the primary channel lookup */
|
||||
bw = WL_CHANSPEC_BW_240;
|
||||
|
||||
|
|
@ -2345,7 +2576,7 @@ wf_chspec_primary40_chspec(chanspec_t chspec)
|
|||
ASSERT(!wf_chspec_malformed(chspec));
|
||||
|
||||
/* if the chanspec is > 80MHz, use the helper routine to find the primary 80 MHz channel */
|
||||
if (CHSPEC_IS160(chspec)) {
|
||||
if (CHSPEC_IS8080(chspec) || CHSPEC_IS160(chspec)) {
|
||||
chspec = wf_chspec_primary80_chspec(chspec);
|
||||
}
|
||||
|
||||
|
|
@ -2373,6 +2604,29 @@ wf_chspec_primary40_chspec(chanspec_t chspec)
|
|||
return chspec40;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the chanspec band for a given frequency.
|
||||
*
|
||||
* @param freq frequency in MHz of the channel center
|
||||
*
|
||||
* @return Returns chanspec band of frequency (chanspec_band_t)
|
||||
*/
|
||||
chanspec_band_t
|
||||
wf_mhz2chanspec_band(uint freq)
|
||||
{
|
||||
chanspec_band_t band = INVCHANSPEC;
|
||||
|
||||
if (freq >= 2400u && freq <= 2500u) {
|
||||
band = WL_CHANSPEC_BAND_2G;
|
||||
} else if (freq >= 5000u && freq < 5935u) {
|
||||
band = WL_CHANSPEC_BAND_5G;
|
||||
} else if (freq >= 5935u && freq <= 7205u) {
|
||||
band = WL_CHANSPEC_BAND_6G;
|
||||
}
|
||||
|
||||
return band;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the channel number for a given frequency and base frequency.
|
||||
*
|
||||
|
|
@ -2674,7 +2928,23 @@ wf_chspec_primary80_chspec(chanspec_t chspec)
|
|||
|
||||
if (CHSPEC_IS80(chspec)) {
|
||||
chspec80 = chspec;
|
||||
} else if (CHSPEC_IS160(chspec)) {
|
||||
}
|
||||
else if (CHSPEC_IS8080(chspec)) {
|
||||
sb = CHSPEC_CTL_SB(chspec);
|
||||
|
||||
/* primary sub-band is stored in seg0 */
|
||||
if (CHSPEC_IS5G(chspec)) {
|
||||
center_chan = wf_chspec_5G_id80_to_ch(CHSPEC_CHAN0(chspec));
|
||||
} else if (CHSPEC_IS6G(chspec)) {
|
||||
center_chan = wf_chspec_6G_id80_to_ch(CHSPEC_CHAN0(chspec));
|
||||
} else {
|
||||
center_chan = INVCHANNEL;
|
||||
}
|
||||
|
||||
/* Create primary 80MHz chanspec */
|
||||
chspec80 = (CHSPEC_BAND(chspec) | WL_CHANSPEC_BW_80 | sb | center_chan);
|
||||
}
|
||||
else if (CHSPEC_IS160(chspec)) {
|
||||
center_chan = CHSPEC_CHANNEL(chspec);
|
||||
sb = CHSPEC_CTL_SB(chspec);
|
||||
|
||||
|
|
@ -2709,7 +2979,23 @@ wf_chspec_secondary80_chspec(chanspec_t chspec)
|
|||
|
||||
ASSERT(!wf_chspec_malformed(chspec));
|
||||
|
||||
if (CHSPEC_IS160(chspec)) {
|
||||
if (CHSPEC_IS8080(chspec)) {
|
||||
/* secondary sub-band is stored in seg1 */
|
||||
if (CHSPEC_IS5G(chspec)) {
|
||||
center_chan = wf_chspec_5G_id80_to_ch(CHSPEC_CHAN1(chspec));
|
||||
} else if (CHSPEC_IS6G(chspec)) {
|
||||
center_chan = wf_chspec_6G_id80_to_ch(CHSPEC_CHAN1(chspec));
|
||||
} else {
|
||||
center_chan = INVCHANNEL;
|
||||
}
|
||||
|
||||
/* Create secondary 80MHz chanspec */
|
||||
chspec80 = (CHSPEC_BAND(chspec) |
|
||||
WL_CHANSPEC_BW_80 |
|
||||
WL_CHANSPEC_CTL_SB_LL |
|
||||
center_chan);
|
||||
}
|
||||
else if (CHSPEC_IS160(chspec)) {
|
||||
center_chan = CHSPEC_CHANNEL(chspec);
|
||||
|
||||
if (CHSPEC_CTL_SB(chspec) < WL_CHANSPEC_CTL_SB_ULL) {
|
||||
|
|
@ -2916,6 +3202,8 @@ channel_bw_to_width(chanspec_t chspec)
|
|||
channel_width = VHT_OP_CHAN_WIDTH_80;
|
||||
else if (CHSPEC_IS160(chspec))
|
||||
channel_width = VHT_OP_CHAN_WIDTH_160;
|
||||
else if (CHSPEC_IS8080(chspec))
|
||||
channel_width = VHT_OP_CHAN_WIDTH_80_80;
|
||||
else
|
||||
channel_width = VHT_OP_CHAN_WIDTH_20_40;
|
||||
|
||||
|
|
@ -2924,11 +3212,6 @@ channel_bw_to_width(chanspec_t chspec)
|
|||
|
||||
uint wf_chspec_first_20_sb(chanspec_t chspec)
|
||||
{
|
||||
#if defined(WL_BW160MHZ)
|
||||
if (CHSPEC_IS160(chspec)) {
|
||||
return LLL_20_SB_160(CHSPEC_CHANNEL(chspec));
|
||||
} else
|
||||
#endif
|
||||
if (CHSPEC_IS80(chspec)) {
|
||||
return LL_20_SB(CHSPEC_CHANNEL(chspec));
|
||||
} else if (CHSPEC_IS40(chspec)) {
|
||||
|
|
@ -2949,6 +3232,56 @@ wf_create_chspec_sb(uint sb, uint center_channel, chanspec_bw_t bw, chanspec_ban
|
|||
return wf_chspec_valid(chspec) ? chspec : INVCHANSPEC;
|
||||
}
|
||||
|
||||
chanspec_t
|
||||
wf_create_8080MHz_chspec_sb(uint sb, uint chan0, uint chan1, chanspec_band_t band)
|
||||
{
|
||||
int chan0_id, chan1_id, seg0, seg1;
|
||||
chanspec_t chspec;
|
||||
|
||||
if (sb > (WL_CHANSPEC_CTL_SB_UUU >> WL_CHANSPEC_CTL_SB_SHIFT)) {
|
||||
return INVCHANSPEC;
|
||||
}
|
||||
/* From here on sb is not an index, but value for SB field */
|
||||
sb <<= WL_CHANSPEC_CTL_SB_SHIFT;
|
||||
|
||||
/* frequency segments need to be non-contiguous, so the channel
|
||||
* separation needs to be greater than 80MHz
|
||||
*/
|
||||
if ((uint)ABS((int)(chan0 - chan1)) <= CH_80MHZ_APART) {
|
||||
return INVCHANSPEC;
|
||||
}
|
||||
|
||||
if (band == WL_CHANSPEC_BAND_5G) {
|
||||
chan0_id = channel_80mhz_to_id(chan0);
|
||||
chan1_id = channel_80mhz_to_id(chan1);
|
||||
} else if (band == WL_CHANSPEC_BAND_6G) {
|
||||
chan0_id = channel_6g_80mhz_to_id(chan0);
|
||||
chan1_id = channel_6g_80mhz_to_id(chan1);
|
||||
} else {
|
||||
return INVCHANSPEC;
|
||||
}
|
||||
|
||||
/* make sure the channel numbers were valid */
|
||||
if ((chan0_id == -1) || (chan1_id == -1)) {
|
||||
return INVCHANSPEC;
|
||||
}
|
||||
/* Optionally swapping channel IDs to make sure that control subchannel
|
||||
* is in chan0
|
||||
*/
|
||||
if (sb < WL_CHANSPEC_CTL_SB_ULL) {
|
||||
seg0 = chan0_id;
|
||||
seg1 = chan1_id;
|
||||
} else {
|
||||
seg0 = chan1_id;
|
||||
seg1 = chan0_id;
|
||||
sb -= WL_CHANSPEC_CTL_SB_ULL;
|
||||
}
|
||||
chspec = ((seg0 << WL_CHANSPEC_CHAN0_SHIFT) |
|
||||
(seg1 << WL_CHANSPEC_CHAN1_SHIFT) |
|
||||
sb | WL_CHANSPEC_BW_8080 | band);
|
||||
return wf_chspec_valid(chspec) ? chspec : INVCHANSPEC;
|
||||
}
|
||||
|
||||
chanspec_t
|
||||
wf_create_160160MHz_chspec_sb(uint sb, uint chan0, uint chan1, chanspec_band_t band)
|
||||
{
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -3,7 +3,7 @@
|
|||
* This file housing the functions use by
|
||||
* wl driver.
|
||||
*
|
||||
* Copyright (C) 2020, Broadcom.
|
||||
* Copyright (C) 2022, Broadcom.
|
||||
*
|
||||
* Unless you and Broadcom execute a separate written software license
|
||||
* agreement governing use of this software, this software is licensed to you
|
||||
|
|
|
|||
|
|
@ -1,607 +0,0 @@
|
|||
/*
|
||||
* Common [OS-independent] rate management
|
||||
* 802.11 Networking Adapter Device Driver.
|
||||
*
|
||||
* Broadcom Proprietary and Confidential. Copyright (C) 2020,
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* This is UNPUBLISHED PROPRIETARY SOURCE CODE of Broadcom;
|
||||
* the contents of this file may not be disclosed to third parties,
|
||||
* copied or duplicated in any form, in whole or in part, without
|
||||
* the prior written permission of Broadcom.
|
||||
*
|
||||
*
|
||||
* <<Broadcom-WL-IPTag/Proprietary:>>
|
||||
*/
|
||||
|
||||
#include <typedefs.h>
|
||||
#ifdef BCMDRIVER
|
||||
#include <osl.h>
|
||||
#else
|
||||
#include <assert.h>
|
||||
#ifndef ASSERT
|
||||
#define ASSERT(e) assert(e)
|
||||
#endif
|
||||
#ifndef ASSERT_FP
|
||||
#define ASSERT_FP(e) assert(e)
|
||||
#endif
|
||||
#endif /* BCMDRIVER */
|
||||
#include <802.11.h>
|
||||
#include <802.11ax.h>
|
||||
#include <bcmutils.h>
|
||||
|
||||
#include <bcmwifi_rspec.h>
|
||||
#include <bcmwifi_rates.h>
|
||||
|
||||
/* TODO: Consolidate rate utility functions from wlc_rate.c and bcmwifi_monitor.c
|
||||
* into here if they're shared by non wl layer as well...
|
||||
*/
|
||||
|
||||
/* ============================================ */
|
||||
/* Moved from wlc_rate.c */
|
||||
/* ============================================ */
|
||||
|
||||
/* HE mcs info */
|
||||
struct ieee_80211_mcs_rate_info {
|
||||
uint8 constellation_bits;
|
||||
uint8 coding_q;
|
||||
uint8 coding_d;
|
||||
uint8 dcm_capable; /* 1 if dcm capable */
|
||||
};
|
||||
|
||||
static const struct ieee_80211_mcs_rate_info wlc_mcs_info[] = {
|
||||
{ 1, 1, 2, 1 }, /* MCS 0: MOD: BPSK, CR 1/2, dcm capable */
|
||||
{ 2, 1, 2, 1 }, /* MCS 1: MOD: QPSK, CR 1/2, dcm capable */
|
||||
{ 2, 3, 4, 0 }, /* MCS 2: MOD: QPSK, CR 3/4, NOT dcm capable */
|
||||
{ 4, 1, 2, 1 }, /* MCS 3: MOD: 16QAM, CR 1/2, dcm capable */
|
||||
{ 4, 3, 4, 1 }, /* MCS 4: MOD: 16QAM, CR 3/4, dcm capable */
|
||||
{ 6, 2, 3, 0 }, /* MCS 5: MOD: 64QAM, CR 2/3, NOT dcm capable */
|
||||
{ 6, 3, 4, 0 }, /* MCS 6: MOD: 64QAM, CR 3/4, NOT dcm capable */
|
||||
{ 6, 5, 6, 0 }, /* MCS 7: MOD: 64QAM, CR 5/6, NOT dcm capable */
|
||||
{ 8, 3, 4, 0 }, /* MCS 8: MOD: 256QAM, CR 3/4, NOT dcm capable */
|
||||
{ 8, 5, 6, 0 }, /* MCS 9: MOD: 256QAM, CR 5/6, NOT dcm capable */
|
||||
{ 10, 3, 4, 0 }, /* MCS 10: MOD: 1024QAM, CR 3/4, NOT dcm capable */
|
||||
{ 10, 5, 6, 0 }, /* MCS 11: MOD: 1024QAM, CR 5/6, NOT dcm capable */
|
||||
#ifdef WL11BE
|
||||
/* TODO: for now EHT shares this table with HE,
|
||||
* create a new table if needed once we know more
|
||||
* about EHT rate calculation...
|
||||
*/
|
||||
{ 12, 3, 4, 0 }, /* MCS 12: MOD: 4096QAM, CR 3/4, NOT dcm capable */
|
||||
{ 12, 5, 6, 0 }, /* MCS 13: MOD: 4096QAM, CR 5/6, NOT dcm capable */
|
||||
#endif
|
||||
};
|
||||
|
||||
/* Nsd values Draft0.4 Table 26.63 onwards */
|
||||
static const uint wlc_he_nsd[] = {
|
||||
234, /* BW20 */
|
||||
468, /* BW40 */
|
||||
980, /* BW80 */
|
||||
1960, /* BW160 */
|
||||
#ifdef WL11BE
|
||||
/* TODO: for now EHT shares this table with HE,
|
||||
* create a new table if needed once we know more
|
||||
* about EHT rate calculation...
|
||||
*/
|
||||
2940, /* BW240 */
|
||||
3920 /* BW320 */
|
||||
#endif
|
||||
};
|
||||
|
||||
/* Nsd values Draft3.3 Table 28-15 */
|
||||
static const uint wlc_he_ru_nsd[] = {
|
||||
24, /* 26T */
|
||||
48, /* 52T */
|
||||
102, /* 106T */
|
||||
234, /* 242T/BW20 */
|
||||
468, /* 484T/BW40 */
|
||||
980, /* 996T/BW80 */
|
||||
1960, /* 2*996T/BW160 */
|
||||
#ifdef WL11BE
|
||||
/* TODO: for now EHT shares this table with HE,
|
||||
* create a new table if needed once we know more
|
||||
* about EHT rate calculation...
|
||||
*/
|
||||
2940, /* 3*996T/BW240 */
|
||||
3920 /* 4*996T/BW320 */
|
||||
#endif
|
||||
};
|
||||
|
||||
#define HE_RU_TO_NSD(ru_idx) \
|
||||
(ru_idx < ARRAYSIZE(wlc_he_ru_nsd)) ? \
|
||||
wlc_he_ru_nsd[ru_idx] : 0
|
||||
|
||||
/* sym_len = 12.8 us. For calculation purpose, *10 */
|
||||
#define HE_SYM_LEN_FACTOR (128)
|
||||
|
||||
/* GI values = 0.8 , 1.6 or 3.2 us. For calculation purpose, *10 */
|
||||
#define HE_GI_800us_FACTOR (8)
|
||||
#define HE_GI_1600us_FACTOR (16)
|
||||
#define HE_GI_3200us_FACTOR (32)
|
||||
|
||||
/* To avoid ROM invalidation use the old macro as is... */
|
||||
#ifdef WL11BE
|
||||
#define HE_BW_TO_NSD(bwi) \
|
||||
((bwi) > 0u && (bwi) <= ARRAYSIZE(wlc_he_nsd)) ? \
|
||||
wlc_he_nsd[(bwi) - 1u] : 0u
|
||||
#else
|
||||
#define HE_BW_TO_NSD(bwi) \
|
||||
((bwi) > 0 && ((bwi) << WL_RSPEC_BW_SHIFT) <= WL_RSPEC_BW_160MHZ) ? \
|
||||
wlc_he_nsd[(bwi)-1] : 0
|
||||
#endif /* WL11BE */
|
||||
|
||||
#define ksps 250 /* kilo symbols per sec, 4 us sym */
|
||||
|
||||
#ifdef WL11BE
|
||||
/* Table "wlc_nsd" is derived from HT and VHT #defines below, but extended for HE
|
||||
* for rate calculation purpose at a given NSS and bandwidth combination.
|
||||
*
|
||||
* It should and can only be used in where it wants to know the relative rate in kbps
|
||||
* for a different NSS and bandwidth combination at a given mcs e.g. in fallback rate
|
||||
* search. It shouldn not and can not be used in where it calculates the absolute rate
|
||||
* i.e. the result doesn't agree with what the spec says otherwise.
|
||||
*
|
||||
* See Std 802.11-2016 "Table 21-61 VHT-MCSs for optional 160 MHz and 80+80 MHz, NSS = 8"
|
||||
* for VHT, and P802.11ax/D6.0 "Table 27-111 HE-MCSs for 2x996-tone RU, NSS = 8" for HE,
|
||||
* for 160Mhz bandwidth for resulting rate comparison.
|
||||
*
|
||||
* It's again extended for EHT 240/320Mhz bandwidth, for the same purpose.
|
||||
*/
|
||||
static const uint16 wlc_nsd[] = {
|
||||
52, /* 20MHz */
|
||||
108, /* 40MHz */
|
||||
234, /* 80Mhz */
|
||||
468, /* 160MHz */
|
||||
702, /* 240MHz */
|
||||
936, /* 320MHz */
|
||||
};
|
||||
|
||||
#define BW_TO_NSD(bwi) \
|
||||
((bwi) > 0u && (bwi) <= ARRAYSIZE(wlc_nsd)) ? \
|
||||
wlc_nsd[(bwi) - 1u] : 0u
|
||||
|
||||
static uint
|
||||
wf_nsd2ndbps(uint mcs, uint nss, uint nsd, bool dcm)
|
||||
{
|
||||
uint Ndbps;
|
||||
|
||||
/* multiply number of spatial streams,
|
||||
* bits per number from the constellation,
|
||||
* and coding quotient
|
||||
*/
|
||||
Ndbps = nsd * nss *
|
||||
wlc_mcs_info[mcs].coding_q * wlc_mcs_info[mcs].constellation_bits;
|
||||
|
||||
/* adjust for the coding rate divisor */
|
||||
Ndbps = Ndbps / wlc_mcs_info[mcs].coding_d;
|
||||
|
||||
/* take care of dcm: dcm divides R by 2. If not dcm mcs, ignore */
|
||||
if (dcm) {
|
||||
if (wlc_mcs_info[mcs].dcm_capable) {
|
||||
Ndbps >>= 1u;
|
||||
}
|
||||
}
|
||||
|
||||
return Ndbps;
|
||||
}
|
||||
#else
|
||||
/* for HT and VHT? */
|
||||
#define Nsd_20MHz 52
|
||||
#define Nsd_40MHz 108
|
||||
#define Nsd_80MHz 234
|
||||
#define Nsd_160MHz 468
|
||||
#endif /* WL11BE */
|
||||
|
||||
uint
|
||||
wf_he_mcs_to_Ndbps(uint mcs, uint nss, uint bw, bool dcm)
|
||||
{
|
||||
uint Nsd;
|
||||
uint Ndbps;
|
||||
|
||||
/* find the number of complex numbers per symbol */
|
||||
Nsd = HE_BW_TO_NSD(bw >> WL_RSPEC_BW_SHIFT);
|
||||
|
||||
#ifdef WL11BE
|
||||
Ndbps = wf_nsd2ndbps(mcs, nss, Nsd, dcm);
|
||||
#else
|
||||
/* multiply number of spatial streams,
|
||||
* bits per number from the constellation,
|
||||
* and coding quotient
|
||||
*/
|
||||
Ndbps = Nsd * nss *
|
||||
wlc_mcs_info[mcs].coding_q * wlc_mcs_info[mcs].constellation_bits;
|
||||
|
||||
/* adjust for the coding rate divisor */
|
||||
Ndbps = Ndbps / wlc_mcs_info[mcs].coding_d;
|
||||
|
||||
/* take care of dcm: dcm divides R by 2. If not dcm mcs, ignore */
|
||||
if (dcm) {
|
||||
if (wlc_mcs_info[mcs].dcm_capable) {
|
||||
Ndbps >>= 1;
|
||||
}
|
||||
}
|
||||
#endif /* WL11BE */
|
||||
|
||||
return Ndbps;
|
||||
}
|
||||
|
||||
uint32
|
||||
wf_he_mcs_ru_to_ndbps(uint8 mcs, uint8 nss, bool dcm, uint8 ru_index)
|
||||
{
|
||||
uint32 nsd;
|
||||
uint32 ndbps;
|
||||
|
||||
/* find the number of complex numbers per symbol */
|
||||
nsd = HE_RU_TO_NSD(ru_index);
|
||||
|
||||
#ifdef WL11BE
|
||||
ndbps = wf_nsd2ndbps(mcs, nss, nsd, dcm);
|
||||
#else
|
||||
/* multiply number of spatial streams,
|
||||
* bits per number from the constellation,
|
||||
* and coding quotient
|
||||
* Ndbps = Nss x Nsd x (Nbpscs x R) x (DCM/2)
|
||||
*/
|
||||
ndbps = nsd * nss *
|
||||
wlc_mcs_info[mcs].coding_q * wlc_mcs_info[mcs].constellation_bits;
|
||||
|
||||
/* adjust for the coding rate divisor */
|
||||
ndbps = ndbps / wlc_mcs_info[mcs].coding_d;
|
||||
|
||||
/* take care of dcm: dcm divides R by 2. If not dcm mcs, ignore */
|
||||
if (dcm && wlc_mcs_info[mcs].dcm_capable) {
|
||||
ndbps >>= 1;
|
||||
}
|
||||
#endif /* WL11BE */
|
||||
return ndbps;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the rate in [Kbps] units for a caller supplied MCS/bandwidth/Nss/Sgi/dcm combination.
|
||||
* 'mcs' : a *single* spatial stream MCS (11ax)
|
||||
* formula as per http:
|
||||
* WLAN&preview=/323036249/344457953/11ax_rate_table.xlsx
|
||||
* Symbol length = 12.8 usec [given as sym_len/10 below]
|
||||
* GI value = 0.8 or 1.6 or 3.2 usec [given as GI_value/10 below]
|
||||
* rate (Kbps) = (Nsd * Nbpscs * nss * (coding_q/coding_d) * 1000) / ((sym_len/10) + (GI_value/10))
|
||||
* Note that, for calculation purpose, following is used. [to be careful with overflows]
|
||||
* rate (Kbps) = (Nsd * Nbpscs * nss * (coding_q/coding_d) * 1000) / ((sym_len + GI_value) / 10)
|
||||
* rate (Kbps) = (Nsd * Nbpscs * nss * (coding_q/coding_d) * 1000) / (sym_len + GI_value) * 10
|
||||
*/
|
||||
uint
|
||||
wf_he_mcs_to_rate(uint mcs, uint nss, uint bw, uint gi, bool dcm)
|
||||
{
|
||||
uint rate;
|
||||
uint rate_deno;
|
||||
|
||||
rate = HE_BW_TO_NSD(bw >> WL_RSPEC_BW_SHIFT);
|
||||
|
||||
#ifdef WL11BE
|
||||
rate = wf_nsd2ndbps(mcs, nss, rate, dcm);
|
||||
#else
|
||||
/* Nbpscs: multiply by bits per number from the constellation in use */
|
||||
rate = rate * wlc_mcs_info[mcs].constellation_bits;
|
||||
|
||||
/* Nss: adjust for the number of spatial streams */
|
||||
rate = rate * nss;
|
||||
|
||||
/* R: adjust for the coding rate given as a quotient and divisor */
|
||||
rate = (rate * wlc_mcs_info[mcs].coding_q) / wlc_mcs_info[mcs].coding_d;
|
||||
|
||||
/* take care of dcm: dcm divides R by 2. If not dcm mcs, ignore */
|
||||
if (dcm) {
|
||||
if (wlc_mcs_info[mcs].dcm_capable) {
|
||||
rate >>= 1;
|
||||
}
|
||||
}
|
||||
#endif /* WL11BE */
|
||||
|
||||
/* add sym len factor */
|
||||
rate_deno = HE_SYM_LEN_FACTOR;
|
||||
|
||||
/* get GI for denominator */
|
||||
if (HE_IS_GI_3_2us(gi)) {
|
||||
rate_deno += HE_GI_3200us_FACTOR;
|
||||
} else if (HE_IS_GI_1_6us(gi)) {
|
||||
rate_deno += HE_GI_1600us_FACTOR;
|
||||
} else {
|
||||
/* assuming HE_GI_0_8us */
|
||||
rate_deno += HE_GI_800us_FACTOR;
|
||||
}
|
||||
|
||||
/* as per above formula */
|
||||
rate *= 1000; /* factor of 10. *100 to accommodate 2 places */
|
||||
rate /= rate_deno;
|
||||
rate *= 10; /* *100 was already done above. Splitting is done to avoid overflow. */
|
||||
|
||||
return rate;
|
||||
}
|
||||
|
||||
uint
|
||||
wf_mcs_to_Ndbps(uint mcs, uint nss, uint bw)
|
||||
{
|
||||
uint Nsd;
|
||||
uint Ndbps;
|
||||
|
||||
/* This calculation works for 11n HT and 11ac VHT if the HT mcs values
|
||||
* are decomposed into a base MCS = MCS % 8, and Nss = 1 + MCS / 8.
|
||||
* That is, HT MCS 23 is a base MCS = 7, Nss = 3
|
||||
*/
|
||||
|
||||
/* find the number of complex numbers per symbol */
|
||||
#ifdef WL11BE
|
||||
Nsd = BW_TO_NSD(bw >> WL_RSPEC_BW_SHIFT);
|
||||
|
||||
Ndbps = wf_nsd2ndbps(mcs, nss, Nsd, FALSE);
|
||||
#else
|
||||
if (bw == WL_RSPEC_BW_20MHZ) {
|
||||
Nsd = Nsd_20MHz;
|
||||
} else if (bw == WL_RSPEC_BW_40MHZ) {
|
||||
Nsd = Nsd_40MHz;
|
||||
} else if (bw == WL_RSPEC_BW_80MHZ) {
|
||||
Nsd = Nsd_80MHz;
|
||||
} else if (bw == WL_RSPEC_BW_160MHZ) {
|
||||
Nsd = Nsd_160MHz;
|
||||
} else {
|
||||
Nsd = 0;
|
||||
}
|
||||
|
||||
/* multiply number of spatial streams,
|
||||
* bits per number from the constellation,
|
||||
* and coding quotient
|
||||
*/
|
||||
Ndbps = Nsd * nss *
|
||||
wlc_mcs_info[mcs].coding_q * wlc_mcs_info[mcs].constellation_bits;
|
||||
|
||||
/* adjust for the coding rate divisor */
|
||||
Ndbps = Ndbps / wlc_mcs_info[mcs].coding_d;
|
||||
#endif /* WL11BE */
|
||||
|
||||
return Ndbps;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the rate in [Kbps] units for a caller supplied MCS/bandwidth/Nss/Sgi combination.
|
||||
* 'mcs' : a *single* spatial stream MCS (11n or 11ac)
|
||||
*/
|
||||
uint
|
||||
wf_mcs_to_rate(uint mcs, uint nss, uint bw, int sgi)
|
||||
{
|
||||
uint rate;
|
||||
|
||||
if (mcs == 32) {
|
||||
/* just return fixed values for mcs32 instead of trying to parametrize */
|
||||
rate = (sgi == 0) ? 6000 : 6778;
|
||||
} else {
|
||||
/* This calculation works for 11n HT, 11ac VHT and 11ax HE if the HT mcs values
|
||||
* are decomposed into a base MCS = MCS % 8, and Nss = 1 + MCS / 8.
|
||||
* That is, HT MCS 23 is a base MCS = 7, Nss = 3
|
||||
*/
|
||||
|
||||
#if defined(WLPROPRIETARY_11N_RATES)
|
||||
switch (mcs) {
|
||||
case 87:
|
||||
mcs = 8; /* MCS 8: MOD: 256QAM, CR 3/4 */
|
||||
break;
|
||||
case 88:
|
||||
mcs = 9; /* MCS 9: MOD: 256QAM, CR 5/6 */
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
#endif /* WLPROPRIETARY_11N_RATES */
|
||||
|
||||
#ifdef WL11BE
|
||||
rate = wf_mcs_to_Ndbps(mcs, nss, bw);
|
||||
#else
|
||||
/* find the number of complex numbers per symbol */
|
||||
if (RSPEC_IS20MHZ(bw)) {
|
||||
/* 4360 TODO: eliminate Phy const in rspec bw, then just compare
|
||||
* as in 80 and 160 case below instead of RSPEC_IS20MHZ(bw)
|
||||
*/
|
||||
rate = Nsd_20MHz;
|
||||
} else if (RSPEC_IS40MHZ(bw)) {
|
||||
/* 4360 TODO: eliminate Phy const in rspec bw, then just compare
|
||||
* as in 80 and 160 case below instead of RSPEC_IS40MHZ(bw)
|
||||
*/
|
||||
rate = Nsd_40MHz;
|
||||
} else if (bw == WL_RSPEC_BW_80MHZ) {
|
||||
rate = Nsd_80MHz;
|
||||
} else if (bw == WL_RSPEC_BW_160MHZ) {
|
||||
rate = Nsd_160MHz;
|
||||
} else {
|
||||
rate = 0;
|
||||
}
|
||||
|
||||
/* multiply by bits per number from the constellation in use */
|
||||
rate = rate * wlc_mcs_info[mcs].constellation_bits;
|
||||
|
||||
/* adjust for the number of spatial streams */
|
||||
rate = rate * nss;
|
||||
|
||||
/* adjust for the coding rate given as a quotient and divisor */
|
||||
rate = (rate * wlc_mcs_info[mcs].coding_q) / wlc_mcs_info[mcs].coding_d;
|
||||
#endif /* WL11BE */
|
||||
|
||||
/* multiply by Kilo symbols per sec to get Kbps */
|
||||
rate = rate * ksps;
|
||||
|
||||
/* adjust the symbols per sec for SGI
|
||||
* symbol duration is 4 us without SGI, and 3.6 us with SGI,
|
||||
* so ratio is 10 / 9
|
||||
*/
|
||||
if (sgi) {
|
||||
/* add 4 for rounding of division by 9 */
|
||||
rate = ((rate * 10) + 4) / 9;
|
||||
}
|
||||
}
|
||||
|
||||
return rate;
|
||||
} /* wf_mcs_to_rate */
|
||||
|
||||
/* This function needs update to handle MU frame PLCP as well (MCS is conveyed via VHT-SIGB
|
||||
* field in case of MU frames). Currently this support needs to be added in uCode to communicate
|
||||
* MCS information for an MU frame
|
||||
*
|
||||
* For VHT frame:
|
||||
* bit 0-3 mcs index
|
||||
* bit 6-4 nsts for VHT
|
||||
* bit 7: 1 for VHT
|
||||
* Note: bit 7 is used to indicate to the rate sel the mcs is a non HT mcs!
|
||||
*
|
||||
* Essentially it's the NSS:MCS portions of the rspec
|
||||
*/
|
||||
uint8
|
||||
wf_vht_plcp_to_rate(uint8 *plcp)
|
||||
{
|
||||
uint8 rate, gid;
|
||||
uint nss;
|
||||
uint32 plcp0 = plcp[0] + (plcp[1] << 8); /* don't need plcp[2] */
|
||||
|
||||
gid = (plcp0 & VHT_SIGA1_GID_MASK) >> VHT_SIGA1_GID_SHIFT;
|
||||
if (gid > VHT_SIGA1_GID_TO_AP && gid < VHT_SIGA1_GID_NOT_TO_AP) {
|
||||
/* for MU packet we hacked Signal Tail field in VHT-SIG-A2 to save nss and mcs,
|
||||
* copy from murate in d11 rx header.
|
||||
* nss = bit 18:19 (for 11ac 2 bits to indicate maximum 4 nss)
|
||||
* mcs = 20:23
|
||||
*/
|
||||
rate = (plcp[5] & 0xF0) >> 4;
|
||||
nss = ((plcp[5] & 0x0C) >> 2) + 1;
|
||||
} else {
|
||||
rate = (plcp[3] >> VHT_SIGA2_MCS_SHIFT);
|
||||
nss = ((plcp0 & VHT_SIGA1_NSTS_SHIFT_MASK_USER0) >>
|
||||
VHT_SIGA1_NSTS_SHIFT) + 1;
|
||||
if (plcp0 & VHT_SIGA1_STBC)
|
||||
nss = nss >> 1;
|
||||
}
|
||||
rate |= ((nss << WL_RSPEC_VHT_NSS_SHIFT) | WF_NON_HT_MCS);
|
||||
|
||||
return rate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function for computing NSS:MCS from HE SU PLCP or
|
||||
* MCS:LTF-GI from HE MU PLCP
|
||||
*
|
||||
* based on rev3.10 :
|
||||
* https://docs.google.com/spreadsheets/d/
|
||||
* 1eP6ZCRrtnF924ds1R-XmbcH0IdQ0WNJpS1-FHmWeb9g/edit#gid=1492656555
|
||||
*
|
||||
* For HE SU frame:
|
||||
* bit 0-3 mcs index
|
||||
* bit 6-4 nsts for HE
|
||||
* bit 7: 1 for HE
|
||||
* Note: bit 7 is used to indicate to the rate sel the mcs is a non HT mcs!
|
||||
* Essentially it's the NSS:MCS portions of the rspec
|
||||
*
|
||||
* For HE MU frame:
|
||||
* bit 0-3 mcs index
|
||||
* bit 4-5 LTF-GI value
|
||||
* bit 6 STBC
|
||||
* Essentially it's the MCS and LTF-GI portion of the rspec
|
||||
*/
|
||||
/* Macros to be used for calculating rate from PLCP */
|
||||
#define HE_SU_PLCP2RATE_MCS_MASK 0x0F
|
||||
#define HE_SU_PLCP2RATE_MCS_SHIFT 0
|
||||
#define HE_SU_PLCP2RATE_NSS_MASK 0x70
|
||||
#define HE_SU_PLCP2RATE_NSS_SHIFT 4
|
||||
#define HE_MU_PLCP2RATE_LTF_GI_MASK 0x30
|
||||
#define HE_MU_PLCP2RATE_LTF_GI_SHIFT 4
|
||||
#define HE_MU_PLCP2RATE_STBC_MASK 0x40
|
||||
#define HE_MU_PLCP2RATE_STBC_SHIFT 6
|
||||
|
||||
uint8
|
||||
wf_he_plcp_to_rate(uint8 *plcp, bool is_mu)
|
||||
{
|
||||
uint8 rate = 0;
|
||||
uint8 nss = 0;
|
||||
uint32 plcp0 = 0;
|
||||
uint32 plcp1 = 0;
|
||||
uint8 he_ltf_gi;
|
||||
uint8 stbc;
|
||||
|
||||
ASSERT(plcp);
|
||||
|
||||
BCM_REFERENCE(nss);
|
||||
BCM_REFERENCE(he_ltf_gi);
|
||||
|
||||
plcp0 = ((plcp[3] << 24) | (plcp[2] << 16) | (plcp[1] << 8) | plcp[0]);
|
||||
plcp1 = ((plcp[5] << 8) | plcp[4]);
|
||||
|
||||
if (!is_mu) {
|
||||
/* For SU frames return rate in MCS:NSS format */
|
||||
rate = ((plcp0 & HE_SU_RE_SIGA_MCS_MASK) >> HE_SU_RE_SIGA_MCS_SHIFT);
|
||||
nss = ((plcp0 & HE_SU_RE_SIGA_NSTS_MASK) >> HE_SU_RE_SIGA_NSTS_SHIFT) + 1;
|
||||
rate |= ((nss << HE_SU_PLCP2RATE_NSS_SHIFT) | WF_NON_HT_MCS);
|
||||
} else {
|
||||
/* For MU frames return rate in MCS:LTF-GI format */
|
||||
rate = (plcp0 & HE_MU_SIGA_SIGB_MCS_MASK) >> HE_MU_SIGA_SIGB_MCS_SHIFT;
|
||||
he_ltf_gi = (plcp0 & HE_MU_SIGA_GI_LTF_MASK) >> HE_MU_SIGA_GI_LTF_SHIFT;
|
||||
stbc = (plcp1 & HE_MU_SIGA_STBC_MASK) >> HE_MU_SIGA_STBC_SHIFT;
|
||||
|
||||
/* LTF-GI shall take the same position as NSS */
|
||||
rate |= (he_ltf_gi << HE_MU_PLCP2RATE_LTF_GI_SHIFT);
|
||||
|
||||
/* STBC needs to be filled in bit 6 */
|
||||
rate |= (stbc << HE_MU_PLCP2RATE_STBC_SHIFT);
|
||||
}
|
||||
|
||||
return rate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function for computing NSS:MCS from EHT SU PLCP or
|
||||
* MCS:LTF-GI from EHT MU PLCP
|
||||
*
|
||||
* TODO: add link to the HW spec.
|
||||
* FIXME: do we really need to support mu?
|
||||
*/
|
||||
uint8
|
||||
wf_eht_plcp_to_rate(uint8 *plcp, bool is_mu)
|
||||
{
|
||||
BCM_REFERENCE(plcp);
|
||||
BCM_REFERENCE(is_mu);
|
||||
ASSERT(!"wf_eht_plcp_to_rate: not implemented!");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ============================================ */
|
||||
/* Moved from wlc_rate_def.c */
|
||||
/* ============================================ */
|
||||
|
||||
/**
|
||||
* Some functions require a single stream MCS as an input parameter. Given an MCS, this function
|
||||
* returns the single spatial stream MCS equivalent.
|
||||
*/
|
||||
uint8
|
||||
wf_get_single_stream_mcs(uint mcs)
|
||||
{
|
||||
if (mcs < 32) {
|
||||
return mcs % 8;
|
||||
}
|
||||
switch (mcs) {
|
||||
case 32:
|
||||
return 32;
|
||||
case 87:
|
||||
case 99:
|
||||
case 101:
|
||||
return 87; /* MCS 87: SS 1, MOD: 256QAM, CR 3/4 */
|
||||
default:
|
||||
return 88; /* MCS 88: SS 1, MOD: 256QAM, CR 5/6 */
|
||||
}
|
||||
}
|
||||
|
||||
/* ============================================ */
|
||||
/* Moved from wlc_phy_iovar.c */
|
||||
/* ============================================ */
|
||||
|
||||
const uint8 plcp_ofdm_rate_tbl[] = {
|
||||
DOT11_RATE_48M, /* 8: 48Mbps */
|
||||
DOT11_RATE_24M, /* 9: 24Mbps */
|
||||
DOT11_RATE_12M, /* A: 12Mbps */
|
||||
DOT11_RATE_6M, /* B: 6Mbps */
|
||||
DOT11_RATE_54M, /* C: 54Mbps */
|
||||
DOT11_RATE_36M, /* D: 36Mbps */
|
||||
DOT11_RATE_18M, /* E: 18Mbps */
|
||||
DOT11_RATE_9M /* F: 9Mbps */
|
||||
};
|
||||
|
|
@ -1,274 +0,0 @@
|
|||
/*
|
||||
* Common [OS-independent] rate management
|
||||
* 802.11 Networking Adapter Device Driver.
|
||||
*
|
||||
* Broadcom Proprietary and Confidential. Copyright (C) 2020,
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* This is UNPUBLISHED PROPRIETARY SOURCE CODE of Broadcom;
|
||||
* the contents of this file may not be disclosed to third parties,
|
||||
* copied or duplicated in any form, in whole or in part, without
|
||||
* the prior written permission of Broadcom.
|
||||
*
|
||||
*
|
||||
* <<Broadcom-WL-IPTag/Proprietary:>>
|
||||
*/
|
||||
|
||||
#include <typedefs.h>
|
||||
#include <osl.h>
|
||||
#include <d11.h>
|
||||
#include <802.11ax.h>
|
||||
|
||||
#include <bcmwifi_rspec.h>
|
||||
#include <bcmwifi_rates.h>
|
||||
|
||||
/* TODO: Consolidate rspec utility functions from wlc_rate.c and bcmwifi_monitor.c
|
||||
* into here if they're shared by non wl layer as well...
|
||||
*/
|
||||
|
||||
/* ============================================ */
|
||||
/* Moved from wlc_rate.c */
|
||||
/* ============================================ */
|
||||
|
||||
/**
|
||||
* Returns the rate in [Kbps] units.
|
||||
*/
|
||||
static uint
|
||||
wf_he_rspec_to_rate(ratespec_t rspec, uint max_mcs, uint max_nss)
|
||||
{
|
||||
uint mcs = (rspec & WL_RSPEC_HE_MCS_MASK);
|
||||
uint nss = (rspec & WL_RSPEC_HE_NSS_MASK) >> WL_RSPEC_HE_NSS_SHIFT;
|
||||
bool dcm = (rspec & WL_RSPEC_DCM) != 0;
|
||||
uint bw = RSPEC_BW(rspec);
|
||||
uint gi = RSPEC_HE_LTF_GI(rspec);
|
||||
|
||||
ASSERT(mcs <= max_mcs);
|
||||
ASSERT(nss <= max_nss);
|
||||
|
||||
if (mcs > max_mcs) {
|
||||
return 0;
|
||||
}
|
||||
BCM_REFERENCE(max_nss);
|
||||
|
||||
return wf_he_mcs_to_rate(mcs, nss, bw, gi, dcm);
|
||||
} /* wf_he_rspec_to_rate */
|
||||
|
||||
/* take a well formed ratespec_t arg and return phy rate in [Kbps] units.
|
||||
* 'rsel' indicates if the call comes from rate selection.
|
||||
*/
|
||||
static uint
|
||||
_wf_rspec_to_rate(ratespec_t rspec, bool rsel)
|
||||
{
|
||||
uint rate = (uint)(-1);
|
||||
|
||||
if (RSPEC_ISLEGACY(rspec)) {
|
||||
rate = 500 * RSPEC2RATE(rspec);
|
||||
} else if (RSPEC_ISHT(rspec)) {
|
||||
uint mcs = (rspec & WL_RSPEC_HT_MCS_MASK);
|
||||
|
||||
ASSERT_FP(mcs <= 32 || IS_PROPRIETARY_11N_MCS(mcs));
|
||||
|
||||
if (mcs == 32) {
|
||||
rate = wf_mcs_to_rate(mcs, 1, WL_RSPEC_BW_40MHZ, RSPEC_ISSGI(rspec));
|
||||
} else {
|
||||
#if defined(WLPROPRIETARY_11N_RATES)
|
||||
uint nss = GET_11N_MCS_NSS(mcs);
|
||||
mcs = wf_get_single_stream_mcs(mcs);
|
||||
#else /* this ifdef prevents ROM abandons */
|
||||
uint nss = 1 + (mcs / 8);
|
||||
mcs = mcs % 8;
|
||||
#endif /* WLPROPRIETARY_11N_RATES */
|
||||
|
||||
rate = wf_mcs_to_rate(mcs, nss, RSPEC_BW(rspec), RSPEC_ISSGI(rspec));
|
||||
}
|
||||
} else if (RSPEC_ISVHT(rspec)) {
|
||||
uint mcs = (rspec & WL_RSPEC_VHT_MCS_MASK);
|
||||
uint nss = (rspec & WL_RSPEC_VHT_NSS_MASK) >> WL_RSPEC_VHT_NSS_SHIFT;
|
||||
|
||||
if (rsel) {
|
||||
rate = wf_mcs_to_rate(mcs, nss, RSPEC_BW(rspec), 0);
|
||||
} else {
|
||||
ASSERT_FP(mcs <= WLC_MAX_VHT_MCS);
|
||||
ASSERT_FP(nss <= 8);
|
||||
|
||||
rate = wf_mcs_to_rate(mcs, nss, RSPEC_BW(rspec), RSPEC_ISSGI(rspec));
|
||||
}
|
||||
} else if (RSPEC_ISHE(rspec)) {
|
||||
rate = wf_he_rspec_to_rate(rspec, WLC_MAX_HE_MCS, 8);
|
||||
} else if (RSPEC_ISEHT(rspec)) {
|
||||
rate = wf_he_rspec_to_rate(rspec, WLC_MAX_EHT_MCS, 16);
|
||||
} else {
|
||||
ASSERT(0);
|
||||
}
|
||||
|
||||
return (rate == 0) ? (uint)(-1) : rate;
|
||||
}
|
||||
|
||||
/* take a well formed ratespec_t 'rspec' and return phy rate in [Kbps] units */
|
||||
uint
|
||||
wf_rspec_to_rate(ratespec_t rspec)
|
||||
{
|
||||
return _wf_rspec_to_rate(rspec, FALSE);
|
||||
}
|
||||
|
||||
/* take a well formed ratespec_t 'rspec' and return phy rate in [Kbps] units,
|
||||
* FOR RATE SELECTION ONLY, WHICH USES LEGACY, HT, AND VHT RATES, AND VHT MCS
|
||||
* COULD BE BIGGER THAN WLC_MAX_VHT_MCS!
|
||||
*/
|
||||
uint
|
||||
wf_rspec_to_rate_rsel(ratespec_t rspec)
|
||||
{
|
||||
return _wf_rspec_to_rate(rspec, TRUE);
|
||||
}
|
||||
|
||||
#ifdef BCMDBG
|
||||
/* Return the rate in 500Kbps units if the rspec is legacy rate, assert otherwise */
|
||||
uint
|
||||
wf_rspec_to_rate_legacy(ratespec_t rspec)
|
||||
{
|
||||
ASSERT(RSPEC_ISLEGACY(rspec));
|
||||
|
||||
return rspec & WL_RSPEC_LEGACY_RATE_MASK;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Function for computing RSPEC from EHT PLCP
|
||||
*
|
||||
* TODO: add link to the HW spec.
|
||||
*/
|
||||
ratespec_t
|
||||
wf_eht_plcp_to_rspec(uint8 *plcp)
|
||||
{
|
||||
ASSERT(!"wf_eht_plcp_to_rspec: not implemented!");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function for computing RSPEC from HE PLCP
|
||||
*
|
||||
* based on rev3.10 :
|
||||
* https://docs.google.com/spreadsheets/d/
|
||||
* 1eP6ZCRrtnF924ds1R-XmbcH0IdQ0WNJpS1-FHmWeb9g/edit#gid=1492656555
|
||||
*/
|
||||
ratespec_t
|
||||
wf_he_plcp_to_rspec(uint8 *plcp)
|
||||
{
|
||||
uint8 rate;
|
||||
uint8 nss;
|
||||
uint8 bw;
|
||||
uint8 gi;
|
||||
ratespec_t rspec;
|
||||
|
||||
/* HE plcp - 6 B */
|
||||
uint32 plcp0;
|
||||
uint16 plcp1;
|
||||
|
||||
ASSERT(plcp);
|
||||
|
||||
plcp0 = ((plcp[3] << 24) | (plcp[2] << 16) | (plcp[1] << 8) | plcp[0]);
|
||||
plcp1 = ((plcp[5] << 8) | plcp[4]);
|
||||
|
||||
/* TBD: only SU supported now */
|
||||
rate = (plcp0 & HE_SU_RE_SIGA_MCS_MASK) >> HE_SU_RE_SIGA_MCS_SHIFT;
|
||||
/* PLCP contains (NSTS - 1) while RSPEC stores NSTS */
|
||||
nss = ((plcp0 & HE_SU_RE_SIGA_NSTS_MASK) >> HE_SU_RE_SIGA_NSTS_SHIFT) + 1;
|
||||
rspec = HE_RSPEC(rate, nss);
|
||||
|
||||
/* GI info comes from CP/LTF */
|
||||
gi = (plcp0 & HE_SU_RE_SIGA_GI_LTF_MASK) >> HE_SU_RE_SIGA_GI_LTF_SHIFT;
|
||||
rspec |= HE_GI_TO_RSPEC(gi);
|
||||
|
||||
/* b19-b20 of plcp indicate bandwidth in the format (2-bit):
|
||||
* 0 for 20M, 1 for 40M, 2 for 80M, and 3 for 80p80/160M
|
||||
* SW store this BW in rspec format (3-bit):
|
||||
* 1 for 20M, 2 for 40M, 3 for 80M, and 4 for 80p80/160M
|
||||
*/
|
||||
bw = ((plcp0 & HE_SU_SIGA_BW_MASK) >> HE_SU_SIGA_BW_SHIFT) + 1;
|
||||
rspec |= (bw << WL_RSPEC_BW_SHIFT);
|
||||
|
||||
if (plcp1 & HE_SU_RE_SIGA_BEAMFORM_MASK)
|
||||
rspec |= WL_RSPEC_TXBF;
|
||||
if (plcp1 & HE_SU_RE_SIGA_CODING_MASK)
|
||||
rspec |= WL_RSPEC_LDPC;
|
||||
if (plcp1 & HE_SU_RE_SIGA_STBC_MASK)
|
||||
rspec |= WL_RSPEC_STBC;
|
||||
if (plcp0 & HE_SU_RE_SIGA_DCM_MASK)
|
||||
rspec |= WL_RSPEC_DCM;
|
||||
|
||||
return rspec;
|
||||
}
|
||||
|
||||
ratespec_t
|
||||
wf_vht_plcp_to_rspec(uint8 *plcp)
|
||||
{
|
||||
uint8 rate;
|
||||
uint vht_sig_a1, vht_sig_a2;
|
||||
ratespec_t rspec;
|
||||
|
||||
ASSERT(plcp);
|
||||
|
||||
rate = wf_vht_plcp_to_rate(plcp) & ~WF_NON_HT_MCS;
|
||||
|
||||
vht_sig_a1 = plcp[0] | (plcp[1] << 8);
|
||||
vht_sig_a2 = plcp[3] | (plcp[4] << 8);
|
||||
|
||||
rspec = VHT_RSPEC((rate & WL_RSPEC_VHT_MCS_MASK),
|
||||
(rate >> WL_RSPEC_VHT_NSS_SHIFT));
|
||||
#if ((((VHT_SIGA1_20MHZ_VAL + 1) << WL_RSPEC_BW_SHIFT) != WL_RSPEC_BW_20MHZ) || \
|
||||
(((VHT_SIGA1_40MHZ_VAL + 1) << WL_RSPEC_BW_SHIFT) != WL_RSPEC_BW_40MHZ) || \
|
||||
(((VHT_SIGA1_80MHZ_VAL + 1) << WL_RSPEC_BW_SHIFT) != WL_RSPEC_BW_80MHZ) || \
|
||||
(((VHT_SIGA1_160MHZ_VAL + 1) << WL_RSPEC_BW_SHIFT) != WL_RSPEC_BW_160MHZ))
|
||||
#error "VHT SIGA BW mapping to RSPEC BW needs correction"
|
||||
#endif
|
||||
rspec |= ((vht_sig_a1 & VHT_SIGA1_160MHZ_VAL) + 1) << WL_RSPEC_BW_SHIFT;
|
||||
if (vht_sig_a1 & VHT_SIGA1_STBC)
|
||||
rspec |= WL_RSPEC_STBC;
|
||||
if (vht_sig_a2 & VHT_SIGA2_GI_SHORT)
|
||||
rspec |= WL_RSPEC_SGI;
|
||||
if (vht_sig_a2 & VHT_SIGA2_CODING_LDPC)
|
||||
rspec |= WL_RSPEC_LDPC;
|
||||
|
||||
return rspec;
|
||||
}
|
||||
|
||||
ratespec_t
|
||||
wf_ht_plcp_to_rspec(uint8 *plcp)
|
||||
{
|
||||
return HT_RSPEC(plcp[0] & MIMO_PLCP_MCS_MASK);
|
||||
}
|
||||
|
||||
/* ============================================ */
|
||||
/* Moved from wlc_rate_def.c */
|
||||
/* ============================================ */
|
||||
|
||||
/**
|
||||
* Rate info per rate: tells for *pre* 802.11n rates whether a given rate is OFDM or not and its
|
||||
* phy_rate value. Table index is a rate in [500Kbps] units, from 0 to 54Mbps.
|
||||
* Contents of a table element:
|
||||
* d[7] : 1=OFDM rate, 0=DSSS/CCK rate
|
||||
* d[3:0] if DSSS/CCK rate:
|
||||
* index into the 'M_RATE_TABLE_B' table maintained by ucode in shm
|
||||
* d[3:0] if OFDM rate: encode rate per 802.11a-1999 sec 17.3.4.1, with lsb transmitted first.
|
||||
* index into the 'M_RATE_TABLE_A' table maintained by ucode in shm
|
||||
*/
|
||||
/* Note: make this table 128 elements so the result of (rspec & 0x7f) can be safely
|
||||
* used as the index into this table...
|
||||
*/
|
||||
const uint8 rate_info[128] = {
|
||||
/* 0 1 2 3 4 5 6 7 8 9 */
|
||||
/* 0 */ 0x00, 0x00, 0x0a, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 10 */ 0x00, 0x37, 0x8b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8f, 0x00,
|
||||
/* 20 */ 0x00, 0x00, 0x6e, 0x00, 0x8a, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 30 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8e, 0x00, 0x00, 0x00,
|
||||
/* 40 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x89, 0x00,
|
||||
/* 50 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 60 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 70 */ 0x00, 0x00, 0x8d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 80 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 90 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00,
|
||||
/* 100 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8c,
|
||||
/* ------------- guard ------------ */ 0x00,
|
||||
/* 110 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 120 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* Driver O/S-independent utility routines
|
||||
*
|
||||
* Copyright (C) 2020, Broadcom.
|
||||
* Copyright (C) 2022, Broadcom.
|
||||
*
|
||||
* Unless you and Broadcom execute a separate written software license
|
||||
* agreement governing use of this software, this software is licensed to you
|
||||
|
|
@ -24,10 +24,6 @@
|
|||
#include <typedefs.h>
|
||||
#include <bcmdefs.h>
|
||||
|
||||
#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 15, 0))
|
||||
#include <stdarg.h>
|
||||
#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(5, 15, 0) */
|
||||
|
||||
#ifdef BCMDRIVER
|
||||
#include <osl.h>
|
||||
#else /* !BCMDRIVER */
|
||||
|
|
@ -428,14 +424,14 @@ int
|
|||
bcm_unpack_xtlv_buf(void *ctx, const uint8 *tlv_buf, uint16 buflen, bcm_xtlv_opts_t opts,
|
||||
bcm_xtlv_unpack_cbfn_t *cbfn)
|
||||
{
|
||||
int res = BCME_OK;
|
||||
const bcm_xtlv_t *ptlv;
|
||||
uint16 len;
|
||||
uint16 type;
|
||||
int res = BCME_OK;
|
||||
int size;
|
||||
const bcm_xtlv_t *ptlv;
|
||||
int sbuflen = buflen;
|
||||
const uint8 *data;
|
||||
int hdr_size;
|
||||
uint32 sbuflen = buflen;
|
||||
uint32 hdr_size; /* size of tlv header */
|
||||
uint32 size; /* size of tlv including header + data */
|
||||
|
||||
ASSERT(!buflen || tlv_buf);
|
||||
ASSERT(!buflen || cbfn);
|
||||
|
|
@ -447,12 +443,11 @@ bcm_unpack_xtlv_buf(void *ctx, const uint8 *tlv_buf, uint16 buflen, bcm_xtlv_opt
|
|||
bcm_xtlv_unpack_xtlv(ptlv, &type, &len, &data, opts);
|
||||
size = bcm_xtlv_size_for_data(len, opts);
|
||||
|
||||
sbuflen -= size;
|
||||
|
||||
/* check for buffer overrun */
|
||||
if (sbuflen < 0) {
|
||||
if (sbuflen < size) {
|
||||
break;
|
||||
}
|
||||
sbuflen -= size;
|
||||
|
||||
if ((res = cbfn(ctx, data, type, len)) != BCME_OK) {
|
||||
break;
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,15 +1,14 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Dongle BUS interface for USB, OS independent
|
||||
*
|
||||
* Copyright (C) 1999-2016, Broadcom Corporation
|
||||
*
|
||||
* Copyright (C) 2022, Broadcom.
|
||||
*
|
||||
* 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
|
||||
|
|
@ -17,15 +16,9 @@
|
|||
* 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: dbus_usb.c 565557 2015-06-22 19:29:44Z $
|
||||
* <<Broadcom-WL-IPTag/Dual:>>
|
||||
*/
|
||||
|
||||
/**
|
||||
|
|
@ -43,10 +36,21 @@
|
|||
#include <bcmdevs.h>
|
||||
#include <bcmendian.h>
|
||||
|
||||
#if defined(BCM_DNGL_EMBEDIMAGE)
|
||||
#ifdef EMBED_IMAGE_43526a
|
||||
#include "rtecdc_43526a.h"
|
||||
#endif /* EMBED_IMAGE_43526a */
|
||||
#ifdef EMBED_IMAGE_43526b
|
||||
#include "rtecdc_43526b.h"
|
||||
#endif /* EMBED_IMAGE_43526b */
|
||||
#ifdef EMBED_IMAGE_GENERIC
|
||||
#include "rtecdc.h"
|
||||
#endif
|
||||
#endif /* BCM_DNGL_EMBEDIMAGE */
|
||||
|
||||
uint dbus_msglevel = DBUS_ERROR_VAL;
|
||||
module_param(dbus_msglevel, int, 0);
|
||||
|
||||
|
||||
#define USB_DLIMAGE_RETRY_TIMEOUT 3000 /* retry Timeout */
|
||||
#define USB_SFLASH_DLIMAGE_SPINWAIT 150 /* in unit of ms */
|
||||
#define USB_SFLASH_DLIMAGE_LIMIT 2000 /* spinwait limit (ms) */
|
||||
|
|
@ -56,6 +60,9 @@ module_param(dbus_msglevel, int, 0);
|
|||
#define USB_DLGO_SPINWAIT 100 /* wait after DL_GO (ms) */
|
||||
#define TEST_CHIP 0x4328
|
||||
|
||||
/* driver info, initialized when bcmsdh_register is called */
|
||||
static dbus_driver_t drvinfo = {NULL, NULL, NULL, NULL};
|
||||
|
||||
typedef struct {
|
||||
dbus_pub_t *pub;
|
||||
|
||||
|
|
@ -83,11 +90,11 @@ static void dbus_usb_rxerr_indicate(void *handle, bool on);
|
|||
static int dbus_usb_resetcfg(usb_info_t *usbinfo);
|
||||
#endif
|
||||
static int dbus_usb_iovar_op(void *bus, const char *name,
|
||||
void *params, int plen, void *arg, int len, bool set);
|
||||
void *params, uint plen, void *arg, uint len, bool set);
|
||||
static int dbus_iovar_process(usb_info_t* usbinfo, const char *name,
|
||||
void *params, int plen, void *arg, int len, bool set);
|
||||
void *params, int plen, void *arg, uint len, bool set);
|
||||
static int dbus_usb_doiovar(usb_info_t *bus, const bcm_iovar_t *vi, uint32 actionid,
|
||||
const char *name, void *params, int plen, void *arg, int len, int val_size);
|
||||
const char *name, void *params, int plen, void *arg, uint len, int val_size);
|
||||
static int dhdusb_downloadvars(usb_info_t *bus, void *arg, int len);
|
||||
|
||||
static int dbus_usb_dl_writeimage(usb_info_t *usbinfo, uint8 *fw, int fwlen);
|
||||
|
|
@ -96,6 +103,9 @@ static int dbus_usb_dlneeded(void *bus);
|
|||
static int dbus_usb_dlrun(void *bus);
|
||||
static int dbus_usb_rdl_dwnld_state(usb_info_t *usbinfo);
|
||||
|
||||
#ifdef BCM_DNGL_EMBEDIMAGE
|
||||
static bool dbus_usb_device_exists(void *bus);
|
||||
#endif
|
||||
|
||||
/* OS specific */
|
||||
extern bool dbus_usbos_dl_cmd(void *info, uint8 cmd, void *buffer, int buflen);
|
||||
|
|
@ -135,12 +145,12 @@ enum {
|
|||
};
|
||||
|
||||
const bcm_iovar_t dhdusb_iovars[] = {
|
||||
{"vars", IOV_VARS, 0, IOVT_BUFFER, 0 },
|
||||
{"dbus_msglevel", IOV_DBUS_MSGLEVEL, 0, IOVT_UINT32, 0 },
|
||||
{"dwnldstate", IOV_SET_DOWNLOAD_STATE, 0, IOVT_BOOL, 0 },
|
||||
{"membytes", IOV_MEMBYTES, 0, IOVT_BUFFER, 2 * sizeof(int) },
|
||||
{"usb_lb_txfer", IOV_LOOPBACK_TX, 0, IOVT_BUFFER, 2 * sizeof(int) },
|
||||
{NULL, 0, 0, 0, 0 }
|
||||
{"vars", IOV_VARS, 0, 0, IOVT_BUFFER, 0 },
|
||||
{"dbus_msglevel", IOV_DBUS_MSGLEVEL, 0, 0, IOVT_UINT32, 0 },
|
||||
{"dwnldstate", IOV_SET_DOWNLOAD_STATE, 0, 0, IOVT_BOOL, 0 },
|
||||
{"membytes", IOV_MEMBYTES, 0, 0, IOVT_BUFFER, 2 * sizeof(int) },
|
||||
{"usb_lb_txfer", IOV_LOOPBACK_TX, 0, 0, IOVT_BUFFER, 2 * sizeof(int) },
|
||||
{NULL, 0, 0, 0, 0, 0 }
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
@ -148,10 +158,6 @@ const bcm_iovar_t dhdusb_iovars[] = {
|
|||
* attach() is not called at probe and detach()
|
||||
* can be called inside disconnect()
|
||||
*/
|
||||
static probe_cb_t probe_cb = NULL;
|
||||
static disconnect_cb_t disconnect_cb = NULL;
|
||||
static void *probe_arg = NULL;
|
||||
static void *disc_arg = NULL;
|
||||
static dbus_intf_t *g_dbusintf = NULL;
|
||||
static dbus_intf_t dbus_usb_intf; /** functions called by higher layer DBUS into lower layer */
|
||||
|
||||
|
|
@ -161,8 +167,10 @@ static dbus_intf_t dbus_usb_intf; /** functions called by higher layer DBUS into
|
|||
*/
|
||||
static void *dbus_usb_attach(dbus_pub_t *pub, void *cbarg, dbus_intf_callbacks_t *cbs);
|
||||
static void dbus_usb_detach(dbus_pub_t *pub, void *info);
|
||||
static void * dbus_usb_probe(void *arg, const char *desc, uint32 bustype,
|
||||
uint16 bus_no, uint16 slot, uint32 hdrlen);
|
||||
/* : g_usb_info needed for over-ridden functions
|
||||
* since the bus argument is actually from dbus_usb_<os>.c.
|
||||
*/
|
||||
static void * dbus_usb_probe(uint16 bus_no, uint16 slot, uint32 hdrlen);
|
||||
|
||||
/* functions */
|
||||
|
||||
|
|
@ -171,12 +179,10 @@ static void * dbus_usb_probe(void *arg, const char *desc, uint32 bustype,
|
|||
* lower level DBUS functions to call (in both dbus_usb.c and dbus_usb_os.c).
|
||||
*/
|
||||
static void *
|
||||
dbus_usb_probe(void *arg, const char *desc, uint32 bustype, uint16 bus_no,
|
||||
uint16 slot, uint32 hdrlen)
|
||||
dbus_usb_probe(uint16 bus_no, uint16 slot, uint32 hdrlen)
|
||||
{
|
||||
DBUSTRACE(("%s(): \n", __FUNCTION__));
|
||||
if (probe_cb) {
|
||||
|
||||
if (drvinfo.probe) {
|
||||
if (g_dbusintf != NULL) {
|
||||
/* First, initialize all lower-level functions as default
|
||||
* so that dbus.c simply calls directly to dbus_usb_os.c.
|
||||
|
|
@ -190,34 +196,60 @@ dbus_usb_probe(void *arg, const char *desc, uint32 bustype, uint16 bus_no,
|
|||
dbus_usb_intf.dlstart = dbus_usb_dlstart;
|
||||
dbus_usb_intf.dlneeded = dbus_usb_dlneeded;
|
||||
dbus_usb_intf.dlrun = dbus_usb_dlrun;
|
||||
#ifdef BCM_DNGL_EMBEDIMAGE
|
||||
dbus_usb_intf.device_exists = dbus_usb_device_exists;
|
||||
#endif
|
||||
}
|
||||
|
||||
disc_arg = probe_cb(probe_arg, "DBUS USB", USB_BUS, bus_no, slot, hdrlen);
|
||||
return disc_arg;
|
||||
return drvinfo.probe(bus_no, slot, hdrlen);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int
|
||||
dbus_usb_suspend(void *handle)
|
||||
{
|
||||
DBUSTRACE(("%s(): \n", __FUNCTION__));
|
||||
|
||||
if (drvinfo.suspend)
|
||||
return drvinfo.suspend(handle);
|
||||
|
||||
return BCME_OK;
|
||||
}
|
||||
|
||||
static int
|
||||
dbus_usb_resume(void *handle)
|
||||
{
|
||||
DBUSTRACE(("%s(): \n", __FUNCTION__));
|
||||
|
||||
if (drvinfo.resume)
|
||||
drvinfo.resume(handle);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static dbus_driver_t dhd_usb_dbus = {
|
||||
dbus_usb_probe,
|
||||
dbus_usb_disconnect,
|
||||
dbus_usb_suspend,
|
||||
dbus_usb_resume
|
||||
};
|
||||
|
||||
/**
|
||||
* On return, *intf contains this or lower-level DBUS functions to be called by higher
|
||||
* level (dbus.c)
|
||||
*/
|
||||
int
|
||||
dbus_bus_register(int vid, int pid, probe_cb_t prcb,
|
||||
disconnect_cb_t discb, void *prarg, dbus_intf_t **intf, void *param1, void *param2)
|
||||
dbus_bus_register(dbus_driver_t *driver, dbus_intf_t **intf)
|
||||
{
|
||||
int err;
|
||||
|
||||
DBUSTRACE(("%s(): \n", __FUNCTION__));
|
||||
probe_cb = prcb;
|
||||
disconnect_cb = discb;
|
||||
probe_arg = prarg;
|
||||
|
||||
drvinfo = *driver;
|
||||
*intf = &dbus_usb_intf;
|
||||
|
||||
err = dbus_bus_osl_register(vid, pid, dbus_usb_probe,
|
||||
dbus_usb_disconnect, NULL, &g_dbusintf, param1, param2);
|
||||
err = dbus_bus_osl_register(&dhd_usb_dbus, &g_dbusintf);
|
||||
|
||||
ASSERT(g_dbusintf);
|
||||
return err;
|
||||
|
|
@ -293,8 +325,8 @@ void
|
|||
dbus_usb_disconnect(void *handle)
|
||||
{
|
||||
DBUSTRACE(("%s(): \n", __FUNCTION__));
|
||||
if (disconnect_cb)
|
||||
disconnect_cb(disc_arg);
|
||||
if (drvinfo.remove)
|
||||
drvinfo.remove(handle);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -433,7 +465,7 @@ dbus_usb_state_change(void *handle, int state)
|
|||
/** called by higher DBUS level (dbus.c) */
|
||||
static int
|
||||
dbus_usb_iovar_op(void *bus, const char *name,
|
||||
void *params, int plen, void *arg, int len, bool set)
|
||||
void *params, uint plen, void *arg, uint len, bool set)
|
||||
{
|
||||
int err = DBUS_OK;
|
||||
|
||||
|
|
@ -444,7 +476,7 @@ dbus_usb_iovar_op(void *bus, const char *name,
|
|||
/** process iovar request from higher DBUS level */
|
||||
static int
|
||||
dbus_iovar_process(usb_info_t* usbinfo, const char *name,
|
||||
void *params, int plen, void *arg, int len, bool set)
|
||||
void *params, int plen, void *arg, uint len, bool set)
|
||||
{
|
||||
const bcm_iovar_t *vi = NULL;
|
||||
int bcmerror = 0;
|
||||
|
|
@ -454,7 +486,6 @@ dbus_iovar_process(usb_info_t* usbinfo, const char *name,
|
|||
DBUSTRACE(("%s: Enter\n", __FUNCTION__));
|
||||
|
||||
ASSERT(name);
|
||||
ASSERT(len >= 0);
|
||||
|
||||
/* Get MUST have return space */
|
||||
ASSERT(set || (arg && len));
|
||||
|
|
@ -500,7 +531,7 @@ exit:
|
|||
|
||||
static int
|
||||
dbus_usb_doiovar(usb_info_t *bus, const bcm_iovar_t *vi, uint32 actionid, const char *name,
|
||||
void *params, int plen, void *arg, int len, int val_size)
|
||||
void *params, int plen, void *arg, uint len, int val_size)
|
||||
{
|
||||
int bcmerror = 0;
|
||||
int32 int_val = 0;
|
||||
|
|
@ -558,7 +589,6 @@ dbus_usb_doiovar(usb_info_t *bus, const bcm_iovar_t *vi, uint32 actionid, const
|
|||
}
|
||||
break;
|
||||
|
||||
|
||||
case IOV_SVAL(IOV_SET_DOWNLOAD_STATE):
|
||||
|
||||
if (bool_val == TRUE) {
|
||||
|
|
@ -700,6 +730,7 @@ dbus_usb_resetcfg(usb_info_t *usbinfo)
|
|||
|
||||
dbus_usbos_dl_cmd(osinfo, DL_RESETCFG, &id, sizeof(bootrom_id_t));
|
||||
|
||||
/* this wait may not be necessary */
|
||||
dbus_usbos_wait(osinfo, USB_RESETCFG_SPINWAIT);
|
||||
return DBUS_OK;
|
||||
} else {
|
||||
|
|
@ -750,13 +781,8 @@ dbus_usb_dl_writeimage(usb_info_t *usbinfo, uint8 *fw, int fwlen)
|
|||
char *bulkchunk = NULL, *dlpos;
|
||||
rdl_state_t state;
|
||||
int err = DBUS_OK;
|
||||
bootrom_id_t id;
|
||||
uint16 wait, wait_time;
|
||||
uint32 dl_trunk_size = RDL_CHUNK;
|
||||
|
||||
if (BCM4350_CHIP(usbinfo->pub->attrib.devid))
|
||||
dl_trunk_size = RDL_CHUNK_MAX;
|
||||
|
||||
while (!bulkchunk) {
|
||||
bulkchunk = MALLOC(osh, dl_trunk_size);
|
||||
if (dl_trunk_size == RDL_CHUNK)
|
||||
|
|
@ -777,10 +803,6 @@ dbus_usb_dl_writeimage(usb_info_t *usbinfo, uint8 *fw, int fwlen)
|
|||
dlpos = fw;
|
||||
dllen = fwlen;
|
||||
|
||||
/* Get chip id and rev */
|
||||
id.chip = usbinfo->pub->attrib.devid;
|
||||
id.chiprev = usbinfo->pub->attrib.chiprev;
|
||||
|
||||
DBUSTRACE(("enter %s: fwlen=%d\n", __FUNCTION__, fwlen));
|
||||
|
||||
dbus_usbos_dl_cmd(osinfo, DL_GETSTATE, &state, sizeof(rdl_state_t));
|
||||
|
|
@ -789,6 +811,7 @@ dbus_usb_dl_writeimage(usb_info_t *usbinfo, uint8 *fw, int fwlen)
|
|||
while ((sent < dllen)) {
|
||||
/* Wait until the usb device reports it received all the bytes we sent */
|
||||
|
||||
/* add a timeout so we dont wait indefinetly */
|
||||
if (sent < dllen) {
|
||||
if ((dllen-sent) < dl_trunk_size)
|
||||
sendlen = dllen-sent;
|
||||
|
|
@ -813,26 +836,11 @@ dbus_usb_dl_writeimage(usb_info_t *usbinfo, uint8 *fw, int fwlen)
|
|||
DBUSTRACE(("%s: sendlen %d\n", __FUNCTION__, sendlen));
|
||||
}
|
||||
|
||||
wait = 0;
|
||||
wait_time = USB_SFLASH_DLIMAGE_SPINWAIT;
|
||||
while (!dbus_usbos_dl_cmd(osinfo, DL_GETSTATE, &state,
|
||||
sizeof(rdl_state_t))) {
|
||||
if ((id.chip == 43236) && (id.chiprev == 0)) {
|
||||
DBUSERR(("%s: 43236a0 SFlash delay, waiting for dongle crc check "
|
||||
"completion!!!\n", __FUNCTION__));
|
||||
dbus_usbos_wait(osinfo, wait_time);
|
||||
wait += wait_time;
|
||||
if (wait >= USB_SFLASH_DLIMAGE_LIMIT) {
|
||||
DBUSERR(("%s: DL_GETSTATE Failed xxxx\n", __FUNCTION__));
|
||||
err = DBUS_ERR;
|
||||
goto fail;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
DBUSERR(("%s: DL_GETSTATE Failed xxxx\n", __FUNCTION__));
|
||||
err = DBUS_ERR;
|
||||
goto fail;
|
||||
}
|
||||
/* Wait for downloaded image crc check to complete in the dongle */
|
||||
while (!dbus_usbos_dl_cmd(osinfo, DL_GETSTATE, &state, sizeof(rdl_state_t))) {
|
||||
DBUSERR(("%s: DL_GETSTATE Failed xxxx\n", __FUNCTION__));
|
||||
err = DBUS_ERR;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
state.state = ltoh32(state.state);
|
||||
|
|
@ -888,58 +896,32 @@ dbus_usb_update_chipinfo(usb_info_t *usbinfo, uint32 chip)
|
|||
bool retval = TRUE;
|
||||
/* based on the CHIP Id, store the ram size which is needed for NVRAM download. */
|
||||
switch (chip) {
|
||||
|
||||
case 0x4319:
|
||||
usbinfo->rdlram_size = RDL_RAM_SIZE_4319;
|
||||
usbinfo->rdlram_base_addr = RDL_RAM_BASE_4319;
|
||||
break;
|
||||
|
||||
case 0x4329:
|
||||
usbinfo->rdlram_size = RDL_RAM_SIZE_4329;
|
||||
usbinfo->rdlram_base_addr = RDL_RAM_BASE_4329;
|
||||
break;
|
||||
|
||||
case 43234:
|
||||
case 43235:
|
||||
case 43236:
|
||||
usbinfo->rdlram_size = RDL_RAM_SIZE_43236;
|
||||
usbinfo->rdlram_base_addr = RDL_RAM_BASE_43236;
|
||||
break;
|
||||
|
||||
case 0x4328:
|
||||
usbinfo->rdlram_size = RDL_RAM_SIZE_4328;
|
||||
usbinfo->rdlram_base_addr = RDL_RAM_BASE_4328;
|
||||
break;
|
||||
|
||||
case 0x4322:
|
||||
usbinfo->rdlram_size = RDL_RAM_SIZE_4322;
|
||||
usbinfo->rdlram_base_addr = RDL_RAM_BASE_4322;
|
||||
break;
|
||||
|
||||
case 0x4360:
|
||||
case 0xAA06:
|
||||
usbinfo->rdlram_size = RDL_RAM_SIZE_4360;
|
||||
usbinfo->rdlram_base_addr = RDL_RAM_BASE_4360;
|
||||
break;
|
||||
|
||||
case 43242:
|
||||
case 43243:
|
||||
usbinfo->rdlram_size = RDL_RAM_SIZE_43242;
|
||||
usbinfo->rdlram_base_addr = RDL_RAM_BASE_43242;
|
||||
break;
|
||||
|
||||
case 43143:
|
||||
usbinfo->rdlram_size = RDL_RAM_SIZE_43143;
|
||||
usbinfo->rdlram_base_addr = RDL_RAM_BASE_43143;
|
||||
break;
|
||||
|
||||
case 0x4350:
|
||||
case 43556:
|
||||
case 43558:
|
||||
case 43569:
|
||||
usbinfo->rdlram_size = RDL_RAM_SIZE_4350;
|
||||
usbinfo->rdlram_base_addr = RDL_RAM_BASE_4350;
|
||||
break;
|
||||
case BCM4381_CHIP_ID:
|
||||
usbinfo->rdlram_size = RDL_RAM_SIZE_4381;
|
||||
usbinfo->rdlram_base_addr = RDL_RAM_BASE_4381;
|
||||
break;
|
||||
|
||||
case BCM4382_CHIP_ID:
|
||||
usbinfo->rdlram_size = RDL_RAM_SIZE_4382;
|
||||
usbinfo->rdlram_base_addr = RDL_RAM_BASE_4382;
|
||||
break;
|
||||
|
||||
case POSTBOOT_ID:
|
||||
break;
|
||||
|
|
@ -1032,6 +1014,9 @@ dbus_usb_dlrun(void *bus)
|
|||
DBUSTRACE(("%s: Issue DL_GO\n", __FUNCTION__));
|
||||
dbus_usbos_dl_cmd(osinfo, DL_GO, &state, sizeof(rdl_state_t));
|
||||
|
||||
/* : Need this for 4326 for some reason
|
||||
* Same issue under both Linux/Windows
|
||||
*/
|
||||
if (usbinfo->pub->attrib.devid == TEST_CHIP)
|
||||
dbus_usbos_wait(osinfo, USB_DLGO_SPINWAIT);
|
||||
|
||||
|
|
@ -1059,111 +1044,12 @@ dbus_bus_fw_get(void *bus, uint8 **fw, int *fwlen, int *decomp)
|
|||
|
||||
devid = usbinfo->pub->attrib.devid;
|
||||
crev = usbinfo->pub->attrib.chiprev;
|
||||
BCM_REFERENCE(crev);
|
||||
|
||||
*fw = NULL;
|
||||
*fwlen = 0;
|
||||
|
||||
switch (devid) {
|
||||
case BCM43236_CHIP_ID:
|
||||
case BCM43235_CHIP_ID:
|
||||
case BCM43234_CHIP_ID:
|
||||
case BCM43238_CHIP_ID: {
|
||||
if (crev == 3 || crev == 2 || crev == 1) {
|
||||
#ifdef EMBED_IMAGE_43236b
|
||||
*fw = (uint8 *)dlarray_43236b;
|
||||
*fwlen = sizeof(dlarray_43236b);
|
||||
|
||||
#endif
|
||||
}
|
||||
} break;
|
||||
case BCM4360_CHIP_ID:
|
||||
case BCM4352_CHIP_ID:
|
||||
case BCM43526_CHIP_ID:
|
||||
#ifdef EMBED_IMAGE_43526a
|
||||
if (crev <= 2) {
|
||||
*fw = (uint8 *)dlarray_43526a;
|
||||
*fwlen = sizeof(dlarray_43526a);
|
||||
}
|
||||
#endif
|
||||
#ifdef EMBED_IMAGE_43526b
|
||||
if (crev > 2) {
|
||||
*fw = (uint8 *)dlarray_43526b;
|
||||
*fwlen = sizeof(dlarray_43526b);
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
|
||||
case BCM43242_CHIP_ID:
|
||||
#ifdef EMBED_IMAGE_43242a0
|
||||
*fw = (uint8 *)dlarray_43242a0;
|
||||
*fwlen = sizeof(dlarray_43242a0);
|
||||
#endif
|
||||
break;
|
||||
|
||||
case BCM43143_CHIP_ID:
|
||||
#ifdef EMBED_IMAGE_43143a0
|
||||
*fw = (uint8 *)dlarray_43143a0;
|
||||
*fwlen = sizeof(dlarray_43143a0);
|
||||
#endif
|
||||
#ifdef EMBED_IMAGE_43143b0
|
||||
*fw = (uint8 *)dlarray_43143b0;
|
||||
*fwlen = sizeof(dlarray_43143b0);
|
||||
#endif
|
||||
break;
|
||||
|
||||
case BCM4350_CHIP_ID:
|
||||
case BCM4354_CHIP_ID:
|
||||
case BCM43556_CHIP_ID:
|
||||
case BCM43558_CHIP_ID:
|
||||
case BCM43566_CHIP_ID:
|
||||
case BCM43568_CHIP_ID:
|
||||
case BCM43570_CHIP_ID:
|
||||
case BCM4358_CHIP_ID:
|
||||
#ifdef EMBED_IMAGE_4350a0
|
||||
if (crev == 0) {
|
||||
*fw = (uint8 *)dlarray_4350a0;
|
||||
*fwlen = sizeof(dlarray_4350a0);
|
||||
}
|
||||
#endif
|
||||
#ifdef EMBED_IMAGE_4350b0
|
||||
if (crev == 1) {
|
||||
*fw = (uint8 *)dlarray_4350b0;
|
||||
*fwlen = sizeof(dlarray_4350b0);
|
||||
}
|
||||
#endif
|
||||
#ifdef EMBED_IMAGE_4350b1
|
||||
if (crev == 2) {
|
||||
*fw = (uint8 *)dlarray_4350b1;
|
||||
*fwlen = sizeof(dlarray_4350b1);
|
||||
}
|
||||
#endif
|
||||
#ifdef EMBED_IMAGE_43556b1
|
||||
if (crev == 2) {
|
||||
*fw = (uint8 *)dlarray_43556b1;
|
||||
*fwlen = sizeof(dlarray_43556b1);
|
||||
}
|
||||
#endif
|
||||
#ifdef EMBED_IMAGE_4350c0
|
||||
if (crev == 3) {
|
||||
*fw = (uint8 *)dlarray_4350c0;
|
||||
*fwlen = sizeof(dlarray_4350c0);
|
||||
}
|
||||
#endif /* EMBED_IMAGE_4350c0 */
|
||||
#ifdef EMBED_IMAGE_4350c1
|
||||
if (crev == 4) {
|
||||
*fw = (uint8 *)dlarray_4350c1;
|
||||
*fwlen = sizeof(dlarray_4350c1);
|
||||
}
|
||||
#endif /* EMBED_IMAGE_4350c1 */
|
||||
break;
|
||||
case BCM43569_CHIP_ID:
|
||||
#ifdef EMBED_IMAGE_43569a0
|
||||
if (crev == 0) {
|
||||
*fw = (uint8 *)dlarray_43569a0;
|
||||
*fwlen = sizeof(dlarray_43569a0);
|
||||
}
|
||||
#endif /* EMBED_IMAGE_43569a0 */
|
||||
break;
|
||||
default:
|
||||
#ifdef EMBED_IMAGE_GENERIC
|
||||
*fw = (uint8 *)dlarray;
|
||||
|
|
@ -1172,3 +1058,31 @@ dbus_bus_fw_get(void *bus, uint8 **fw, int *fwlen, int *decomp)
|
|||
break;
|
||||
}
|
||||
} /* dbus_bus_fw_get */
|
||||
|
||||
#ifdef BCM_DNGL_EMBEDIMAGE
|
||||
static bool
|
||||
dbus_usb_device_exists(void *bus)
|
||||
{
|
||||
usb_info_t *usbinfo = BUS_INFO(bus, usb_info_t);
|
||||
void *osinfo;
|
||||
bootrom_id_t id;
|
||||
|
||||
DBUSTRACE(("%s\n", __FUNCTION__));
|
||||
|
||||
if (usbinfo == NULL)
|
||||
return FALSE;
|
||||
|
||||
osinfo = usbinfo->usbosl_info;
|
||||
ASSERT(osinfo);
|
||||
|
||||
id.chip = 0xDEAD;
|
||||
/* Query device to see if we get a response */
|
||||
dbus_usbos_dl_cmd(osinfo, DL_GETVER, &id, sizeof(bootrom_id_t));
|
||||
|
||||
usbinfo->pub->attrib.devid = id.chip;
|
||||
if (id.chip == 0xDEAD)
|
||||
return FALSE;
|
||||
else
|
||||
return TRUE;
|
||||
}
|
||||
#endif /* BCM_DNGL_EMBEDIMAGE */
|
||||
|
|
|
|||
1961
drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dbus_usb_linux.c
Executable file → Normal file
1961
drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dbus_usb_linux.c
Executable file → Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
|
@ -1,228 +0,0 @@
|
|||
/*
|
||||
* Bit packing and Base64 utils for EWP
|
||||
*
|
||||
* Copyright (C) 2020, Broadcom.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*
|
||||
* <<Broadcom-WL-IPTag/Open:>>
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include <dhd_bitpack.h>
|
||||
|
||||
#define BIT_PACK_OVERFLOW 0xFFFFFFFFu
|
||||
|
||||
const char* base64_table = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||
|
||||
#define BASE64_MAX_VALUE 63u
|
||||
|
||||
#define BASE64_UNIT_LEN 6u
|
||||
|
||||
#define BASE64_OFFSET0 0u
|
||||
#define BASE64_OFFSET1 6u
|
||||
#define BASE64_OFFSET2 12u
|
||||
|
||||
#define MASK_UPPER_6BIT 0xfc
|
||||
#define MASK_LOWER_6BIT 0x3f
|
||||
|
||||
#define MASK_UPPER_4BIT 0xf0
|
||||
#define MASK_LOWER_4BIT 0x0f
|
||||
|
||||
#define MASK_UPPER_2BIT 0xc0
|
||||
#define MASK_LOWER_2BIT 0x03
|
||||
|
||||
#define SHIFT_2BIT 2u
|
||||
#define SHIFT_4BIT 4u
|
||||
#define SHIFT_6BIT 6u
|
||||
|
||||
#define BASE64_PADDING_MARGIN 4u
|
||||
|
||||
/*
|
||||
* Function: dhd_bit_pack
|
||||
*
|
||||
* Purpose: bit data packing to given buffer
|
||||
*
|
||||
* Input Parameters:
|
||||
* buf buffer to pack bit data
|
||||
* buf_len total buffer length
|
||||
* bit_offset offset in buffer (bitwise)
|
||||
* data data to pack (max 32 bit)
|
||||
* bit_length bit length to pack
|
||||
*
|
||||
* Output:
|
||||
* Updated bit offset in buf
|
||||
*/
|
||||
int32
|
||||
dhd_bit_pack(char *buf, int buf_len, int bit_offset, uint32 data, int32 bit_length)
|
||||
{
|
||||
|
||||
int32 byte_shift = (bit_offset / 8);
|
||||
int32 local_bit_offset = bit_offset % 8;
|
||||
int32 available_bit = 8 - local_bit_offset;
|
||||
int32 remain_bit = bit_length;
|
||||
uint32 cropped_data;
|
||||
int32 idx;
|
||||
int32 total_byte = BYTE_SIZE(local_bit_offset + bit_length);
|
||||
|
||||
if (bit_length > 32) {
|
||||
/* exceeded max bit length, do nothing */
|
||||
return bit_offset;
|
||||
}
|
||||
if (BYTE_SIZE(bit_offset + bit_length) > buf_len) {
|
||||
/* can't pack more bits if expected offset is
|
||||
* exceeded then buffer size
|
||||
*/
|
||||
return bit_offset;
|
||||
}
|
||||
if (bit_length < 32 && data >= 1<<bit_length) {
|
||||
cropped_data = BIT_PACK_OVERFLOW << (32 - bit_length);
|
||||
cropped_data = cropped_data >> (32 - bit_length);
|
||||
} else {
|
||||
cropped_data = data << (32 - bit_length);
|
||||
cropped_data = cropped_data >> (32 - bit_length);
|
||||
}
|
||||
|
||||
buf += byte_shift;
|
||||
|
||||
remain_bit = bit_length;
|
||||
if (total_byte > 10) {
|
||||
return bit_offset;
|
||||
}
|
||||
for (idx = 0; idx < total_byte; idx++) {
|
||||
char temp_byte = 0x00;
|
||||
if (idx == 0) {
|
||||
local_bit_offset = bit_offset % 8;
|
||||
} else {
|
||||
local_bit_offset = 0;
|
||||
}
|
||||
|
||||
available_bit = 8 - local_bit_offset;
|
||||
remain_bit -= available_bit;
|
||||
if (remain_bit >= 0) {
|
||||
temp_byte = cropped_data >> remain_bit;
|
||||
} else {
|
||||
temp_byte = cropped_data << (-1*remain_bit);
|
||||
}
|
||||
*buf = *buf | temp_byte;
|
||||
buf ++;
|
||||
}
|
||||
bit_offset += bit_length;
|
||||
|
||||
return bit_offset;
|
||||
}
|
||||
|
||||
static char
|
||||
dhd_base64_get_code(char input)
|
||||
{
|
||||
if (input > BASE64_MAX_VALUE) {
|
||||
return '=';
|
||||
}
|
||||
return base64_table[(int)input];
|
||||
}
|
||||
|
||||
/*
|
||||
* Function: dhd_base64_encode
|
||||
*
|
||||
* Purpose: base64 encoding module which converts from 8 bits to
|
||||
* 6 bit based, base64 format using base64_table
|
||||
* eg: input: hex-123456
|
||||
* bin-0001|0010|0011|0100|0101|0110
|
||||
* encode every 6 bit :
|
||||
* bin-000100|100011|010001|010110
|
||||
* base64 code :
|
||||
* base64-EjRW
|
||||
*
|
||||
* Input Parameters:
|
||||
* in_buf input buffer
|
||||
* in_buf_len length of input buffer
|
||||
* out_buf output buffer
|
||||
* out_buf_len length_ of output buffer
|
||||
*
|
||||
* Output:
|
||||
* length of encoded base64 string
|
||||
*/
|
||||
int32
|
||||
dhd_base64_encode(char* in_buf, int32 in_buf_len, char* out_buf, int32 out_buf_len)
|
||||
{
|
||||
char* input_pos;
|
||||
char* input_end;
|
||||
char* base64_out;
|
||||
char* base64_out_pos;
|
||||
char* base64_output_end;
|
||||
char current_byte = 0;
|
||||
char masked_byte = 0;
|
||||
int32 estimated_out_len = 0;
|
||||
int32 offset = 0;
|
||||
|
||||
if (!in_buf || !out_buf || in_buf_len == 0 || out_buf_len == 0) {
|
||||
/* wrong input parameters */
|
||||
return 0;
|
||||
}
|
||||
|
||||
input_pos = in_buf;
|
||||
input_end = in_buf + in_buf_len;
|
||||
base64_out = out_buf;
|
||||
base64_out_pos = base64_out;
|
||||
base64_output_end = out_buf + out_buf_len - BASE64_PADDING_MARGIN;
|
||||
estimated_out_len = in_buf_len / 3 * 4;
|
||||
|
||||
if (estimated_out_len > out_buf_len) {
|
||||
/* estimated output length is
|
||||
* larger than output buffer size
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
while (input_pos != input_end) {
|
||||
if (base64_out_pos > base64_output_end) {
|
||||
/* outbuf buffer size exceeded, finish encoding */
|
||||
break;
|
||||
}
|
||||
if (offset == BASE64_OFFSET0) {
|
||||
current_byte = *input_pos++;
|
||||
masked_byte = (current_byte & MASK_UPPER_6BIT) >> SHIFT_2BIT;
|
||||
*base64_out_pos++ = dhd_base64_get_code(masked_byte);
|
||||
masked_byte = (current_byte & MASK_LOWER_2BIT) << SHIFT_4BIT;
|
||||
offset += BASE64_UNIT_LEN;
|
||||
} else if (offset == BASE64_OFFSET1) {
|
||||
current_byte = *input_pos++;
|
||||
masked_byte |= (current_byte & MASK_UPPER_4BIT) >> SHIFT_4BIT;
|
||||
*base64_out_pos++ = dhd_base64_get_code(masked_byte);
|
||||
masked_byte = (current_byte & MASK_LOWER_4BIT) << SHIFT_2BIT;
|
||||
offset += BASE64_UNIT_LEN;
|
||||
} else if (offset == BASE64_OFFSET2) {
|
||||
current_byte = *input_pos++;
|
||||
masked_byte |= (current_byte & MASK_UPPER_2BIT) >> SHIFT_6BIT;
|
||||
*base64_out_pos++ = dhd_base64_get_code(masked_byte);
|
||||
offset += BASE64_UNIT_LEN;
|
||||
masked_byte = (current_byte & MASK_LOWER_6BIT);
|
||||
*base64_out_pos++ = dhd_base64_get_code(masked_byte);
|
||||
offset = BASE64_OFFSET0;
|
||||
}
|
||||
}
|
||||
if (offset == BASE64_OFFSET1) {
|
||||
*base64_out_pos++ = dhd_base64_get_code(masked_byte);
|
||||
*base64_out_pos++ = '=';
|
||||
*base64_out_pos++ = '=';
|
||||
} else if (offset == BASE64_OFFSET2) {
|
||||
*base64_out_pos++ = dhd_base64_get_code(masked_byte);
|
||||
*base64_out_pos++ = '=';
|
||||
}
|
||||
|
||||
return base64_out_pos - base64_out;
|
||||
}
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* Bit packing and Base64 utils for EWP
|
||||
*
|
||||
* Copyright (C) 2020, Broadcom.
|
||||
* Copyright (C) 2022, Broadcom.
|
||||
*
|
||||
* Unless you and Broadcom execute a separate written software license
|
||||
* agreement governing use of this software, this software is licensed to you
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
* Provides type definitions and function prototypes used to link the
|
||||
* DHD OS, bus, and protocol modules.
|
||||
*
|
||||
* Copyright (C) 2020, Broadcom.
|
||||
* Copyright (C) 2022, Broadcom.
|
||||
*
|
||||
* Unless you and Broadcom execute a separate written software license
|
||||
* agreement governing use of this software, this software is licensed to you
|
||||
|
|
@ -31,8 +31,6 @@
|
|||
|
||||
extern int dbus_up(struct dhd_bus *pub);
|
||||
extern int dbus_stop(struct dhd_bus *pub);
|
||||
extern int dbus_send_ctl(struct dhd_bus *pub, uint8 *buf, int len);
|
||||
extern int dbus_recv_ctl(struct dhd_bus *pub, uint8 *buf, int len);
|
||||
/*
|
||||
* Exported from dhd bus module (dhd_usb, dhd_sdio)
|
||||
*/
|
||||
|
|
@ -72,6 +70,7 @@ extern int dhd_bus_txdata(struct dhd_bus *bus, void *txp);
|
|||
|
||||
#ifdef BCMPCIE
|
||||
extern uint16 dhd_prot_get_rxbufpost_sz(dhd_pub_t *dhd);
|
||||
extern uint16 dhd_prot_get_rxbufpost_alloc_sz(dhd_pub_t *dhd);
|
||||
extern uint16 dhd_prot_get_h2d_rx_post_active(dhd_pub_t *dhd);
|
||||
extern uint16 dhd_prot_get_d2h_rx_cpln_active(dhd_pub_t *dhd);
|
||||
extern void dhdpcie_cto_recovery_handler(dhd_pub_t *dhd);
|
||||
|
|
@ -111,6 +110,7 @@ extern int dhd_bus_iovar_op(dhd_pub_t *dhdp, const char *name,
|
|||
|
||||
/* Add bus dump output to a buffer */
|
||||
extern void dhd_bus_dump(dhd_pub_t *dhdp, struct bcmstrbuf *strbuf);
|
||||
extern void dhd_bus_dump_flowring(dhd_pub_t *dhdp, struct bcmstrbuf *strbuf);
|
||||
|
||||
/* Clear any bus counters */
|
||||
extern void dhd_bus_clearcounts(dhd_pub_t *dhdp);
|
||||
|
|
@ -198,6 +198,7 @@ enum {
|
|||
#endif /* D2H_MINIDUMP */
|
||||
DNGL_TO_HOST_TRAP_ADDR,
|
||||
HOST_SCB_ADDR, /* update host scb base address to dongle */
|
||||
HOST_CAP2, /* Host capability 2 flags */
|
||||
};
|
||||
|
||||
typedef void (*dhd_mb_ring_t) (struct dhd_bus *, uint32);
|
||||
|
|
@ -225,7 +226,8 @@ extern void dhd_bus_flow_ring_delete_response(struct dhd_bus *bus, uint16 flowid
|
|||
extern int dhd_bus_flow_ring_flush_request(struct dhd_bus *bus, void *flow_ring_node);
|
||||
extern void dhd_bus_flow_ring_flush_response(struct dhd_bus *bus, uint16 flowid, uint32 status);
|
||||
extern uint32 dhd_bus_max_h2d_queues(struct dhd_bus *bus);
|
||||
extern int dhd_bus_schedule_queue(struct dhd_bus *bus, uint16 flow_id, bool txs);
|
||||
extern int dhd_bus_schedule_queue(struct dhd_bus *bus, uint16 flow_id, bool txs,
|
||||
uint32 bound, bool *is_qempty);
|
||||
|
||||
#ifdef IDLE_TX_FLOW_MGMT
|
||||
extern void dhd_bus_flow_ring_resume_response(struct dhd_bus *bus, uint16 flowid, int32 status);
|
||||
|
|
@ -252,8 +254,6 @@ extern void dhd_bus_aer_config(struct dhd_bus *bus);
|
|||
static INLINE void dhd_bus_aer_config(struct dhd_bus *bus) { }
|
||||
#endif /* LINUX || linux */
|
||||
|
||||
extern struct device * dhd_bus_to_dev(struct dhd_bus *bus);
|
||||
|
||||
extern int dhdpcie_cto_init(struct dhd_bus *bus, bool enable);
|
||||
extern int dhdpcie_cto_cfg_init(struct dhd_bus *bus, bool enable);
|
||||
|
||||
|
|
@ -273,7 +273,6 @@ extern void dhd_bus_handle_mb_data(struct dhd_bus *bus, uint32 d2h_mb_data);
|
|||
extern void dhd_bus_dump_trap_info(struct dhd_bus *bus, struct bcmstrbuf *b);
|
||||
extern void dhd_bus_copy_trap_sig(struct dhd_bus *bus, trap_t *tr);
|
||||
#ifdef WL_CFGVENDOR_SEND_HANG_EVENT
|
||||
extern void dhd_dump_pcie_rc_regs_for_linkdown(dhd_pub_t *dhd, int *bytes_written);
|
||||
void copy_hang_info_linkdown(dhd_pub_t *dhd);
|
||||
void copy_ext_trap_sig(dhd_pub_t *dhd, trap_t *tr);
|
||||
void copy_hang_info_trap(dhd_pub_t *dhd);
|
||||
|
|
@ -298,11 +297,12 @@ extern bool dhd_bus_query_dpc_sched_errors(dhd_pub_t *dhdp);
|
|||
extern int dhd_bus_dmaxfer_lpbk(dhd_pub_t *dhdp, uint32 type);
|
||||
extern bool dhd_bus_check_driver_up(void);
|
||||
extern int dhd_bus_get_cto(dhd_pub_t *dhdp);
|
||||
extern bool dhd_bus_get_read_shm(dhd_pub_t *dhdp);
|
||||
extern void dhd_bus_set_linkdown(dhd_pub_t *dhdp, bool val);
|
||||
extern int dhd_bus_get_linkdown(dhd_pub_t *dhdp);
|
||||
#ifdef CONFIG_ARCH_MSM
|
||||
#if defined(CONFIG_ARCH_MSM) && defined(CONFIG_SEC_PCIE_L1SS)
|
||||
extern void dhd_bus_inform_ep_loaded_to_rc(dhd_pub_t *dhdp, bool up);
|
||||
#endif /* CONFIG_ARCH_MSM */
|
||||
#endif /* CONFIG_ARCH_MSM && CONFIG_SEC_PCIE_L1SS */
|
||||
extern int dhd_bus_checkdied(struct dhd_bus *bus, char *data, uint size);
|
||||
#else
|
||||
#define dhd_bus_dump_console_buffer(x)
|
||||
|
|
@ -313,7 +313,8 @@ static INLINE bool dhd_bus_check_driver_up(void) { return FALSE; }
|
|||
static INLINE void dhd_bus_set_linkdown(dhd_pub_t *dhdp, bool val) { }
|
||||
static INLINE int dhd_bus_get_linkdown(dhd_pub_t *dhdp) { return 0; }
|
||||
static INLINE int dhd_bus_get_cto(dhd_pub_t *dhdp) { return 0; }
|
||||
extern INLINE int dhd_bus_checkdied(struct dhd_bus *bus, char *data, uint size) { return 0; }
|
||||
static INLINE bool dhd_bus_get_read_shm(dhd_pub_t *dhdp) { return 0; }
|
||||
static INLINE int dhd_bus_checkdied(struct dhd_bus *bus, char *data, uint size) { return 0; }
|
||||
#endif /* BCMPCIE */
|
||||
|
||||
#if defined(BCMPCIE) && defined(EWP_ETD_PRSRV_LOGS)
|
||||
|
|
@ -322,14 +323,15 @@ void dhdpcie_get_etd_preserve_logs(dhd_pub_t *dhd, uint8 *ext_trap_data,
|
|||
#endif
|
||||
|
||||
extern uint16 dhd_get_chipid(struct dhd_bus *bus);
|
||||
|
||||
#ifdef BTLOG
|
||||
extern void dhd_bus_rx_bt_log(struct dhd_bus *bus, void* pkt);
|
||||
#endif /* BTLOG */
|
||||
extern uint16 dhd_get_chiprev(struct dhd_bus *bus);
|
||||
|
||||
#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);
|
||||
extern int dhd_bus_set_get_bus_wake(dhd_pub_t * dhd, int set);
|
||||
#if defined(BCMPCIE)
|
||||
extern int dhd_bus_set_get_bus_wake_pkt_dump(dhd_pub_t *dhd, int wake_pkt_dump);
|
||||
#endif /* BCMPCIE */
|
||||
#endif /* DHD_WAKE_STATUS */
|
||||
|
||||
#ifdef BT_OVER_SDIO
|
||||
|
|
@ -348,26 +350,18 @@ int dhd_bus_perform_flr(struct dhd_bus *bus, bool force_fail);
|
|||
extern bool dhd_bus_get_flr_force_fail(struct dhd_bus *bus);
|
||||
|
||||
extern bool dhd_bus_aspm_enable_rc_ep(struct dhd_bus *bus, bool enable);
|
||||
extern bool dhd_bus_is_aspm_enab_rc_ep(struct dhd_bus *bus);
|
||||
extern void dhd_bus_l1ss_enable_rc_ep(struct dhd_bus *bus, bool enable);
|
||||
extern bool dhd_bus_is_l1ss_enab_rc_ep(struct dhd_bus *bus);
|
||||
|
||||
bool dhd_bus_is_multibp_capable(struct dhd_bus *bus);
|
||||
|
||||
#ifdef BT_OVER_PCIE
|
||||
int dhd_bus_pwr_off(dhd_pub_t *dhdp, int reason);
|
||||
int dhd_bus_pwr_on(dhd_pub_t *dhdp, int reason);
|
||||
int dhd_bus_pwr_toggle(dhd_pub_t *dhdp, int reason);
|
||||
bool dhdpcie_is_btop_chip(struct dhd_bus *bus);
|
||||
bool dhdpcie_is_bt_loaded(struct dhd_bus *bus);
|
||||
int dhdpcie_redownload_fw(dhd_pub_t *dhdp);
|
||||
extern void dhd_bus_pcie_pwr_req_reload_war(struct dhd_bus *bus);
|
||||
int dhd_bus_perform_flr_with_quiesce(dhd_pub_t *dhdp, struct dhd_bus *bus,
|
||||
bool init_deinit_path);
|
||||
#endif /* BT_OVER_PCIE */
|
||||
|
||||
#ifdef BCMPCIE
|
||||
extern void dhdpcie_advertise_bus_cleanup(dhd_pub_t *dhdp);
|
||||
extern void dhd_msgbuf_iovar_timeout_dump(dhd_pub_t *dhd);
|
||||
extern void dhdpcie_induce_cbp_hang(dhd_pub_t *dhd);
|
||||
extern void dhdpcie_busbusy_wait(dhd_pub_t *dhdp);
|
||||
extern int dhd_dump_flowrings(dhd_pub_t *dhdp, char *buf, int buflen);
|
||||
#endif /* BCMPCIE */
|
||||
|
||||
extern bool dhd_bus_force_bt_quiesce_enabled(struct dhd_bus *bus);
|
||||
|
|
@ -414,7 +408,9 @@ extern int dhd_bus_get_sdtc_etb(dhd_pub_t *dhd, uint8 *sdtc_etb_mempool,
|
|||
uint addr, uint read_bytes);
|
||||
#endif /* DHD_SDTC_ETB_DUMP */
|
||||
|
||||
#ifndef BCMDBUS
|
||||
extern int dhd_socram_dump(struct dhd_bus *bus);
|
||||
#endif /* BCMDBUS */
|
||||
|
||||
extern int dhdpcie_get_max_eventbufpost(struct dhd_bus *bus);
|
||||
|
||||
|
|
@ -422,4 +418,15 @@ extern int dhdpcie_get_max_eventbufpost(struct dhd_bus *bus);
|
|||
extern void dhd_bus_flow_ring_status_isr_trace(dhd_pub_t *dhd);
|
||||
extern void dhd_bus_flow_ring_status_dpc_trace(dhd_pub_t *dhd);
|
||||
#endif /* DHD_FLOW_RING_STATUS_TRACE */
|
||||
|
||||
extern bool dhd_bus_init_done(struct dhd_bus *bus);
|
||||
|
||||
extern void dhdpcie_db7_trap(struct dhd_bus *bus);
|
||||
|
||||
#if defined(NDIS)
|
||||
void * dhd_bus_get_socram_buf(struct dhd_bus *bus, struct dhd_pub *dhdp);
|
||||
#endif
|
||||
|
||||
void dhd_bus_set_signature_path(struct dhd_bus *bus, char *sig_path);
|
||||
|
||||
#endif /* _dhd_bus_h_ */
|
||||
|
|
|
|||
|
|
@ -1,224 +0,0 @@
|
|||
#ifndef _DHD_BUZZZ_H_INCLUDED_
|
||||
#define _DHD_BUZZZ_H_INCLUDED_
|
||||
|
||||
*/
|
||||
* Copyright (C) 2020, Broadcom.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*
|
||||
* <<Broadcom-WL-IPTag/Open:>>
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#if defined(DHD_BUZZZ_LOG_ENABLED)
|
||||
/*
|
||||
* Broadcom proprietary logging system. Deleted performance counters.
|
||||
*/
|
||||
void dhd_buzzz_attach(void);
|
||||
void dhd_buzzz_detach(void);
|
||||
void dhd_buzzz_panic(uint32 crash);
|
||||
void dhd_buzzz_dump(void);
|
||||
void dhd_buzzz_log_disable(void);
|
||||
void dhd_buzzz_crash(void);
|
||||
|
||||
void dhd_buzzz_log0(uint32 evt_id);
|
||||
void dhd_buzzz_log1(uint32 evt_id, uint32 arg1);
|
||||
void dhd_buzzz_log2(uint32 evt_id, uint32 arg1, uintptr arg2);
|
||||
|
||||
void dhd_buzzz_fmt_reg(uint32 id, char * fmt);
|
||||
|
||||
extern void* dhd_os_create_buzzz_thread(void);
|
||||
extern void dhd_os_destroy_buzzz_thread(void *thr_hdl);
|
||||
extern void dhd_os_sched_buzzz_thread(void *thr_hdl);
|
||||
|
||||
#undef BUZZZ_EVT
|
||||
#define BUZZZ_EVT(ID) BUZZZ_EVT__## ID,
|
||||
|
||||
#undef BUZZZ_FMT
|
||||
#define BUZZZ_FMT(ID, format) \
|
||||
dhd_buzzz_fmt_reg(BUZZZ_EVT__## ID, "\t" format);
|
||||
|
||||
typedef enum buzzz_evt_id
|
||||
{
|
||||
BUZZZ_EVT__DHD = 100, /* BUZZZ_EVT(DHD) */
|
||||
BUZZZ_EVT(GENERAL_LOCK)
|
||||
BUZZZ_EVT(GENERAL_UNLOCK)
|
||||
BUZZZ_EVT(FLOWRING_LOCK)
|
||||
BUZZZ_EVT(FLOWRING_UNLOCK)
|
||||
BUZZZ_EVT(FLOWID_LOCK)
|
||||
BUZZZ_EVT(FLOWID_UNLOCK)
|
||||
|
||||
BUZZZ_EVT(START_XMIT_BGN)
|
||||
BUZZZ_EVT(START_XMIT_END)
|
||||
BUZZZ_EVT(PROCESS_CTRL_BGN)
|
||||
BUZZZ_EVT(PROCESS_CTRL_END)
|
||||
BUZZZ_EVT(UPDATE_TXFLOWRINGS_BGN)
|
||||
BUZZZ_EVT(UPDATE_TXFLOWRINGS_END)
|
||||
BUZZZ_EVT(PROCESS_TXCPL_BGN)
|
||||
BUZZZ_EVT(PROCESS_TXCPL_END)
|
||||
BUZZZ_EVT(PROCESS_RXCPL_BGN)
|
||||
BUZZZ_EVT(PROCESS_RXCPL_END)
|
||||
|
||||
BUZZZ_EVT(GET_SRC_ADDR)
|
||||
BUZZZ_EVT(WRITE_COMPLETE)
|
||||
BUZZZ_EVT(ALLOC_RING_SPACE)
|
||||
BUZZZ_EVT(ALLOC_RING_SPACE_RET)
|
||||
BUZZZ_EVT(ALLOC_RING_SPACE_FAIL)
|
||||
|
||||
BUZZZ_EVT(PKTID_MAP_CLEAR)
|
||||
BUZZZ_EVT(PKTID_NOT_AVAILABLE)
|
||||
BUZZZ_EVT(PKTID_MAP_RSV)
|
||||
BUZZZ_EVT(PKTID_MAP_SAVE)
|
||||
BUZZZ_EVT(PKTID_MAP_ALLOC)
|
||||
BUZZZ_EVT(PKTID_MAP_FREE)
|
||||
BUZZZ_EVT(LOCKER_INUSE_ABORT)
|
||||
BUZZZ_EVT(BUFFER_TYPE_ABORT1)
|
||||
BUZZZ_EVT(BUFFER_TYPE_ABORT2)
|
||||
|
||||
BUZZZ_EVT(UPD_READ_IDX)
|
||||
BUZZZ_EVT(STORE_RXCPLN_RD)
|
||||
BUZZZ_EVT(EARLY_UPD_RXCPLN_RD)
|
||||
|
||||
BUZZZ_EVT(POST_TXDATA)
|
||||
BUZZZ_EVT(RETURN_RXBUF)
|
||||
BUZZZ_EVT(RXBUF_POST)
|
||||
BUZZZ_EVT(RXBUF_POST_EVENT)
|
||||
BUZZZ_EVT(RXBUF_POST_IOCTL)
|
||||
BUZZZ_EVT(RXBUF_POST_CTRL_PKTGET_FAIL)
|
||||
BUZZZ_EVT(RXBUF_POST_PKTGET_FAIL)
|
||||
BUZZZ_EVT(RXBUF_POST_PKTID_FAIL)
|
||||
|
||||
BUZZZ_EVT(DHD_DUPLICATE_ALLOC)
|
||||
BUZZZ_EVT(DHD_DUPLICATE_FREE)
|
||||
BUZZZ_EVT(DHD_TEST_IS_ALLOC)
|
||||
BUZZZ_EVT(DHD_TEST_IS_FREE)
|
||||
|
||||
BUZZZ_EVT(DHD_PROT_IOCT_BGN)
|
||||
BUZZZ_EVT(DHDMSGBUF_CMPLT_BGN)
|
||||
BUZZZ_EVT(DHDMSGBUF_CMPLT_END)
|
||||
BUZZZ_EVT(DHD_PROT_IOCT_END)
|
||||
BUZZZ_EVT(DHD_FILLUP_IOCT_REQST_BGN)
|
||||
BUZZZ_EVT(DHD_FILLUP_IOCT_REQST_END)
|
||||
BUZZZ_EVT(DHD_MSGBUF_RXBUF_POST_IOCTLRESP_BUFS_BGN)
|
||||
BUZZZ_EVT(DHD_MSGBUF_RXBUF_POST_IOCTLRESP_BUFS_END)
|
||||
BUZZZ_EVT(DHD_PROT_IOCTCMPLT_PROCESS_ONE)
|
||||
BUZZZ_EVT(DHD_PROT_IOCTCMPLT_PROCESS_TWO)
|
||||
BUZZZ_EVT(DHD_PROT_EVENT_PROCESS_BGN)
|
||||
BUZZZ_EVT(DHD_PROT_EVENT_PROCESS_END)
|
||||
BUZZZ_EVT(DHD_PROT_D2H_SYNC_LIVELOCK)
|
||||
BUZZZ_EVT(DHD_IOCTL_BUFPOST)
|
||||
BUZZZ_EVT(DHD_EVENT_BUFPOST)
|
||||
BUZZZ_EVT(DHD_PROC_MSG_TYPE)
|
||||
BUZZZ_EVT(DHD_BUS_RXCTL_ONE)
|
||||
BUZZZ_EVT(DHD_BUS_RXCTL_TWO)
|
||||
} buzzz_evt_id_t;
|
||||
|
||||
static inline void dhd_buzzz_fmt_init(void)
|
||||
{
|
||||
BUZZZ_FMT(DHD, "DHD events")
|
||||
BUZZZ_FMT(GENERAL_LOCK, "+++LOCK GENERAL flags<0x%08x>")
|
||||
BUZZZ_FMT(GENERAL_UNLOCK, "---UNLK GENERAL flags<0x%08x>")
|
||||
BUZZZ_FMT(FLOWRING_LOCK, "+++LOCK FLOWRING flags<0x%08x>")
|
||||
BUZZZ_FMT(FLOWRING_UNLOCK, "---UNLK FLOWRING flags<0x%08x>")
|
||||
BUZZZ_FMT(FLOWID_LOCK, "+++LOCK FLOWID flags<0x%08x>")
|
||||
BUZZZ_FMT(FLOWID_UNLOCK, "---UNLK FLOWID flags<0x%08x>")
|
||||
|
||||
BUZZZ_FMT(START_XMIT_BGN, "{ dhd_start_xmit() ifidx<%u> skb<0x%p>")
|
||||
BUZZZ_FMT(START_XMIT_END, "} dhd_start_xmit()")
|
||||
BUZZZ_FMT(PROCESS_CTRL_BGN, "{ dhd_prot_process_ctrlbuf()")
|
||||
BUZZZ_FMT(PROCESS_CTRL_END, "} dhd_prot_process_ctrlbuf()")
|
||||
BUZZZ_FMT(UPDATE_TXFLOWRINGS_BGN, "{ dhd_update_txflowrings()");
|
||||
BUZZZ_FMT(UPDATE_TXFLOWRINGS_END, "} dhd_update_txflowrings()");
|
||||
BUZZZ_FMT(PROCESS_TXCPL_BGN, "{ dhd_prot_process_msgbuf_txcpl()")
|
||||
BUZZZ_FMT(PROCESS_TXCPL_END, "} dhd_prot_process_msgbuf_txcpl()")
|
||||
BUZZZ_FMT(PROCESS_RXCPL_BGN, "{ dhd_prot_process_msgbuf_rxcpl()")
|
||||
BUZZZ_FMT(PROCESS_RXCPL_END, "} dhd_prot_process_msgbuf_rxcpl()")
|
||||
|
||||
BUZZZ_FMT(GET_SRC_ADDR, "bytes<%u> @<0x%p> prot_get_src_addr()")
|
||||
BUZZZ_FMT(WRITE_COMPLETE, "WR<%u> prot_ring_write_complete")
|
||||
BUZZZ_FMT(ALLOC_RING_SPACE, "{ dhd_alloc_ring_space nitems<%d>")
|
||||
BUZZZ_FMT(ALLOC_RING_SPACE_RET, "} dhd_alloc_ring_space() alloc<%d> @<0x%p>")
|
||||
BUZZZ_FMT(ALLOC_RING_SPACE_FAIL, "FAILURE } dhd_alloc_ring_space() alloc<%d>")
|
||||
|
||||
BUZZZ_FMT(PKTID_MAP_CLEAR, "pktid map clear")
|
||||
BUZZZ_FMT(PKTID_NOT_AVAILABLE, "FAILURE pktid pool depletion failures<%u>")
|
||||
BUZZZ_FMT(PKTID_MAP_RSV, "pktid<%u> pkt<0x%p> dhd_pktid_map_reserve()")
|
||||
BUZZZ_FMT(PKTID_MAP_SAVE, "pktid<%u> pkt<0x%p> dhd_pktid_map_save()")
|
||||
BUZZZ_FMT(PKTID_MAP_ALLOC, "pktid<%u> pkt<0x%p> dhd_pktid_map_alloc()")
|
||||
BUZZZ_FMT(PKTID_MAP_FREE, "pktid<%u> pkt<0x%p> dhd_pktid_map_free()")
|
||||
BUZZZ_FMT(LOCKER_INUSE_ABORT, "ASSERT pktid<%u> pkt<0x%p> locker->inuse")
|
||||
BUZZZ_FMT(BUFFER_TYPE_ABORT1, "ASSERT pktid<%u> pkt<0x%p> locker->dma")
|
||||
BUZZZ_FMT(BUFFER_TYPE_ABORT2, "ASSERT locker->dma<%u> buf_type<%u>")
|
||||
|
||||
BUZZZ_FMT(UPD_READ_IDX, "RD<%u> prot_upd_read_idx()")
|
||||
BUZZZ_FMT(STORE_RXCPLN_RD, "RD<%u> prot_store_rxcpln_read_idx()")
|
||||
BUZZZ_FMT(EARLY_UPD_RXCPLN_RD, "RD<%u> prot_early_upd_rxcpln_read_idx()")
|
||||
|
||||
BUZZZ_FMT(POST_TXDATA, "flr<%u> pkt<0x%p> dhd_prot_txdata()")
|
||||
BUZZZ_FMT(RETURN_RXBUF, "cnt<%u> dhd_prot_return_rxbuf()");
|
||||
BUZZZ_FMT(RXBUF_POST, "cnt<%u> dhd_prot_rxbufpost()");
|
||||
BUZZZ_FMT(RXBUF_POST_EVENT, "event dhd_prot_rxbufpost_ctrl()");
|
||||
BUZZZ_FMT(RXBUF_POST_IOCTL, "ioctl dhd_prot_rxbufpost_ctrl()");
|
||||
BUZZZ_FMT(RXBUF_POST_CTRL_PKTGET_FAIL, "FAILURE pktget dhd_prot_rxbufpost_ctrl()");
|
||||
BUZZZ_FMT(RXBUF_POST_PKTGET_FAIL, "FAILURE pktget loop<%u> dhd_prot_rxbufpost()")
|
||||
BUZZZ_FMT(RXBUF_POST_PKTID_FAIL, "FAILURE pktid loop<%u> dhd_prot_rxbufpost()")
|
||||
|
||||
BUZZZ_FMT(DHD_DUPLICATE_ALLOC, "ASSERT dhd_pktid_audit(%u) DHD_DUPLICATE_ALLOC")
|
||||
BUZZZ_FMT(DHD_DUPLICATE_FREE, "ASSERT dhd_pktid_audit(%u) DHD_DUPLICATE_FREE")
|
||||
BUZZZ_FMT(DHD_TEST_IS_ALLOC, "ASSERT dhd_pktid_audit(%u) DHD_TEST_IS_ALLOC")
|
||||
BUZZZ_FMT(DHD_TEST_IS_FREE, "ASSERT dhd_pktid_audit(%u) DHD_TEST_IS_FREE")
|
||||
|
||||
BUZZZ_FMT(DHD_PROT_IOCT_BGN, "{ dhd_prot_ioct pending<%u> thread<0x%p>")
|
||||
BUZZZ_FMT(DHDMSGBUF_CMPLT_BGN, "{ dhdmsgbuf_cmplt bus::retlen<%u> bus::pktid<%u>")
|
||||
BUZZZ_FMT(DHDMSGBUF_CMPLT_END, "} dhdmsgbuf_cmplt resp_len<%d> pktid<%u>")
|
||||
BUZZZ_FMT(DHD_PROT_IOCT_END, "} dhd_prot_ioct pending<%u> thread<0x%p>")
|
||||
BUZZZ_FMT(DHD_FILLUP_IOCT_REQST_BGN, "{ dhd_fillup_ioct_reqst_ptrbased cmd<%u> transid<%u>")
|
||||
BUZZZ_FMT(DHD_FILLUP_IOCT_REQST_END,
|
||||
"} dhd_fillup_ioct_reqst_ptrbased transid<%u> bus::pktid<%u>")
|
||||
BUZZZ_FMT(DHD_MSGBUF_RXBUF_POST_IOCTLRESP_BUFS_BGN,
|
||||
"{ dhd_msgbuf_rxbuf_post_ioctlresp_bufs cur_posted<%u> bus::pktid<%u>")
|
||||
BUZZZ_FMT(DHD_MSGBUF_RXBUF_POST_IOCTLRESP_BUFS_END,
|
||||
"} dhd_msgbuf_rxbuf_post_ioctlresp_bufs cur_posted<%u> bus::pktid<%u>")
|
||||
BUZZZ_FMT(DHD_PROT_IOCTCMPLT_PROCESS_ONE,
|
||||
"{ dhd_prot_ioctlcmplt_process cmd<%d> transid<%d>")
|
||||
BUZZZ_FMT(DHD_PROT_IOCTCMPLT_PROCESS_TWO,
|
||||
"} dhd_prot_ioctlcmplt_process resplen<%u> pktid<%u>")
|
||||
BUZZZ_FMT(DHD_PROT_EVENT_PROCESS_BGN, "{ dhd_prot_event_process pktid<%u>")
|
||||
BUZZZ_FMT(DHD_PROT_EVENT_PROCESS_END, "} dhd_prot_event_process buflen<%u> pkt<0x%p>")
|
||||
BUZZZ_FMT(DHD_PROT_D2H_SYNC_LIVELOCK, " dhd_prot_d2h_sync_livelock seqnum<%u>")
|
||||
BUZZZ_FMT(DHD_IOCTL_BUFPOST, " dhd_prot_rxbufpost_ctrl ioctl pktid<%u> phyaddr<0x%x>")
|
||||
BUZZZ_FMT(DHD_EVENT_BUFPOST, " dhd_prot_rxbufpost_ctrl event pktid<%u> phyaddr<0x%x>")
|
||||
BUZZZ_FMT(DHD_PROC_MSG_TYPE, " dhd_process_msgtype msg<0x%x> epoch<%u>")
|
||||
BUZZZ_FMT(DHD_BUS_RXCTL_ONE, "dhd_bus_rxctl prev resplen<%u> pktid<%u>")
|
||||
BUZZZ_FMT(DHD_BUS_RXCTL_TWO, "dhd_bus_rxctl cur resplen<%u> pktid<%u>")
|
||||
}
|
||||
|
||||
#define BUZZZ_LOG(ID, N, ARG...) dhd_buzzz_log ##N(BUZZZ_EVT__ ##ID, ##ARG)
|
||||
|
||||
#else /* DHD_BUZZZ_LOG_ENABLED */
|
||||
/*
|
||||
* Broadcom logging system - Empty implementaiton
|
||||
*/
|
||||
|
||||
#define dhd_buzzz_attach() do { /* noop */ } while (0)
|
||||
#define dhd_buzzz_detach() do { /* noop */ } while (0)
|
||||
#define dhd_buzzz_panic(x) do { /* noop */ } while (0)
|
||||
#define BUZZZ_LOG(ID, N, ARG...) do { /* noop */ } while (0)
|
||||
|
||||
#endif /* DHD_BUZZZ_LOG_ENABLED */
|
||||
|
||||
#endif /* _DHD_BUZZZ_H_INCLUDED_ */
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
#ifdef CCODE_LIST
|
||||
#ifdef CONFIG_COMPAT
|
||||
#include <linux/compat.h>
|
||||
|
|
@ -16,7 +16,7 @@
|
|||
#define CCODE_4359C0
|
||||
#endif
|
||||
#if defined(BCMPCIE)
|
||||
#define CCODE_4375B4
|
||||
//#define CCODE_4375B4
|
||||
#endif
|
||||
#ifdef BCMDBUS
|
||||
#define CCODE_4358U
|
||||
|
|
@ -232,7 +232,7 @@ const ccode_list_map_t ccode_list_map[] = {
|
|||
{BCM4354_CHIP_ID, 2, ccode_4356a2, "XZ/11"},
|
||||
{BCM4356_CHIP_ID, 2, ccode_4356a2, "XZ/11"},
|
||||
{BCM4359_CHIP_ID, 9, ccode_4359c0, "XZ/11"},
|
||||
{BCM4375_CHIP_ID, 5, ccode_4375b4, "XZ/11"},
|
||||
{BCM4375_CHIP_ID, 5, ccode_4375b4, ""},
|
||||
#endif
|
||||
#ifdef BCMDBUS
|
||||
{BCM43569_CHIP_ID, 2, ccode_4358u, "XW/0"},
|
||||
|
|
@ -264,9 +264,11 @@ dhd_ccode_map_country_list(dhd_pub_t *dhd, wl_country_t *cspec)
|
|||
}
|
||||
}
|
||||
|
||||
if (bcmerror && ccode_ww && strlen(ccode_ww)>=4) {
|
||||
memcpy(cspec->ccode, ccode_ww, 2);
|
||||
cspec->rev = (int)simple_strtol(ccode_ww+3, NULL, 0);
|
||||
if (dhd->op_mode != DHD_FLAG_MFG_MODE) {
|
||||
if (bcmerror && ccode_ww && strlen(ccode_ww)>=4) {
|
||||
memcpy(cspec->ccode, ccode_ww, 2);
|
||||
cspec->rev = (int)simple_strtol(ccode_ww+3, NULL, 0);
|
||||
}
|
||||
}
|
||||
|
||||
return bcmerror;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* DHD Protocol Module for CDC and BDC.
|
||||
*
|
||||
* Copyright (C) 2020, Broadcom.
|
||||
* Copyright (C) 2022, Broadcom.
|
||||
*
|
||||
* Unless you and Broadcom execute a separate written software license
|
||||
* agreement governing use of this software, this software is licensed to you
|
||||
|
|
@ -71,9 +71,6 @@ typedef struct dhd_prot {
|
|||
uint16 reqid;
|
||||
uint8 pending;
|
||||
uint32 lastcmd;
|
||||
#ifdef BCMDBUS
|
||||
uint ctl_completed;
|
||||
#endif /* BCMDBUS */
|
||||
uint8 bus_header[BUS_HEADER_LEN];
|
||||
cdc_ioctl_t msg;
|
||||
unsigned char buf[WLC_IOCTL_MAXLEN + ROUND_UP_MARGIN];
|
||||
|
|
@ -89,9 +86,6 @@ dhd_prot_get_ioctl_trans_id(dhd_pub_t *dhdp)
|
|||
static int
|
||||
dhdcdc_msg(dhd_pub_t *dhd)
|
||||
{
|
||||
#ifdef BCMDBUS
|
||||
int timeout = 0;
|
||||
#endif /* BCMDBUS */
|
||||
int err = 0;
|
||||
dhd_prot_t *prot = dhd->prot;
|
||||
int len = ltoh32(prot->msg.len) + sizeof(cdc_ioctl_t);
|
||||
|
|
@ -108,46 +102,8 @@ dhdcdc_msg(dhd_pub_t *dhd)
|
|||
len = CDC_MAX_MSG_SIZE;
|
||||
|
||||
/* Send request */
|
||||
#ifdef BCMDBUS
|
||||
prot->ctl_completed = FALSE;
|
||||
err = dbus_send_ctl(dhd->bus, (void *)&prot->msg, len);
|
||||
if (err) {
|
||||
DHD_ERROR(("dbus_send_ctl error=0x%x\n", err));
|
||||
DHD_OS_WAKE_UNLOCK(dhd);
|
||||
return err;
|
||||
}
|
||||
#else
|
||||
err = dhd_bus_txctl(dhd->bus, (uchar*)&prot->msg, len);
|
||||
#endif /* BCMDBUS */
|
||||
|
||||
#ifdef BCMDBUS
|
||||
timeout = dhd_os_ioctl_resp_wait(dhd, &prot->ctl_completed);
|
||||
if ((!timeout) || (!prot->ctl_completed)) {
|
||||
DHD_ERROR(("Txctl timeout %d ctl_completed %d\n",
|
||||
timeout, prot->ctl_completed));
|
||||
DHD_ERROR(("Txctl wait timed out\n"));
|
||||
err = -1;
|
||||
}
|
||||
#endif /* BCMDBUS */
|
||||
#if defined(BCMDBUS) && defined(INTR_EP_ENABLE)
|
||||
/* If the ctl write is successfully completed, wait for an acknowledgement
|
||||
* that indicates that it is now ok to do ctl read from the dongle
|
||||
*/
|
||||
if (err != -1) {
|
||||
prot->ctl_completed = FALSE;
|
||||
if (dbus_poll_intr(dhd->dbus)) {
|
||||
DHD_ERROR(("dbus_poll_intr not submitted\n"));
|
||||
} else {
|
||||
/* interrupt polling is sucessfully submitted. Wait for dongle to send
|
||||
* interrupt
|
||||
*/
|
||||
timeout = dhd_os_ioctl_resp_wait(dhd, &prot->ctl_completed);
|
||||
if (!timeout) {
|
||||
DHD_ERROR(("intr poll wait timed out\n"));
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* defined(BCMDBUS) && defined(INTR_EP_ENABLE) */
|
||||
DHD_OS_WAKE_UNLOCK(dhd);
|
||||
return err;
|
||||
}
|
||||
|
|
@ -155,39 +111,34 @@ dhdcdc_msg(dhd_pub_t *dhd)
|
|||
static int
|
||||
dhdcdc_cmplt(dhd_pub_t *dhd, uint32 id, uint32 len)
|
||||
{
|
||||
#ifdef BCMDBUS
|
||||
int timeout = 0;
|
||||
#endif /* BCMDBUS */
|
||||
int ret;
|
||||
int cdc_len = len + sizeof(cdc_ioctl_t);
|
||||
dhd_prot_t *prot = dhd->prot;
|
||||
|
||||
DHD_TRACE(("%s: Enter\n", __FUNCTION__));
|
||||
/*
|
||||
* prot->msg is the buffer used to send the ioctl msg in dhdcdc_msg and the same is
|
||||
* used for receiving the ioctl response.
|
||||
* As this buffer is not cleared after sending message and before re-using for receive
|
||||
* operation, problems are seen when bus errors occur.
|
||||
* Example:- An error is seen on the bus where a 0 byte pkt is received.
|
||||
* the bus-controller "layer below cdc" does not update the buffer in this 0 byte pkt case.
|
||||
* bus-controller layer calls the completion callback without any error and with the
|
||||
* same buffer.(no change)
|
||||
* This issue is seen on DBUS/USB + FPGA platforms
|
||||
* In this function if there is no update to the buffer, the stale id field of sent msg
|
||||
* matches to expected ID and further processing is done thinking that
|
||||
* proper response is received.
|
||||
* This is a generic problem and its a good idea to clear the buffer or atleast
|
||||
* the buffer's key value (ioctl ID within flags field in this case) before re-using it.
|
||||
*
|
||||
* To ensure that a new content is indeed received from the bus making flags = 0.
|
||||
* Note that ID=0 is invalid value.
|
||||
*/
|
||||
prot->msg.flags = 0;
|
||||
|
||||
do {
|
||||
#ifdef BCMDBUS
|
||||
prot->ctl_completed = FALSE;
|
||||
ret = dbus_recv_ctl(dhd->bus, (uchar*)&prot->msg, cdc_len);
|
||||
if (ret) {
|
||||
DHD_ERROR(("dbus_recv_ctl error=0x%x(%d)\n", ret, ret));
|
||||
goto done;
|
||||
}
|
||||
timeout = dhd_os_ioctl_resp_wait(dhd, &prot->ctl_completed);
|
||||
if ((!timeout) || (!prot->ctl_completed)) {
|
||||
DHD_ERROR(("Rxctl timeout %d ctl_completed %d\n",
|
||||
timeout, prot->ctl_completed));
|
||||
ret = -ETIMEDOUT;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* XXX FIX: Must return cdc_len, not len, because after query_ioctl()
|
||||
* it subtracts sizeof(cdc_ioctl_t); The other approach is
|
||||
* to have dbus_recv_ctl() return actual len.
|
||||
*/
|
||||
ret = cdc_len;
|
||||
#else
|
||||
ret = dhd_bus_rxctl(dhd->bus, (uchar*)&prot->msg, cdc_len);
|
||||
#endif /* BCMDBUS */
|
||||
if (ret < 0)
|
||||
break;
|
||||
} while (CDC_IOC_ID(ltoh32(prot->msg.flags)) != id);
|
||||
|
|
@ -197,9 +148,6 @@ dhdcdc_cmplt(dhd_pub_t *dhd, uint32 id, uint32 len)
|
|||
ret = len;
|
||||
}
|
||||
|
||||
#ifdef BCMDBUS
|
||||
done:
|
||||
#endif /* BCMDBUS */
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -230,6 +178,12 @@ dhdcdc_query_ioctl(dhd_pub_t *dhd, int ifidx, uint cmd, void *buf, uint len, uin
|
|||
}
|
||||
}
|
||||
|
||||
if (ifidx >= DHD_MAX_IFS) {
|
||||
DHD_ERROR(("%s: IF index %d Invalid for the dongle FW\n",
|
||||
__FUNCTION__, ifidx));
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
memset(msg, 0, sizeof(cdc_ioctl_t));
|
||||
|
||||
#ifdef BCMSPI
|
||||
|
|
@ -343,16 +297,15 @@ dhdcdc_set_ioctl(dhd_pub_t *dhd, int ifidx, uint cmd, void *buf, uint len, uint8
|
|||
}
|
||||
}
|
||||
#endif /* DHD_PM_OVERRIDE */
|
||||
#if defined(WLAIBSS)
|
||||
if (dhd->op_mode == DHD_FLAG_IBSS_MODE) {
|
||||
DHD_ERROR(("%s: SET PM ignored for IBSS!(Requested:%d)\n",
|
||||
__FUNCTION__, buf ? *(char *)buf : 0));
|
||||
goto done;
|
||||
}
|
||||
#endif /* WLAIBSS */
|
||||
DHD_TRACE_HW4(("%s: SET PM to %d\n", __FUNCTION__, buf ? *(char *)buf : 0));
|
||||
}
|
||||
|
||||
if (ifidx >= DHD_MAX_IFS) {
|
||||
DHD_ERROR(("%s: IF index %d Invalid for the dongle FW\n",
|
||||
__FUNCTION__, ifidx));
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
memset(msg, 0, sizeof(cdc_ioctl_t));
|
||||
|
||||
msg->cmd = htol32(cmd);
|
||||
|
|
@ -403,24 +356,6 @@ done:
|
|||
return ret;
|
||||
}
|
||||
|
||||
#ifdef BCMDBUS
|
||||
int
|
||||
dhd_prot_ctl_complete(dhd_pub_t *dhd)
|
||||
{
|
||||
dhd_prot_t *prot;
|
||||
|
||||
if (dhd == NULL)
|
||||
return BCME_ERROR;
|
||||
|
||||
prot = dhd->prot;
|
||||
|
||||
ASSERT(prot);
|
||||
prot->ctl_completed = TRUE;
|
||||
dhd_os_ioctl_resp_wake(dhd);
|
||||
return 0;
|
||||
}
|
||||
#endif /* BCMDBUS */
|
||||
|
||||
/* XXX: due to overlays this should not be called directly; call dhd_wl_ioctl() instead */
|
||||
int
|
||||
dhd_prot_ioctl(dhd_pub_t *dhd, int ifidx, wl_ioctl_t * ioc, void * buf, int len)
|
||||
|
|
@ -516,6 +451,19 @@ dhd_prot_dump(dhd_pub_t *dhdp, struct bcmstrbuf *strbuf)
|
|||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
dhd_prot_counters(dhd_pub_t *dhdp, struct bcmstrbuf *strbuf,
|
||||
bool print_ringinfo, bool print_pktidinfo)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
dhd_bus_counters(dhd_pub_t *dhdp, struct bcmstrbuf *strbuf)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/* The FreeBSD PKTPUSH could change the packet buf pinter
|
||||
so we need to make it changable
|
||||
*/
|
||||
|
|
@ -640,6 +588,17 @@ exit:
|
|||
return 0;
|
||||
}
|
||||
|
||||
#ifdef DHD_LOSSLESS_ROAMING
|
||||
int dhd_update_sdio_data_prio_map(dhd_pub_t *dhdp)
|
||||
{
|
||||
const uint8 prio2tid[8] = { 0, 1, 2, 3, 4, 5, 6, 7 };
|
||||
|
||||
bcopy(prio2tid, dhdp->flow_prio_map, sizeof(uint8) * NUMPRIO);
|
||||
|
||||
return BCME_OK;
|
||||
}
|
||||
#endif // DHD_LOSSLESS_ROAMING
|
||||
|
||||
int
|
||||
dhd_prot_attach(dhd_pub_t *dhd)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* Linux cfg80211 driver - Dongle Host Driver (DHD) related
|
||||
*
|
||||
* Copyright (C) 2020, Broadcom.
|
||||
* Copyright (C) 2022, Broadcom.
|
||||
*
|
||||
* Unless you and Broadcom execute a separate written software license
|
||||
* agreement governing use of this software, this software is licensed to you
|
||||
|
|
@ -57,7 +57,6 @@ static int dhd_dongle_up = FALSE;
|
|||
static s32 wl_dongle_up(struct net_device *ndev);
|
||||
static s32 wl_dongle_down(struct net_device *ndev);
|
||||
#ifndef OEM_ANDROID
|
||||
#ifndef CUSTOMER_HW6
|
||||
static s32 wl_dongle_power(struct net_device *ndev, u32 power_mode);
|
||||
#ifdef BCMSDIO /* glomming is a sdio specific feature */
|
||||
static s32 wl_dongle_glom(struct net_device *ndev, s32 glom, u32 dongle_align);
|
||||
|
|
@ -66,7 +65,6 @@ static s32 wl_dongle_scantime(struct net_device *ndev, s32 scan_assoc_time, s32
|
|||
static s32 wl_dongle_offload(struct net_device *ndev, s32 arpoe, s32 arp_ol);
|
||||
static s32 wl_pattern_atoh(s8 *src, s8 *dst);
|
||||
static s32 wl_dongle_filter(struct net_device *ndev, u32 filter_mode);
|
||||
#endif /* !CUSTOMER_HW6 */
|
||||
#endif /* !OEM_ANDROID */
|
||||
|
||||
/**
|
||||
|
|
@ -142,20 +140,13 @@ int wl_cfg80211_register_if(struct bcm_cfg80211 *cfg,
|
|||
int wl_cfg80211_remove_if(struct bcm_cfg80211 *cfg,
|
||||
int ifidx, struct net_device* ndev, bool rtnl_lock_reqd)
|
||||
{
|
||||
#ifdef DHD_PCIE_RUNTIMEPM
|
||||
dhdpcie_runtime_bus_wake(cfg->pub, CAN_SLEEP(), __builtin_return_address(0));
|
||||
#endif /* DHD_PCIE_RUNTIMEPM */
|
||||
return dhd_remove_if(cfg->pub, ifidx, rtnl_lock_reqd);
|
||||
}
|
||||
|
||||
void wl_cfg80211_cleanup_if(struct net_device *net)
|
||||
{
|
||||
struct bcm_cfg80211 *cfg = wl_get_cfg(net);
|
||||
#ifdef DHD_PCIE_RUNTIMEPM
|
||||
dhdpcie_runtime_bus_wake(cfg->pub, CAN_SLEEP(), __builtin_return_address(0));
|
||||
#else
|
||||
BCM_REFERENCE(cfg);
|
||||
#endif /* DHD_PCIE_RUNTIMEPM */
|
||||
dhd_cleanup_if(net);
|
||||
}
|
||||
|
||||
|
|
@ -233,7 +224,6 @@ wl_dongle_down(struct net_device *ndev)
|
|||
}
|
||||
|
||||
#ifndef OEM_ANDROID
|
||||
#ifndef CUSTOMER_HW6
|
||||
static s32 wl_dongle_power(struct net_device *ndev, u32 power_mode)
|
||||
{
|
||||
s32 err = 0;
|
||||
|
|
@ -271,7 +261,6 @@ dongle_glom_out:
|
|||
}
|
||||
|
||||
#endif /* BCMSDIO */
|
||||
#endif /* !CUSTOMER_HW6 */
|
||||
#endif /* !OEM_ANDROID */
|
||||
|
||||
s32
|
||||
|
|
@ -293,12 +282,12 @@ wl_dongle_roam(struct net_device *ndev, u32 roamvar, u32 bcn_timeout)
|
|||
WL_ERR(("roam_off error (%d)\n", err));
|
||||
goto dongle_rom_out;
|
||||
}
|
||||
ROAMOFF_DBG_SAVE(ndev, SET_ROAM_FILS_TOGGLE, roamvar);
|
||||
dongle_rom_out:
|
||||
return err;
|
||||
}
|
||||
|
||||
#ifndef OEM_ANDROID
|
||||
#ifndef CUSTOMER_HW6
|
||||
static s32
|
||||
wl_dongle_scantime(struct net_device *ndev, s32 scan_assoc_time,
|
||||
s32 scan_unassoc_time)
|
||||
|
|
@ -494,7 +483,6 @@ static s32 wl_dongle_filter(struct net_device *ndev, u32 filter_mode)
|
|||
dongle_filter_out:
|
||||
return err;
|
||||
}
|
||||
#endif /* !CUSTOMER_HW6 */
|
||||
#endif /* !OEM_ANDROID */
|
||||
|
||||
s32 dhd_config_dongle(struct bcm_cfg80211 *cfg)
|
||||
|
|
@ -527,7 +515,6 @@ s32 dhd_config_dongle(struct bcm_cfg80211 *cfg)
|
|||
}
|
||||
|
||||
#ifndef OEM_ANDROID
|
||||
#ifndef CUSTOMER_HW6
|
||||
err = wl_dongle_power(ndev, PM_FAST);
|
||||
if (unlikely(err)) {
|
||||
WL_ERR(("wl_dongle_power failed\n"));
|
||||
|
|
@ -548,7 +535,6 @@ s32 dhd_config_dongle(struct bcm_cfg80211 *cfg)
|
|||
wl_dongle_scantime(ndev, 40, 80);
|
||||
wl_dongle_offload(ndev, 1, 0xf);
|
||||
wl_dongle_filter(ndev, 1);
|
||||
#endif /* !CUSTOMER_HW6 */
|
||||
#endif /* OEM_ANDROID */
|
||||
|
||||
default_conf_out:
|
||||
|
|
@ -595,3 +581,35 @@ done:
|
|||
DHD_OS_WAKE_UNLOCK(dhd);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
dhd_set_wsec_info(dhd_pub_t *dhd, uint32 data, int tag)
|
||||
{
|
||||
struct net_device *ndev;
|
||||
uint32 wsec_info = data;
|
||||
int ret = BCME_OK;
|
||||
|
||||
ndev = dhd_linux_get_primary_netdev(dhd);
|
||||
if (!ndev) {
|
||||
WL_ERR(("Cannot find primary netdev\n"));
|
||||
return -ENODEV;
|
||||
}
|
||||
BCM_REFERENCE(wsec_info);
|
||||
#if defined(WL_CFG80211)
|
||||
ret = wl_cfg80211_set_wsec_info(ndev, &wsec_info, sizeof(wsec_info), tag);
|
||||
if (unlikely(ret)) {
|
||||
WL_ERR(("Set wsec_info tag 0x%04x failed \n", tag));
|
||||
}
|
||||
#endif /* WL_CFG80211 */
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef RPM_FAST_TRIGGER
|
||||
void
|
||||
dhd_trigger_rpm_fast(struct bcm_cfg80211 *cfg)
|
||||
{
|
||||
dhd_pub_t *dhd = (dhd_pub_t *)cfg->pub;
|
||||
dhdpcie_trigger_rpm_fast(dhd);
|
||||
}
|
||||
#endif /* RPM_FAST_TRIGGER */
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* Linux cfg80211 driver - Dongle Host Driver (DHD) related
|
||||
*
|
||||
* Copyright (C) 2020, Broadcom.
|
||||
* Copyright (C) 2022, Broadcom.
|
||||
*
|
||||
* Unless you and Broadcom execute a separate written software license
|
||||
* agreement governing use of this software, this software is licensed to you
|
||||
|
|
@ -46,4 +46,8 @@ s32 dhd_config_dongle(struct bcm_cfg80211 *cfg);
|
|||
int dhd_cfgvendor_priv_string_handler(struct bcm_cfg80211 *cfg,
|
||||
struct wireless_dev *wdev, const struct bcm_nlmsg_hdr *nlioc, void *data);
|
||||
s32 wl_dongle_roam(struct net_device *ndev, u32 roamvar, u32 bcn_timeout);
|
||||
int dhd_set_wsec_info(dhd_pub_t *dhd, uint32 data, int tag);
|
||||
#ifdef RPM_FAST_TRIGGER
|
||||
void dhd_trigger_rpm_fast(struct bcm_cfg80211 *cfg);
|
||||
#endif /* RPM_FAST_TRIGGER */
|
||||
#endif /* __DHD_CFG80211__ */
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
|
@ -1,4 +1,3 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
|
||||
#ifndef _dhd_config_
|
||||
#define _dhd_config_
|
||||
|
|
@ -28,7 +27,7 @@
|
|||
//#define CONFIG_PATH_AUTO_SELECT
|
||||
#endif
|
||||
extern char firmware_path[MOD_PARAM_PATHLEN];
|
||||
#if defined(BCMSDIO) || defined(BCMPCIE)
|
||||
#if defined(BCMSDIO)
|
||||
extern uint dhd_rxbound;
|
||||
extern uint dhd_txbound;
|
||||
#endif
|
||||
|
|
@ -68,12 +67,6 @@ typedef struct wl_chip_nv_path_list_ctrl {
|
|||
struct wl_chip_nv_path *m_chip_nv_path_head;
|
||||
} wl_chip_nv_path_list_ctrl_t;
|
||||
|
||||
#define MAX_CTRL_CHANSPECS 256
|
||||
typedef struct wl_channel_list {
|
||||
uint32 count;
|
||||
uint32 channel[MAX_CTRL_CHANSPECS];
|
||||
} wl_channel_list_t;
|
||||
|
||||
typedef struct wmes_param {
|
||||
int aifsn[AC_COUNT];
|
||||
int ecwmin[AC_COUNT];
|
||||
|
|
@ -126,7 +119,8 @@ enum war_flags {
|
|||
FW_REINIT_INCSA = (1 << (1)),
|
||||
FW_REINIT_EMPTY_SCAN = (1 << (2)),
|
||||
P2P_AP_MAC_CONFLICT = (1 << (3)),
|
||||
RESEND_EAPOL_PKT = (1 << (4))
|
||||
RESEND_EAPOL_PKT = (1 << (4)),
|
||||
FW_REINIT_RXF0OVFL = (1 << (5))
|
||||
};
|
||||
|
||||
enum in4way_flags {
|
||||
|
|
@ -171,25 +165,27 @@ enum conn_state {
|
|||
CONN_STATE_AUTH_SAE_M2 = 3,
|
||||
CONN_STATE_AUTH_SAE_M3 = 4,
|
||||
CONN_STATE_AUTH_SAE_M4 = 5,
|
||||
CONN_STATE_REQID = 6,
|
||||
CONN_STATE_RSPID = 7,
|
||||
CONN_STATE_WSC_START = 8,
|
||||
CONN_STATE_WPS_M1 = 9,
|
||||
CONN_STATE_WPS_M2 = 10,
|
||||
CONN_STATE_WPS_M3 = 11,
|
||||
CONN_STATE_WPS_M4 = 12,
|
||||
CONN_STATE_WPS_M5 = 13,
|
||||
CONN_STATE_WPS_M6 = 14,
|
||||
CONN_STATE_WPS_M7 = 15,
|
||||
CONN_STATE_WPS_M8 = 16,
|
||||
CONN_STATE_WSC_DONE = 17,
|
||||
CONN_STATE_4WAY_M1 = 18,
|
||||
CONN_STATE_4WAY_M2 = 19,
|
||||
CONN_STATE_4WAY_M3 = 20,
|
||||
CONN_STATE_4WAY_M4 = 21,
|
||||
CONN_STATE_CONNECTED = 22,
|
||||
CONN_STATE_GROUPKEY_M1 = 23,
|
||||
CONN_STATE_GROUPKEY_M2 = 24,
|
||||
CONN_STATE_ASSOCIATED = 6,
|
||||
CONN_STATE_REQID = 7,
|
||||
CONN_STATE_RSPID = 8,
|
||||
CONN_STATE_WSC_START = 9,
|
||||
CONN_STATE_WPS_M1 = 10,
|
||||
CONN_STATE_WPS_M2 = 11,
|
||||
CONN_STATE_WPS_M3 = 12,
|
||||
CONN_STATE_WPS_M4 = 13,
|
||||
CONN_STATE_WPS_M5 = 14,
|
||||
CONN_STATE_WPS_M6 = 15,
|
||||
CONN_STATE_WPS_M7 = 16,
|
||||
CONN_STATE_WPS_M8 = 17,
|
||||
CONN_STATE_WSC_DONE = 18,
|
||||
CONN_STATE_4WAY_M1 = 19,
|
||||
CONN_STATE_4WAY_M2 = 20,
|
||||
CONN_STATE_4WAY_M3 = 21,
|
||||
CONN_STATE_4WAY_M4 = 22,
|
||||
CONN_STATE_ADD_KEY = 23,
|
||||
CONN_STATE_CONNECTED = 24,
|
||||
CONN_STATE_GROUPKEY_M1 = 25,
|
||||
CONN_STATE_GROUPKEY_M2 = 26,
|
||||
};
|
||||
|
||||
enum enq_pkt_type {
|
||||
|
|
@ -218,10 +214,10 @@ typedef struct dhd_conf {
|
|||
#endif
|
||||
wl_chip_nv_path_list_ctrl_t nv_by_chip;
|
||||
country_list_t *country_head;
|
||||
int ioctl_ver;
|
||||
int band;
|
||||
int bw_cap[2];
|
||||
wl_country_t cspec;
|
||||
wl_channel_list_t channels;
|
||||
uint roam_off;
|
||||
uint roam_off_suspend;
|
||||
int roam_trigger[2];
|
||||
|
|
@ -297,6 +293,8 @@ typedef struct dhd_conf {
|
|||
int d2h_intr_method;
|
||||
int d2h_intr_control;
|
||||
int enq_hdr_pkt;
|
||||
int aspm;
|
||||
int l1ss;
|
||||
#endif
|
||||
int dpc_cpucore;
|
||||
int rxf_cpucore;
|
||||
|
|
@ -345,6 +343,9 @@ typedef struct dhd_conf {
|
|||
uint war;
|
||||
#ifdef WL_EXT_WOWL
|
||||
uint wowl;
|
||||
#ifdef BCMDBUS
|
||||
uint wowl_dngldown;
|
||||
#endif
|
||||
#endif
|
||||
#ifdef GET_CUSTOM_MAC_FROM_CONFIG
|
||||
char hw_ether[62];
|
||||
|
|
@ -395,23 +396,27 @@ void dhd_conf_get_otp(dhd_pub_t *dhd, bcmsdh_info_t *sdh, si_t *sih);
|
|||
void dhd_conf_set_hw_oob_intr(bcmsdh_info_t *sdh, struct si_pub *sih);
|
||||
#endif
|
||||
void dhd_conf_set_txglom_params(dhd_pub_t *dhd, bool enable);
|
||||
bool dhd_conf_legacy_otp_chip(dhd_pub_t *dhd);
|
||||
#endif
|
||||
#ifdef BCMPCIE
|
||||
int dhd_conf_get_otp(dhd_pub_t *dhd, si_t *sih);
|
||||
bool dhd_conf_legacy_msi_chip(dhd_pub_t *dhd);
|
||||
#endif
|
||||
#ifdef WL_CFG80211
|
||||
bool dhd_conf_legacy_chip_check(dhd_pub_t *dhd);
|
||||
bool dhd_conf_new_chip_check(dhd_pub_t *dhd);
|
||||
bool dhd_conf_extsae_chip(dhd_pub_t *dhd);
|
||||
#endif
|
||||
void dhd_conf_set_path_params(dhd_pub_t *dhd, char *fw_path, char *nv_path);
|
||||
int dhd_conf_set_intiovar(dhd_pub_t *dhd, int ifidx, uint cmd, char *name,
|
||||
int val, int def, bool down);
|
||||
int dhd_conf_get_band(dhd_pub_t *dhd);
|
||||
int dhd_conf_set_country(dhd_pub_t *dhd, wl_country_t *cspec);
|
||||
bool dhd_conf_same_country(dhd_pub_t *dhd, char *buf);
|
||||
int dhd_conf_country(dhd_pub_t *dhd, char *cmd, char *buf);
|
||||
int dhd_conf_get_country(dhd_pub_t *dhd, wl_country_t *cspec);
|
||||
int dhd_conf_map_country_list(dhd_pub_t *dhd, wl_country_t *cspec);
|
||||
#ifdef CCODE_LIST
|
||||
int dhd_ccode_map_country_list(dhd_pub_t *dhd, wl_country_t *cspec);
|
||||
#endif
|
||||
int dhd_conf_fix_country(dhd_pub_t *dhd);
|
||||
bool dhd_conf_match_channel(dhd_pub_t *dhd, uint32 channel);
|
||||
void dhd_conf_set_wme(dhd_pub_t *dhd, int ifidx, int mode);
|
||||
void dhd_conf_set_mchan_bw(dhd_pub_t *dhd, int go, int source);
|
||||
void dhd_conf_add_pkt_filter(dhd_pub_t *dhd);
|
||||
|
|
@ -422,6 +427,7 @@ int dhd_conf_set_chiprev(dhd_pub_t *dhd, uint chip, uint chiprev);
|
|||
uint dhd_conf_get_chip(void *context);
|
||||
uint dhd_conf_get_chiprev(void *context);
|
||||
int dhd_conf_get_pm(dhd_pub_t *dhd);
|
||||
int dhd_conf_reg2args(dhd_pub_t *dhd, char *cmd, bool set, uint32 index, uint32 *val);
|
||||
int dhd_conf_check_hostsleep(dhd_pub_t *dhd, int cmd, void *buf, int len,
|
||||
int *hostsleep_set, int *hostsleep_val, int *ret);
|
||||
void dhd_conf_get_hostsleep(dhd_pub_t *dhd,
|
||||
|
|
@ -440,6 +446,7 @@ void dhd_conf_tput_monitor(dhd_pub_t *dhd);
|
|||
uint dhd_conf_get_insuspend(dhd_pub_t *dhd, uint mask);
|
||||
int dhd_conf_set_suspend_resume(dhd_pub_t *dhd, int suspend);
|
||||
void dhd_conf_postinit_ioctls(dhd_pub_t *dhd);
|
||||
void dhd_conf_preinit_ioctls_sta(dhd_pub_t *dhd, int ifidx);
|
||||
int dhd_conf_preinit(dhd_pub_t *dhd);
|
||||
int dhd_conf_reset(dhd_pub_t *dhd);
|
||||
int dhd_conf_attach(dhd_pub_t *dhd);
|
||||
|
|
@ -449,7 +456,10 @@ int wl_pattern_atoh(char *src, char *dst);
|
|||
int dhd_conf_suspend_resume_sta(dhd_pub_t *dhd, int ifidx, int suspend);
|
||||
/* Add to adjust 802.1x priority */
|
||||
extern void pktset8021xprio(void *pkt, int prio);
|
||||
#ifdef BCMSDIO
|
||||
#if defined(BCMSDIO) || defined(BCMPCIE) || defined(BCMDBUS)
|
||||
extern int dhd_bus_sleep(dhd_pub_t *dhdp, bool sleep, uint32 *intstatus);
|
||||
#endif
|
||||
#ifdef WL_EXT_WOWL
|
||||
int dhd_conf_wowl_dngldown(dhd_pub_t *dhd);
|
||||
#endif
|
||||
#endif /* _dhd_config_ */
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* Broadcom Dongle Host Driver (DHD)
|
||||
* Broadcom Dongle Host Driver (DHD), Channel State information Module
|
||||
*
|
||||
* Copyright (C) 1999-2018, Broadcom.
|
||||
* Copyright (C) 2023, Broadcom.
|
||||
*
|
||||
* Unless you and Broadcom execute a separate written software license
|
||||
* agreement governing use of this software, this software is licensed to you
|
||||
|
|
@ -17,12 +17,13 @@
|
|||
* 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.
|
||||
*
|
||||
* $Id: dhd_csi.c 606280 2015-12-15 05:28:25Z $
|
||||
* <<Broadcom-WL-IPTag/Open:>>
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#ifdef CSI_SUPPORT
|
||||
#include <osl.h>
|
||||
|
||||
#include <bcmutils.h>
|
||||
|
|
@ -38,182 +39,789 @@
|
|||
#include <dhd.h>
|
||||
#include <dhd_dbg.h>
|
||||
#include <dhd_csi.h>
|
||||
#include <wldev_common.h>
|
||||
#include <dhd_linux.h>
|
||||
|
||||
#define NULL_CHECK(p, s, err) \
|
||||
do { \
|
||||
if (!(p)) { \
|
||||
printf("NULL POINTER (%s) : %s\n", __FUNCTION__, (s)); \
|
||||
err = BCME_ERROR; \
|
||||
return err; \
|
||||
} \
|
||||
} while (0)
|
||||
#define SYNA_ALIGN_BYTES (sizeof(uint32))
|
||||
#define SYNA_ALIGN_PADDING (SYNA_ALIGN_BYTES -1LL)
|
||||
#define SYNA_ALIGN_MASK (~SYNA_ALIGN_PADDING)
|
||||
#define SYNA_ALIGN(value) \
|
||||
(\
|
||||
(SYNA_ALIGN_PADDING + ((long long int)(value))) \
|
||||
& SYNA_ALIGN_MASK \
|
||||
)
|
||||
|
||||
#define TIMESPEC_TO_US(ts) (((uint64)(ts).tv_sec * USEC_PER_SEC) + \
|
||||
(ts).tv_nsec / NSEC_PER_USEC)
|
||||
static const uint8 _gpMAC_zero[6] = {0, 0, 0, 0, 0, 0};
|
||||
|
||||
#define NULL_ADDR "\x00\x00\x00\x00\x00\x00"
|
||||
|
||||
int
|
||||
dhd_csi_event_handler(dhd_pub_t *dhd, wl_event_msg_t *event, void *event_data)
|
||||
static int dhd_csi_data_append(uint32 remain_length, uint32 data_length,
|
||||
const uint8 *pData, struct csi_cfr_node *ptr)
|
||||
{
|
||||
int ret = BCME_OK;
|
||||
bool is_new = TRUE;
|
||||
cfr_dump_data_t *p_event;
|
||||
cfr_dump_list_t *ptr, *next, *new;
|
||||
struct syna_csi_header *pEntry = NULL;
|
||||
int error_status = 0;
|
||||
int ret = BCME_OK;
|
||||
int append_len = 0;
|
||||
|
||||
NULL_CHECK(dhd, "dhd is NULL", ret);
|
||||
if ((!pData) || (!ptr) || (ptr->pNode != ptr)) {
|
||||
DHD_ERROR(("%s-%d: *Error, invalid parameter, "
|
||||
"pData=0x%px, ptr=0x%px, pNode=0x%px\n",
|
||||
__func__, __LINE__,
|
||||
pData, ptr, ptr?(ptr->pNode):(NULL)));
|
||||
ret = BCME_BADARG;
|
||||
goto done;
|
||||
} else {
|
||||
pEntry = (struct syna_csi_header *)&(ptr->entry);
|
||||
error_status = SYNA_CSI_FLAG_ERROR_MASK & pEntry->flags;
|
||||
}
|
||||
/* find the append length */
|
||||
if (remain_length) {
|
||||
append_len = data_length
|
||||
- pEntry->data_length
|
||||
- remain_length;
|
||||
} else if (pEntry->remain_length) {
|
||||
append_len = pEntry->remain_length;
|
||||
} else if (SYNA_CSI_CFR_NODE_FREE_LEN(ptr) >= data_length) {
|
||||
append_len = data_length;
|
||||
}
|
||||
|
||||
DHD_TRACE(("Enter %s\n", __FUNCTION__));
|
||||
DHD_TRACE(("%s-%d: data_length=%d, remain=%d, append=%d "
|
||||
"pNode: pEntry=0x%px, global_id=%d, flags=0x%x, "
|
||||
"data_len=%d, remain_len=%d, copied_len=%d\n",
|
||||
__func__, __LINE__,
|
||||
data_length, remain_length, append_len,
|
||||
pEntry, pEntry->global_id, pEntry->flags,
|
||||
pEntry->data_length,
|
||||
pEntry->remain_length, pEntry->copied_length));
|
||||
|
||||
/* copy and update */
|
||||
if (append_len) {
|
||||
memcpy((pEntry->data_length + ((uint8 *)pEntry->data)),
|
||||
pData, append_len);
|
||||
pEntry->data_length += append_len;
|
||||
|
||||
if ((!error_status)
|
||||
&& (!remain_length)
|
||||
&& (pEntry->checksum)) {
|
||||
uint16 checksum = 0;
|
||||
uint i;
|
||||
pData = (uint8 *)pEntry->data;
|
||||
for (i = 0; i < data_length; i++) {
|
||||
checksum += pData[i];
|
||||
}
|
||||
if (checksum != pEntry->checksum) {
|
||||
DHD_ERROR(("%s-%d: *Error, global_id=%d, "
|
||||
"checksum=0x%X mismatch to FW=0x%X, "
|
||||
"data_length=%d, remain_length=%d, "
|
||||
"pData=0x%px\n",
|
||||
__func__, __LINE__,
|
||||
pEntry->global_id,
|
||||
checksum, pEntry->checksum,
|
||||
data_length, remain_length, pData));
|
||||
pEntry->flags |= SYNA_CSI_FLAG_ERROR_CHECKSUM;
|
||||
}
|
||||
}
|
||||
} else if (!error_status) {
|
||||
DHD_ERROR(("%s-%d: *Error, no data append, "
|
||||
"total_size=%d, free_len=%d, "
|
||||
"in_data_length=%d, in_remain_length=%d, "
|
||||
" Node: global_id=%d, flags=0x%X, "
|
||||
"data_length=%d, remain_length=%d\n",
|
||||
__func__, __LINE__,
|
||||
ptr->total_size,
|
||||
(int)SYNA_CSI_CFR_NODE_FREE_LEN(ptr),
|
||||
data_length, remain_length,
|
||||
pEntry->global_id, pEntry->flags,
|
||||
pEntry->data_length, pEntry->remain_length));
|
||||
} else {
|
||||
DHD_ERROR(("%s-%d: *Warning, error report frame, "
|
||||
"size=%d, free=%d, "
|
||||
"in_data_length=%d, in_remain_length=%d, "
|
||||
" Node: global_id=%d, flags=0x%X%s, "
|
||||
"data_length=%d, remain_length=%d\n",
|
||||
__func__, __LINE__,
|
||||
ptr->total_size,
|
||||
(int)SYNA_CSI_CFR_NODE_FREE_LEN(ptr),
|
||||
data_length, remain_length,
|
||||
pEntry->global_id, pEntry->flags,
|
||||
(SYNA_CSI_FLAG_ERROR_CHECKSUM & pEntry->flags)
|
||||
? "(error_checksum)"
|
||||
: (SYNA_CSI_FLAG_ERROR_NO_ACK & pEntry->flags)
|
||||
? "(error_no_ack)"
|
||||
: (SYNA_CSI_FLAG_ERROR_READ & pEntry->flags)
|
||||
? "(error_read)"
|
||||
: (SYNA_CSI_FLAG_ERROR_PS & pEntry->flags)
|
||||
? "(error_ps)"
|
||||
: (SYNA_CSI_FLAG_ERROR_GENERIC & pEntry->flags)
|
||||
? "(error_generic)"
|
||||
: "",
|
||||
pEntry->data_length, pEntry->remain_length));
|
||||
}
|
||||
|
||||
/* make this as final step to avoid packet early retrieved */
|
||||
pEntry->copied_length = 0;
|
||||
pEntry->remain_length = remain_length;
|
||||
|
||||
ret = append_len;
|
||||
|
||||
done:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int dhd_csi_data_new_v0(dhd_pub_t *dhdp, const wl_event_msg_t *event,
|
||||
struct dhd_cfr_header_v0 *pEvent)
|
||||
{
|
||||
struct csi_cfr_node *ptr = NULL;
|
||||
struct syna_csi_header *pEntry = NULL;
|
||||
struct timespec64 ts;
|
||||
dhd_if_t *ifp = NULL;
|
||||
int ret = BCME_ERROR;
|
||||
uint total_size = 0;
|
||||
u32 chanspec = 0;
|
||||
uint32 remain_length = 0;
|
||||
uint32 data_length = 0;
|
||||
uint8 *pData = NULL;
|
||||
|
||||
ktime_get_real_ts64(&ts);
|
||||
total_size = SYNA_CSI_CFR_NODE_LEN + ltoh32_ua(&(pEvent->cfr_dump_length));
|
||||
|
||||
ptr = (struct csi_cfr_node *)MALLOCZ(dhdp->osh, total_size);
|
||||
if (!ptr) {
|
||||
DHD_ERROR(("%s-%d: *Error, malloc %d for cfr dump list error\n",
|
||||
__func__, __LINE__, total_size));
|
||||
return BCME_NOMEM;
|
||||
}
|
||||
ptr->pNode = ptr; /* Not useful */
|
||||
ptr->total_size = total_size;
|
||||
pEntry = &(ptr->entry);
|
||||
|
||||
DHD_TRACE(("%s-%d: ptr=0x%p, ptr=0x%px, pEntry=0x%px, "
|
||||
"delta=%d, header_size=%d\n",
|
||||
__func__, __LINE__, ptr, ptr, pEntry,
|
||||
(int)((uintptr)pEntry - (uintptr)ptr),
|
||||
(int)SYNA_CSI_CFR_NODE_LEN));
|
||||
|
||||
/* process one by one for alignment consideration */
|
||||
pEntry->magic_flag = CONST_SYNA_CSI_MAGIC_FLAG;
|
||||
pEntry->version = CONST_SYNA_CSI_COMMON_HEADER_VERSION;
|
||||
pEntry->format_type = SYNA_CSI_FORMAT_Q8;
|
||||
pEntry->fc = 0;
|
||||
if (pEvent->status) {
|
||||
pEntry->flags |= SYNA_CSI_FLAG_ERROR_GENERIC;
|
||||
}
|
||||
memcpy(pEntry->client_ea, pEvent->peer_macaddr, ETHER_ADDR_LEN);
|
||||
|
||||
ifp = dhd_get_ifp(dhdp, event->ifidx);
|
||||
if (!ifp) {
|
||||
DHD_ERROR(("%s-%d: *Error, get ifp error\n",
|
||||
__func__, __LINE__));
|
||||
} else {
|
||||
memcpy(pEntry->bsscfg_ea, ifp->mac_addr, ETHER_ADDR_LEN);
|
||||
}
|
||||
|
||||
if ((ret = dhd_iovar(dhdp, event->ifidx, "chanspec",
|
||||
NULL, 0, (char*)&chanspec,
|
||||
sizeof(chanspec), FALSE) != BCME_OK)) {
|
||||
pEntry->band = SYNA_CSI_BAND_UNKNOWN;
|
||||
pEntry->bandwidth = SYNA_CSI_BW_UNKNOWN;
|
||||
pEntry->channel = 0;
|
||||
} else {
|
||||
switch (CHSPEC_BAND(chanspec)) {
|
||||
case WL_CHANSPEC_BAND_2G:
|
||||
pEntry->band = SYNA_CSI_BAND_2G;
|
||||
break;
|
||||
case WL_CHANSPEC_BAND_5G:
|
||||
pEntry->band = SYNA_CSI_BAND_5G;
|
||||
break;
|
||||
case WL_CHANSPEC_BAND_6G:
|
||||
pEntry->band = SYNA_CSI_BAND_6G;
|
||||
break;
|
||||
default:
|
||||
pEntry->band = SYNA_CSI_BAND_UNKNOWN;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (CHSPEC_BW(chanspec)) {
|
||||
case WL_CHANSPEC_BW_20:
|
||||
pEntry->bandwidth = SYNA_CSI_BW_20MHz;
|
||||
break;
|
||||
case WL_CHANSPEC_BW_40:
|
||||
pEntry->bandwidth = SYNA_CSI_BW_40MHz;
|
||||
break;
|
||||
case WL_CHANSPEC_BW_80:
|
||||
pEntry->bandwidth = SYNA_CSI_BW_80MHz;
|
||||
break;
|
||||
case WL_CHANSPEC_BW_160:
|
||||
pEntry->bandwidth = SYNA_CSI_BW_160MHz;
|
||||
break;
|
||||
case WL_CHANSPEC_BW_320:
|
||||
pEntry->bandwidth = SYNA_CSI_BW_320MHz;
|
||||
break;
|
||||
default:
|
||||
pEntry->bandwidth = SYNA_CSI_BAND_UNKNOWN;
|
||||
break;
|
||||
}
|
||||
|
||||
pEntry->channel = CHSPEC_CHANNEL(chanspec);
|
||||
}
|
||||
|
||||
pEntry->num_txstream = pEvent->sts;
|
||||
pEntry->num_rxchain = pEvent->num_rx;
|
||||
pEntry->num_subcarrier = ltoh16_ua(&(pEvent->num_carrier));
|
||||
pEntry->report_tsf = (uint64)TIMESPEC64_TO_US(ts);
|
||||
pEntry->rssi = pEvent->rssi;
|
||||
pEntry->data_length = 0;
|
||||
pEntry->remain_length = 0;
|
||||
pEntry->copied_length = 0;
|
||||
|
||||
DHD_TRACE(("%s-%d: Entry data_size=%d, remain_size=%d, @%llu\n",
|
||||
__func__, __LINE__,
|
||||
ltoh32_ua(&(pEvent->cfr_dump_length)),
|
||||
ltoh32_ua(&(pEvent->remain_length)),
|
||||
ltoh64_ua(&(pEntry->report_tsf))));
|
||||
|
||||
remain_length = ltoh32_ua(&(pEvent->remain_length));
|
||||
data_length = ltoh32_ua(&(pEvent->cfr_dump_length));
|
||||
pData = (uint8 *)pEvent->data;
|
||||
ret = dhd_csi_data_append(remain_length, data_length, pData, ptr);
|
||||
if (0 <= ret) {
|
||||
INIT_LIST_HEAD(&(ptr->list));
|
||||
mutex_lock(&dhdp->csi_lock);
|
||||
list_add_tail(&(ptr->list), &dhdp->csi_list);
|
||||
dhdp->csi_count++;
|
||||
mutex_unlock(&dhdp->csi_lock);
|
||||
} else {
|
||||
MFREE(dhdp->osh, ptr, total_size);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int dhd_csi_data_new_v1(dhd_pub_t *dhdp, const wl_event_msg_t *event,
|
||||
struct dhd_cfr_header_v1 *pEvent)
|
||||
{
|
||||
struct csi_cfr_node *ptr = NULL;
|
||||
struct syna_csi_header *pEntry = NULL;
|
||||
dhd_if_t *ifp = NULL;
|
||||
int ret = BCME_ERROR;
|
||||
uint total_size = 0;
|
||||
u32 chanspec = 0;
|
||||
uint32 remain_length = 0;
|
||||
uint32 data_length = 0;
|
||||
uint8 *pData = NULL;
|
||||
|
||||
total_size = SYNA_CSI_CFR_NODE_LEN + ltoh32_ua(&(pEvent->cfr_dump_length));
|
||||
|
||||
ptr = (struct csi_cfr_node *)MALLOCZ(dhdp->osh, total_size);
|
||||
if (!ptr) {
|
||||
DHD_ERROR(("%s-%d: *Error, malloc %d for cfr dump list error\n",
|
||||
__func__, __LINE__, total_size));
|
||||
return BCME_NOMEM;
|
||||
}
|
||||
ptr->pNode = ptr; /* Not useful */
|
||||
ptr->total_size = total_size;
|
||||
pEntry = &(ptr->entry);
|
||||
|
||||
DHD_TRACE(("%s-%d: ptr=0x%p, ptr=0x%px, pEntry=0x%px, "
|
||||
"delta=%d, header_size=%d\n",
|
||||
__func__, __LINE__, ptr, ptr, pEntry,
|
||||
(int)((uintptr)pEntry - (uintptr)ptr),
|
||||
(int)SYNA_CSI_CFR_NODE_LEN));
|
||||
|
||||
/* process one by one for alignment consideration */
|
||||
pEntry->magic_flag = CONST_SYNA_CSI_MAGIC_FLAG;
|
||||
pEntry->version = CONST_SYNA_CSI_COMMON_HEADER_VERSION;
|
||||
pEntry->format_type = SYNA_CSI_FORMAT_Q8;
|
||||
pEntry->fc = pEvent->fc;
|
||||
if (pEvent->status) {
|
||||
pEntry->flags |= SYNA_CSI_FLAG_ERROR_GENERIC;
|
||||
}
|
||||
|
||||
memcpy(pEntry->client_ea, pEvent->peer_macaddr, ETHER_ADDR_LEN);
|
||||
|
||||
ifp = dhd_get_ifp(dhdp, event->ifidx);
|
||||
|
||||
if (!ifp) {
|
||||
DHD_ERROR(("%s-%d: *Error, get ifp error\n",
|
||||
__func__, __LINE__));
|
||||
} else {
|
||||
memcpy(pEntry->bsscfg_ea, ifp->mac_addr, ETHER_ADDR_LEN);
|
||||
}
|
||||
|
||||
if ((ret = dhd_iovar(dhdp, event->ifidx, "chanspec",
|
||||
NULL, 0, (char*)&chanspec, sizeof(chanspec), FALSE) != BCME_OK)) {
|
||||
pEntry->band = SYNA_CSI_BAND_UNKNOWN;
|
||||
pEntry->bandwidth = SYNA_CSI_BW_UNKNOWN;
|
||||
pEntry->channel = 0;
|
||||
} else {
|
||||
switch (CHSPEC_BAND(chanspec)) {
|
||||
case WL_CHANSPEC_BAND_2G:
|
||||
pEntry->band = SYNA_CSI_BAND_2G;
|
||||
break;
|
||||
case WL_CHANSPEC_BAND_5G:
|
||||
pEntry->band = SYNA_CSI_BAND_5G;
|
||||
break;
|
||||
case WL_CHANSPEC_BAND_6G:
|
||||
pEntry->band = SYNA_CSI_BAND_6G;
|
||||
break;
|
||||
default:
|
||||
pEntry->band = SYNA_CSI_BAND_UNKNOWN;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (CHSPEC_BW(chanspec)) {
|
||||
case WL_CHANSPEC_BW_20:
|
||||
pEntry->bandwidth = SYNA_CSI_BW_20MHz;
|
||||
break;
|
||||
case WL_CHANSPEC_BW_40:
|
||||
pEntry->bandwidth = SYNA_CSI_BW_40MHz;
|
||||
break;
|
||||
case WL_CHANSPEC_BW_80:
|
||||
pEntry->bandwidth = SYNA_CSI_BW_80MHz;
|
||||
break;
|
||||
case WL_CHANSPEC_BW_160:
|
||||
pEntry->bandwidth = SYNA_CSI_BW_160MHz;
|
||||
break;
|
||||
case WL_CHANSPEC_BW_320:
|
||||
pEntry->bandwidth = SYNA_CSI_BW_320MHz;
|
||||
break;
|
||||
default:
|
||||
pEntry->bandwidth = SYNA_CSI_BAND_UNKNOWN;
|
||||
break;
|
||||
}
|
||||
|
||||
pEntry->channel = CHSPEC_CHANNEL(chanspec);
|
||||
}
|
||||
|
||||
pEntry->num_txstream = pEvent->sts;
|
||||
pEntry->num_rxchain = pEvent->num_rx;
|
||||
pEntry->num_subcarrier = ltoh16_ua(&(pEvent->num_carrier));
|
||||
pEntry->report_tsf = ltoh64_ua(&(pEvent->cfr_timestamp));
|
||||
pEntry->rssi = pEvent->rssi;
|
||||
pEntry->data_length = 0;
|
||||
pEntry->remain_length = 0;
|
||||
pEntry->copied_length = 0;
|
||||
|
||||
DHD_TRACE(("%s-%d: Entry data_size=%d, remain_size=%d, @%llu\n",
|
||||
__func__, __LINE__,
|
||||
ltoh32_ua(&(pEvent->cfr_dump_length)),
|
||||
ltoh32_ua(&(pEvent->remain_length)),
|
||||
ltoh64_ua(&(pEntry->report_tsf))));
|
||||
|
||||
remain_length = ltoh32_ua(&(pEvent->remain_length));
|
||||
data_length = ltoh32_ua(&(pEvent->cfr_dump_length));
|
||||
pData = (uint8 *)pEvent->data;
|
||||
ret = dhd_csi_data_append(remain_length, data_length, pData, ptr);
|
||||
if (0 <= ret) {
|
||||
INIT_LIST_HEAD(&(ptr->list));
|
||||
mutex_lock(&dhdp->csi_lock);
|
||||
list_add_tail(&(ptr->list), &dhdp->csi_list);
|
||||
dhdp->csi_count++;
|
||||
mutex_unlock(&dhdp->csi_lock);
|
||||
} else {
|
||||
MFREE(dhdp->osh, ptr, total_size);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int dhd_csi_data_new_v2(dhd_pub_t *dhdp, const wl_event_msg_t *event,
|
||||
struct dhd_cfr_header_v2 *pEvent)
|
||||
{
|
||||
struct csi_cfr_node *ptr = NULL;
|
||||
struct syna_csi_header *pEntry = NULL;
|
||||
int ret = BCME_ERROR;
|
||||
uint total_size = 0;
|
||||
uint32 remain_length = 0;
|
||||
uint32 data_length = 0;
|
||||
uint8 *pData = NULL;
|
||||
|
||||
if (SYNA_ALIGN_PADDING & (uintptr)pEvent) {
|
||||
DHD_ERROR(("%s-%d: *Error, pEvent=0x%px is not aligned!",
|
||||
__func__, __LINE__, pEvent));
|
||||
}
|
||||
|
||||
total_size = SYNA_CSI_CFR_NODE_LEN + pEvent->data_length;
|
||||
|
||||
ptr = (struct csi_cfr_node *)MALLOCZ(dhdp->osh, total_size);
|
||||
if (!ptr) {
|
||||
DHD_ERROR(("%s-%d: *Error, malloc %d for cfr dump list error\n",
|
||||
__func__, __LINE__, total_size));
|
||||
return BCME_NOMEM;
|
||||
}
|
||||
ptr->pNode = ptr; /* Not useful */
|
||||
ptr->total_size = total_size;
|
||||
pEntry = &(ptr->entry);
|
||||
|
||||
DHD_TRACE(("%s-%d: ptr=0x%p, ptr=0x%px, pEntry=0x%px, "
|
||||
"delta=%d, header_size=%d\n",
|
||||
__func__, __LINE__, ptr, ptr, pEntry,
|
||||
(int)((uintptr)pEntry - (uintptr)ptr),
|
||||
(int)SYNA_CSI_CFR_NODE_LEN));
|
||||
|
||||
/* process one by one for alignment consideration */
|
||||
memcpy(pEntry, pEvent, sizeof(struct syna_csi_header));
|
||||
pEntry->magic_flag = CONST_SYNA_CSI_MAGIC_FLAG;
|
||||
pEntry->version = CONST_SYNA_CSI_COMMON_HEADER_VERSION;
|
||||
|
||||
if ((pEvent->status_compat)
|
||||
&& (!(SYNA_CSI_FLAG_ERROR_MASK & pEntry->flags))) {
|
||||
pEntry->flags |= SYNA_CSI_FLAG_ERROR_GENERIC;
|
||||
DHD_ERROR(("%s-%d: *Warning, status=0x%X, "
|
||||
" global_id=%d!\n",
|
||||
__func__, __LINE__,
|
||||
pEvent->status_compat,
|
||||
pEvent->global_id));
|
||||
}
|
||||
if (!pEntry->format_type) {
|
||||
pEntry->format_type = SYNA_CSI_FORMAT_Q8;
|
||||
}
|
||||
if (!memcmp(_gpMAC_zero, pEntry->bsscfg_ea, ETHER_ADDR_LEN)) {
|
||||
dhd_if_t *ifp = dhd_get_ifp(dhdp, event->ifidx);
|
||||
if (!ifp) {
|
||||
DHD_ERROR(("%s-%d: *Error, get ifp error\n",
|
||||
__func__, __LINE__));
|
||||
} else {
|
||||
memcpy(pEntry->bsscfg_ea, ifp->mac_addr, ETHER_ADDR_LEN);
|
||||
}
|
||||
}
|
||||
|
||||
if (!pEntry->report_tsf) {
|
||||
struct timespec64 ts;
|
||||
ktime_get_real_ts64(&ts);
|
||||
pEntry->report_tsf = (uint64)TIMESPEC64_TO_US(ts);
|
||||
}
|
||||
|
||||
pEntry->data_length = 0;
|
||||
pEntry->remain_length = 0;
|
||||
pEntry->copied_length = 0;
|
||||
pEntry->checksum = pEvent->checksum;
|
||||
|
||||
DHD_TRACE(("%s-%d: Entry data_size=%d, remain_size=%d, @%llu\n",
|
||||
__func__, __LINE__,
|
||||
pEvent->data_length,
|
||||
pEvent->remain_length,
|
||||
pEntry->report_tsf));
|
||||
|
||||
remain_length = pEvent->remain_length;
|
||||
data_length = pEvent->data_length;
|
||||
pData = (uint8 *)pEvent->data;
|
||||
ret = dhd_csi_data_append(remain_length, data_length, pData, ptr);
|
||||
if (0 <= ret) {
|
||||
INIT_LIST_HEAD(&(ptr->list));
|
||||
mutex_lock(&dhdp->csi_lock);
|
||||
list_add_tail(&(ptr->list), &dhdp->csi_list);
|
||||
dhdp->csi_count++;
|
||||
mutex_unlock(&dhdp->csi_lock);
|
||||
} else {
|
||||
MFREE(dhdp->osh, ptr, total_size);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int dhd_csi_event_handler(dhd_pub_t *dhdp, const wl_event_msg_t *event, void *event_data)
|
||||
{
|
||||
union dhd_cfr_header *pEvent = NULL;
|
||||
struct csi_cfr_node *ptr = NULL, *next = NULL, *save_ptr = NULL;
|
||||
const uint8 *pMAC = NULL, *pData = NULL;
|
||||
uint8 version = 0xff;
|
||||
uint32 data_length = 0, remain_length = 0, header_length = 0;
|
||||
int ret = BCME_OK;
|
||||
|
||||
NULL_CHECK(dhdp, "dhdp is NULL", ret);
|
||||
|
||||
DHD_TRACE(("%s-%d: Enter\n", __func__, __LINE__));
|
||||
|
||||
if (!event_data) {
|
||||
DHD_ERROR(("%s: event_data is NULL\n", __FUNCTION__));
|
||||
return -EINVAL;
|
||||
DHD_ERROR(("%s-%d: event_data is NULL\n",
|
||||
__func__, __LINE__));
|
||||
ret = BCME_BADARG;
|
||||
goto done;
|
||||
}
|
||||
p_event = (cfr_dump_data_t *)event_data;
|
||||
|
||||
pEvent = (union dhd_cfr_header *)event_data;
|
||||
if (pEvent->header_v0.status) {
|
||||
DHD_ERROR(("%s-%d: *Warning, status=0x%X "
|
||||
" may indicate error!\n",
|
||||
__func__, __LINE__,
|
||||
pEvent->header_v0.status));
|
||||
/* TODO: do need to abandon this scenario? */
|
||||
}
|
||||
|
||||
version = pEvent->header_v0.version;
|
||||
switch (version) {
|
||||
case CSI_VERSION_V0:
|
||||
pMAC = pEvent->header_v0.peer_macaddr;
|
||||
header_length = sizeof(struct dhd_cfr_header_v0);
|
||||
remain_length = ltoh32_ua(&(pEvent->header_v0.remain_length));
|
||||
data_length = ltoh32_ua(&(pEvent->header_v0.cfr_dump_length));
|
||||
pData = (uint8 *)pEvent->header_v0.data;
|
||||
break;
|
||||
case CSI_VERSION_V1:
|
||||
pMAC = pEvent->header_v1.peer_macaddr;
|
||||
header_length = sizeof(struct dhd_cfr_header_v1);
|
||||
remain_length = ltoh32_ua(&(pEvent->header_v1.remain_length));
|
||||
data_length = ltoh32_ua(&(pEvent->header_v1.cfr_dump_length));
|
||||
pData = (uint8 *)pEvent->header_v1.data;
|
||||
break;
|
||||
case CSI_VERSION_V2:
|
||||
pMAC = pEvent->header_v2.client_ea;
|
||||
header_length = sizeof(struct dhd_cfr_header_v2);
|
||||
remain_length = pEvent->header_v2.remain_length;
|
||||
data_length = pEvent->header_v2.data_length;
|
||||
pData = (uint8 *)pEvent->header_v2.data;
|
||||
break;
|
||||
default:
|
||||
DHD_ERROR(("%s-%d: CSI version=%d error\n",
|
||||
__func__, __LINE__, version));
|
||||
ret = BCME_BADOPTION;
|
||||
goto done;
|
||||
break;
|
||||
}
|
||||
|
||||
if (header_length <= remain_length) {
|
||||
remain_length -= header_length;
|
||||
}
|
||||
if (CONST_CSI_MAXIMUM_DATA_BYTES < remain_length) {
|
||||
DHD_ERROR(("%s-%d: *Error, drop too big length, "
|
||||
"global_id=%d, version=%d, status=%d, "
|
||||
"data_length=%d(0x%X), remain_length=%d(0x%X) > %d\n",
|
||||
__func__, __LINE__,
|
||||
pEvent->header_v2.global_id,
|
||||
version, pEvent->header_v2.status_compat,
|
||||
data_length, data_length,
|
||||
remain_length, remain_length,
|
||||
(int)CONST_CSI_MAXIMUM_DATA_BYTES));
|
||||
prhex("TOO_BIG_LENGTH", (uchar *)pEvent, 128);
|
||||
ret = BCME_BADLEN;
|
||||
goto done;
|
||||
}
|
||||
|
||||
mutex_lock(&dhdp->csi_lock);
|
||||
/* check if this addr exist */
|
||||
if (!list_empty(&dhd->csi_list)) {
|
||||
list_for_each_entry_safe(ptr, next, &dhd->csi_list, list) {
|
||||
if (bcmp(&ptr->entry.header.peer_macaddr, &p_event->header.peer_macaddr,
|
||||
ETHER_ADDR_LEN) == 0) {
|
||||
int pos = 0, dump_len = 0, remain = 0;
|
||||
is_new = FALSE;
|
||||
DHD_INFO(("CSI data exist\n"));
|
||||
if (p_event->header.status == 0) {
|
||||
bcopy(&p_event->header, &ptr->entry.header, sizeof(cfr_dump_header_t));
|
||||
dump_len = p_event->header.cfr_dump_length;
|
||||
if (dump_len < MAX_EVENT_SIZE) {
|
||||
bcopy(&p_event->data, &ptr->entry.data, dump_len);
|
||||
} else {
|
||||
/* for big csi data */
|
||||
uint8 *p = (uint8 *)&ptr->entry.data;
|
||||
remain = p_event->header.remain_length;
|
||||
if (remain) {
|
||||
pos = dump_len - remain - MAX_EVENT_SIZE;
|
||||
p += pos;
|
||||
bcopy(&p_event->data, p, MAX_EVENT_SIZE);
|
||||
}
|
||||
/* copy rest of csi data */
|
||||
else {
|
||||
pos = dump_len - (dump_len % MAX_EVENT_SIZE);
|
||||
p += pos;
|
||||
bcopy(&p_event->data, p, (dump_len % MAX_EVENT_SIZE));
|
||||
}
|
||||
}
|
||||
return BCME_OK;
|
||||
if (!list_empty(&dhdp->csi_list)) {
|
||||
list_for_each_entry_safe(ptr, next, &dhdp->csi_list, list) {
|
||||
struct syna_csi_header *pEntry = &(ptr->entry);
|
||||
/* check if is new */
|
||||
if (bcmp(&pEntry->client_ea, pMAC, ETHER_ADDR_LEN) == 0) {
|
||||
if (pEntry->remain_length > 0) {
|
||||
save_ptr = ptr;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (is_new) {
|
||||
if (dhd->csi_count < MAX_CSI_NUM) {
|
||||
new = (cfr_dump_list_t *)MALLOCZ(dhd->osh, sizeof(cfr_dump_list_t));
|
||||
if (!new){
|
||||
DHD_ERROR(("Malloc cfr dump list error\n"));
|
||||
return BCME_NOMEM;
|
||||
}
|
||||
bcopy(&p_event->header, &new->entry.header, sizeof(cfr_dump_header_t));
|
||||
DHD_INFO(("New entry data size %d\n", p_event->header.cfr_dump_length));
|
||||
/* for big csi data */
|
||||
if (p_event->header.remain_length) {
|
||||
DHD_TRACE(("remain %d\n", p_event->header.remain_length));
|
||||
bcopy(&p_event->data, &new->entry.data, MAX_EVENT_SIZE);
|
||||
}
|
||||
else
|
||||
bcopy(&p_event->data, &new->entry.data, p_event->header.cfr_dump_length);
|
||||
INIT_LIST_HEAD(&(new->list));
|
||||
list_add_tail(&(new->list), &dhd->csi_list);
|
||||
dhd->csi_count++;
|
||||
}
|
||||
else {
|
||||
DHD_TRACE(("Over maximum CSI Number 8. SKIP it.\n"));
|
||||
}
|
||||
/* check if need to drop head packet */
|
||||
if ((!save_ptr) && (dhdp->csi_count >= MAX_CSI_BUF_NUM)) {
|
||||
DHD_ERROR(("%s-%d: CSI data is full, drop pkt \n",
|
||||
__func__, __LINE__));
|
||||
ptr = list_first_entry(&dhdp->csi_list, struct csi_cfr_node, list);
|
||||
list_del_init(&ptr->list);
|
||||
MFREE(dhdp->osh, ptr, ptr->total_size);
|
||||
dhdp->csi_count--;
|
||||
}
|
||||
mutex_unlock(&dhdp->csi_lock);
|
||||
|
||||
/* try to append new node if needs */
|
||||
DHD_TRACE(("%s-%d: save_ptr=0x%px, version=%d\n",
|
||||
__func__, __LINE__, save_ptr, version));
|
||||
if (!save_ptr) {
|
||||
switch (version) {
|
||||
case CSI_VERSION_V0:
|
||||
ret = dhd_csi_data_new_v0(dhdp, event, &(pEvent->header_v0));
|
||||
break;
|
||||
case CSI_VERSION_V1:
|
||||
ret = dhd_csi_data_new_v1(dhdp, event, &(pEvent->header_v1));
|
||||
break;
|
||||
case CSI_VERSION_V2:
|
||||
ret = dhd_csi_data_new_v2(dhdp, event, &(pEvent->header_v2));
|
||||
break;
|
||||
default:
|
||||
DHD_ERROR(("%s-%d: CSI version=%d error\n",
|
||||
__func__, __LINE__, version));
|
||||
ret = BCME_BADOPTION;
|
||||
goto done;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
ret = dhd_csi_data_append(remain_length, data_length, pData, save_ptr);
|
||||
}
|
||||
|
||||
done:
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
dhd_csi_init(dhd_pub_t *dhd)
|
||||
static void
|
||||
dhd_csi_clean_list(dhd_pub_t *dhdp)
|
||||
{
|
||||
int err = BCME_OK;
|
||||
|
||||
NULL_CHECK(dhd, "dhd is NULL", err);
|
||||
INIT_LIST_HEAD(&dhd->csi_list);
|
||||
dhd->csi_count = 0;
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
int
|
||||
dhd_csi_deinit(dhd_pub_t *dhd)
|
||||
{
|
||||
int err = BCME_OK;
|
||||
cfr_dump_list_t *ptr, *next;
|
||||
|
||||
NULL_CHECK(dhd, "dhd is NULL", err);
|
||||
|
||||
if (!list_empty(&dhd->csi_list)) {
|
||||
list_for_each_entry_safe(ptr, next, &dhd->csi_list, list) {
|
||||
list_del(&ptr->list);
|
||||
MFREE(dhd->osh, ptr, sizeof(cfr_dump_list_t));
|
||||
}
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
void
|
||||
dhd_csi_clean_list(dhd_pub_t *dhd)
|
||||
{
|
||||
cfr_dump_list_t *ptr, *next;
|
||||
struct csi_cfr_node *ptr, *next;
|
||||
int num = 0;
|
||||
|
||||
if (!dhd) {
|
||||
DHD_ERROR(("NULL POINTER: %s\n", __FUNCTION__));
|
||||
if (!dhdp) {
|
||||
DHD_ERROR(("%s-%d: *Error, NULL POINTER\n",
|
||||
__func__, __LINE__));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!list_empty(&dhd->csi_list)) {
|
||||
list_for_each_entry_safe(ptr, next, &dhd->csi_list, list) {
|
||||
if (0 == ptr->entry.header.remain_length) {
|
||||
list_del(&ptr->list);
|
||||
num++;
|
||||
MFREE(dhd->osh, ptr, sizeof(cfr_dump_list_t));
|
||||
}
|
||||
mutex_lock(&dhdp->csi_lock);
|
||||
if (!list_empty(&dhdp->csi_list)) {
|
||||
list_for_each_entry_safe(ptr, next, &dhdp->csi_list, list) {
|
||||
list_del(&ptr->list);
|
||||
num++;
|
||||
MFREE(dhdp->osh, ptr, ptr->total_size);
|
||||
}
|
||||
}
|
||||
dhd->csi_count = 0;
|
||||
DHD_TRACE(("Clean up %d record\n", num));
|
||||
dhdp->csi_count = 0;
|
||||
mutex_unlock(&dhdp->csi_lock);
|
||||
|
||||
DHD_TRACE(("%s-%d: Clean up %d record\n",
|
||||
__func__, __LINE__, num));
|
||||
}
|
||||
|
||||
int dhd_csi_config(dhd_pub_t *dhdp, char *pBuf, uint length, bool is_set)
|
||||
{
|
||||
int ret = BCME_OK;
|
||||
|
||||
if ((!dhdp) || (!pBuf) || (sizeof(uint32) > length)) {
|
||||
DHD_ERROR(("%s-%d: *Error, Bad argument\n",
|
||||
__func__, __LINE__));
|
||||
ret = BCME_BADARG;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (is_set) {
|
||||
uint value = *((uint *)pBuf);
|
||||
if (SYNA_CSI_DATA_MODE_LAST <= value) {
|
||||
ret = BCME_BADOPTION;
|
||||
goto done;
|
||||
} else if (SYNA_CSI_DATA_MODE_NONE != value) {
|
||||
dhdp->csi_data_send_manner = value;
|
||||
dhd_csi_clean_list(dhdp);
|
||||
}
|
||||
} else {
|
||||
memcpy(pBuf, &dhdp->csi_data_send_manner, sizeof(uint32));
|
||||
}
|
||||
|
||||
done:
|
||||
return ret;
|
||||
}
|
||||
|
||||
int dhd_csi_init(dhd_pub_t *dhdp)
|
||||
{
|
||||
int err = BCME_OK;
|
||||
|
||||
mutex_init(&dhdp->csi_lock);
|
||||
mutex_lock(&dhdp->csi_lock);
|
||||
NULL_CHECK(dhdp, "dhdp is NULL", err);
|
||||
INIT_LIST_HEAD(&dhdp->csi_list);
|
||||
dhdp->csi_count = 0;
|
||||
mutex_unlock(&dhdp->csi_lock);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
int
|
||||
dhd_csi_dump_list(dhd_pub_t *dhd, char *buf)
|
||||
dhd_csi_deinit(dhd_pub_t *dhdp)
|
||||
{
|
||||
int ret = BCME_OK;
|
||||
cfr_dump_list_t *ptr, *next;
|
||||
uint8 * pbuf = buf;
|
||||
int num = 0;
|
||||
int length = 0;
|
||||
int err = BCME_OK;
|
||||
|
||||
NULL_CHECK(dhd, "dhd is NULL", ret);
|
||||
NULL_CHECK(dhdp, "dhdp is NULL", err);
|
||||
|
||||
/* check if this addr exist */
|
||||
if (!list_empty(&dhd->csi_list)) {
|
||||
list_for_each_entry_safe(ptr, next, &dhd->csi_list, list) {
|
||||
if (ptr->entry.header.remain_length) {
|
||||
DHD_ERROR(("data not ready %d\n", ptr->entry.header.remain_length));
|
||||
dhd_csi_clean_list(dhdp);
|
||||
|
||||
mutex_destroy(&dhdp->csi_lock);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
int dhd_csi_retrieve_queue_data(dhd_pub_t *dhdp, char *buf, uint count)
|
||||
{
|
||||
struct csi_cfr_node *ptr = NULL, *next = NULL;
|
||||
int ret = BCME_OK;
|
||||
char *pbuf = buf;
|
||||
int num = 0;
|
||||
int copy_len = 0;
|
||||
int left_data = 0;
|
||||
int total_copy_len = 0;
|
||||
|
||||
NULL_CHECK(dhdp, "dhdp is NULL", ret);
|
||||
|
||||
mutex_lock(&dhdp->csi_lock);
|
||||
if (!list_empty(&dhdp->csi_list)) {
|
||||
list_for_each_entry_safe(ptr, next, &dhdp->csi_list, list) {
|
||||
struct syna_csi_header *pEntry = &(ptr->entry);
|
||||
if (pEntry->remain_length) {
|
||||
DHD_ERROR(("%s-%d: *Warning, data not ready "
|
||||
"for %02X:%02X:%02X:%02X:%02X:%02X,"
|
||||
"global_id=%d, data_length=%d, "
|
||||
"remain_length=%d\n",
|
||||
__func__, __LINE__,
|
||||
pEntry->client_ea[0],
|
||||
pEntry->client_ea[1],
|
||||
pEntry->client_ea[2],
|
||||
pEntry->client_ea[3],
|
||||
pEntry->client_ea[4],
|
||||
pEntry->client_ea[5],
|
||||
pEntry->global_id,
|
||||
pEntry->data_length,
|
||||
pEntry->remain_length));
|
||||
continue;
|
||||
}
|
||||
bcopy(&ptr->entry.header, pbuf, sizeof(cfr_dump_header_t));
|
||||
length += sizeof(cfr_dump_header_t);
|
||||
pbuf += sizeof(cfr_dump_header_t);
|
||||
DHD_TRACE(("Copy data size %d\n", ptr->entry.header.cfr_dump_length));
|
||||
bcopy(&ptr->entry.data, pbuf, ptr->entry.header.cfr_dump_length);
|
||||
length += ptr->entry.header.cfr_dump_length;
|
||||
pbuf += ptr->entry.header.cfr_dump_length;
|
||||
num++;
|
||||
|
||||
left_data = SYNA_CSI_PKT_TOTAL_LEN(pEntry)
|
||||
- pEntry->copied_length;
|
||||
copy_len = count;
|
||||
|
||||
if (0 > left_data) {
|
||||
DHD_ERROR(("%s-%d: *Error, invalid case, "
|
||||
"total_len=%d, data_len=%d, "
|
||||
"remain_len=%d, copied_len=%d\n",
|
||||
__func__, __LINE__,
|
||||
(int)SYNA_CSI_PKT_TOTAL_LEN(pEntry),
|
||||
pEntry->data_length,
|
||||
pEntry->remain_length,
|
||||
pEntry->copied_length));
|
||||
copy_len = 0;
|
||||
} else if (copy_len > left_data) {
|
||||
copy_len = left_data;
|
||||
}
|
||||
|
||||
DHD_TRACE(("%s-%d: Packet[%d]: "
|
||||
"left_room=%d, copy_len=%d, "
|
||||
"pNode_data_len=%d, pNode_reamin_len=%d, "
|
||||
"pNode_copied_len=%d, csi_count=%d\n",
|
||||
__func__, __LINE__,
|
||||
num, count, copy_len,
|
||||
pEntry->data_length,
|
||||
pEntry->remain_length,
|
||||
pEntry->copied_length,
|
||||
dhdp->csi_count));
|
||||
|
||||
if (0 < copy_len) {
|
||||
memcpy(pbuf,
|
||||
pEntry->copied_length + (uint8 *)pEntry,
|
||||
copy_len);
|
||||
pEntry->copied_length += copy_len;
|
||||
count -= copy_len;
|
||||
pbuf += copy_len;
|
||||
num++;
|
||||
}
|
||||
|
||||
if (pEntry->copied_length >= SYNA_CSI_PKT_TOTAL_LEN(pEntry)) {
|
||||
list_del(&ptr->list);
|
||||
MFREE(dhdp->osh, ptr, ptr->total_size);
|
||||
dhdp->csi_count--;
|
||||
}
|
||||
|
||||
if (0 >= copy_len) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
DHD_TRACE(("dump %d record %d bytes\n", num, length));
|
||||
mutex_unlock(&dhdp->csi_lock);
|
||||
total_copy_len = pbuf - buf;
|
||||
DHD_TRACE(("%s-%d: dump %d record %d bytes\n",
|
||||
__func__, __LINE__, num, total_copy_len));
|
||||
|
||||
return length;
|
||||
return total_copy_len;
|
||||
}
|
||||
#endif /* CSI_SUPPORT */
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
/*
|
||||
* Broadcom Dongle Host Driver (DHD), CSI
|
||||
* Broadcom Dongle Host Driver (DHD), Linux-specific network interface.
|
||||
* Basically selected code segments from usb-cdc.c and usb-rndis.c
|
||||
*
|
||||
* Copyright (C) 1999-2018, Broadcom.
|
||||
* Copyright (C) 2023, Broadcom.
|
||||
*
|
||||
* Unless you and Broadcom execute a separate written software license
|
||||
* agreement governing use of this software, this software is licensed to you
|
||||
|
|
@ -17,27 +18,252 @@
|
|||
* 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.
|
||||
*
|
||||
* $Id: dhd_csi.h 558438 2015-05-22 06:05:11Z $
|
||||
* <<Broadcom-WL-IPTag/Open:>>
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#ifndef __DHD_CSI_H__
|
||||
#define __DHD_CSI_H__
|
||||
|
||||
/* definition for structure and API between APPP and driver */
|
||||
|
||||
/* **** SYNA CSI header interface with driver **** */
|
||||
|
||||
enum syna_csi_data_mode_type {
|
||||
SYNA_CSI_DATA_MODE_NONE = 0,
|
||||
/* upper layer will fetch data by sysfs */
|
||||
SYNA_CSI_DATA_MODE_SYSFS,
|
||||
/* upper layer will fetch data by UDP socket */
|
||||
SYNA_CSI_DATA_MODE_UDP_SOCKET,
|
||||
SYNA_CSI_DATA_MODE_LAST
|
||||
};
|
||||
|
||||
enum syna_csi_format_type {
|
||||
SYNA_CSI_FORMAT_UNKNOWN = 0,
|
||||
SYNA_CSI_FORMAT_Q8, /* (9,9,5) Q8 floating point
|
||||
* BCM4358/4359
|
||||
*/
|
||||
SYNA_CSI_FORMAT_Q13, /* (14,14) Q13 fixed point
|
||||
* BCM4339/43455/43456/43458
|
||||
*/
|
||||
SYNA_CSI_FORMAT_Q11, /* (12,12,6) Q11 floating point
|
||||
* BCM4360/4366
|
||||
*/
|
||||
SYNA_CSI_FORMAT_LAST
|
||||
};
|
||||
/* (9,9,5) Q8 floating point data format */
|
||||
#define _Q8_REAL_MA(t) (0x000ff &((t)>>14))
|
||||
#define _Q8_REAL_SI(t) (0x00001 &((t)>>22))
|
||||
#define _Q8_IMAGE_MA(t) (0x000ff &((t)>> 5))
|
||||
#define _Q8_IMAGE_SI(t) (0x00001 &((t)>>13))
|
||||
#define SYNA_CSI_DATA_Q8_REAL(t) \
|
||||
(((0 < _Q8_REAL_SI(t)) \
|
||||
? (-1) \
|
||||
: (1)) \
|
||||
* ((int32)_Q8_REAL_MA(t)) \
|
||||
)
|
||||
#define SYNA_CSI_DATA_Q8_IMAGE(t) \
|
||||
(((0 < _Q8_IMAGE_SI(t)) \
|
||||
? (-1) \
|
||||
: (1)) \
|
||||
* ((int32)_Q8_IMAGE_MA(t)) \
|
||||
)
|
||||
#define SYNA_CSI_DATA_Q8_EXP(t) \
|
||||
(((int8)(0xf8 \
|
||||
& ((t) << 3))) \
|
||||
>> 3 \
|
||||
)
|
||||
/* (14,14) Q13 fixed point data format */
|
||||
#define SYNA_CSI_DATA_Q13_REAL(t) \
|
||||
(((int32)(0xfff30000 \
|
||||
& ((t) << 4))) \
|
||||
>> (14 + 4) \
|
||||
)
|
||||
#define SYNA_CSI_DATA_Q13_IMAGE(t) \
|
||||
(((int32)(0xfff30000 \
|
||||
& ((t) << 18))) \
|
||||
>> (0 + 18) \
|
||||
)
|
||||
/* (12,12,6) Q11 floating point */
|
||||
#define _Q11_REAL_MA(t) (0x007ff &((t)>>18))
|
||||
#define _Q11_REAL_SI(t) (0x00001 &((t)>>29))
|
||||
#define _Q11_IMAGE_MA(t) (0x007ff &((t)>> 6))
|
||||
#define _Q11_IMAGE_SI(t) (0x00001 &((t)>>17))
|
||||
#define SYNA_CSI_DATA_Q11_REAL(t) \
|
||||
(((0 < _Q11_REAL_SI(t)) \
|
||||
? (-1) \
|
||||
: (1)) \
|
||||
* ((int32)_Q11_REAL_MA(t)) \
|
||||
)
|
||||
#define SYNA_CSI_DATA_Q11_IMAGE(t) \
|
||||
(((0 < _Q11_IMAGE_SI(t)) \
|
||||
? (-1) \
|
||||
: (1)) \
|
||||
* ((int32)_Q11_IMAGE_MA(t)) \
|
||||
)
|
||||
#define SYNA_CSI_DATA_Q11_EXP(t) \
|
||||
(((int8)(0xfc \
|
||||
& ((t) << 2))) \
|
||||
>> 2 \
|
||||
)
|
||||
|
||||
enum syna_csi_error_status {
|
||||
SYNA_CSI_ERROR_NONE,
|
||||
SYNA_CSI_ERROR_GENERIC, /* generic error */
|
||||
SYNA_CSI_ERROR_NO_ACK, /* peer doesn't ACK */
|
||||
SYNA_CSI_ERROR_READ, /* read data error */
|
||||
SYNA_CSI_ERROR_PS, /* peer device under powersaving */
|
||||
SYNA_CSI_ERROR_LAST
|
||||
};
|
||||
|
||||
enum syna_csi_flag {
|
||||
/* bit 0 ~ bit 15 are for error information */
|
||||
SYNA_CSI_FLAG_ERROR_MASK = 0x0FFFF,
|
||||
SYNA_CSI_FLAG_ERROR_CHECKSUM = (1 << 0),
|
||||
SYNA_CSI_FLAG_ERROR_GENERIC = (1 << SYNA_CSI_ERROR_GENERIC),
|
||||
SYNA_CSI_FLAG_ERROR_NO_ACK = (1 << SYNA_CSI_ERROR_NO_ACK),
|
||||
SYNA_CSI_FLAG_ERROR_READ = (1 << SYNA_CSI_ERROR_READ),
|
||||
SYNA_CSI_FLAG_ERROR_PS = (1 << SYNA_CSI_ERROR_PS),
|
||||
|
||||
/* subcarrier real position along FFT index: (total N=2*M subcarries)
|
||||
* -M, -(M-1), -(M-2), -(M-3),...,-1, 0, 1, 2,...M-1, M
|
||||
*
|
||||
* Data Output order with positive part first(*default*):
|
||||
* 0, 1, 2,...M-1, M, -M, -(M-1), -(M-2), -(M-3),...,-1,
|
||||
*
|
||||
* Data Output order with negative part first:
|
||||
* -M, -(M-1), -(M-2), -(M-3),...,-1, 0, 1, 2,...M-1, M
|
||||
*/
|
||||
SYNA_CSI_FLAG_FFT_NEGATIVE_FIRST = (1 << 16),
|
||||
SYNA_CSI_FLAG_LAST
|
||||
};
|
||||
|
||||
enum syna_csi_band_type {
|
||||
SYNA_CSI_BAND_UNKNOWN = 0,
|
||||
SYNA_CSI_BAND_2G,
|
||||
SYNA_CSI_BAND_5G,
|
||||
SYNA_CSI_BAND_6G,
|
||||
SYNA_CSI_BAND_LAST
|
||||
};
|
||||
|
||||
enum syna_csi_bandwidth_type {
|
||||
SYNA_CSI_BW_UNKNOWN = 0x000,
|
||||
SYNA_CSI_BW_5MHz = 0x001,
|
||||
SYNA_CSI_BW_10MHz = 0x002,
|
||||
SYNA_CSI_BW_20MHz = 0x004,
|
||||
SYNA_CSI_BW_40MHz = 0x008,
|
||||
SYNA_CSI_BW_80MHz = 0x010,
|
||||
SYNA_CSI_BW_160MHz = 0x020,
|
||||
SYNA_CSI_BW_320MHz = 0x040,
|
||||
SYNA_CSI_BW_LAST
|
||||
};
|
||||
|
||||
/* 'SYNA' -> 'A'53, 'N'59, 'Y'4e, 'S'41 */
|
||||
#define CONST_SYNA_CSI_MAGIC_FLAG 0x414E5953
|
||||
|
||||
/* CSI API common header structure (8 bytes alignment for 64bit system) */
|
||||
/* below is version 1 'syna_csi_header' */
|
||||
#define CONST_SYNA_CSI_COMMON_HEADER_VERSION 0x01
|
||||
struct syna_csi_header {
|
||||
/* byte 0 ~ 3 */
|
||||
uint32 magic_flag; /* flag for protecting and detecting header */
|
||||
|
||||
/* byte 4 ~ 7 */
|
||||
uint8 version; /* header version of this structure */
|
||||
uint8 format_type; /* data format type of current CSI packet,
|
||||
* enumerated in 'syna_csi_format_type'
|
||||
*/
|
||||
uint8 fc; /* packet frame control type of current
|
||||
* CSI data for further checking if it
|
||||
* is correct expected result
|
||||
*/
|
||||
uint8 flags; /* flag may use for extra emendation
|
||||
* which enumerated as 'syna_csi_flag'
|
||||
*/
|
||||
|
||||
/* byte 8 ~ 19 */
|
||||
uint8 client_ea[6]; /* client MAC address */
|
||||
uint8 bsscfg_ea[6]; /* BSSCFG address of current interface */
|
||||
|
||||
/* byte 20 ~ 23 */
|
||||
uint8 band; /* enumerated in 'syna_csi_band_type' */
|
||||
uint8 bandwidth; /* enumerated in 'syna_csi_bandwidth_type' */
|
||||
uint16 channel; /* channel number of corresponding band */
|
||||
|
||||
/* byte 24 ~ 31 */
|
||||
uint64 report_tsf; /* current CSI DATA RX timestamp */
|
||||
|
||||
/* byte 32 ~ 35 */
|
||||
uint8 num_txstream; /* peer side TX spatial steams */
|
||||
uint8 num_rxchain; /* number of RX side chain/antenna */
|
||||
uint16 num_subcarrier; /* Number of subcarrier */
|
||||
|
||||
/* byte 36 ~ 39 */
|
||||
int8 rssi; /* average RSSI, and goto check the
|
||||
* 'rssi_ant' if this 'rssi' is zero
|
||||
*/
|
||||
int8 noise; /* average noise */
|
||||
int16 global_id; /* CSI frame global ID */
|
||||
|
||||
/* byte 40 ~ 47 */
|
||||
int8 rssi_ant[8]; /* RSSI of each RX chain/antenna
|
||||
* (Depends on solution, and some
|
||||
* chipsets may only provide 'rssi'
|
||||
* rather than 'rssi_ant')
|
||||
*/
|
||||
|
||||
/* byte 48 ~ 55 */
|
||||
uint64 padding_future; /* reserved */
|
||||
|
||||
/* byte 56 ~ 63 */
|
||||
uint16 data_length; /* the bytes of 'data[]' */
|
||||
uint16 remain_length; /* remain length of not received data */
|
||||
uint16 copied_length; /* the length has been copied to user */
|
||||
uint16 checksum; /* 'data[]' checksum, 0 - not used */
|
||||
|
||||
/* byte 64 ~ End */
|
||||
uint32 data[0]; /* variable length according to the
|
||||
* 'data_length', but the minimal
|
||||
* valid data length will be
|
||||
* decided by the 'num_txchains'
|
||||
* 'num_rxchain' 'num_subcarrier'.
|
||||
* For example, the index quantity
|
||||
* of 'uint32' in the 11N 80MHz can
|
||||
* be got via:
|
||||
* 256 SubCarriers * 2 TXStream * 2 RXChain
|
||||
* Note: 'data_length' is bytes quantity,
|
||||
* and the 'data[]' array index range should
|
||||
* be 0 ~ (data_length/4 - 1)
|
||||
*/
|
||||
};
|
||||
|
||||
#define SYNA_CSI_PKT_TOTAL_LEN(ptr) \
|
||||
(sizeof(struct syna_csi_header) \
|
||||
+ ((struct syna_csi_header *)(ptr))->data_length \
|
||||
)
|
||||
|
||||
/* definition for structure and functions between driver and FW */
|
||||
|
||||
/* Maxinum csi file dump size */
|
||||
#define MAX_CSI_FILESZ (32 * 1024)
|
||||
/* Maxinum subcarrier number */
|
||||
#define MAXINUM_CFR_DATA 256 * 4
|
||||
#define MAXIMUM_CFR_DATA 2048
|
||||
#define CSI_DUMP_PATH "/sys/bcm-dhd/csi"
|
||||
#define MAX_EVENT_SIZE 1400
|
||||
/* maximun csi number stored at dhd */
|
||||
#define MAX_CSI_NUM 8
|
||||
#define MAX_CSI_NUM 16
|
||||
#define MAX_CSI_BUF_NUM 1024
|
||||
|
||||
typedef struct cfr_dump_header {
|
||||
/* 0 - successful; 1 - Failed */
|
||||
uint8 status;
|
||||
/* CSI VERSION */
|
||||
#define CSI_VERSION_V0 0 /* V0 */
|
||||
#define CSI_VERSION_V1 1 /* V1 */
|
||||
#define CSI_VERSION_V2 2 /* V2 */
|
||||
|
||||
struct dhd_cfr_header_v0 {
|
||||
uint8 status:4; /* bit3-0 */
|
||||
uint8 version:4; /* bit7-4 */
|
||||
/* Peer MAC address */
|
||||
uint8 peer_macaddr[6];
|
||||
/* Number of Space Time Streams */
|
||||
|
|
@ -52,25 +278,189 @@ typedef struct cfr_dump_header {
|
|||
uint32 remain_length;
|
||||
/* RSSI */
|
||||
int8 rssi;
|
||||
} __attribute__((packed)) cfr_dump_header_t;
|
||||
uint32 data[0];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
typedef struct cfr_dump_data {
|
||||
cfr_dump_header_t header;
|
||||
uint32 data[MAXINUM_CFR_DATA];
|
||||
} cfr_dump_data_t;
|
||||
struct dhd_cfr_header_v1 {
|
||||
uint8 status:4; /* bit3-0 */
|
||||
uint8 version:4; /* bit7-4 */
|
||||
/* Peer MAC address */
|
||||
uint8 peer_macaddr[6];
|
||||
/* Number of Space Time Streams */
|
||||
uint8 sts;
|
||||
/* Number of RX chain */
|
||||
uint8 num_rx;
|
||||
/* Number of subcarrier */
|
||||
uint16 num_carrier;
|
||||
/* Length of the CSI dump */
|
||||
uint32 cfr_dump_length;
|
||||
/* remain unsend CSI data length */
|
||||
uint32 remain_length;
|
||||
/* RSSI */
|
||||
int8 rssi;
|
||||
|
||||
typedef struct {
|
||||
struct list_head list;
|
||||
cfr_dump_data_t entry;
|
||||
} cfr_dump_list_t;
|
||||
/* Chip id. 1 for BCM43456/8 */
|
||||
uint8 chip_id;
|
||||
/* Frame control field */
|
||||
uint8 fc;
|
||||
/* Time stamp when CFR capture is taken,
|
||||
* in microseconds since the epoch
|
||||
*/
|
||||
uint64 cfr_timestamp;
|
||||
|
||||
int dhd_csi_event_handler(dhd_pub_t *dhd, wl_event_msg_t *event, void *event_data);
|
||||
uint32 data[0];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
int dhd_csi_init(dhd_pub_t *dhd);
|
||||
struct dhd_cfr_header_v2 { /* 8 bytes aligment for x64 */
|
||||
/* byte 0 ~ 7 */
|
||||
uint8 status_compat:4; /* bit3-0, current CSI data status: 0->good */
|
||||
uint8 version_compat:4; /* bit7-4, duplicate but compatible part */
|
||||
uint8 padding_magic;
|
||||
uint16 magic_flag; /* flag for protecting and detecting header */
|
||||
|
||||
int dhd_csi_deinit(dhd_pub_t *dhd);
|
||||
uint8 version; /* header version of this structure */
|
||||
uint8 format_type; /* data format type of current CSI packet,
|
||||
* enumerated in 'syna_csi_format_type'
|
||||
*/
|
||||
uint8 fc; /* packet frame control type of current
|
||||
* CSI data for further checking if it
|
||||
* is correct expected result
|
||||
*/
|
||||
uint8 flags; /* flag may use for extra emendation
|
||||
* which enumerated as 'syna_csi_flag'
|
||||
*/
|
||||
|
||||
void dhd_csi_clean_list(dhd_pub_t *dhd);
|
||||
/* byte 8 ~ 19 */
|
||||
uint8 client_ea[6]; /* client MAC address */
|
||||
uint8 bsscfg_ea[6]; /* BSSCFG address of current interface */
|
||||
|
||||
/* byte 20 ~ 23 */
|
||||
uint8 band; /* enumerated in 'syna_csi_band_type' */
|
||||
uint8 bandwidth; /* enumerated in 'syna_csi_bandwidth_type' */
|
||||
uint16 channel; /* channel number of corresponding band */
|
||||
|
||||
/* byte 24 ~ 31 */
|
||||
uint64 report_tsf; /* current CSI DATA RX timestamp */
|
||||
|
||||
/* byte 32 ~ 35 */
|
||||
uint8 num_txstream; /* peer side TX spatial steams */
|
||||
uint8 num_rxchain; /* number of RX side chain/antenna */
|
||||
uint16 num_subcarrier; /* Number of subcarrier */
|
||||
|
||||
/* byte 36 ~ 39 */
|
||||
int8 rssi; /* average RSSI, and goto check the
|
||||
* 'rssi_ant' if this 'rssi' is zero
|
||||
*/
|
||||
int8 noise; /* average noise */
|
||||
int16 global_id; /* CSI frame global ID */
|
||||
|
||||
/* byte 40 ~ 47 */
|
||||
int8 rssi_ant[8]; /* RSSI of each RX chain/antenna
|
||||
* (Depends on solution, and some
|
||||
* chipsets may only provide 'rssi'
|
||||
* rather than 'rssi_ant')
|
||||
*/
|
||||
|
||||
/* byte 48 ~ 55 */
|
||||
uint64 padding_future; /* reserved */
|
||||
|
||||
/* byte 56 ~ 63 */
|
||||
uint16 data_length; /* the data length of 'data[]' */
|
||||
uint16 remain_length; /* the remain unsent length of 'data[]' */
|
||||
uint16 padding_length; /* reserved */
|
||||
uint16 checksum; /* 'data[]' checksum, 0 - not used */
|
||||
|
||||
/* byte 64 ~ End */
|
||||
uint32 data[0]; /* variable according to 'data_length', but
|
||||
* the minial valid data length will be
|
||||
* decided by 'num_txchains', 'num_rxchain'
|
||||
* 'num_subcarrier'. For example, the
|
||||
* quantity of uint32(4 bytes) in the
|
||||
* 11N 80MHz can be got via:
|
||||
* 256 SubCarriers * 2 TXStream * 2 RXChain
|
||||
*/
|
||||
};
|
||||
|
||||
union dhd_cfr_header {
|
||||
struct dhd_cfr_header_v0 header_v0;
|
||||
struct dhd_cfr_header_v1 header_v1;
|
||||
struct dhd_cfr_header_v2 header_v2;
|
||||
};
|
||||
#define CSI_CFR_TOTAL_LENGTH(data_len) \
|
||||
(sizeof(union dhd_cfr_header) + data_len)
|
||||
|
||||
/* BW80 2x2 => 4bytes*256subcarries*2txstream*2rxchain */
|
||||
#define CONST_CSI_MAXIMUM_DATA_BYTES (CSI_CFR_TOTAL_LENGTH(256 *2 *2 *4))
|
||||
|
||||
struct csi_cfr_node {
|
||||
struct list_head list;
|
||||
void *pNode; /* recording current node pointer
|
||||
* especially for UDP data manner
|
||||
*/
|
||||
uint32 total_size;
|
||||
|
||||
struct syna_csi_header entry;
|
||||
};
|
||||
|
||||
#define SYNA_CSI_CFR_NODE_LEN sizeof(struct csi_cfr_node)
|
||||
|
||||
#define SYNA_CSI_CFR_NODE_TOTAL_LEN(ptr, data_length) \
|
||||
(\
|
||||
SYNA_CSI_CFR_NODE_LEN + data_length \
|
||||
)
|
||||
|
||||
#define SYNA_CSI_CFR_NODE_FREE_LEN(ptr) \
|
||||
(\
|
||||
((struct csi_cfr_node *)(ptr))->total_size \
|
||||
- SYNA_CSI_CFR_NODE_LEN \
|
||||
)
|
||||
|
||||
extern int dhd_csi_config(dhd_pub_t *dhdp, char *buf, uint length, bool is_set);
|
||||
|
||||
/* Function: change the upper layer fetching data manner
|
||||
* Input: uint is_set indicate it's set or get action
|
||||
* uint type the expected fetch type(ignore when get)
|
||||
* uint param extra param when set(UDP socket port)
|
||||
* Output: < 0 error encounter
|
||||
* == 0 successful
|
||||
* > 0 corresponding 'fetch type' when get
|
||||
*/
|
||||
extern int dhd_csi_data_fetch_type_access(uint is_set, uint type, uint param);
|
||||
|
||||
/* Function: parse the CSI event and convert to 'dhd_csi_header' format,
|
||||
* and queue the item into the common 'csi_cfr_queue'
|
||||
* Input: dhd_pub_t *dhdp context for operation
|
||||
* char *buf buffer for storing csi data
|
||||
* uint count total bytes available in 'buf'
|
||||
* Output: < 0 error encounter
|
||||
* == 0 successful but no csi data in queue
|
||||
* > 0 bytes write into 'buf'
|
||||
*/
|
||||
extern int dhd_csi_retrieve_queue_data(dhd_pub_t *dhdp, char *buf, uint count);
|
||||
|
||||
/* Function: parse the CSI event and convert to 'dhd_csi_header' format,
|
||||
* and queue the item into the common 'csi_cfr_queue'
|
||||
* Input: dhd_pub_t *dhdp context for operation
|
||||
* wl_event_msg_t *event wl event message header
|
||||
* void *event_data extra event data
|
||||
* Output: < 0 error encounter
|
||||
* == 0 successful
|
||||
*/
|
||||
extern int dhd_csi_event_handler(dhd_pub_t *dhdp,
|
||||
const wl_event_msg_t *event, void *event_data);
|
||||
|
||||
/* Function: Initialize the CSI module
|
||||
* Input: dhd_pub_t *dhdp context for operation
|
||||
* Output: < 0 error encounter
|
||||
* == 0 successful
|
||||
*/
|
||||
extern int dhd_csi_init(dhd_pub_t *dhdp);
|
||||
|
||||
/* Function: Deinitialize the CSI module
|
||||
* Input: dhd_pub_t *dhdp context for operation
|
||||
* Output: < 0 error encounter
|
||||
* == 0 successful
|
||||
*/
|
||||
extern int dhd_csi_deinit(dhd_pub_t *dhdp);
|
||||
|
||||
int dhd_csi_dump_list(dhd_pub_t *dhd, char *buf);
|
||||
#endif /* __DHD_CSI_H__ */
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,333 +0,0 @@
|
|||
/*
|
||||
* Platform Dependent file for Samsung Exynos
|
||||
*
|
||||
* Copyright (C) 2020, Broadcom.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*
|
||||
* <<Broadcom-WL-IPTag/Open:>>
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
#include <linux/device.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/of_gpio.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/workqueue.h>
|
||||
#include <linux/poll.h>
|
||||
#include <linux/miscdevice.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/workqueue.h>
|
||||
#include <linux/unistd.h>
|
||||
#include <linux/bug.h>
|
||||
#include <linux/skbuff.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/platform_device.h>
|
||||
#if defined(CONFIG_SOC_EXYNOS8895) || defined(CONFIG_SOC_EXYNOS9810) || \
|
||||
defined(CONFIG_SOC_EXYNOS9820) || defined(CONFIG_SOC_EXYNOS9830) || \
|
||||
defined(CONFIG_SOC_EXYNOS2100) || defined(CONFIG_SOC_EXYNOS1000)
|
||||
#include <linux/exynos-pci-ctrl.h>
|
||||
#endif /* CONFIG_SOC_EXYNOS8895 || CONFIG_SOC_EXYNOS9810 ||
|
||||
* CONFIG_SOC_EXYNOS9820 || CONFIG_SOC_EXYNOS9830 ||
|
||||
* CONFIG_SOC_EXYNOS2100 || CONFIG_SOC_EXYNOS1000
|
||||
*/
|
||||
|
||||
#if defined(CONFIG_64BIT)
|
||||
#include <asm-generic/gpio.h>
|
||||
#endif /* CONFIG_64BIT */
|
||||
|
||||
#ifdef BCMDHD_MODULAR
|
||||
#if IS_ENABLED(CONFIG_SEC_SYSFS)
|
||||
#include <linux/sec_sysfs.h>
|
||||
#endif /* CONFIG_SEC_SYSFS */
|
||||
#if IS_ENABLED(CONFIG_DRV_SAMSUNG)
|
||||
#include <linux/sec_class.h>
|
||||
#endif /* CONFIG_SEC_SYSFS */
|
||||
#else
|
||||
#if defined(CONFIG_SEC_SYSFS)
|
||||
#include <linux/sec_sysfs.h>
|
||||
#elif defined(CONFIG_DRV_SAMSUNG)
|
||||
#include <linux/sec_class.h>
|
||||
#endif /* CONFIG_SEC_SYSFS */
|
||||
#endif /* BCMDHD_MODULAR */
|
||||
#include <linux/wlan_plat.h>
|
||||
|
||||
#if defined(CONFIG_MACH_A7LTE) || defined(CONFIG_NOBLESSE)
|
||||
#define PINCTL_DELAY 150
|
||||
#endif /* CONFIG_MACH_A7LTE || CONFIG_NOBLESSE */
|
||||
|
||||
#ifdef CONFIG_BROADCOM_WIFI_RESERVED_MEM
|
||||
extern void dhd_exit_wlan_mem(void);
|
||||
extern int dhd_init_wlan_mem(void);
|
||||
extern void *dhd_wlan_mem_prealloc(int section, unsigned long size);
|
||||
#endif /* CONFIG_BROADCOM_WIFI_RESERVED_MEM */
|
||||
|
||||
#define WIFI_TURNON_DELAY 200
|
||||
static int wlan_pwr_on = -1;
|
||||
|
||||
#ifdef CONFIG_BCMDHD_OOB_HOST_WAKE
|
||||
static int wlan_host_wake_irq = 0;
|
||||
static unsigned int wlan_host_wake_up = -1;
|
||||
#endif /* CONFIG_BCMDHD_OOB_HOST_WAKE */
|
||||
|
||||
#if defined(CONFIG_MACH_A7LTE) || defined(CONFIG_NOBLESSE)
|
||||
extern struct device *mmc_dev_for_wlan;
|
||||
#endif /* CONFIG_MACH_A7LTE || CONFIG_NOBLESSE */
|
||||
|
||||
#ifdef CONFIG_BCMDHD_PCIE
|
||||
extern int pcie_ch_num;
|
||||
extern void exynos_pcie_pm_resume(int);
|
||||
extern void exynos_pcie_pm_suspend(int);
|
||||
#endif /* CONFIG_BCMDHD_PCIE */
|
||||
|
||||
#if defined(CONFIG_SOC_EXYNOS7870) || defined(CONFIG_SOC_EXYNOS9110)
|
||||
extern struct mmc_host *wlan_mmc;
|
||||
extern void mmc_ctrl_power(struct mmc_host *host, bool onoff);
|
||||
#endif /* SOC_EXYNOS7870 || CONFIG_SOC_EXYNOS9110 */
|
||||
|
||||
static int
|
||||
dhd_wlan_power(int onoff)
|
||||
{
|
||||
#if defined(CONFIG_MACH_A7LTE) || defined(CONFIG_NOBLESSE)
|
||||
struct pinctrl *pinctrl = NULL;
|
||||
#endif /* CONFIG_MACH_A7LTE || ONFIG_NOBLESSE */
|
||||
|
||||
printk(KERN_INFO"%s Enter: power %s\n", __FUNCTION__, onoff ? "on" : "off");
|
||||
|
||||
#if defined(CONFIG_MACH_A7LTE) || defined(CONFIG_NOBLESSE)
|
||||
if (onoff) {
|
||||
pinctrl = devm_pinctrl_get_select(mmc_dev_for_wlan, "sdio_wifi_on");
|
||||
if (IS_ERR(pinctrl))
|
||||
printk(KERN_INFO "%s WLAN SDIO GPIO control error\n", __FUNCTION__);
|
||||
msleep(PINCTL_DELAY);
|
||||
}
|
||||
#endif /* CONFIG_MACH_A7LTE || CONFIG_NOBLESSE */
|
||||
|
||||
if (gpio_direction_output(wlan_pwr_on, onoff)) {
|
||||
printk(KERN_ERR "%s failed to control WLAN_REG_ON to %s\n",
|
||||
__FUNCTION__, onoff ? "HIGH" : "LOW");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_MACH_A7LTE) || defined(CONFIG_NOBLESSE)
|
||||
if (!onoff) {
|
||||
pinctrl = devm_pinctrl_get_select(mmc_dev_for_wlan, "sdio_wifi_off");
|
||||
if (IS_ERR(pinctrl))
|
||||
printk(KERN_INFO "%s WLAN SDIO GPIO control error\n", __FUNCTION__);
|
||||
}
|
||||
#endif /* CONFIG_MACH_A7LTE || CONFIG_NOBLESSE */
|
||||
|
||||
#if defined(CONFIG_SOC_EXYNOS7870) || defined(CONFIG_SOC_EXYNOS9110)
|
||||
if (wlan_mmc)
|
||||
mmc_ctrl_power(wlan_mmc, onoff);
|
||||
#endif /* SOC_EXYNOS7870 || CONFIG_SOC_EXYNOS9110 */
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
dhd_wlan_reset(int onoff)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifndef CONFIG_BCMDHD_PCIE
|
||||
extern void (*notify_func_callback)(void *dev_id, int state);
|
||||
extern void *mmc_host_dev;
|
||||
#endif /* !CONFIG_BCMDHD_PCIE */
|
||||
|
||||
static int
|
||||
dhd_wlan_set_carddetect(int val)
|
||||
{
|
||||
#ifndef CONFIG_BCMDHD_PCIE
|
||||
pr_err("%s: notify_func=%p, mmc_host_dev=%p, val=%d\n",
|
||||
__FUNCTION__, notify_func_callback, mmc_host_dev, val);
|
||||
|
||||
if (notify_func_callback) {
|
||||
notify_func_callback(mmc_host_dev, val);
|
||||
} else {
|
||||
pr_warning("%s: Nobody to notify\n", __FUNCTION__);
|
||||
}
|
||||
#else
|
||||
if (val) {
|
||||
exynos_pcie_pm_resume(pcie_ch_num);
|
||||
} else {
|
||||
exynos_pcie_pm_suspend(pcie_ch_num);
|
||||
}
|
||||
#endif /* CONFIG_BCMDHD_PCIE */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int __init
|
||||
dhd_wlan_init_gpio(void)
|
||||
{
|
||||
const char *wlan_node = "samsung,brcm-wlan";
|
||||
struct device_node *root_node = NULL;
|
||||
struct device *wlan_dev;
|
||||
|
||||
wlan_dev = sec_device_create(NULL, "wlan");
|
||||
|
||||
root_node = of_find_compatible_node(NULL, NULL, wlan_node);
|
||||
if (!root_node) {
|
||||
WARN(1, "failed to get device node of bcm4354\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
/* ========== WLAN_PWR_EN ============ */
|
||||
wlan_pwr_on = of_get_gpio(root_node, 0);
|
||||
if (!gpio_is_valid(wlan_pwr_on)) {
|
||||
WARN(1, "Invalied gpio pin : %d\n", wlan_pwr_on);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
if (gpio_request(wlan_pwr_on, "WLAN_REG_ON")) {
|
||||
WARN(1, "fail to request gpio(WLAN_REG_ON)\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
#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 */
|
||||
gpio_export(wlan_pwr_on, 1);
|
||||
if (wlan_dev)
|
||||
gpio_export_link(wlan_dev, "WLAN_REG_ON", wlan_pwr_on);
|
||||
|
||||
#ifdef CONFIG_BCMDHD_PCIE
|
||||
exynos_pcie_pm_resume(pcie_ch_num);
|
||||
#endif /* CONFIG_BCMDHD_PCIE */
|
||||
|
||||
#ifdef CONFIG_BCMDHD_OOB_HOST_WAKE
|
||||
/* ========== WLAN_HOST_WAKE ============ */
|
||||
wlan_host_wake_up = of_get_gpio(root_node, 1);
|
||||
if (!gpio_is_valid(wlan_host_wake_up)) {
|
||||
WARN(1, "Invalied gpio pin : %d\n", wlan_host_wake_up);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
if (gpio_request(wlan_host_wake_up, "WLAN_HOST_WAKE")) {
|
||||
WARN(1, "fail to request gpio(WLAN_HOST_WAKE)\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
gpio_direction_input(wlan_host_wake_up);
|
||||
gpio_export(wlan_host_wake_up, 1);
|
||||
if (wlan_dev)
|
||||
gpio_export_link(wlan_dev, "WLAN_HOST_WAKE", wlan_host_wake_up);
|
||||
|
||||
wlan_host_wake_irq = gpio_to_irq(wlan_host_wake_up);
|
||||
#endif /* CONFIG_BCMDHD_OOB_HOST_WAKE */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_BCMDHD_OOB_HOST_WAKE) && defined(CONFIG_BCMDHD_GET_OOB_STATE)
|
||||
int
|
||||
dhd_get_wlan_oob_gpio(void)
|
||||
{
|
||||
return gpio_is_valid(wlan_host_wake_up) ?
|
||||
gpio_get_value(wlan_host_wake_up) : -1;
|
||||
}
|
||||
EXPORT_SYMBOL(dhd_get_wlan_oob_gpio);
|
||||
#endif /* CONFIG_BCMDHD_OOB_HOST_WAKE && CONFIG_BCMDHD_GET_OOB_STATE */
|
||||
|
||||
struct resource dhd_wlan_resources = {
|
||||
.name = "bcmdhd_wlan_irq",
|
||||
.start = 0,
|
||||
.end = 0,
|
||||
.flags = IORESOURCE_IRQ | IORESOURCE_IRQ_SHAREABLE |
|
||||
#ifdef CONFIG_BCMDHD_PCIE
|
||||
IORESOURCE_IRQ_HIGHEDGE,
|
||||
#else
|
||||
IORESOURCE_IRQ_HIGHLEVEL,
|
||||
#endif /* CONFIG_BCMDHD_PCIE */
|
||||
};
|
||||
EXPORT_SYMBOL(dhd_wlan_resources);
|
||||
|
||||
struct wifi_platform_data dhd_wlan_control = {
|
||||
.set_power = dhd_wlan_power,
|
||||
.set_reset = dhd_wlan_reset,
|
||||
.set_carddetect = dhd_wlan_set_carddetect,
|
||||
#ifdef CONFIG_BROADCOM_WIFI_RESERVED_MEM
|
||||
.mem_prealloc = dhd_wlan_mem_prealloc,
|
||||
#endif /* CONFIG_BROADCOM_WIFI_RESERVED_MEM */
|
||||
};
|
||||
EXPORT_SYMBOL(dhd_wlan_control);
|
||||
|
||||
int __init
|
||||
dhd_wlan_init(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
printk(KERN_INFO "%s: START.......\n", __FUNCTION__);
|
||||
ret = dhd_wlan_init_gpio();
|
||||
if (ret < 0) {
|
||||
printk(KERN_ERR "%s: failed to initiate GPIO, ret=%d\n",
|
||||
__FUNCTION__, ret);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_BCMDHD_OOB_HOST_WAKE
|
||||
dhd_wlan_resources.start = wlan_host_wake_irq;
|
||||
dhd_wlan_resources.end = wlan_host_wake_irq;
|
||||
#endif /* CONFIG_BCMDHD_OOB_HOST_WAKE */
|
||||
|
||||
#ifdef CONFIG_BROADCOM_WIFI_RESERVED_MEM
|
||||
ret = dhd_init_wlan_mem();
|
||||
if (ret < 0) {
|
||||
printk(KERN_ERR "%s: failed to alloc reserved memory,"
|
||||
" ret=%d\n", __FUNCTION__, ret);
|
||||
}
|
||||
#endif /* CONFIG_BROADCOM_WIFI_RESERVED_MEM */
|
||||
|
||||
fail:
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
dhd_wlan_deinit(void)
|
||||
{
|
||||
#ifdef CONFIG_BCMDHD_OOB_HOST_WAKE
|
||||
gpio_free(wlan_host_wake_up);
|
||||
#endif /* CONFIG_BCMDHD_OOB_HOST_WAKE */
|
||||
gpio_free(wlan_pwr_on);
|
||||
|
||||
#ifdef CONFIG_BROADCOM_WIFI_RESERVED_MEM
|
||||
dhd_exit_wlan_mem();
|
||||
#endif /* CONFIG_BROADCOM_WIFI_RESERVED_MEM */
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifndef BCMDHD_MODULAR
|
||||
#if defined(CONFIG_MACH_UNIVERSAL7420) || defined(CONFIG_SOC_EXYNOS8890) || \
|
||||
defined(CONFIG_SOC_EXYNOS8895) || defined(CONFIG_SOC_EXYNOS9810) || \
|
||||
defined(CONFIG_SOC_EXYNOS9820) || defined(CONFIG_SOC_EXYNOS9830)
|
||||
#if defined(CONFIG_DEFERRED_INITCALLS)
|
||||
deferred_module_init(dhd_wlan_init);
|
||||
#else
|
||||
late_initcall(dhd_wlan_init);
|
||||
#endif /* CONFIG_DEFERRED_INITCALLS */
|
||||
#else
|
||||
device_initcall(dhd_wlan_init);
|
||||
#endif /* CONFIG Exynos PCIE Platforms */
|
||||
#endif /* !BCMDHD_MODULAR */
|
||||
341
drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_custom_gpio.c
Executable file → Normal file
341
drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_custom_gpio.c
Executable file → Normal file
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* Customer code to add GPIO control during WLAN start/stop
|
||||
*
|
||||
* Copyright (C) 2020, Broadcom.
|
||||
* Copyright (C) 2022, Broadcom.
|
||||
*
|
||||
* Unless you and Broadcom execute a separate written software license
|
||||
* agreement governing use of this software, this software is licensed to you
|
||||
|
|
@ -33,6 +33,8 @@
|
|||
|
||||
#include <wlioctl.h>
|
||||
|
||||
#include <dhd_dbg.h>
|
||||
|
||||
#ifndef BCMDONGLEHOST
|
||||
#include <wlc_pub.h>
|
||||
#include <wl_dbg.h>
|
||||
|
|
@ -68,7 +70,7 @@ int dhd_customer_oob_irq_map(void *adapter, unsigned long *irq_flags_ptr)
|
|||
{
|
||||
int host_oob_irq = 0;
|
||||
|
||||
#if defined(CUSTOMER_HW2) || defined(CUSTOMER_HW4) || defined(BOARD_HIKEY)
|
||||
#if defined(BOARD_HIKEY)
|
||||
host_oob_irq = wifi_platform_get_irq_number(adapter, irq_flags_ptr);
|
||||
|
||||
#else
|
||||
|
|
@ -87,7 +89,7 @@ int dhd_customer_oob_irq_map(void *adapter, unsigned long *irq_flags_ptr)
|
|||
WL_ERROR(("%s: customer specific Host GPIO number is (%d)\n",
|
||||
__FUNCTION__, dhd_oob_gpio_num));
|
||||
|
||||
#endif /* CUSTOMER_HW2 || CUSTOMER_HW4 || BOARD_HIKEY */
|
||||
#endif /* BOARD_HIKER */
|
||||
|
||||
return (host_oob_irq);
|
||||
}
|
||||
|
|
@ -114,8 +116,7 @@ dhd_custom_get_mac_address(void *adapter, unsigned char *buf)
|
|||
return -EINVAL;
|
||||
|
||||
/* Customer access to MAC address stored outside of DHD driver */
|
||||
#if (defined(CUSTOMER_HW2) || defined(CUSTOMER_HW10) || defined(BOARD_HIKEY)) && \
|
||||
(LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35))
|
||||
#if defined(BOARD_HIKEY) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35))
|
||||
ret = wifi_platform_get_mac_addr(adapter, buf);
|
||||
#endif
|
||||
|
||||
|
|
@ -131,7 +132,195 @@ dhd_custom_get_mac_address(void *adapter, unsigned char *buf)
|
|||
}
|
||||
#endif /* GET_CUSTOM_MAC_ENABLE */
|
||||
|
||||
#ifndef CUSTOMER_HW4
|
||||
#ifdef SYNA_SAR_CUSTOMER_PARAMETER
|
||||
struct customer_cntry_list {
|
||||
eCountry_flag_type type;
|
||||
char ccode[WLC_CNTRY_BUF_SZ]; /* Country code */
|
||||
};
|
||||
|
||||
/* maximum: (A~Z+0~9) * (A~Z+0~9) = (26+10)*(26+10) = 1296 */
|
||||
#define MAX_COUNTRY_LIST 500
|
||||
struct customer_cntry_list syna_cntry_flag[MAX_COUNTRY_LIST] = {
|
||||
/* FCC TYPE */
|
||||
{SYNA_COUNTRY_TYPE_FCC, "AG"},
|
||||
{SYNA_COUNTRY_TYPE_FCC, "AI"},
|
||||
{SYNA_COUNTRY_TYPE_FCC, "AR"},
|
||||
{SYNA_COUNTRY_TYPE_FCC, "AW"},
|
||||
{SYNA_COUNTRY_TYPE_FCC, "BB"},
|
||||
{SYNA_COUNTRY_TYPE_FCC, "BL"},
|
||||
{SYNA_COUNTRY_TYPE_FCC, "BM"},
|
||||
{SYNA_COUNTRY_TYPE_FCC, "BO"},
|
||||
{SYNA_COUNTRY_TYPE_FCC, "BS"},
|
||||
{SYNA_COUNTRY_TYPE_FCC, "BZ"},
|
||||
{SYNA_COUNTRY_TYPE_FCC, "CA"},
|
||||
{SYNA_COUNTRY_TYPE_FCC, "CL"},
|
||||
{SYNA_COUNTRY_TYPE_FCC, "CO"},
|
||||
{SYNA_COUNTRY_TYPE_FCC, "CR"},
|
||||
{SYNA_COUNTRY_TYPE_FCC, "CW"},
|
||||
{SYNA_COUNTRY_TYPE_FCC, "DO"},
|
||||
{SYNA_COUNTRY_TYPE_FCC, "EC"},
|
||||
{SYNA_COUNTRY_TYPE_FCC, "FM"},
|
||||
{SYNA_COUNTRY_TYPE_FCC, "GT"},
|
||||
{SYNA_COUNTRY_TYPE_FCC, "GU"},
|
||||
{SYNA_COUNTRY_TYPE_FCC, "GY"},
|
||||
{SYNA_COUNTRY_TYPE_FCC, "HN"},
|
||||
{SYNA_COUNTRY_TYPE_FCC, "HT"},
|
||||
{SYNA_COUNTRY_TYPE_FCC, "IN"},
|
||||
{SYNA_COUNTRY_TYPE_FCC, "IR"},
|
||||
{SYNA_COUNTRY_TYPE_FCC, "JM"},
|
||||
{SYNA_COUNTRY_TYPE_FCC, "KH"},
|
||||
{SYNA_COUNTRY_TYPE_FCC, "KN"},
|
||||
{SYNA_COUNTRY_TYPE_FCC, "KR"},
|
||||
{SYNA_COUNTRY_TYPE_FCC, "KY"},
|
||||
{SYNA_COUNTRY_TYPE_FCC, "LC"},
|
||||
{SYNA_COUNTRY_TYPE_FCC, "MF"},
|
||||
{SYNA_COUNTRY_TYPE_FCC, "MP"},
|
||||
{SYNA_COUNTRY_TYPE_FCC, "NI"},
|
||||
{SYNA_COUNTRY_TYPE_FCC, "PA"},
|
||||
{SYNA_COUNTRY_TYPE_FCC, "PE"},
|
||||
{SYNA_COUNTRY_TYPE_FCC, "PG"},
|
||||
{SYNA_COUNTRY_TYPE_FCC, "PM"},
|
||||
{SYNA_COUNTRY_TYPE_FCC, "PW"},
|
||||
{SYNA_COUNTRY_TYPE_FCC, "PR"},
|
||||
{SYNA_COUNTRY_TYPE_FCC, "PY"},
|
||||
{SYNA_COUNTRY_TYPE_FCC, "SR"},
|
||||
{SYNA_COUNTRY_TYPE_FCC, "SV"},
|
||||
{SYNA_COUNTRY_TYPE_FCC, "SX"},
|
||||
{SYNA_COUNTRY_TYPE_FCC, "TC"},
|
||||
{SYNA_COUNTRY_TYPE_FCC, "TT"},
|
||||
{SYNA_COUNTRY_TYPE_FCC, "US"},
|
||||
{SYNA_COUNTRY_TYPE_FCC, "UY"},
|
||||
{SYNA_COUNTRY_TYPE_FCC, "VC"},
|
||||
{SYNA_COUNTRY_TYPE_FCC, "VE"},
|
||||
{SYNA_COUNTRY_TYPE_FCC, "VG"},
|
||||
{SYNA_COUNTRY_TYPE_FCC, "VI"},
|
||||
{SYNA_COUNTRY_TYPE_FCC, "VU"},
|
||||
{SYNA_COUNTRY_TYPE_FCC, "WF"},
|
||||
{SYNA_COUNTRY_TYPE_FCC, "WS"},
|
||||
{SYNA_COUNTRY_TYPE_INVALID, ""}
|
||||
};
|
||||
|
||||
static int gSyna_country_flag_qty = 55;
|
||||
|
||||
static int syna_country_flag_find(char *cntry)
|
||||
{
|
||||
char country[WLC_CNTRY_BUF_SZ];
|
||||
int ret = BCME_NOTFOUND;
|
||||
int n;
|
||||
|
||||
if (!cntry) {
|
||||
DHD_ERROR(("%s: invalid cntry!\n", __FUNCTION__));
|
||||
return BCME_BADARG;
|
||||
} else {
|
||||
n = strcspn(cntry, " ,");
|
||||
if ((n != 2) && (n != 3)) {
|
||||
DHD_ERROR(("%s: invalid n=%d!\n", __FUNCTION__, n));
|
||||
return BCME_BUFTOOLONG;
|
||||
} else {
|
||||
strlcpy(country, cntry, WLC_CNTRY_BUF_SZ);
|
||||
country[n] = '\0';
|
||||
DHD_TRACE(("%s: here n=%d, country='%s'!\n",
|
||||
__FUNCTION__, n, country));
|
||||
}
|
||||
}
|
||||
|
||||
n = 0;
|
||||
while ((MAX_COUNTRY_LIST > n) &&
|
||||
(SYNA_COUNTRY_TYPE_INVALID != syna_cntry_flag[n].type) &&
|
||||
(0 < strlen(syna_cntry_flag[n].ccode))) {
|
||||
if (!strncmp(country, syna_cntry_flag[n].ccode, WLC_CNTRY_BUF_SZ)) {
|
||||
ret = n;
|
||||
break;
|
||||
} else {
|
||||
n++;
|
||||
}
|
||||
}
|
||||
|
||||
/* sync up the quantity for appending new item */
|
||||
if ((MAX_COUNTRY_LIST > n) &&
|
||||
(SYNA_COUNTRY_TYPE_INVALID == syna_cntry_flag[n].type)) {
|
||||
gSyna_country_flag_qty = n;
|
||||
DHD_TRACE(("%s: update qty=%d!\n", __FUNCTION__, n));
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
eCountry_flag_type syna_country_check_type(char *cntry)
|
||||
{
|
||||
int ret = SYNA_COUNTRY_TYPE_INVALID;
|
||||
int i;
|
||||
|
||||
i = syna_country_flag_find(cntry);
|
||||
if (0 <= i) {
|
||||
ret = syna_cntry_flag[i].type;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int syna_country_update_type_list(eCountry_flag_type type, char *list_str)
|
||||
{
|
||||
char *next = NULL;
|
||||
int n = 0;
|
||||
size_t len;
|
||||
|
||||
if (SYNA_COUNTRY_TYPE_QTY <= type) {
|
||||
return BCME_BADARG;
|
||||
} else if ((next = list_str) == NULL) {
|
||||
return BCME_BADARG;
|
||||
}
|
||||
|
||||
while ((len = strcspn(next, " ,")) > 0) {
|
||||
if (len >= WLC_CNTRY_BUF_SZ) {
|
||||
DHD_ERROR(("%s: string '%s' before ',' or ' ' is too long\n",
|
||||
__FUNCTION__, next));
|
||||
return BCME_ERROR;
|
||||
}
|
||||
|
||||
n = syna_country_flag_find(next);
|
||||
if (0 > n) {
|
||||
if (BCME_NOTFOUND == n) {
|
||||
if (MAX_COUNTRY_LIST <= (1 + gSyna_country_flag_qty)) {
|
||||
DHD_ERROR(("%s: too many ccode(max=%d) list: '%s'\n",
|
||||
__FUNCTION__, MAX_COUNTRY_LIST, list_str));
|
||||
break;
|
||||
} else {
|
||||
/* adopt this new item */
|
||||
n = gSyna_country_flag_qty;
|
||||
gSyna_country_flag_qty++;
|
||||
}
|
||||
} else {
|
||||
DHD_ERROR(("%s: skip this invalid item '%s', err=%d\n",
|
||||
__FUNCTION__, next, n));
|
||||
}
|
||||
}
|
||||
|
||||
if (0 <= n) {
|
||||
/* update or add a new item */
|
||||
syna_cntry_flag[n].type = type;
|
||||
strlcpy(syna_cntry_flag[n].ccode, next, WLC_CNTRY_BUF_SZ);
|
||||
syna_cntry_flag[n].ccode[len] = '\0';
|
||||
DHD_TRACE(("%s: cntry list [%d] type=%d ccode=%s\n",
|
||||
__FUNCTION__, n,
|
||||
syna_cntry_flag[n].type, syna_cntry_flag[n].ccode));
|
||||
|
||||
/* fill with a new blank item as terminate */
|
||||
if ((gSyna_country_flag_qty == (n + 1)) &&
|
||||
(MAX_COUNTRY_LIST > gSyna_country_flag_qty)) {
|
||||
syna_cntry_flag[n+1].type = SYNA_COUNTRY_TYPE_INVALID;
|
||||
syna_cntry_flag[n+1].ccode[0] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
next += len;
|
||||
next += strspn(next, " ,");
|
||||
}
|
||||
|
||||
return BCME_OK;
|
||||
}
|
||||
#endif /* SYNA_SAR_CUSTOMER_PARAMETER */
|
||||
|
||||
/* Customized Locale table : OPTIONAL feature */
|
||||
const struct cntry_locales_custom translate_custom_table[] = {
|
||||
/* Table should be filled out based on custom platform regulatory requirement */
|
||||
|
|
@ -179,7 +368,7 @@ const struct cntry_locales_custom translate_custom_table[] = {
|
|||
{"TR", "TR", 0},
|
||||
{"NO", "NO", 0},
|
||||
#endif /* EXMAPLE_TABLE */
|
||||
#if (defined(CUSTOMER_HW2) || defined(BOARD_HIKEY)) && !defined(CUSTOMER_HW5)
|
||||
#if defined(BOARD_HIKEY)
|
||||
#if defined(BCM4335_CHIP)
|
||||
{"", "XZ", 11}, /* Universal if Country code is unknown or empty */
|
||||
#endif
|
||||
|
|
@ -236,142 +425,7 @@ const struct cntry_locales_custom translate_custom_table[] = {
|
|||
{"PS", "XZ", 11}, /* Universal if Country code is PALESTINIAN TERRITORY, OCCUPIED */
|
||||
{"TL", "XZ", 11}, /* Universal if Country code is TIMOR-LESTE (EAST TIMOR) */
|
||||
{"MH", "XZ", 11}, /* Universal if Country code is MARSHALL ISLANDS */
|
||||
#elif defined(CUSTOMER_HW5)
|
||||
{"", "XZ", 11},
|
||||
{"AE", "AE", 212},
|
||||
{"AG", "AG", 2},
|
||||
{"AI", "AI", 2},
|
||||
{"AL", "AL", 2},
|
||||
{"AN", "AN", 3},
|
||||
{"AR", "AR", 212},
|
||||
{"AS", "AS", 15},
|
||||
{"AT", "AT", 4},
|
||||
{"AU", "AU", 212},
|
||||
{"AW", "AW", 2},
|
||||
{"AZ", "AZ", 2},
|
||||
{"BA", "BA", 2},
|
||||
{"BD", "BD", 2},
|
||||
{"BE", "BE", 4},
|
||||
{"BG", "BG", 4},
|
||||
{"BH", "BH", 4},
|
||||
{"BM", "BM", 15},
|
||||
{"BN", "BN", 4},
|
||||
{"BR", "BR", 212},
|
||||
{"BS", "BS", 2},
|
||||
{"BY", "BY", 3},
|
||||
{"BW", "BW", 1},
|
||||
{"CA", "CA", 212},
|
||||
{"CH", "CH", 212},
|
||||
{"CL", "CL", 212},
|
||||
{"CN", "CN", 212},
|
||||
{"CO", "CO", 212},
|
||||
{"CR", "CR", 21},
|
||||
{"CY", "CY", 212},
|
||||
{"CZ", "CZ", 212},
|
||||
{"DE", "DE", 212},
|
||||
{"DK", "DK", 4},
|
||||
{"DZ", "DZ", 1},
|
||||
{"EC", "EC", 23},
|
||||
{"EE", "EE", 4},
|
||||
{"EG", "EG", 212},
|
||||
{"ES", "ES", 212},
|
||||
{"ET", "ET", 2},
|
||||
{"FI", "FI", 4},
|
||||
{"FR", "FR", 212},
|
||||
{"GB", "GB", 212},
|
||||
{"GD", "GD", 2},
|
||||
{"GF", "GF", 2},
|
||||
{"GP", "GP", 2},
|
||||
{"GR", "GR", 212},
|
||||
{"GT", "GT", 0},
|
||||
{"GU", "GU", 17},
|
||||
{"HK", "HK", 212},
|
||||
{"HR", "HR", 4},
|
||||
{"HU", "HU", 4},
|
||||
{"IN", "IN", 212},
|
||||
{"ID", "ID", 212},
|
||||
{"IE", "IE", 5},
|
||||
{"IL", "IL", 7},
|
||||
{"IN", "IN", 212},
|
||||
{"IS", "IS", 4},
|
||||
{"IT", "IT", 212},
|
||||
{"JO", "JO", 3},
|
||||
{"JP", "JP", 212},
|
||||
{"KH", "KH", 4},
|
||||
{"KI", "KI", 1},
|
||||
{"KR", "KR", 212},
|
||||
{"KW", "KW", 5},
|
||||
{"KY", "KY", 4},
|
||||
{"KZ", "KZ", 212},
|
||||
{"LA", "LA", 4},
|
||||
{"LB", "LB", 6},
|
||||
{"LI", "LI", 4},
|
||||
{"LK", "LK", 3},
|
||||
{"LS", "LS", 2},
|
||||
{"LT", "LT", 4},
|
||||
{"LR", "LR", 2},
|
||||
{"LU", "LU", 3},
|
||||
{"LV", "LV", 4},
|
||||
{"MA", "MA", 2},
|
||||
{"MC", "MC", 1},
|
||||
{"MD", "MD", 2},
|
||||
{"ME", "ME", 2},
|
||||
{"MK", "MK", 2},
|
||||
{"MN", "MN", 0},
|
||||
{"MO", "MO", 2},
|
||||
{"MR", "MR", 2},
|
||||
{"MT", "MT", 4},
|
||||
{"MQ", "MQ", 2},
|
||||
{"MU", "MU", 2},
|
||||
{"MV", "MV", 3},
|
||||
{"MX", "MX", 212},
|
||||
{"MY", "MY", 212},
|
||||
{"NI", "NI", 0},
|
||||
{"NL", "NL", 212},
|
||||
{"NO", "NO", 4},
|
||||
{"NP", "NP", 3},
|
||||
{"NZ", "NZ", 9},
|
||||
{"OM", "OM", 4},
|
||||
{"PA", "PA", 17},
|
||||
{"PE", "PE", 212},
|
||||
{"PG", "PG", 2},
|
||||
{"PH", "PH", 212},
|
||||
{"PL", "PL", 212},
|
||||
{"PR", "PR", 25},
|
||||
{"PT", "PT", 212},
|
||||
{"PY", "PY", 4},
|
||||
{"RE", "RE", 2},
|
||||
{"RO", "RO", 212},
|
||||
{"RS", "RS", 2},
|
||||
{"RU", "RU", 212},
|
||||
{"SA", "SA", 212},
|
||||
{"SE", "SE", 212},
|
||||
{"SG", "SG", 212},
|
||||
{"SI", "SI", 4},
|
||||
{"SK", "SK", 212},
|
||||
{"SN", "SN", 2},
|
||||
{"SV", "SV", 25},
|
||||
{"TH", "TH", 212},
|
||||
{"TR", "TR", 212},
|
||||
{"TT", "TT", 5},
|
||||
{"TW", "TW", 212},
|
||||
{"UA", "UA", 212},
|
||||
{"UG", "UG", 2},
|
||||
{"US", "US", 212},
|
||||
{"UY", "UY", 5},
|
||||
{"VA", "VA", 2},
|
||||
{"VE", "VE", 3},
|
||||
{"VG", "VG", 2},
|
||||
{"VI", "VI", 18},
|
||||
{"VN", "VN", 4},
|
||||
{"YT", "YT", 2},
|
||||
{"ZA", "ZA", 212},
|
||||
{"ZM", "ZM", 2},
|
||||
{"XT", "XT", 212},
|
||||
{"XZ", "XZ", 11},
|
||||
{"XV", "XV", 17},
|
||||
{"Q1", "Q1", 77},
|
||||
#endif /* (CUSTOMER_HW2 || BOARD_HIKEY) && CUSTOMER_HW5 */
|
||||
#endif /* BOARD_HIKEY */
|
||||
};
|
||||
|
||||
/* Customized Locale convertor
|
||||
|
|
@ -434,4 +488,3 @@ get_customized_country_code(void *adapter, char *country_iso_code, wl_country_t
|
|||
*/
|
||||
#endif /* OEM_ANDROID */
|
||||
}
|
||||
#endif /* !CUSTOMER_HW4 */
|
||||
|
|
|
|||
90
drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_custom_hikey.c
Executable file → Normal file
90
drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_custom_hikey.c
Executable file → Normal file
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* Platform Dependent file for Hikey
|
||||
*
|
||||
* Copyright (C) 2020, Broadcom.
|
||||
* Copyright (C) 2022, Broadcom.
|
||||
*
|
||||
* Unless you and Broadcom execute a separate written software license
|
||||
* agreement governing use of this software, this software is licensed to you
|
||||
|
|
@ -47,6 +47,9 @@ extern int dhd_init_wlan_mem(void);
|
|||
extern void *dhd_wlan_mem_prealloc(int section, unsigned long size);
|
||||
#endif /* CONFIG_BROADCOM_WIFI_RESERVED_MEM */
|
||||
|
||||
#define HIKEY_PCIE_VENDOR_ID 0x19e5
|
||||
#define HIKEY_PCIE_DEVICE_ID 0x3660
|
||||
|
||||
#define WLAN_REG_ON_GPIO 491
|
||||
#define WLAN_HOST_WAKE_GPIO 493
|
||||
|
||||
|
|
@ -58,6 +61,30 @@ static int wlan_host_wake_up = -1;
|
|||
static int wlan_host_wake_irq = 0;
|
||||
#define WIFI_WLAN_HOST_WAKE_PROPNAME "wl_host_wake"
|
||||
|
||||
extern void kirin_pcie_power_on_atu_fixup(void) __attribute__ ((weak));
|
||||
extern int kirin_pcie_lp_ctrl(u32 enable) __attribute__ ((weak));
|
||||
|
||||
void
|
||||
dhd_wifi_deinit_gpio(void)
|
||||
{
|
||||
/* Disable ASPM before powering off */
|
||||
if (kirin_pcie_lp_ctrl) {
|
||||
kirin_pcie_lp_ctrl(0);
|
||||
} else {
|
||||
DHD_ERROR(("[%s] kirin_pcie_lp_ctrl is NULL. "
|
||||
"ASPM may not work\n", __func__));
|
||||
}
|
||||
if (gpio_direction_output(wlan_reg_on, 0)) {
|
||||
DHD_ERROR(("%s: WL_REG_ON is failed to pull up\n", __FUNCTION__));
|
||||
}
|
||||
if (gpio_get_value(wlan_reg_on)) {
|
||||
DHD_INFO(("WL_REG_ON on-step-2 : [%d]\n",
|
||||
gpio_get_value(wlan_reg_on)));
|
||||
}
|
||||
gpio_free(wlan_host_wake_up);
|
||||
gpio_free(wlan_reg_on);
|
||||
}
|
||||
|
||||
int
|
||||
dhd_wifi_init_gpio(void)
|
||||
{
|
||||
|
|
@ -83,7 +110,7 @@ dhd_wifi_init_gpio(void)
|
|||
* For reg_on, gpio_request will fail if the gpio is configured to output-high
|
||||
* in the dts using gpio-hog, so do not return error for failure.
|
||||
*/
|
||||
if (gpio_request_one(wlan_reg_on, GPIOF_OUT_INIT_HIGH, "WL_REG_ON")) {
|
||||
if (gpio_request_one(wlan_reg_on, GPIOF_DIR_OUT, "WL_REG_ON")) {
|
||||
DHD_ERROR(("%s: Failed to request gpio %d for WL_REG_ON, "
|
||||
"might have configured in the dts\n",
|
||||
__FUNCTION__, wlan_reg_on));
|
||||
|
|
@ -93,7 +120,7 @@ dhd_wifi_init_gpio(void)
|
|||
}
|
||||
|
||||
gpio_reg_on_val = gpio_get_value(wlan_reg_on);
|
||||
DHD_INFO(("%s: Initial WL_REG_ON: [%d]\n",
|
||||
DHD_ERROR(("%s: Initial WL_REG_ON: [%d]\n",
|
||||
__FUNCTION__, gpio_get_value(wlan_reg_on)));
|
||||
|
||||
if (gpio_reg_on_val == 0) {
|
||||
|
|
@ -102,10 +129,27 @@ dhd_wifi_init_gpio(void)
|
|||
DHD_ERROR(("%s: WL_REG_ON is failed to pull up\n", __FUNCTION__));
|
||||
return -EIO;
|
||||
}
|
||||
}
|
||||
/* Wait for WIFI_TURNON_DELAY due to power stability */
|
||||
msleep(WIFI_TURNON_DELAY);
|
||||
|
||||
/* Wait for WIFI_TURNON_DELAY due to power stability */
|
||||
msleep(WIFI_TURNON_DELAY);
|
||||
/*
|
||||
* Call Kiric RC ATU fixup else si_attach will fail due to
|
||||
* improper BAR0/1 address translations
|
||||
*/
|
||||
if (kirin_pcie_power_on_atu_fixup) {
|
||||
kirin_pcie_power_on_atu_fixup();
|
||||
} else {
|
||||
DHD_ERROR(("[%s] kirin_pcie_power_on_atu_fixup is NULL. "
|
||||
"REG_ON may not work\n", __func__));
|
||||
}
|
||||
/* Enable ASPM after powering ON */
|
||||
if (kirin_pcie_lp_ctrl) {
|
||||
kirin_pcie_lp_ctrl(1);
|
||||
} else {
|
||||
DHD_ERROR(("[%s] kirin_pcie_lp_ctrl is NULL. "
|
||||
"ASPM may not work\n", __func__));
|
||||
}
|
||||
}
|
||||
|
||||
/* ========== WLAN_HOST_WAKE ============ */
|
||||
DHD_INFO(("%s: gpio_wlan_host_wake : %d\n", __FUNCTION__, wlan_host_wake_up));
|
||||
|
|
@ -130,9 +174,6 @@ dhd_wifi_init_gpio(void)
|
|||
return 0;
|
||||
}
|
||||
|
||||
extern void kirin_pcie_power_on_atu_fixup(void) __attribute__ ((weak));
|
||||
extern int kirin_pcie_lp_ctrl(u32 enable) __attribute__ ((weak));
|
||||
|
||||
int
|
||||
dhd_wlan_power(int onoff)
|
||||
{
|
||||
|
|
@ -254,6 +295,15 @@ dhd_wlan_init(void)
|
|||
int ret;
|
||||
|
||||
DHD_INFO(("%s: START.......\n", __FUNCTION__));
|
||||
#ifdef CONFIG_BROADCOM_WIFI_RESERVED_MEM
|
||||
ret = dhd_init_wlan_mem();
|
||||
if (ret < 0) {
|
||||
DHD_ERROR(("%s: failed to alloc reserved memory,"
|
||||
" ret=%d\n", __FUNCTION__, ret));
|
||||
goto fail;
|
||||
}
|
||||
#endif /* CONFIG_BROADCOM_WIFI_RESERVED_MEM */
|
||||
|
||||
ret = dhd_wifi_init_gpio();
|
||||
if (ret < 0) {
|
||||
DHD_ERROR(("%s: failed to initiate GPIO, ret=%d\n",
|
||||
|
|
@ -264,14 +314,6 @@ dhd_wlan_init(void)
|
|||
dhd_wlan_resources.start = wlan_host_wake_irq;
|
||||
dhd_wlan_resources.end = wlan_host_wake_irq;
|
||||
|
||||
#ifdef CONFIG_BROADCOM_WIFI_RESERVED_MEM
|
||||
ret = dhd_init_wlan_mem();
|
||||
if (ret < 0) {
|
||||
DHD_ERROR(("%s: failed to alloc reserved memory,"
|
||||
" ret=%d\n", __FUNCTION__, ret));
|
||||
}
|
||||
#endif /* CONFIG_BROADCOM_WIFI_RESERVED_MEM */
|
||||
|
||||
fail:
|
||||
DHD_INFO(("%s: FINISH.......\n", __FUNCTION__));
|
||||
return ret;
|
||||
|
|
@ -280,10 +322,20 @@ fail:
|
|||
int
|
||||
dhd_wlan_deinit(void)
|
||||
{
|
||||
gpio_free(wlan_host_wake_up);
|
||||
gpio_free(wlan_reg_on);
|
||||
dhd_wifi_deinit_gpio();
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32 dhd_plat_get_rc_vendor_id(void)
|
||||
{
|
||||
return HIKEY_PCIE_VENDOR_ID;
|
||||
}
|
||||
|
||||
uint32 dhd_plat_get_rc_device_id(void)
|
||||
{
|
||||
return HIKEY_PCIE_DEVICE_ID;
|
||||
}
|
||||
|
||||
#ifndef BCMDHD_MODULAR
|
||||
/* Required only for Built-in DHD */
|
||||
device_initcall(dhd_wlan_init);
|
||||
|
|
|
|||
174
drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_custom_memprealloc.c
Executable file → Normal file
174
drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_custom_memprealloc.c
Executable file → Normal file
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* Platform Dependent file for usage of Preallocted Memory
|
||||
*
|
||||
* Copyright (C) 2020, Broadcom.
|
||||
* Copyright (C) 2022, Broadcom.
|
||||
*
|
||||
* Unless you and Broadcom execute a separate written software license
|
||||
* agreement governing use of this software, this software is licensed to you
|
||||
|
|
@ -38,7 +38,7 @@
|
|||
#include <linux/init.h>
|
||||
|
||||
#ifdef CONFIG_BROADCOM_WIFI_RESERVED_MEM
|
||||
|
||||
/* Please refer to 'enum dhd_prealloc_index' in dhd.h */
|
||||
#define WLAN_STATIC_SCAN_BUF0 5
|
||||
#define WLAN_STATIC_SCAN_BUF1 6
|
||||
#define WLAN_STATIC_DHD_INFO_BUF 7
|
||||
|
|
@ -46,11 +46,11 @@
|
|||
#define WLAN_STATIC_DHD_IF_FLOW_LKUP 9
|
||||
#define WLAN_STATIC_DHD_MEMDUMP_RAM 11
|
||||
#define WLAN_STATIC_DHD_WLFC_HANGER 12
|
||||
#define WLAN_STATIC_DHD_PKTID_MAP 13
|
||||
#define WLAN_STATIC_DHD_PKTID_IOCTL_MAP 14
|
||||
#define WLAN_STATIC_DHD_PKTID_MAP 13 /* Deprecated */
|
||||
#define WLAN_STATIC_DHD_PKTID_IOCTL_MAP 14 /* Deprecated */
|
||||
#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_DHD_PKTLOG_DUMP_BUF 17 /* Deprecated */
|
||||
|
||||
#define WLAN_SCAN_BUF_SIZE (64 * 1024)
|
||||
|
||||
|
|
@ -112,7 +112,7 @@
|
|||
((WLAN_MAX_PKTID_IOCTL_ITEMS+1) * WLAN_DHD_PKTID_IOCTL_MAP_ITEM_SIZE))
|
||||
|
||||
#define DHD_LOG_DUMP_BUF_SIZE (1024 * 1024 * 4)
|
||||
#define DHD_LOG_DUMP_BUF_EX_SIZE (1024 * 1024 * 2)
|
||||
#define DHD_LOG_DUMP_BUF_EX_SIZE (1024 * 8)
|
||||
|
||||
#define DHD_PKTLOG_DUMP_BUF_SIZE (64 * 1024)
|
||||
|
||||
|
|
@ -138,15 +138,17 @@ static struct wlan_mem_prealloc wlan_mem_array[PREALLOC_WLAN_SEC_NUM] = {
|
|||
static void *wlan_static_scan_buf0 = NULL;
|
||||
static void *wlan_static_scan_buf1 = NULL;
|
||||
static void *wlan_static_dhd_info_buf = NULL;
|
||||
static void *wlan_static_dhd_wlfc_buf = NULL;
|
||||
#ifdef CONFIG_BCMDHD_PCIE
|
||||
static void *wlan_static_if_flow_lkup = NULL;
|
||||
static void *wlan_static_dhd_memdump_ram = NULL;
|
||||
#else
|
||||
static void *wlan_static_dhd_wlfc_buf = NULL;
|
||||
static void *wlan_static_dhd_wlfc_hanger = NULL;
|
||||
static void *wlan_static_dhd_pktid_map = NULL;
|
||||
static void *wlan_static_dhd_pktid_ioctl_map = NULL;
|
||||
#endif /* CONFIG_BCMDHD_PCIE */
|
||||
#ifdef CONFIG_BCMDHD_PREALLOC_MEMDUMP
|
||||
static void *wlan_static_dhd_memdump_ram = NULL;
|
||||
#endif /* #ifdef CONFIG_BCMDHD_PREALLOC_MEMDUMP */
|
||||
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;
|
||||
|
||||
void dhd_exit_wlan_mem(void);
|
||||
|
||||
|
|
@ -174,7 +176,17 @@ void
|
|||
}
|
||||
return wlan_static_dhd_info_buf;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_BCMDHD_PCIE
|
||||
if (section == WLAN_STATIC_DHD_IF_FLOW_LKUP) {
|
||||
if (size > WLAN_DHD_IF_FLOW_LKUP_SIZE) {
|
||||
pr_err("request DHD_WLFC size(%lu) is bigger than"
|
||||
" static size(%d).\n",
|
||||
size, WLAN_DHD_WLFC_BUF_SIZE);
|
||||
return NULL;
|
||||
}
|
||||
return wlan_static_if_flow_lkup;
|
||||
}
|
||||
#else
|
||||
if (section == WLAN_STATIC_DHD_WLFC_BUF) {
|
||||
if (size > WLAN_DHD_WLFC_BUF_SIZE) {
|
||||
pr_err("request DHD_WLFC size(%lu) is bigger than"
|
||||
|
|
@ -194,17 +206,8 @@ void
|
|||
}
|
||||
return wlan_static_dhd_wlfc_hanger;
|
||||
}
|
||||
|
||||
if (section == WLAN_STATIC_DHD_IF_FLOW_LKUP) {
|
||||
if (size > WLAN_DHD_IF_FLOW_LKUP_SIZE) {
|
||||
pr_err("request DHD_WLFC size(%lu) is bigger than"
|
||||
" static size(%d).\n",
|
||||
size, WLAN_DHD_WLFC_BUF_SIZE);
|
||||
return NULL;
|
||||
}
|
||||
return wlan_static_if_flow_lkup;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_BCMDHD_PCIE */
|
||||
#ifdef CONFIG_BCMDHD_PREALLOC_MEMDUMP
|
||||
if (section == WLAN_STATIC_DHD_MEMDUMP_RAM) {
|
||||
if (size > WLAN_DHD_MEMDUMP_SIZE) {
|
||||
pr_err("request DHD_MEMDUMP_RAM size(%lu) is bigger"
|
||||
|
|
@ -214,27 +217,7 @@ void
|
|||
}
|
||||
return wlan_static_dhd_memdump_ram;
|
||||
}
|
||||
|
||||
if (section == WLAN_STATIC_DHD_PKTID_MAP) {
|
||||
if (size > WLAN_DHD_PKTID_MAP_SIZE) {
|
||||
pr_err("request DHD_PKTID_MAP size(%lu) is bigger than"
|
||||
" static size(%d).\n",
|
||||
size, WLAN_DHD_PKTID_MAP_SIZE);
|
||||
return NULL;
|
||||
}
|
||||
return wlan_static_dhd_pktid_map;
|
||||
}
|
||||
|
||||
if (section == WLAN_STATIC_DHD_PKTID_IOCTL_MAP) {
|
||||
if (size > WLAN_DHD_PKTID_IOCTL_MAP_SIZE) {
|
||||
pr_err("request DHD_PKTID_IOCTL_MAP size(%lu) is bigger than"
|
||||
" static size(%d).\n",
|
||||
size, WLAN_DHD_PKTID_IOCTL_MAP_SIZE);
|
||||
return NULL;
|
||||
}
|
||||
return wlan_static_dhd_pktid_ioctl_map;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_BCMDHD_PREALLOC_MEMDUMP */
|
||||
if (section == WLAN_STATIC_DHD_LOG_DUMP_BUF) {
|
||||
if (size > DHD_LOG_DUMP_BUF_SIZE) {
|
||||
pr_err("request DHD_LOG_DUMP_BUF size(%lu) is bigger then"
|
||||
|
|
@ -255,16 +238,6 @@ void
|
|||
return wlan_static_dhd_log_dump_buf_ex;
|
||||
}
|
||||
|
||||
if (section == WLAN_STATIC_DHD_PKTLOG_DUMP_BUF) {
|
||||
if (size > DHD_PKTLOG_DUMP_BUF_SIZE) {
|
||||
pr_err("request DHD_PKTLOG_DUMP_BUF size(%lu) is bigger then"
|
||||
" static size(%d).\n",
|
||||
size, DHD_PKTLOG_DUMP_BUF_SIZE);
|
||||
return NULL;
|
||||
}
|
||||
return wlan_static_dhd_pktlog_dump_buf;
|
||||
}
|
||||
|
||||
if ((section < 0) || (section >= PREALLOC_WLAN_SEC_NUM)) {
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -277,6 +250,13 @@ void
|
|||
}
|
||||
EXPORT_SYMBOL(dhd_wlan_mem_prealloc);
|
||||
|
||||
#ifdef DHD_DUMP_BUF_KVMALLOC
|
||||
#define DUMP_BUF_MALLOC(size) kvmalloc(size, GFP_KERNEL)
|
||||
#define DUMP_BUF_MFREE(addr) kvfree(addr)
|
||||
#else
|
||||
#define DUMP_BUF_MALLOC(size) kmalloc(size, GFP_KERNEL)
|
||||
#define DUMP_BUF_MFREE(addr) kfree(addr)
|
||||
#endif /* DHD_DUMP_BUF_KVMALLOC */
|
||||
int
|
||||
dhd_init_wlan_mem(void)
|
||||
{
|
||||
|
|
@ -311,8 +291,13 @@ dhd_init_wlan_mem(void)
|
|||
|
||||
for (i = 0; i < PREALLOC_WLAN_SEC_NUM; i++) {
|
||||
if (wlan_mem_array[i].size > 0) {
|
||||
#ifdef CONFIG_BCMDHD_PCIE
|
||||
wlan_mem_array[i].mem_ptr =
|
||||
kvmalloc(wlan_mem_array[i].size, GFP_KERNEL);
|
||||
#else
|
||||
wlan_mem_array[i].mem_ptr =
|
||||
kmalloc(wlan_mem_array[i].size, GFP_KERNEL);
|
||||
#endif /* CONFIG_BCMDHD_PCIE */
|
||||
|
||||
if (!wlan_mem_array[i].mem_ptr) {
|
||||
pr_err("Failed to mem_alloc for WLAN\n");
|
||||
|
|
@ -321,59 +306,55 @@ dhd_init_wlan_mem(void)
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef CONFIG_BCMDHD_PCIE
|
||||
wlan_static_scan_buf0 = kvmalloc(WLAN_SCAN_BUF_SIZE, GFP_KERNEL);
|
||||
#else
|
||||
wlan_static_scan_buf0 = kmalloc(WLAN_SCAN_BUF_SIZE, GFP_KERNEL);
|
||||
#endif /* CONFIG_BCMDHD_PCIE */
|
||||
if (!wlan_static_scan_buf0) {
|
||||
pr_err("Failed to alloc wlan_static_scan_buf0\n");
|
||||
goto err_mem_alloc;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_BCMDHD_PCIE
|
||||
wlan_static_scan_buf1 = kvmalloc(WLAN_SCAN_BUF_SIZE, GFP_KERNEL);
|
||||
#else
|
||||
wlan_static_scan_buf1 = kmalloc(WLAN_SCAN_BUF_SIZE, GFP_KERNEL);
|
||||
#endif /* CONFIG_BCMDHD_PCIE */
|
||||
if (!wlan_static_scan_buf1) {
|
||||
pr_err("Failed to alloc wlan_static_scan_buf1\n");
|
||||
goto err_mem_alloc;
|
||||
}
|
||||
|
||||
wlan_static_dhd_log_dump_buf = kmalloc(DHD_LOG_DUMP_BUF_SIZE, GFP_KERNEL);
|
||||
wlan_static_dhd_log_dump_buf = DUMP_BUF_MALLOC(DHD_LOG_DUMP_BUF_SIZE);
|
||||
if (!wlan_static_dhd_log_dump_buf) {
|
||||
pr_err("Failed to alloc wlan_static_dhd_log_dump_buf\n");
|
||||
goto err_mem_alloc;
|
||||
}
|
||||
|
||||
wlan_static_dhd_log_dump_buf_ex = kmalloc(DHD_LOG_DUMP_BUF_EX_SIZE, GFP_KERNEL);
|
||||
wlan_static_dhd_log_dump_buf_ex = DUMP_BUF_MALLOC(DHD_LOG_DUMP_BUF_EX_SIZE);
|
||||
if (!wlan_static_dhd_log_dump_buf_ex) {
|
||||
pr_err("Failed to alloc wlan_static_dhd_log_dump_buf_ex\n");
|
||||
goto err_mem_alloc;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_BCMDHD_PCIE
|
||||
wlan_static_dhd_info_buf = kvmalloc(WLAN_DHD_INFO_BUF_SIZE, GFP_KERNEL);
|
||||
#else
|
||||
wlan_static_dhd_info_buf = kmalloc(WLAN_DHD_INFO_BUF_SIZE, GFP_KERNEL);
|
||||
#endif /* CONFIG_BCMDHD_PCIE */
|
||||
if (!wlan_static_dhd_info_buf) {
|
||||
pr_err("Failed to alloc wlan_static_dhd_info_buf\n");
|
||||
goto err_mem_alloc;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_BCMDHD_PCIE
|
||||
wlan_static_if_flow_lkup = kmalloc(WLAN_DHD_IF_FLOW_LKUP_SIZE,
|
||||
wlan_static_if_flow_lkup = kvmalloc(WLAN_DHD_IF_FLOW_LKUP_SIZE,
|
||||
GFP_KERNEL);
|
||||
if (!wlan_static_if_flow_lkup) {
|
||||
pr_err("Failed to alloc wlan_static_if_flow_lkup\n");
|
||||
goto err_mem_alloc;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_BCMDHD_PREALLOC_PKTIDMAP
|
||||
wlan_static_dhd_pktid_map = kmalloc(WLAN_DHD_PKTID_MAP_SIZE,
|
||||
GFP_KERNEL);
|
||||
if (!wlan_static_dhd_pktid_map) {
|
||||
pr_err("Failed to alloc wlan_static_dhd_pktid_map\n");
|
||||
goto err_mem_alloc;
|
||||
}
|
||||
|
||||
wlan_static_dhd_pktid_ioctl_map = kmalloc(WLAN_DHD_PKTID_IOCTL_MAP_SIZE,
|
||||
GFP_KERNEL);
|
||||
if (!wlan_static_dhd_pktid_ioctl_map) {
|
||||
pr_err("Failed to alloc wlan_static_dhd_pktid_ioctl_map\n");
|
||||
goto err_mem_alloc;
|
||||
}
|
||||
#endif /* CONFIG_BCMDHD_PREALLOC_PKTIDMAP */
|
||||
#else
|
||||
wlan_static_dhd_wlfc_buf = kmalloc(WLAN_DHD_WLFC_BUF_SIZE,
|
||||
GFP_KERNEL);
|
||||
|
|
@ -391,19 +372,13 @@ dhd_init_wlan_mem(void)
|
|||
#endif /* CONFIG_BCMDHD_PCIE */
|
||||
|
||||
#ifdef CONFIG_BCMDHD_PREALLOC_MEMDUMP
|
||||
wlan_static_dhd_memdump_ram = kmalloc(WLAN_DHD_MEMDUMP_SIZE, GFP_KERNEL);
|
||||
wlan_static_dhd_memdump_ram = DUMP_BUF_MALLOC(WLAN_DHD_MEMDUMP_SIZE);
|
||||
if (!wlan_static_dhd_memdump_ram) {
|
||||
pr_err("Failed to alloc wlan_static_dhd_memdump_ram\n");
|
||||
goto err_mem_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;
|
||||
}
|
||||
|
||||
pr_err("%s: WIFI MEM Allocated\n", __FUNCTION__);
|
||||
return 0;
|
||||
|
||||
|
|
@ -432,25 +407,14 @@ dhd_exit_wlan_mem(void)
|
|||
|
||||
#ifdef CONFIG_BCMDHD_PREALLOC_MEMDUMP
|
||||
if (wlan_static_dhd_memdump_ram) {
|
||||
kfree(wlan_static_dhd_memdump_ram);
|
||||
DUMP_BUF_MFREE(wlan_static_dhd_memdump_ram);
|
||||
}
|
||||
|
||||
#endif /* CONFIG_BCMDHD_PREALLOC_MEMDUMP */
|
||||
|
||||
#ifdef CONFIG_BCMDHD_PCIE
|
||||
if (wlan_static_if_flow_lkup) {
|
||||
kfree(wlan_static_if_flow_lkup);
|
||||
kvfree(wlan_static_if_flow_lkup);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_BCMDHD_PREALLOC_PKTIDMAP
|
||||
if (wlan_static_dhd_pktid_map) {
|
||||
kfree(wlan_static_dhd_pktid_map);
|
||||
}
|
||||
|
||||
if (wlan_static_dhd_pktid_ioctl_map) {
|
||||
kfree(wlan_static_dhd_pktid_ioctl_map);
|
||||
}
|
||||
#endif /* CONFIG_BCMDHD_PREALLOC_PKTIDMAP */
|
||||
#else
|
||||
if (wlan_static_dhd_wlfc_buf) {
|
||||
kfree(wlan_static_dhd_wlfc_buf);
|
||||
|
|
@ -461,32 +425,44 @@ dhd_exit_wlan_mem(void)
|
|||
}
|
||||
#endif /* CONFIG_BCMDHD_PCIE */
|
||||
if (wlan_static_dhd_info_buf) {
|
||||
#ifdef CONFIG_BCMDHD_PCIE
|
||||
kvfree(wlan_static_dhd_info_buf);
|
||||
#else
|
||||
kfree(wlan_static_dhd_info_buf);
|
||||
#endif /* CONFIG_BCMDHD_PCIE */
|
||||
}
|
||||
|
||||
if (wlan_static_dhd_log_dump_buf) {
|
||||
kfree(wlan_static_dhd_log_dump_buf);
|
||||
DUMP_BUF_MFREE(wlan_static_dhd_log_dump_buf);
|
||||
}
|
||||
|
||||
if (wlan_static_dhd_log_dump_buf_ex) {
|
||||
kfree(wlan_static_dhd_log_dump_buf_ex);
|
||||
DUMP_BUF_MFREE(wlan_static_dhd_log_dump_buf_ex);
|
||||
}
|
||||
|
||||
if (wlan_static_scan_buf1) {
|
||||
#ifdef CONFIG_BCMDHD_PCIE
|
||||
kvfree(wlan_static_scan_buf1);
|
||||
#else
|
||||
kfree(wlan_static_scan_buf1);
|
||||
#endif /* CONFIG_BCMDHD_PCIE */
|
||||
}
|
||||
|
||||
if (wlan_static_scan_buf0) {
|
||||
#ifdef CONFIG_BCMDHD_PCIE
|
||||
kvfree(wlan_static_scan_buf0);
|
||||
#else
|
||||
kfree(wlan_static_scan_buf0);
|
||||
}
|
||||
|
||||
if (wlan_static_dhd_pktlog_dump_buf) {
|
||||
kfree(wlan_static_dhd_pktlog_dump_buf);
|
||||
#endif /* CONFIG_BCMDHD_PCIE */
|
||||
}
|
||||
|
||||
for (i = 0; i < PREALLOC_WLAN_SEC_NUM; i++) {
|
||||
if (wlan_mem_array[i].mem_ptr) {
|
||||
#ifdef CONFIG_BCMDHD_PCIE
|
||||
kvfree(wlan_mem_array[i].mem_ptr);
|
||||
#else
|
||||
kfree(wlan_mem_array[i].mem_ptr);
|
||||
#endif /* CONFIG_BCMDHD_PCIE */
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,283 +0,0 @@
|
|||
/*
|
||||
* Platform Dependent file for Qualcomm MSM/APQ
|
||||
*
|
||||
* Copyright (C) 2020, Broadcom.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*
|
||||
* <<Broadcom-WL-IPTag/Open:>>
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/skbuff.h>
|
||||
#include <linux/mmc/host.h>
|
||||
#ifdef CONFIG_BCMDHD_PCIE
|
||||
#include <linux/msm_pcie.h>
|
||||
#endif /* CONFIG_BCMDHD_PCIE */
|
||||
#include <linux/fcntl.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/of_gpio.h>
|
||||
#include <linux/wlan_plat.h>
|
||||
|
||||
#ifdef CONFIG_BROADCOM_WIFI_RESERVED_MEM
|
||||
extern void dhd_exit_wlan_mem(void);
|
||||
extern int dhd_init_wlan_mem(void);
|
||||
extern void *dhd_wlan_mem_prealloc(int section, unsigned long size);
|
||||
#endif /* CONFIG_BROADCOM_WIFI_RESERVED_MEM */
|
||||
|
||||
#define WIFI_TURNON_DELAY 200
|
||||
static int wlan_reg_on = -1;
|
||||
#define DHD_DT_COMPAT_ENTRY "android,bcmdhd_wlan"
|
||||
#ifdef CUSTOMER_HW2
|
||||
#define WIFI_WL_REG_ON_PROPNAME "wl_reg_on"
|
||||
#else
|
||||
#define WIFI_WL_REG_ON_PROPNAME "wlan-en-gpio"
|
||||
#endif /* CUSTOMER_HW2 */
|
||||
|
||||
#if defined(CONFIG_ARCH_MSM8996) || defined(CONFIG_ARCH_MSM8998) || \
|
||||
defined(CONFIG_ARCH_SDM845) || defined(CONFIG_ARCH_SM8150) || \
|
||||
defined(CONFIG_ARCH_KONA) || defined(CONFIG_ARCH_LAHAINA)
|
||||
#define MSM_PCIE_CH_NUM 0
|
||||
#else
|
||||
#define MSM_PCIE_CH_NUM 1
|
||||
#endif /* MSM PCIE Platforms */
|
||||
|
||||
#ifdef CONFIG_BCMDHD_OOB_HOST_WAKE
|
||||
static int wlan_host_wake_up = -1;
|
||||
static int wlan_host_wake_irq = 0;
|
||||
#ifdef CUSTOMER_HW2
|
||||
#define WIFI_WLAN_HOST_WAKE_PROPNAME "wl_host_wake"
|
||||
#else
|
||||
#define WIFI_WLAN_HOST_WAKE_PROPNAME "wlan-host-wake-gpio"
|
||||
#endif /* CUSTOMER_HW2 */
|
||||
#endif /* CONFIG_BCMDHD_OOB_HOST_WAKE */
|
||||
|
||||
int __init
|
||||
dhd_wifi_init_gpio(void)
|
||||
{
|
||||
char *wlan_node = DHD_DT_COMPAT_ENTRY;
|
||||
struct device_node *root_node = NULL;
|
||||
|
||||
root_node = of_find_compatible_node(NULL, NULL, wlan_node);
|
||||
if (!root_node) {
|
||||
WARN(1, "failed to get device node of BRCM WLAN\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
/* ========== WLAN_PWR_EN ============ */
|
||||
wlan_reg_on = of_get_named_gpio(root_node, WIFI_WL_REG_ON_PROPNAME, 0);
|
||||
printk(KERN_INFO "%s: gpio_wlan_power : %d\n", __FUNCTION__, wlan_reg_on);
|
||||
|
||||
if (gpio_request_one(wlan_reg_on, GPIOF_OUT_INIT_LOW, "WL_REG_ON")) {
|
||||
printk(KERN_ERR "%s: Faiiled to request gpio %d for WL_REG_ON\n",
|
||||
__FUNCTION__, wlan_reg_on);
|
||||
} else {
|
||||
printk(KERN_ERR "%s: gpio_request WL_REG_ON done - WLAN_EN: GPIO %d\n",
|
||||
__FUNCTION__, wlan_reg_on);
|
||||
}
|
||||
|
||||
if (gpio_direction_output(wlan_reg_on, 1)) {
|
||||
printk(KERN_ERR "%s: WL_REG_ON failed to pull up\n", __FUNCTION__);
|
||||
} else {
|
||||
printk(KERN_ERR "%s: WL_REG_ON is pulled up\n", __FUNCTION__);
|
||||
}
|
||||
|
||||
if (gpio_get_value(wlan_reg_on)) {
|
||||
printk(KERN_INFO "%s: Initial WL_REG_ON: [%d]\n",
|
||||
__FUNCTION__, gpio_get_value(wlan_reg_on));
|
||||
}
|
||||
|
||||
/* Wait for WIFI_TURNON_DELAY due to power stability */
|
||||
msleep(WIFI_TURNON_DELAY);
|
||||
|
||||
#ifdef CONFIG_BCMDHD_OOB_HOST_WAKE
|
||||
/* ========== WLAN_HOST_WAKE ============ */
|
||||
wlan_host_wake_up = of_get_named_gpio(root_node, WIFI_WLAN_HOST_WAKE_PROPNAME, 0);
|
||||
printk(KERN_INFO "%s: gpio_wlan_host_wake : %d\n", __FUNCTION__, wlan_host_wake_up);
|
||||
|
||||
#ifndef CUSTOMER_HW2
|
||||
if (gpio_request_one(wlan_host_wake_up, GPIOF_IN, "WLAN_HOST_WAKE")) {
|
||||
printk(KERN_ERR "%s: Faiiled to request gpio %d for WLAN_HOST_WAKE\n",
|
||||
__FUNCTION__, wlan_host_wake_up);
|
||||
return -ENODEV;
|
||||
} else {
|
||||
printk(KERN_ERR "%s: gpio_request WLAN_HOST_WAKE done"
|
||||
" - WLAN_HOST_WAKE: GPIO %d\n",
|
||||
__FUNCTION__, wlan_host_wake_up);
|
||||
}
|
||||
#endif /* !CUSTOMER_HW2 */
|
||||
|
||||
gpio_direction_input(wlan_host_wake_up);
|
||||
wlan_host_wake_irq = gpio_to_irq(wlan_host_wake_up);
|
||||
#endif /* CONFIG_BCMDHD_OOB_HOST_WAKE */
|
||||
|
||||
#ifdef CONFIG_BCMDHD_PCIE
|
||||
printk(KERN_INFO "%s: Call msm_pcie_enumerate\n", __FUNCTION__);
|
||||
msm_pcie_enumerate(MSM_PCIE_CH_NUM);
|
||||
#endif /* CONFIG_BCMDHD_PCIE */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
dhd_wlan_power(int onoff)
|
||||
{
|
||||
printk(KERN_INFO"%s Enter: power %s\n", __func__, onoff ? "on" : "off");
|
||||
|
||||
if (onoff) {
|
||||
if (gpio_direction_output(wlan_reg_on, 1)) {
|
||||
printk(KERN_ERR "%s: WL_REG_ON is failed to pull up\n", __FUNCTION__);
|
||||
return -EIO;
|
||||
}
|
||||
if (gpio_get_value(wlan_reg_on)) {
|
||||
printk(KERN_INFO"WL_REG_ON on-step-2 : [%d]\n",
|
||||
gpio_get_value(wlan_reg_on));
|
||||
} else {
|
||||
printk("[%s] gpio value is 0. We need reinit.\n", __func__);
|
||||
if (gpio_direction_output(wlan_reg_on, 1)) {
|
||||
printk(KERN_ERR "%s: WL_REG_ON is "
|
||||
"failed to pull up\n", __func__);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (gpio_direction_output(wlan_reg_on, 0)) {
|
||||
printk(KERN_ERR "%s: WL_REG_ON is failed to pull up\n", __FUNCTION__);
|
||||
return -EIO;
|
||||
}
|
||||
if (gpio_get_value(wlan_reg_on)) {
|
||||
printk(KERN_INFO"WL_REG_ON on-step-2 : [%d]\n",
|
||||
gpio_get_value(wlan_reg_on));
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(dhd_wlan_power);
|
||||
|
||||
static int
|
||||
dhd_wlan_reset(int onoff)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
dhd_wlan_set_carddetect(int val)
|
||||
{
|
||||
#ifdef CONFIG_BCMDHD_PCIE
|
||||
printk(KERN_INFO "%s: Call msm_pcie_enumerate\n", __FUNCTION__);
|
||||
msm_pcie_enumerate(MSM_PCIE_CH_NUM);
|
||||
#endif /* CONFIG_BCMDHD_PCIE */
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_BCMDHD_OOB_HOST_WAKE) && defined(CONFIG_BCMDHD_GET_OOB_STATE)
|
||||
int
|
||||
dhd_get_wlan_oob_gpio(void)
|
||||
{
|
||||
return gpio_is_valid(wlan_host_wake_up) ?
|
||||
gpio_get_value(wlan_host_wake_up) : -1;
|
||||
}
|
||||
EXPORT_SYMBOL(dhd_get_wlan_oob_gpio);
|
||||
#endif /* CONFIG_BCMDHD_OOB_HOST_WAKE && CONFIG_BCMDHD_GET_OOB_STATE */
|
||||
|
||||
struct resource dhd_wlan_resources = {
|
||||
.name = "bcmdhd_wlan_irq",
|
||||
.start = 0, /* Dummy */
|
||||
.end = 0, /* Dummy */
|
||||
.flags = IORESOURCE_IRQ | IORESOURCE_IRQ_SHAREABLE |
|
||||
#ifdef CONFIG_BCMDHD_PCIE
|
||||
IORESOURCE_IRQ_HIGHEDGE,
|
||||
#else
|
||||
IORESOURCE_IRQ_HIGHLEVEL,
|
||||
#endif /* CONFIG_BCMDHD_PCIE */
|
||||
};
|
||||
EXPORT_SYMBOL(dhd_wlan_resources);
|
||||
|
||||
struct wifi_platform_data dhd_wlan_control = {
|
||||
.set_power = dhd_wlan_power,
|
||||
.set_reset = dhd_wlan_reset,
|
||||
.set_carddetect = dhd_wlan_set_carddetect,
|
||||
#ifdef CONFIG_BROADCOM_WIFI_RESERVED_MEM
|
||||
.mem_prealloc = dhd_wlan_mem_prealloc,
|
||||
#endif /* CONFIG_BROADCOM_WIFI_RESERVED_MEM */
|
||||
};
|
||||
EXPORT_SYMBOL(dhd_wlan_control);
|
||||
|
||||
int __init
|
||||
dhd_wlan_init(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
printk(KERN_INFO"%s: START.......\n", __FUNCTION__);
|
||||
ret = dhd_wifi_init_gpio();
|
||||
if (ret < 0) {
|
||||
printk(KERN_ERR "%s: failed to initiate GPIO, ret=%d\n",
|
||||
__FUNCTION__, ret);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_BCMDHD_OOB_HOST_WAKE
|
||||
dhd_wlan_resources.start = wlan_host_wake_irq;
|
||||
dhd_wlan_resources.end = wlan_host_wake_irq;
|
||||
#endif /* CONFIG_BCMDHD_OOB_HOST_WAKE */
|
||||
|
||||
#ifdef CONFIG_BROADCOM_WIFI_RESERVED_MEM
|
||||
ret = dhd_init_wlan_mem();
|
||||
if (ret < 0) {
|
||||
printk(KERN_ERR "%s: failed to alloc reserved memory,"
|
||||
" ret=%d\n", __FUNCTION__, ret);
|
||||
}
|
||||
#endif /* CONFIG_BROADCOM_WIFI_RESERVED_MEM */
|
||||
|
||||
fail:
|
||||
printk(KERN_INFO"%s: FINISH.......\n", __FUNCTION__);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
dhd_wlan_deinit(void)
|
||||
{
|
||||
#ifdef CONFIG_BCMDHD_OOB_HOST_WAKE
|
||||
gpio_free(wlan_host_wake_up);
|
||||
#endif /* CONFIG_BCMDHD_OOB_HOST_WAKE */
|
||||
gpio_free(wlan_reg_on);
|
||||
|
||||
#ifdef CONFIG_BROADCOM_WIFI_RESERVED_MEM
|
||||
dhd_exit_wlan_mem();
|
||||
#endif /* CONFIG_BROADCOM_WIFI_RESERVED_MEM */
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifndef BCMDHD_MODULAR
|
||||
#if defined(CONFIG_ARCH_MSM8996) || defined(CONFIG_ARCH_MSM8998) || \
|
||||
defined(CONFIG_ARCH_SDM845) || defined(CONFIG_ARCH_SM8150) || \
|
||||
defined(CONFIG_ARCH_KONA) || defined(CONFIG_ARCH_LAHAINA)
|
||||
#if defined(CONFIG_DEFERRED_INITCALLS)
|
||||
deferred_module_init(dhd_wlan_init);
|
||||
#else
|
||||
late_initcall(dhd_wlan_init);
|
||||
#endif /* CONFIG_DEFERRED_INITCALLS */
|
||||
#else
|
||||
device_initcall(dhd_wlan_init);
|
||||
#endif /* MSM PCIE Platforms */
|
||||
#endif /* !BCMDHD_MODULAR */
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* Debug/trace/assert driver definitions for Dongle Host Driver.
|
||||
*
|
||||
* Copyright (C) 2020, Broadcom.
|
||||
* Copyright (C) 2022, Broadcom.
|
||||
*
|
||||
* Unless you and Broadcom execute a separate written software license
|
||||
* agreement governing use of this software, this software is licensed to you
|
||||
|
|
@ -29,102 +29,38 @@
|
|||
#if defined(NDIS)
|
||||
#include "wl_nddbg.h"
|
||||
#endif /* defined(NDIS) */
|
||||
|
||||
#ifdef DHD_LOG_DUMP
|
||||
extern char *dhd_log_dump_get_timestamp(void);
|
||||
#ifdef DHD_EFI
|
||||
/* FW verbose/console output to FW ring buffer */
|
||||
extern void dhd_log_dump_print(const char *fmt, ...);
|
||||
/* DHD verbose/console output to DHD ring buffer */
|
||||
extern void dhd_log_dump_print_drv(const char *fmt, ...);
|
||||
#define DHD_LOG_DUMP_WRITE(fmt, ...) dhd_log_dump_print_drv(fmt, ##__VA_ARGS__)
|
||||
#define DHD_LOG_DUMP_WRITE_FW(fmt, ...) dhd_log_dump_print(fmt, ##__VA_ARGS__)
|
||||
#else
|
||||
#ifndef _DHD_LOG_DUMP_DEFINITIONS_
|
||||
#define _DHD_LOG_DUMP_DEFINITIONS_
|
||||
#define GENERAL_LOG_HDR "\n-------------------- General log ---------------------------\n"
|
||||
#define PRESERVE_LOG_HDR "\n-------------------- Preserve log ---------------------------\n"
|
||||
#define SPECIAL_LOG_HDR "\n-------------------- Special log ---------------------------\n"
|
||||
#define DHD_DUMP_LOG_HDR "\n-------------------- 'dhd dump' log -----------------------\n"
|
||||
#define EXT_TRAP_LOG_HDR "\n-------------------- Extended trap data -------------------\n"
|
||||
#define HEALTH_CHK_LOG_HDR "\n-------------------- Health check data --------------------\n"
|
||||
#ifdef DHD_DUMP_PCIE_RINGS
|
||||
#define FLOWRING_DUMP_HDR "\n-------------------- Flowring dump --------------------\n"
|
||||
#endif /* DHD_DUMP_PCIE_RINGS */
|
||||
#define DHD_LOG_DUMP_DLD(fmt, ...) \
|
||||
dhd_log_dump_write(DLD_BUF_TYPE_GENERAL, NULL, 0, fmt, ##__VA_ARGS__)
|
||||
#define DHD_LOG_DUMP_DLD_EX(fmt, ...) \
|
||||
dhd_log_dump_write(DLD_BUF_TYPE_SPECIAL, NULL, 0, fmt, ##__VA_ARGS__)
|
||||
#define DHD_LOG_DUMP_DLD_PRSRV(fmt, ...) \
|
||||
dhd_log_dump_write(DLD_BUF_TYPE_PRESERVE, NULL, 0, fmt, ##__VA_ARGS__)
|
||||
#endif /* !_DHD_LOG_DUMP_DEFINITIONS_ */
|
||||
|
||||
#ifndef DHD_LOG_DUMP_RING_DEFINITIONS
|
||||
#define DHD_LOG_DUMP_RING_DEFINITIONS
|
||||
#ifdef DHD_DEBUGABILITY_LOG_DUMP_RING
|
||||
/* Enabled DHD_DEBUGABILITY_LOG_DUMP_RING */
|
||||
extern void dhd_dbg_ring_write(int type, char *binary_data,
|
||||
int binary_len, const char *fmt, ...);
|
||||
extern char* dhd_dbg_get_system_timestamp(void);
|
||||
#define DHD_DBG_RING(fmt, ...) \
|
||||
dhd_dbg_ring_write(DRIVER_LOG_RING_ID, NULL, 0, fmt, ##__VA_ARGS__)
|
||||
#define DHD_DBG_RING_EX(fmt, ...) \
|
||||
dhd_dbg_ring_write(FW_VERBOSE_RING_ID, NULL, 0, fmt, ##__VA_ARGS__)
|
||||
#define DHD_DBG_RING_ROAM(fmt, ...) \
|
||||
dhd_dbg_ring_write(ROAM_STATS_RING_ID, NULL, 0, fmt, ##__VA_ARGS__)
|
||||
|
||||
#define DHD_LOG_DUMP_WRITE DHD_DBG_RING
|
||||
#define DHD_LOG_DUMP_WRITE_EX DHD_DBG_RING_EX
|
||||
#define DHD_LOG_DUMP_WRITE_PRSRV DHD_DBG_RING
|
||||
#define DHD_LOG_DUMP_WRITE_ROAM DHD_DBG_RING_ROAM
|
||||
|
||||
#define DHD_PREFIX_TS "[%s][%s]: ", dhd_dbg_get_system_timestamp(), dhd_log_dump_get_timestamp()
|
||||
#define DHD_PREFIX_TS_FN DHD_PREFIX_TS
|
||||
#define DHD_LOG_DUMP_WRITE_TS DHD_DBG_RING(DHD_PREFIX_TS)
|
||||
#define DHD_LOG_DUMP_WRITE_TS_FN DHD_DBG_RING(DHD_PREFIX_TS_FN)
|
||||
#define DHD_LOG_DUMP_WRITE_EX_TS DHD_DBG_RING_EX(DHD_PREFIX_TS)
|
||||
#define DHD_LOG_DUMP_WRITE_EX_TS_FN DHD_DBG_RING_EX(DHD_PREFIX_TS_FN)
|
||||
#define DHD_LOG_DUMP_WRITE_PRSRV_TS DHD_DBG_RING(DHD_PREFIX_TS)
|
||||
#define DHD_LOG_DUMP_WRITE_PRSRV_TS_FN DHD_DBG_RING(DHD_PREFIX_TS_FN)
|
||||
#define DHD_LOG_DUMP_WRITE_ROAM_TS DHD_DBG_RING_ROAM(DHD_PREFIX_TS)
|
||||
#define DHD_LOG_DUMP_WRITE_ROAM_TS_FN DHD_DBG_RING_ROAM(DHD_PREFIX_TS_FN)
|
||||
#else
|
||||
/* Not enabled DHD_DEBUGABILITY_LOG_DUMP_RING */
|
||||
#define DHD_LOG_DUMP_WRITE DHD_LOG_DUMP_DLD
|
||||
#define DHD_LOG_DUMP_WRITE_EX DHD_LOG_DUMP_DLD_EX
|
||||
#define DHD_LOG_DUMP_WRITE_PRSRV DHD_LOG_DUMP_DLD_PRSRV
|
||||
#define DHD_LOG_DUMP_WRITE_ROAM DHD_LOG_DUMP_DLD
|
||||
|
||||
#define DHD_PREFIX_TS "[%s]: ", dhd_log_dump_get_timestamp()
|
||||
#define DHD_PREFIX_TS_FN "[%s] %s: ", dhd_log_dump_get_timestamp(), __func__
|
||||
#define DHD_LOG_DUMP_WRITE_TS DHD_LOG_DUMP_DLD(DHD_PREFIX_TS)
|
||||
#define DHD_LOG_DUMP_WRITE_TS_FN DHD_LOG_DUMP_DLD(DHD_PREFIX_TS_FN)
|
||||
#define DHD_LOG_DUMP_WRITE_EX_TS DHD_LOG_DUMP_DLD_EX(DHD_PREFIX_TS)
|
||||
#define DHD_LOG_DUMP_WRITE_EX_TS_FN DHD_LOG_DUMP_DLD_EX(DHD_PREFIX_TS_FN)
|
||||
#define DHD_LOG_DUMP_WRITE_PRSRV_TS DHD_LOG_DUMP_DLD_PRSRV(DHD_PREFIX_TS)
|
||||
#define DHD_LOG_DUMP_WRITE_PRSRV_TS_FN DHD_LOG_DUMP_DLD_PRSRV(DHD_PREFIX_TS_FN)
|
||||
#define DHD_LOG_DUMP_WRITE_ROAM_TS DHD_LOG_DUMP_DLD(DHD_PREFIX_TS)
|
||||
#define DHD_LOG_DUMP_WRITE_ROAM_TS_FN DHD_LOG_DUMP_DLD(DHD_PREFIX_TS_FN)
|
||||
#endif /* DHD_DEBUGABILITY_LOG_DUMP_RING */
|
||||
#endif /* DHD_LOG_DUMP_RING_DEFINITIONS */
|
||||
|
||||
#endif /* DHD_EFI */
|
||||
#define CONCISE_DUMP_BUFLEN 32 * 1024
|
||||
#define ECNTRS_LOG_HDR "\n-------------------- Ecounters log --------------------------\n"
|
||||
#ifdef DHD_STATUS_LOGGING
|
||||
#define STATUS_LOG_HDR "\n-------------------- Status log -----------------------\n"
|
||||
#endif /* DHD_STATUS_LOGGING */
|
||||
#define RTT_LOG_HDR "\n-------------------- RTT log --------------------------\n"
|
||||
#define BCM_TRACE_LOG_HDR "\n-------------------- BCM Trace log --------------------------\n"
|
||||
#define COOKIE_LOG_HDR "\n-------------------- Cookie List ----------------------------\n"
|
||||
#endif /* DHD_LOG_DUMP */
|
||||
|
||||
#if defined(CUSTOMER_DBG_SYSTEM_TIME) && defined(DHD_DEBUGABILITY_LOG_DUMP_RING)
|
||||
#define DBG_PRINT_PREFIX "[%s][dhd][wlan]", dhd_dbg_get_system_timestamp()
|
||||
#else
|
||||
#define DBG_PRINT_PREFIX
|
||||
#include <dhd_log_dump.h>
|
||||
#endif
|
||||
|
||||
#ifdef DHD_DEBUGABILITY_LOG_DUMP_RING
|
||||
/* Only for writing to ring */
|
||||
#define DHD_INFO_RING(args) DHD_ERROR(args)
|
||||
/* FW_VERBOSE RING */
|
||||
#define DHD_LOG_DUMP_FWLOG DHD_LOG_DUMP_WRITE_EX
|
||||
#define DHD_LOG_DUMP_FWLOG_TS DHD_LOG_DUMP_WRITE_EX_TS
|
||||
#else
|
||||
#define DHD_INFO_RING(args)
|
||||
/* DLD_BUF_TYPE_GENERAL */
|
||||
#define DHD_LOG_DUMP_FWLOG DHD_LOG_DUMP_WRITE
|
||||
#define DHD_LOG_DUMP_FWLOG_TS DHD_LOG_DUMP_WRITE_TS
|
||||
#endif
|
||||
|
||||
#ifdef CUSTOM_PREFIX
|
||||
#define DBG_PRINT_PREFIX "[%s]"CUSTOM_PREFIX, OSL_GET_RTCTIME()
|
||||
#elif defined(CUSTOM_PREFIX_NORTCTIME)
|
||||
#define DBG_PRINT_PREFIX CUSTOM_PREFIX_NORTCTIME
|
||||
|
||||
#define DBG_PRINT_SYSTEM_TIME pr_cont(DBG_PRINT_PREFIX)
|
||||
#define DHD_CONS_ONLY(args) \
|
||||
do { \
|
||||
DBG_PRINT_SYSTEM_TIME; \
|
||||
pr_cont args; \
|
||||
} while (0)
|
||||
#else
|
||||
#define DBG_PRINT_SYSTEM_TIME
|
||||
#define DHD_CONS_ONLY(args) do { printf args;} while (0)
|
||||
#endif /* CUSTOM_PREFIX */
|
||||
|
||||
#if defined(BCMDBG) || defined(DHD_DEBUG)
|
||||
|
||||
|
|
@ -139,38 +75,32 @@ extern char* dhd_dbg_get_system_timestamp(void);
|
|||
#else
|
||||
/* NON-NDIS cases */
|
||||
#ifdef DHD_LOG_DUMP
|
||||
#ifdef DHD_EFI
|
||||
/* defined(DHD_EFI) && defined(DHD_LOG_DUMP) */
|
||||
#define DHD_ERROR(args) \
|
||||
do { \
|
||||
if (dhd_msg_level & DHD_ERROR_VAL) { \
|
||||
printf args; \
|
||||
DHD_LOG_DUMP_WRITE("[%s]: ", dhd_log_dump_get_timestamp()); \
|
||||
DHD_LOG_DUMP_WRITE args; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define DHD_INFO(args) \
|
||||
do { \
|
||||
if (dhd_msg_level & DHD_INFO_VAL) { \
|
||||
printf args; \
|
||||
DHD_LOG_DUMP_WRITE("[%s]: ", dhd_log_dump_get_timestamp()); \
|
||||
DHD_LOG_DUMP_WRITE args; \
|
||||
} \
|
||||
} while (0)
|
||||
#else /* DHD_EFI */
|
||||
/* !defined(DHD_EFI) and defined(DHD_LOG_DUMP) */
|
||||
#define DHD_ERROR(args) \
|
||||
do { \
|
||||
if (dhd_msg_level & DHD_ERROR_VAL) { \
|
||||
printf args; \
|
||||
} \
|
||||
if (dhd_log_level & DHD_ERROR_VAL) { \
|
||||
DHD_LOG_DUMP_WRITE_TS; \
|
||||
DHD_LOG_DUMP_WRITE args; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#ifdef DHD_DEBUGABILITY_LOG_DUMP_RING
|
||||
#define DHD_INFO(args) \
|
||||
do { \
|
||||
if (dhd_msg_level & DHD_INFO_VAL) { \
|
||||
printf args; \
|
||||
} \
|
||||
if (dhd_log_level & DHD_INFO_VAL) { \
|
||||
DHD_LOG_DUMP_WRITE_TS; \
|
||||
DHD_LOG_DUMP_WRITE args; \
|
||||
} \
|
||||
} while (0)
|
||||
#else
|
||||
#define DHD_INFO(args) do {if (dhd_msg_level & DHD_INFO_VAL) printf args;} while (0)
|
||||
#endif /* DHD_EFI */
|
||||
#endif /* DHD_DEBUGABILITY_LOG_DUMP_RING */
|
||||
#else /* DHD_LOG_DUMP */
|
||||
/* !defined(DHD_LOG_DUMP cases) */
|
||||
#define DHD_ERROR(args) do {if (dhd_msg_level & DHD_ERROR_VAL) printf args;} while (0)
|
||||
|
|
@ -183,55 +113,6 @@ do { \
|
|||
|
||||
#ifdef DHD_LOG_DUMP
|
||||
/* LOG_DUMP defines common to EFI and NON-EFI */
|
||||
#ifdef DHD_EFI
|
||||
/* EFI builds with LOG DUMP enabled */
|
||||
#define DHD_ERROR_MEM(args) \
|
||||
do { \
|
||||
if (dhd_msg_level & DHD_ERROR_VAL) { \
|
||||
if (dhd_msg_level & DHD_ERROR_MEM_VAL) { \
|
||||
printf args; \
|
||||
} \
|
||||
DHD_LOG_DUMP_WRITE("[%s]: ", dhd_log_dump_get_timestamp()); \
|
||||
DHD_LOG_DUMP_WRITE args; \
|
||||
} \
|
||||
} while (0)
|
||||
#define DHD_IOVAR_MEM(args) \
|
||||
do { \
|
||||
if (dhd_msg_level & DHD_ERROR_VAL) { \
|
||||
if (dhd_msg_level & DHD_IOVAR_MEM_VAL) { \
|
||||
printf args; \
|
||||
} \
|
||||
DHD_LOG_DUMP_WRITE("[%s]: ", dhd_log_dump_get_timestamp()); \
|
||||
DHD_LOG_DUMP_WRITE args; \
|
||||
} \
|
||||
} while (0)
|
||||
#define DHD_LOG_MEM(args) \
|
||||
do { \
|
||||
if (dhd_msg_level & DHD_ERROR_VAL) { \
|
||||
DHD_LOG_DUMP_WRITE("[%s]: ", dhd_log_dump_get_timestamp()); \
|
||||
DHD_LOG_DUMP_WRITE args; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define DHD_EVENT(args) \
|
||||
do { \
|
||||
if (dhd_msg_level & DHD_EVENT_VAL) { \
|
||||
DHD_LOG_DUMP_WRITE_FW("[%s]: ", dhd_log_dump_get_timestamp()); \
|
||||
DHD_LOG_DUMP_WRITE_FW args; \
|
||||
} \
|
||||
} while (0)
|
||||
#define DHD_ECNTR_LOG(args) DHD_EVENT(args)
|
||||
#define DHD_ERROR_EX(args) DHD_ERROR(args)
|
||||
#define DHD_ERROR_ROAM(args) DHD_ERROR(args)
|
||||
#define DHD_MSGTRACE_LOG(args) \
|
||||
do { \
|
||||
if (dhd_msg_level & DHD_MSGTRACE_VAL) { \
|
||||
DHD_LOG_DUMP_WRITE_FW("[%s]: ", dhd_log_dump_get_timestamp()); \
|
||||
DHD_LOG_DUMP_WRITE_FW args; \
|
||||
} \
|
||||
} while (0)
|
||||
#define DHD_PRSRV_MEM(args) DHD_EVENT(args)
|
||||
#else
|
||||
/* NON-EFI builds with LOG DUMP enabled */
|
||||
#define DHD_ERROR_MEM(args) \
|
||||
do { \
|
||||
|
|
@ -239,6 +120,9 @@ do { \
|
|||
if (dhd_msg_level & DHD_ERROR_MEM_VAL) { \
|
||||
printf args; \
|
||||
} \
|
||||
} \
|
||||
if (dhd_log_level & DHD_ERROR_VAL) { \
|
||||
DHD_LOG_DUMP_WRITE_TS; \
|
||||
DHD_LOG_DUMP_WRITE args; \
|
||||
} \
|
||||
} while (0)
|
||||
|
|
@ -248,12 +132,16 @@ do { \
|
|||
if (dhd_msg_level & DHD_IOVAR_MEM_VAL) { \
|
||||
printf args; \
|
||||
} \
|
||||
} \
|
||||
if (dhd_log_level & DHD_ERROR_VAL) { \
|
||||
DHD_LOG_DUMP_WRITE_TS; \
|
||||
DHD_LOG_DUMP_WRITE args; \
|
||||
} \
|
||||
} while (0)
|
||||
#define DHD_LOG_MEM(args) \
|
||||
do { \
|
||||
if (dhd_msg_level & DHD_ERROR_VAL) { \
|
||||
if (dhd_log_level & DHD_ERROR_VAL) { \
|
||||
DHD_LOG_DUMP_WRITE_TS; \
|
||||
DHD_LOG_DUMP_WRITE args; \
|
||||
} \
|
||||
} while (0)
|
||||
|
|
@ -262,6 +150,8 @@ do { \
|
|||
do { \
|
||||
if (dhd_msg_level & DHD_EVENT_VAL) { \
|
||||
printf args; \
|
||||
} \
|
||||
if (dhd_log_level & DHD_EVENT_VAL) { \
|
||||
DHD_LOG_DUMP_WRITE_PRSRV_TS; \
|
||||
DHD_LOG_DUMP_WRITE_PRSRV args; \
|
||||
} \
|
||||
|
|
@ -272,8 +162,10 @@ do { \
|
|||
if (dhd_msg_level & DHD_PRSRV_MEM_VAL) { \
|
||||
printf args; \
|
||||
} \
|
||||
DHD_LOG_DUMP_WRITE_TS; \
|
||||
DHD_LOG_DUMP_WRITE args; \
|
||||
} \
|
||||
if (dhd_log_level & DHD_EVENT_VAL) { \
|
||||
DHD_LOG_DUMP_WRITE_PRSRV_TS; \
|
||||
DHD_LOG_DUMP_WRITE_PRSRV args; \
|
||||
} \
|
||||
} while (0)
|
||||
/* Re-using 'DHD_MSGTRACE_VAL' for controlling printing of ecounter binary event
|
||||
|
|
@ -286,6 +178,10 @@ do { \
|
|||
if (dhd_msg_level & DHD_EVENT_VAL) { \
|
||||
if (dhd_msg_level & DHD_MSGTRACE_VAL) { \
|
||||
printf args; \
|
||||
} \
|
||||
} \
|
||||
if (dhd_log_level & DHD_EVENT_VAL) { \
|
||||
if (dhd_log_level & DHD_MSGTRACE_VAL) { \
|
||||
DHD_LOG_DUMP_WRITE_TS; \
|
||||
DHD_LOG_DUMP_WRITE args; \
|
||||
} \
|
||||
|
|
@ -295,6 +191,8 @@ do { \
|
|||
do { \
|
||||
if (dhd_msg_level & DHD_ERROR_VAL) { \
|
||||
printf args; \
|
||||
} \
|
||||
if (dhd_log_level & DHD_ERROR_VAL) { \
|
||||
DHD_LOG_DUMP_WRITE_EX_TS; \
|
||||
DHD_LOG_DUMP_WRITE_EX args; \
|
||||
} \
|
||||
|
|
@ -312,11 +210,122 @@ do { \
|
|||
do { \
|
||||
if (dhd_msg_level & DHD_ERROR_VAL) { \
|
||||
printf args; \
|
||||
} \
|
||||
if (dhd_log_level & DHD_ERROR_VAL) { \
|
||||
DHD_LOG_DUMP_WRITE_ROAM_TS; \
|
||||
DHD_LOG_DUMP_WRITE_ROAM args; \
|
||||
} \
|
||||
} while (0)
|
||||
#endif /* DHD_EFI */
|
||||
|
||||
#define DHD_PKT_MON(args) \
|
||||
do { \
|
||||
if (dhd_msg_level & DHD_PKT_MON_VAL) { \
|
||||
printf args; \
|
||||
} \
|
||||
if (dhd_log_level & DHD_PKT_MON_VAL) { \
|
||||
DHD_LOG_DUMP_WRITE_TS; \
|
||||
DHD_LOG_DUMP_WRITE args; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define DHD_CTL(args) \
|
||||
do { \
|
||||
if (dhd_msg_level & DHD_CTL_VAL) { \
|
||||
printf args; \
|
||||
} \
|
||||
if (dhd_log_level & DHD_CTL_VAL) { \
|
||||
DHD_LOG_DUMP_WRITE_TS; \
|
||||
DHD_LOG_DUMP_WRITE args; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define DHD_TIMER(args) \
|
||||
do { \
|
||||
if (dhd_msg_level & DHD_TIMER_VAL) { \
|
||||
printf args; \
|
||||
} \
|
||||
if (dhd_log_level & DHD_TIMER_VAL) { \
|
||||
DHD_LOG_DUMP_WRITE_TS; \
|
||||
DHD_LOG_DUMP_WRITE args; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define DHD_INTR(args) \
|
||||
do { \
|
||||
if (dhd_msg_level & DHD_INTR_VAL) { \
|
||||
printf args; \
|
||||
} \
|
||||
if (dhd_log_level & DHD_INTR_VAL) { \
|
||||
DHD_LOG_DUMP_WRITE_TS; \
|
||||
DHD_LOG_DUMP_WRITE args; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define DHD_ISCAN(args) \
|
||||
do { \
|
||||
if (dhd_msg_level & DHD_ISCAN_VAL) { \
|
||||
printf args; \
|
||||
} \
|
||||
if (dhd_log_level & DHD_ISCAN_VAL) { \
|
||||
DHD_LOG_DUMP_WRITE_TS; \
|
||||
DHD_LOG_DUMP_WRITE args; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define DHD_ARPOE(args) \
|
||||
do { \
|
||||
if (dhd_msg_level & DHD_ARPOE_VAL) { \
|
||||
printf args; \
|
||||
} \
|
||||
if (dhd_log_level & DHD_ARPOE_VAL) { \
|
||||
DHD_LOG_DUMP_WRITE_TS; \
|
||||
DHD_LOG_DUMP_WRITE args; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define DHD_REORDER(args) \
|
||||
do { \
|
||||
if (dhd_msg_level & DHD_REORDER_VAL) { \
|
||||
printf args; \
|
||||
} \
|
||||
if (dhd_log_level & DHD_REORDER_VAL) { \
|
||||
DHD_LOG_DUMP_WRITE_TS; \
|
||||
DHD_LOG_DUMP_WRITE args; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define DHD_PNO(args) \
|
||||
do { \
|
||||
if (dhd_msg_level & DHD_PNO_VAL) { \
|
||||
printf args; \
|
||||
} \
|
||||
if (dhd_log_level & DHD_PNO_VAL) { \
|
||||
DHD_LOG_DUMP_WRITE_TS; \
|
||||
DHD_LOG_DUMP_WRITE args; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define DHD_RTT(args) \
|
||||
do { \
|
||||
if (dhd_msg_level & DHD_RTT_VAL) { \
|
||||
printf args; \
|
||||
} \
|
||||
if (dhd_log_level & DHD_RTT_VAL) { \
|
||||
DHD_LOG_DUMP_WRITE_TS; \
|
||||
DHD_LOG_DUMP_WRITE args; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define DHD_RPM(args) \
|
||||
do { \
|
||||
if (dhd_msg_level & DHD_RPM_VAL) { \
|
||||
printf args; \
|
||||
} \
|
||||
if (dhd_log_level & DHD_RPM_VAL) { \
|
||||
DHD_LOG_DUMP_WRITE_TS; \
|
||||
DHD_LOG_DUMP_WRITE args; \
|
||||
} \
|
||||
} while (0)
|
||||
#else /* DHD_LOG_DUMP */
|
||||
/* !DHD_LOG_DUMP */
|
||||
#define DHD_MSGTRACE_LOG(args) do {if (dhd_msg_level & DHD_MSGTRACE_VAL) printf args;} while (0)
|
||||
|
|
@ -328,50 +337,43 @@ do { \
|
|||
#define DHD_PRSRV_MEM(args) DHD_EVENT(args)
|
||||
#define DHD_ERROR_EX(args) DHD_ERROR(args)
|
||||
#define DHD_ERROR_ROAM(args) DHD_ERROR(args)
|
||||
#define DHD_PKT_MON(args) DHD_ERROR(args)
|
||||
#endif /* DHD_LOG_DUMP */
|
||||
|
||||
#define DHD_DATA(args) do {if (dhd_msg_level & DHD_DATA_VAL) printf args;} while (0)
|
||||
#if !defined(DHD_LOG_DUMP)
|
||||
#define DHD_CTL(args) do {if (dhd_msg_level & DHD_CTL_VAL) printf args;} while (0)
|
||||
#define DHD_TIMER(args) do {if (dhd_msg_level & DHD_TIMER_VAL) printf args;} while (0)
|
||||
#define DHD_HDRS(args) do {if (dhd_msg_level & DHD_HDRS_VAL) printf args;} while (0)
|
||||
#define DHD_BYTES(args) do {if (dhd_msg_level & DHD_BYTES_VAL) printf args;} while (0)
|
||||
#define DHD_INTR(args) do {if (dhd_msg_level & DHD_INTR_VAL) printf args;} while (0)
|
||||
#define DHD_GLOM(args) do {if (dhd_msg_level & DHD_GLOM_VAL) printf args;} while (0)
|
||||
#define DHD_BTA(args) do {if (dhd_msg_level & DHD_BTA_VAL) printf args;} while (0)
|
||||
#define DHD_ISCAN(args) do {if (dhd_msg_level & DHD_ISCAN_VAL) printf args;} while (0)
|
||||
#define DHD_ARPOE(args) do {if (dhd_msg_level & DHD_ARPOE_VAL) printf args;} while (0)
|
||||
#define DHD_REORDER(args) do {if (dhd_msg_level & DHD_REORDER_VAL) printf args;} while (0)
|
||||
#define DHD_PNO(args) do {if (dhd_msg_level & DHD_PNO_VAL) printf args;} while (0)
|
||||
#define DHD_RTT(args) do {if (dhd_msg_level & DHD_RTT_VAL) printf args;} while (0)
|
||||
#define DHD_RPM(args) do {if (dhd_msg_level & DHD_RPM_VAL) printf args;} while (0)
|
||||
#define DHD_PKT_MON(args) do {if (dhd_msg_level & DHD_PKT_MON_VAL) printf args;} while (0)
|
||||
#endif
|
||||
|
||||
#define DHD_DATA(args) do {if (dhd_msg_level & DHD_DATA_VAL) printf args;} while (0)
|
||||
#define DHD_HDRS(args) do {if (dhd_msg_level & DHD_HDRS_VAL) printf args;} while (0)
|
||||
#define DHD_BYTES(args) do {if (dhd_msg_level & DHD_BYTES_VAL) printf args;} while (0)
|
||||
#define DHD_GLOM(args) do {if (dhd_msg_level & DHD_GLOM_VAL) printf args;} while (0)
|
||||
#define DHD_BTA(args) do {if (dhd_msg_level & DHD_BTA_VAL) printf args;} while (0)
|
||||
|
||||
#if defined(DHD_LOG_DUMP)
|
||||
#if defined(DHD_EFI)
|
||||
#define DHD_FWLOG(args) DHD_MSGTRACE_LOG(args)
|
||||
#elif defined(DHD_LOG_PRINT_RATE_LIMIT)
|
||||
#define DHD_FW_VERBOSE(args) \
|
||||
do { \
|
||||
if (dbgring_msg_level & DHD_FWLOG_VAL) { \
|
||||
DHD_LOG_DUMP_WRITE_EX args; \
|
||||
} \
|
||||
} while (0)
|
||||
#if defined(DHD_LOG_PRINT_RATE_LIMIT)
|
||||
|
||||
#define DHD_FWLOG(args) \
|
||||
do { \
|
||||
if (dhd_msg_level & DHD_FWLOG_VAL) { \
|
||||
if (control_logtrace && !log_print_threshold) \
|
||||
printf args; \
|
||||
DHD_LOG_DUMP_WRITE args; \
|
||||
} \
|
||||
} while (0)
|
||||
#else
|
||||
#define DHD_FW_VERBOSE(args) \
|
||||
do { \
|
||||
if (dbgring_msg_level & DHD_FWLOG_VAL) { \
|
||||
DHD_LOG_DUMP_WRITE_EX args; \
|
||||
} \
|
||||
do { \
|
||||
if (dhd_msg_level & DHD_FWLOG_VAL) { \
|
||||
if (control_logtrace && !log_print_threshold) \
|
||||
printf args; \
|
||||
} \
|
||||
if (dhd_log_level & DHD_FWLOG_VAL) { \
|
||||
DHD_LOG_DUMP_FWLOG_TS; \
|
||||
DHD_LOG_DUMP_FWLOG args; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#else
|
||||
#define DHD_FWLOG(args) \
|
||||
do { \
|
||||
if (dhd_msg_level & DHD_FWLOG_VAL) { \
|
||||
|
|
@ -380,7 +382,7 @@ do { \
|
|||
DHD_LOG_DUMP_WRITE args; \
|
||||
} \
|
||||
} while (0)
|
||||
#endif /* DHD_EFI */
|
||||
#endif
|
||||
#else /* DHD_LOG_DUMP */
|
||||
#if defined(NDIS) && (NDISVER >= 0x0630)
|
||||
#define DHD_FWLOG(args) do {if (dhd_msg_level & DHD_FWLOG_VAL) \
|
||||
|
|
@ -391,20 +393,11 @@ do { \
|
|||
#endif /* DHD_LOG_DUMP */
|
||||
|
||||
#define DHD_DBGIF(args) do {if (dhd_msg_level & DHD_DBGIF_VAL) printf args;} while (0)
|
||||
#define DHD_TXFLOWCTL(args) DHD_RPM(args)
|
||||
|
||||
#ifdef DHD_PCIE_NATIVE_RUNTIMEPM
|
||||
#define DHD_RPM(args) do {if (dhd_msg_level & DHD_RPM_VAL) printf args;} while (0)
|
||||
#endif /* DHD_PCIE_NATIVE_RUNTIMEPM */
|
||||
|
||||
#ifdef CUSTOMER_HW4_DEBUG
|
||||
#define DHD_TRACE_HW4 DHD_ERROR
|
||||
#define DHD_INFO_HW4 DHD_ERROR
|
||||
#define DHD_ERROR_NO_HW4 DHD_INFO
|
||||
#else
|
||||
#define DHD_TRACE_HW4 DHD_TRACE
|
||||
#define DHD_INFO_HW4 DHD_INFO
|
||||
#define DHD_ERROR_NO_HW4 DHD_ERROR
|
||||
#endif /* CUSTOMER_HW4_DEBUG */
|
||||
|
||||
#define DHD_ERROR_ON() (dhd_msg_level & DHD_ERROR_VAL)
|
||||
#define DHD_TRACE_ON() (dhd_msg_level & DHD_TRACE_VAL)
|
||||
|
|
@ -442,25 +435,6 @@ do { \
|
|||
{DHD_NDDBG_OUTPUT args;}} while (0)
|
||||
#define DHD_INFO(args) do {if (dhd_msg_level & DHD_INFO_VAL) \
|
||||
{DHD_NDDBG_OUTPUT args;}} while (0)
|
||||
#elif defined(DHD_EFI) && defined(DHD_LOG_DUMP)
|
||||
#define DHD_ERROR(args) \
|
||||
do { \
|
||||
if (dhd_msg_level & DHD_ERROR_VAL) { \
|
||||
printf args; \
|
||||
DHD_LOG_DUMP_WRITE("[%s]: ", dhd_log_dump_get_timestamp()); \
|
||||
DHD_LOG_DUMP_WRITE args; \
|
||||
} \
|
||||
} while (0)
|
||||
#define DHD_INFO(args) \
|
||||
do { \
|
||||
if (dhd_msg_level & DHD_INFO_VAL) { \
|
||||
printf args; \
|
||||
DHD_LOG_DUMP_WRITE("[%s]: ", dhd_log_dump_get_timestamp()); \
|
||||
DHD_LOG_DUMP_WRITE args; \
|
||||
} \
|
||||
} while (0)
|
||||
#define DHD_TRACE(args)
|
||||
#define DHD_ERROR_ROAM(args) DHD_ERROR(args)
|
||||
#else /* DHD_EFI && DHD_LOG_DUMP */
|
||||
|
||||
#define DHD_ERROR(args) do {if (dhd_msg_level & DHD_ERROR_VAL) \
|
||||
|
|
@ -478,19 +452,8 @@ do { \
|
|||
#define DHD_INTR(args)
|
||||
#define DHD_GLOM(args)
|
||||
|
||||
#if defined(DHD_EFI) && defined(DHD_LOG_DUMP)
|
||||
#define DHD_EVENT(args) \
|
||||
do { \
|
||||
if (dhd_msg_level & DHD_EVENT_VAL) { \
|
||||
DHD_LOG_DUMP_WRITE_FW("[%s]: ", dhd_log_dump_get_timestamp()); \
|
||||
DHD_LOG_DUMP_WRITE_FW args; \
|
||||
} \
|
||||
} while (0)
|
||||
#define DHD_ECNTR_LOG(args) DHD_EVENT(args)
|
||||
#else
|
||||
#define DHD_EVENT(args)
|
||||
#define DHD_ECNTR_LOG(args) DHD_EVENT(args)
|
||||
#endif /* DHD_EFI && DHD_LOG_DUMP */
|
||||
|
||||
#define DHD_PRSRV_MEM(args) DHD_EVENT(args)
|
||||
|
||||
|
|
@ -502,61 +465,21 @@ do { \
|
|||
#define DHD_RTT(args)
|
||||
#define DHD_PKT_MON(args)
|
||||
|
||||
#if defined(DHD_EFI) && defined(DHD_LOG_DUMP)
|
||||
#define DHD_MSGTRACE_LOG(args) \
|
||||
do { \
|
||||
if (dhd_msg_level & DHD_MSGTRACE_VAL) { \
|
||||
DHD_LOG_DUMP_WRITE_FW("[%s]: ", dhd_log_dump_get_timestamp()); \
|
||||
DHD_LOG_DUMP_WRITE_FW args; \
|
||||
} \
|
||||
} while (0)
|
||||
#define DHD_FWLOG(args) DHD_MSGTRACE_LOG(args)
|
||||
#else
|
||||
#define DHD_MSGTRACE_LOG(args)
|
||||
#define DHD_FWLOG(args)
|
||||
#endif /* DHD_EFI && DHD_LOG_DUMP */
|
||||
|
||||
#define DHD_DBGIF(args)
|
||||
|
||||
#if defined(DHD_EFI) && defined(DHD_LOG_DUMP)
|
||||
#define DHD_ERROR_MEM(args) \
|
||||
do { \
|
||||
if (dhd_msg_level & DHD_ERROR_VAL) { \
|
||||
DHD_LOG_DUMP_WRITE("[%s]: ", dhd_log_dump_get_timestamp()); \
|
||||
DHD_LOG_DUMP_WRITE args; \
|
||||
} \
|
||||
} while (0)
|
||||
#define DHD_IOVAR_MEM(args) \
|
||||
do { \
|
||||
if (dhd_msg_level & DHD_ERROR_VAL) { \
|
||||
DHD_LOG_DUMP_WRITE("[%s]: ", dhd_log_dump_get_timestamp()); \
|
||||
DHD_LOG_DUMP_WRITE args; \
|
||||
} \
|
||||
} while (0)
|
||||
#define DHD_LOG_MEM(args) \
|
||||
do { \
|
||||
if (dhd_msg_level & DHD_ERROR_VAL) { \
|
||||
DHD_LOG_DUMP_WRITE("[%s]: ", dhd_log_dump_get_timestamp()); \
|
||||
DHD_LOG_DUMP_WRITE args; \
|
||||
} \
|
||||
} while (0)
|
||||
#define DHD_ERROR_EX(args) DHD_ERROR(args)
|
||||
#else
|
||||
#define DHD_ERROR_MEM(args) DHD_ERROR(args)
|
||||
#define DHD_IOVAR_MEM(args) DHD_ERROR(args)
|
||||
#define DHD_LOG_MEM(args) DHD_ERROR(args)
|
||||
#define DHD_ERROR_EX(args) DHD_ERROR(args)
|
||||
#endif /* DHD_EFI */
|
||||
#define DHD_ERROR_ROAM(args) DHD_ERROR(args)
|
||||
#ifdef CUSTOMER_HW4_DEBUG
|
||||
#define DHD_TRACE_HW4 DHD_ERROR
|
||||
#define DHD_INFO_HW4 DHD_ERROR
|
||||
#define DHD_ERROR_NO_HW4 DHD_INFO
|
||||
#else
|
||||
#define DHD_RPM(args) DHD_ERROR(args)
|
||||
#define DHD_TXFLOWCTL(args) DHD_ERROR(args)
|
||||
#define DHD_TRACE_HW4 DHD_TRACE
|
||||
#define DHD_INFO_HW4 DHD_INFO
|
||||
#define DHD_ERROR_NO_HW4 DHD_ERROR
|
||||
#endif /* CUSTOMER_HW4_DEBUG */
|
||||
|
||||
#define DHD_ERROR_ON() 0
|
||||
#define DHD_TRACE_ON() 0
|
||||
|
|
@ -616,21 +539,34 @@ do { \
|
|||
#define DHD_LOG(args)
|
||||
#endif
|
||||
|
||||
#if defined(BCMINTERNAL) && defined(LINUX) && defined(BCMSDIO) && (defined(BCMDBG) || \
|
||||
defined(DHD_DEBUG))
|
||||
extern void dhd_blog(char *cp, int size);
|
||||
#define DHD_BLOG(cp, size) do { dhd_blog(cp, size);} while (0)
|
||||
#else
|
||||
#define DHD_BLOG(cp, size)
|
||||
#endif
|
||||
|
||||
#define DHD_NONE(args)
|
||||
extern int dhd_msg_level;
|
||||
extern int dbgring_msg_level;
|
||||
extern int dhd_log_level;
|
||||
#ifdef DHD_LOG_PRINT_RATE_LIMIT
|
||||
extern int log_print_threshold;
|
||||
#endif /* DHD_LOG_PRINT_RATE_LIMIT */
|
||||
|
||||
#ifdef DHD_IOVAR_LOG_FILTER_DUMP
|
||||
#define DHD_IOVAR_LOG_CHECK(dhd_pub, ioc_cmd, ioc_msg) \
|
||||
dhd_iovar_log_dump_check(dhd_pub, ioc_cmd, ioc_msg)
|
||||
#else
|
||||
#define DHD_IOVAR_LOG_CHECK(dhd_pub, ioc_cmd, ioc_msg) TRUE
|
||||
#endif /* DHD_IOVAR_LOG_FILTER_DUMP */
|
||||
|
||||
#define DHD_IOVAR_LOG(dhd_pub, ioc_cmd, ioc_msg, fmt) \
|
||||
do { \
|
||||
if (DHD_IOVAR_LOG_CHECK(dhd_pub, ioc_cmd, ioc_msg)) { \
|
||||
DHD_IOVAR_MEM(fmt); \
|
||||
} else { \
|
||||
DHD_TRACE(fmt); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/* DHD_PRINT - informational non-error messages which need to be always printed */
|
||||
#define DHD_PRINT DHD_ERROR
|
||||
|
||||
/* Defines msg bits */
|
||||
#include <dhdioctl.h>
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* DHD debug ring API and structures - implementation
|
||||
*
|
||||
* Copyright (C) 2020, Broadcom.
|
||||
* Copyright (C) 2022, Broadcom.
|
||||
*
|
||||
* Unless you and Broadcom execute a separate written software license
|
||||
* agreement governing use of this software, this software is licensed to you
|
||||
|
|
@ -30,6 +30,7 @@
|
|||
#include <dhd.h>
|
||||
#include <dhd_dbg.h>
|
||||
#include <dhd_dbg_ring.h>
|
||||
#include <dhd_debug.h>
|
||||
|
||||
dhd_dbg_ring_t *
|
||||
dhd_dbg_ring_alloc_init(dhd_pub_t *dhd, uint16 ring_id,
|
||||
|
|
@ -97,7 +98,14 @@ dhd_dbg_ring_init(dhd_pub_t *dhdp, dhd_dbg_ring_t *ring, uint16 id, uint8 *name,
|
|||
unsigned long flags = 0;
|
||||
|
||||
if (allocd_buf == NULL) {
|
||||
return BCME_NOMEM;
|
||||
/* for DEBUG_DUMP and MEM_DUMP, buffer can be NULL
|
||||
* since act as delayed allocation or fake rings
|
||||
*/
|
||||
if (id != DEBUG_DUMP_RING1_ID && id != DEBUG_DUMP_RING2_ID &&
|
||||
id != MEM_DUMP_RING_ID) {
|
||||
return BCME_NOMEM;
|
||||
}
|
||||
buf = NULL;
|
||||
} else {
|
||||
buf = allocd_buf;
|
||||
}
|
||||
|
|
@ -120,6 +128,17 @@ dhd_dbg_ring_init(dhd_pub_t *dhdp, dhd_dbg_ring_t *ring, uint16 id, uint8 *name,
|
|||
return BCME_OK;
|
||||
}
|
||||
|
||||
int
|
||||
dhd_dbg_ring_set_buf(dhd_pub_t *dhdp, dhd_dbg_ring_t *ring, void *buf)
|
||||
{
|
||||
unsigned long flags = 0;
|
||||
|
||||
DHD_DBG_RING_LOCK(ring->lock, flags);
|
||||
ring->ring_buf = buf;
|
||||
DHD_DBG_RING_UNLOCK(ring->lock, flags);
|
||||
|
||||
return BCME_OK;
|
||||
}
|
||||
void
|
||||
dhd_dbg_ring_deinit(dhd_pub_t *dhdp, dhd_dbg_ring_t *ring)
|
||||
{
|
||||
|
|
@ -182,6 +201,38 @@ dhd_dbg_ring_get_pending_len(dhd_dbg_ring_t *ring)
|
|||
return pending_len;
|
||||
}
|
||||
|
||||
#ifdef DHD_PKT_LOGGING_DBGRING
|
||||
int
|
||||
dhd_dbg_ring_update(void *dbg_ring, uint32 w_len)
|
||||
{
|
||||
unsigned long flags;
|
||||
dhd_dbg_ring_t *ring = (dhd_dbg_ring_t *)dbg_ring;
|
||||
|
||||
if (ring->id != PACKET_LOG_RING_ID) {
|
||||
return BCME_UNSUPPORTED;
|
||||
}
|
||||
|
||||
DHD_DBG_RING_LOCK(ring->lock, flags);
|
||||
|
||||
if (ring->state != RING_ACTIVE) {
|
||||
DHD_DBG_RING_UNLOCK(ring->lock, flags);
|
||||
return BCME_OK;
|
||||
}
|
||||
|
||||
/* update statistics */
|
||||
ring->stat.written_records++;
|
||||
ring->stat.written_bytes += w_len;
|
||||
DHD_DBGIF(("%s : RING%d[%s] written_records %d, written_bytes %d, read_bytes=%d,"
|
||||
" ring->threshold=%d, wp=%d, rp=%d\n", __FUNCTION__, ring->id, ring->name,
|
||||
ring->stat.written_records, ring->stat.written_bytes, ring->stat.read_bytes,
|
||||
ring->threshold, ring->wp, ring->rp));
|
||||
|
||||
DHD_DBG_RING_UNLOCK(ring->lock, flags);
|
||||
|
||||
return BCME_OK;
|
||||
}
|
||||
#endif /* DHD_PKT_LOGGING_DBGRING */
|
||||
|
||||
int
|
||||
dhd_dbg_ring_push(dhd_dbg_ring_t *ring, dhd_dbg_ring_entry_t *hdr, void *data)
|
||||
{
|
||||
|
|
@ -189,11 +240,22 @@ dhd_dbg_ring_push(dhd_dbg_ring_t *ring, dhd_dbg_ring_entry_t *hdr, void *data)
|
|||
uint32 w_len;
|
||||
uint32 avail_size;
|
||||
dhd_dbg_ring_entry_t *w_entry, *r_entry;
|
||||
int ret;
|
||||
|
||||
if (!ring || !hdr || !data) {
|
||||
return BCME_BADARG;
|
||||
}
|
||||
|
||||
#if defined(__linux__)
|
||||
/* Prevents the case of accessing the ring buffer in the HardIRQ context.
|
||||
* If an interrupt arise after holding ring lock, It could try the same lock.
|
||||
* This is to use the ring lock as spin_lock_bh instead of spin_lock_irqsave.
|
||||
*/
|
||||
if (in_irq()) {
|
||||
return BCME_BUSY;
|
||||
}
|
||||
#endif /* defined(__linux__) */
|
||||
|
||||
DHD_DBG_RING_LOCK(ring->lock, flags);
|
||||
|
||||
if (ring->state != RING_ACTIVE) {
|
||||
|
|
@ -254,7 +316,7 @@ dhd_dbg_ring_push(dhd_dbg_ring_t *ring, dhd_dbg_ring_entry_t *hdr, void *data)
|
|||
ring->rp);
|
||||
/* check bounds before incrementing read ptr */
|
||||
if (ring->rp + ENTRY_LENGTH(r_entry) >= ring->ring_size) {
|
||||
DHD_ERROR(("%s: RING%d[%s] rp points out of boundary,"
|
||||
DHD_DBGIF(("%s: RING%d[%s] rp points out of boundary,"
|
||||
"ring->wp=%u, ring->rp=%u, ring->ring_size=%d\n",
|
||||
__FUNCTION__, ring->id, ring->name, ring->wp,
|
||||
ring->rp, ring->ring_size));
|
||||
|
|
@ -286,7 +348,7 @@ dhd_dbg_ring_push(dhd_dbg_ring_t *ring, dhd_dbg_ring_entry_t *hdr, void *data)
|
|||
|
||||
/* check before writing to the ring */
|
||||
if (ring->wp + w_len >= ring->ring_size) {
|
||||
DHD_ERROR(("%s: RING%d[%s] wp pointed out of ring boundary, "
|
||||
DHD_DBGIF(("%s: RING%d[%s] wp pointed out of ring boundary, "
|
||||
"wp=%d, ring_size=%d, w_len=%u\n", __FUNCTION__, ring->id,
|
||||
ring->name, ring->wp, ring->ring_size, w_len));
|
||||
ASSERT(0);
|
||||
|
|
@ -296,10 +358,22 @@ dhd_dbg_ring_push(dhd_dbg_ring_t *ring, dhd_dbg_ring_entry_t *hdr, void *data)
|
|||
|
||||
w_entry = (dhd_dbg_ring_entry_t *)((uint8 *)ring->ring_buf + ring->wp);
|
||||
/* header */
|
||||
memcpy(w_entry, hdr, DBG_RING_ENTRY_SIZE);
|
||||
ret = memcpy_s(w_entry, avail_size, hdr, DBG_RING_ENTRY_SIZE);
|
||||
if (ret) {
|
||||
DHD_ERROR((" memcpy_s() error : %d, destsz: %d, n: %d\n",
|
||||
ret, avail_size, (int)DBG_RING_ENTRY_SIZE));
|
||||
return BCME_ERROR;
|
||||
}
|
||||
w_entry->len = hdr->len;
|
||||
/* payload */
|
||||
memcpy((char *)w_entry + DBG_RING_ENTRY_SIZE, data, w_entry->len);
|
||||
avail_size -= DBG_RING_ENTRY_SIZE;
|
||||
ret = memcpy_s((char *)w_entry + DBG_RING_ENTRY_SIZE,
|
||||
avail_size, data, w_entry->len);
|
||||
if (ret) {
|
||||
DHD_ERROR((" memcpy_s() error : %d, destsz: %d, n: %d\n",
|
||||
ret, avail_size, w_entry->len));
|
||||
return BCME_ERROR;
|
||||
}
|
||||
/* update write pointer */
|
||||
ring->wp += w_len;
|
||||
|
||||
|
|
@ -325,11 +399,13 @@ dhd_dbg_ring_pull_single(dhd_dbg_ring_t *ring, void *data, uint32 buf_len, bool
|
|||
dhd_dbg_ring_entry_t *r_entry = NULL;
|
||||
uint32 rlen = 0;
|
||||
char *buf = NULL;
|
||||
unsigned long flags;
|
||||
|
||||
if (!ring || !data || buf_len <= 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
DHD_DBG_RING_LOCK(ring->lock, flags);
|
||||
/* pull from ring is allowed for inactive (suspended) ring
|
||||
* in case of ecounters only, this is because, for ecounters
|
||||
* when a trap occurs the ring is suspended and data is then
|
||||
|
|
@ -353,7 +429,7 @@ dhd_dbg_ring_pull_single(dhd_dbg_ring_t *ring, void *data, uint32 buf_len, bool
|
|||
/* Boundary Check */
|
||||
rlen = ENTRY_LENGTH(r_entry);
|
||||
if ((ring->rp + rlen) > ring->ring_size) {
|
||||
DHD_ERROR(("%s: entry len %d is out of boundary of ring size %d,"
|
||||
DHD_DBGIF(("%s: entry len %d is out of boundary of ring size %d,"
|
||||
" current ring %d[%s] - rp=%d\n", __FUNCTION__, rlen,
|
||||
ring->ring_size, ring->id, ring->name, ring->rp));
|
||||
rlen = 0;
|
||||
|
|
@ -368,12 +444,17 @@ dhd_dbg_ring_pull_single(dhd_dbg_ring_t *ring, void *data, uint32 buf_len, bool
|
|||
buf = (char *)r_entry;
|
||||
}
|
||||
if (rlen > buf_len) {
|
||||
DHD_ERROR(("%s: buf len %d is too small for entry len %d\n",
|
||||
DHD_DBGIF(("%s: buf len %d is too small for entry len %d\n",
|
||||
__FUNCTION__, buf_len, rlen));
|
||||
DHD_ERROR(("%s: ring %d[%s] - ring size=%d, wp=%d, rp=%d\n",
|
||||
DHD_DBGIF(("%s: ring %d[%s] - ring size=%d, wp=%d, rp=%d\n",
|
||||
__FUNCTION__, ring->id, ring->name, ring->ring_size,
|
||||
ring->wp, ring->rp));
|
||||
ASSERT(0);
|
||||
/* The state of ringbuffer is different between calculating buf_len
|
||||
* and current. ring->rp have chance to be update by pushing data
|
||||
* to ring buffer when unlocking after calculating buf_len.
|
||||
* But, It doesn't need to ASSERT because we only send up the
|
||||
* entries stored so far.
|
||||
*/
|
||||
rlen = 0;
|
||||
goto exit;
|
||||
}
|
||||
|
|
@ -391,7 +472,7 @@ dhd_dbg_ring_pull_single(dhd_dbg_ring_t *ring, void *data, uint32 buf_len, bool
|
|||
ring->rem_len = 0;
|
||||
}
|
||||
if (ring->rp >= ring->ring_size) {
|
||||
DHD_ERROR(("%s: RING%d[%s] rp pointed out of ring boundary,"
|
||||
DHD_DBGIF(("%s: RING%d[%s] rp pointed out of ring boundary,"
|
||||
" rp=%d, ring_size=%d\n", __FUNCTION__, ring->id,
|
||||
ring->name, ring->rp, ring->ring_size));
|
||||
ASSERT(0);
|
||||
|
|
@ -403,21 +484,27 @@ dhd_dbg_ring_pull_single(dhd_dbg_ring_t *ring, void *data, uint32 buf_len, bool
|
|||
ring->id, ring->name, ring->stat.read_bytes, ring->wp, ring->rp));
|
||||
|
||||
exit:
|
||||
DHD_DBG_RING_UNLOCK(ring->lock, flags);
|
||||
|
||||
return rlen;
|
||||
}
|
||||
|
||||
int
|
||||
dhd_dbg_ring_pull(dhd_dbg_ring_t *ring, void *data, uint32 buf_len, bool strip_hdr)
|
||||
dhd_dbg_ring_pull(dhd_dbg_ring_t *ring, void *data, uint32 buf_len,
|
||||
bool strip_hdr, int *num_entries)
|
||||
{
|
||||
int32 r_len, total_r_len = 0;
|
||||
unsigned long flags;
|
||||
|
||||
if (!ring || !data)
|
||||
return 0;
|
||||
|
||||
DHD_DBG_RING_LOCK(ring->lock, flags);
|
||||
if (!ring->pull_inactive && (ring->state != RING_ACTIVE)) {
|
||||
DHD_DBG_RING_UNLOCK(ring->lock, flags);
|
||||
return 0;
|
||||
}
|
||||
DHD_DBG_RING_UNLOCK(ring->lock, flags);
|
||||
|
||||
while (buf_len > 0) {
|
||||
r_len = dhd_dbg_ring_pull_single(ring, data, buf_len, strip_hdr);
|
||||
|
|
@ -426,6 +513,7 @@ dhd_dbg_ring_pull(dhd_dbg_ring_t *ring, void *data, uint32 buf_len, bool strip_h
|
|||
data = (uint8 *)data + r_len;
|
||||
buf_len -= r_len;
|
||||
total_r_len += r_len;
|
||||
(*num_entries)++;
|
||||
}
|
||||
|
||||
return total_r_len;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* DHD debug ring header file - interface
|
||||
*
|
||||
* Copyright (C) 2020, Broadcom.
|
||||
* Copyright (C) 2022, Broadcom.
|
||||
*
|
||||
* Unless you and Broadcom execute a separate written software license
|
||||
* agreement governing use of this software, this software is licensed to you
|
||||
|
|
@ -52,6 +52,11 @@ typedef struct dhd_dbg_ring_entry {
|
|||
uint64 timestamp; /* present if has_timestamp bit is set. */
|
||||
} PACKED_STRUCT dhd_dbg_ring_entry_t;
|
||||
|
||||
typedef struct dhd_dbg_ring_entry_pack {
|
||||
uint32 magic;
|
||||
int num_entries;
|
||||
} PACKED_STRUCT dhd_dbg_ring_entry_pack_t;
|
||||
|
||||
struct ring_statistics {
|
||||
/* number of bytes that was written to the buffer by driver */
|
||||
uint32 written_bytes;
|
||||
|
|
@ -95,7 +100,9 @@ typedef struct dhd_dbg_ring {
|
|||
bool pull_inactive; /* pull contents from ring even if it is inactive */
|
||||
} dhd_dbg_ring_t;
|
||||
|
||||
#define DBGRING_FLUSH_THRESHOLD(ring) (ring->ring_size / 3)
|
||||
#define DBGRING_FLUSH_THRESHOLD(ring) \
|
||||
(ring->id != PACKET_LOG_RING_ID) ? \
|
||||
(ring->ring_size / 3u) : (ring->ring_size / 4u)
|
||||
#define RING_STAT_TO_STATUS(ring, status) \
|
||||
do { \
|
||||
/* status.name/ring->name are the same length so no need to check return value */ \
|
||||
|
|
@ -108,10 +115,11 @@ typedef struct dhd_dbg_ring {
|
|||
status.verbose_level = ring->log_level; \
|
||||
} while (0)
|
||||
|
||||
#define DBG_RING_PACK_MAGIC 0xDBAADBAA
|
||||
#define DBG_RING_ENTRY_PACK_SIZE (sizeof(dhd_dbg_ring_entry_pack_t))
|
||||
#define DBG_RING_ENTRY_SIZE (sizeof(dhd_dbg_ring_entry_t))
|
||||
#define ENTRY_LENGTH(hdr) ((hdr)->len + DBG_RING_ENTRY_SIZE)
|
||||
#define PAYLOAD_MAX_LEN 65535
|
||||
#define PAYLOAD_ECNTR_MAX_LEN 1648u
|
||||
#define PAYLOAD_RTT_MAX_LEN 1648u
|
||||
#define PAYLOAD_BCM_TRACE_MAX_LEN 1648u
|
||||
#define PENDING_LEN_MAX 0xFFFFFFFF
|
||||
|
|
@ -133,9 +141,13 @@ void dhd_dbg_ring_dealloc_deinit(void **dbgring, dhd_pub_t *dhd);
|
|||
int dhd_dbg_ring_init(dhd_pub_t *dhdp, dhd_dbg_ring_t *ring, uint16 id, uint8 *name,
|
||||
uint32 ring_sz, void *allocd_buf, bool pull_inactive);
|
||||
void dhd_dbg_ring_deinit(dhd_pub_t *dhdp, dhd_dbg_ring_t *ring);
|
||||
int dhd_dbg_ring_set_buf(dhd_pub_t *dhdp, dhd_dbg_ring_t *ring, void *buf);
|
||||
#ifdef DHD_PKT_LOGGING_DBGRING
|
||||
int dhd_dbg_ring_update(void *dbg_ring, uint32 w_len);
|
||||
#endif /* DHD_PKT_LOGGING_DBGRING */
|
||||
int dhd_dbg_ring_push(dhd_dbg_ring_t *ring, dhd_dbg_ring_entry_t *hdr, void *data);
|
||||
int dhd_dbg_ring_pull(dhd_dbg_ring_t *ring, void *data, uint32 buf_len,
|
||||
bool strip_hdr);
|
||||
bool strip_hdr, int* num_entries);
|
||||
int dhd_dbg_ring_pull_single(dhd_dbg_ring_t *ring, void *data, uint32 buf_len,
|
||||
bool strip_header);
|
||||
uint32 dhd_dbg_ring_get_pending_len(dhd_dbg_ring_t *ring);
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* DHD debugability header file
|
||||
*
|
||||
* Copyright (C) 2020, Broadcom.
|
||||
* Copyright (C) 2022, Broadcom.
|
||||
*
|
||||
* Unless you and Broadcom execute a separate written software license
|
||||
* agreement governing use of this software, this software is licensed to you
|
||||
|
|
@ -41,6 +41,7 @@ enum {
|
|||
DBG_DRIVER_DUMP_SUPPORTED = (1 << (7)), /* dumps driver state */
|
||||
DBG_PACKET_FATE_SUPPORTED = (1 << (8)), /* tracks connection packets' fate */
|
||||
DBG_NAN_EVENT_SUPPORTED = (1 << (9)), /* NAN Events */
|
||||
DBG_PACKET_LOG_SUPPORTED = (1 << (10)), /* Packet log with dbgring */
|
||||
};
|
||||
|
||||
enum {
|
||||
|
|
@ -50,6 +51,14 @@ enum {
|
|||
DBG_RING_ENTRY_FLAGS_HAS_TIMESTAMP = (1 << (1))
|
||||
};
|
||||
|
||||
enum {
|
||||
/* Verbose logging level to set for each debug ring buffer */
|
||||
RING_LOG_LEVEL_NONE = 0,
|
||||
RING_LOG_LEVEL_DEFAULT = 1,
|
||||
RING_LOG_LEVEL_VERBOSE = 2,
|
||||
RING_LOG_LEVEL_EXCESSIVE = 3
|
||||
};
|
||||
|
||||
/* firmware verbose ring, ring id 1 */
|
||||
#define FW_VERBOSE_RING_NAME "fw_verbose"
|
||||
#define FW_VERBOSE_RING_SIZE (256 * 1024)
|
||||
|
|
@ -70,13 +79,31 @@ enum {
|
|||
/* ROAM stats log ring */
|
||||
#define ROAM_STATS_RING_NAME "roam_stats"
|
||||
#define ROAM_STATS_RING_SIZE (64 * 1024)
|
||||
|
||||
#define DEBUG_DUMP_RING1_NAME "debug_dump1_"
|
||||
#define DEBUG_DUMP_RING1_SIZE (2 * 1024 * 1024)
|
||||
|
||||
#define DEBUG_DUMP_RING2_NAME "debug_dump2_"
|
||||
#define DEBUG_DUMP_RING2_SIZE (2 * 1024 * 1024)
|
||||
|
||||
#define MEM_DUMP_RING_NAME "mem_dump"
|
||||
#define MEM_DUMP_RING_SIZE (3 * 1024 * 1024)
|
||||
|
||||
#define DHD_DEBUG_DUMP_NETLINK_MAX (1024 * 8)
|
||||
#define DHD_DEBUG_DUMP_MAX_SYNC_CNT 5u
|
||||
#endif /* DHD_DEBUGABILITY_LOG_DUMP_RING */
|
||||
|
||||
#ifdef BTLOG
|
||||
/* BT log ring, ring id 5 */
|
||||
#define BT_LOG_RING_NAME "bt_log"
|
||||
#define BT_LOG_RING_SIZE (64 * 1024)
|
||||
#endif /* BTLOG */
|
||||
/* Packet log ring, ring id 7 */
|
||||
#ifdef DHD_PKT_LOGGING_DBGRING
|
||||
#define DHD_PACKET_LOG_RING_NAME "packet_log"
|
||||
#define DHD_PACKET_LOG_RING_PKTS MIN_PKTLOG_LEN
|
||||
#define DHD_PACKET_LOG_RING_SUSPEND_THRESHOLD \
|
||||
(DHD_PACKET_LOG_RING_PKTS * 8u / 10u)
|
||||
#define DHD_PACKET_LOG_RING_RESUME_THRESHOLD \
|
||||
(DHD_PACKET_LOG_RING_PKTS * 2u / 10u)
|
||||
#define DHD_PACKET_LOG_RING_SIZE \
|
||||
(DHD_PACKET_LOG_RING_PKTS * sizeof(dhd_pktlog_ring_info_t))
|
||||
#endif /* DHD_PKT_LOGGING_DBGRING */
|
||||
|
||||
#define TLV_LOG_SIZE(tlv) ((tlv) ? (sizeof(tlv_log) + (tlv)->len) : 0)
|
||||
|
||||
|
|
@ -90,7 +117,7 @@ enum {
|
|||
|
||||
#ifdef DEBUGABILITY
|
||||
#define DBG_RING_ACTIVE(dhdp, ring_id) \
|
||||
((dhdp)->dbg->dbg_rings[(ring_id)].state == RING_ACTIVE)
|
||||
((dhdp)->dbg && (dhdp)->dbg->dbg_rings[(ring_id)].state == RING_ACTIVE)
|
||||
#else
|
||||
#define DBG_RING_ACTIVE(dhdp, ring_id) 0
|
||||
#endif /* DEBUGABILITY */
|
||||
|
|
@ -424,6 +451,16 @@ typedef enum {
|
|||
/* Packet free by firmware. */
|
||||
TX_PKT_FATE_FW_PKT_FREE,
|
||||
|
||||
/* Firmware dropped the frame after suppress retries reached max */
|
||||
TX_PKT_FATE_FW_MAX_SUP_RETR,
|
||||
|
||||
/* Firmware forced packet lifetime expiry */
|
||||
TX_PKT_FATE_FW_FORCED_EXPIRED,
|
||||
|
||||
#ifdef DHD_PKT_LOGGING_DBGRING
|
||||
/* Indicate to wait for updating txfate. */
|
||||
TX_PKT_FATE_DRV_WAIT_UPDATE = 0x80000000,
|
||||
#endif /* DHD_PKT_LOGGING_DBGRING */
|
||||
} wifi_tx_packet_fate;
|
||||
|
||||
typedef enum {
|
||||
|
|
@ -627,22 +664,26 @@ typedef struct dhd_dbg_rx_info
|
|||
typedef struct dhd_dbg_tx_report
|
||||
{
|
||||
dhd_dbg_tx_info_t *tx_pkts;
|
||||
/* Indicates how many packets queued to send over the air */
|
||||
uint16 pkt_pos;
|
||||
/* Indicates how many packets sent over the air and received txstatus */
|
||||
uint16 status_pos;
|
||||
} dhd_dbg_tx_report_t;
|
||||
|
||||
typedef struct dhd_dbg_rx_report
|
||||
{
|
||||
dhd_dbg_rx_info_t *rx_pkts;
|
||||
/* Indicates how many packets sent over the air and received txstatus */
|
||||
uint16 pkt_pos;
|
||||
} dhd_dbg_rx_report_t;
|
||||
|
||||
typedef void (*dbg_pullreq_t)(void *os_priv, const int ring_id);
|
||||
typedef void (*dbg_urgent_noti_t) (dhd_pub_t *dhdp, const void *data, const uint32 len);
|
||||
typedef int (*dbg_mon_tx_pkts_t) (dhd_pub_t *dhdp, void *pkt, uint32 pktid);
|
||||
typedef int (*dbg_mon_tx_pkts_t) (dhd_pub_t *dhdp, void *pkt, uint32 pktid,
|
||||
frame_type type, uint8 mgmt_acked);
|
||||
typedef int (*dbg_mon_tx_status_t) (dhd_pub_t *dhdp, void *pkt,
|
||||
uint32 pktid, uint16 status);
|
||||
typedef int (*dbg_mon_rx_pkts_t) (dhd_pub_t *dhdp, void *pkt);
|
||||
typedef int (*dbg_mon_rx_pkts_t) (dhd_pub_t *dhdp, void *pkt, frame_type type);
|
||||
|
||||
typedef struct dhd_dbg_pkt_mon
|
||||
{
|
||||
|
|
@ -682,10 +723,11 @@ typedef struct dhd_dbg {
|
|||
(((status_count) >= (pkt_count)) || ((status_count) >= MAX_FATE_LOG_LEN))
|
||||
|
||||
#ifdef DBG_PKT_MON
|
||||
#define DHD_DBG_PKT_MON_TX(dhdp, pkt, pktid) \
|
||||
#define DHD_DBG_PKT_MON_TX(dhdp, pkt, pktid, type, mgmt_acked) \
|
||||
do { \
|
||||
if ((dhdp) && (dhdp)->dbg && (dhdp)->dbg->pkt_mon.tx_pkt_mon && (pkt)) { \
|
||||
(dhdp)->dbg->pkt_mon.tx_pkt_mon((dhdp), (pkt), (pktid)); \
|
||||
(dhdp)->dbg->pkt_mon.tx_pkt_mon((dhdp), (pkt), \
|
||||
(pktid), (type), (mgmt_acked)); \
|
||||
} \
|
||||
} while (0);
|
||||
#define DHD_DBG_PKT_MON_TX_STATUS(dhdp, pkt, pktid, status) \
|
||||
|
|
@ -694,11 +736,11 @@ typedef struct dhd_dbg {
|
|||
(dhdp)->dbg->pkt_mon.tx_status_mon((dhdp), (pkt), (pktid), (status)); \
|
||||
} \
|
||||
} while (0);
|
||||
#define DHD_DBG_PKT_MON_RX(dhdp, pkt) \
|
||||
#define DHD_DBG_PKT_MON_RX(dhdp, pkt, type) \
|
||||
do { \
|
||||
if ((dhdp) && (dhdp)->dbg && (dhdp)->dbg->pkt_mon.rx_pkt_mon && (pkt)) { \
|
||||
if (ntoh16((pkt)->protocol) != ETHER_TYPE_BRCM) { \
|
||||
(dhdp)->dbg->pkt_mon.rx_pkt_mon((dhdp), (pkt)); \
|
||||
(dhdp)->dbg->pkt_mon.rx_pkt_mon((dhdp), (pkt), (type)); \
|
||||
} \
|
||||
} \
|
||||
} while (0);
|
||||
|
|
@ -708,9 +750,9 @@ typedef struct dhd_dbg {
|
|||
#define DHD_DBG_PKT_MON_STOP(dhdp) \
|
||||
dhd_os_dbg_stop_pkt_monitor((dhdp));
|
||||
#else
|
||||
#define DHD_DBG_PKT_MON_TX(dhdp, pkt, pktid)
|
||||
#define DHD_DBG_PKT_MON_TX(dhdp, pkt, pktid, type, mgmt_acked)
|
||||
#define DHD_DBG_PKT_MON_TX_STATUS(dhdp, pkt, pktid, status)
|
||||
#define DHD_DBG_PKT_MON_RX(dhdp, pkt)
|
||||
#define DHD_DBG_PKT_MON_RX(dhdp, pkt, type)
|
||||
#define DHD_DBG_PKT_MON_START(dhdp)
|
||||
#define DHD_DBG_PKT_MON_STOP(dhdp)
|
||||
#endif /* DBG_PKT_MON */
|
||||
|
|
@ -741,6 +783,8 @@ typedef struct {
|
|||
|
||||
#define DHD_EVENT_LOG_FMT_NUM_OFFSET 2
|
||||
#define DHD_EVENT_LOG_FMT_NUM_MASK 0x3FFF
|
||||
|
||||
#define DHD_EXT_FMTNUM_MASK 0xF /* bits[3..0] used */
|
||||
/**
|
||||
* OW:- one word
|
||||
* TW:- two word
|
||||
|
|
@ -783,9 +827,6 @@ void dhd_dbg_msgtrace_log_parser(dhd_pub_t *dhdp, void *event_data,
|
|||
void *raw_event_ptr, uint datalen, bool msgtrace_hdr_present,
|
||||
uint32 msgtrace_seqnum);
|
||||
|
||||
#ifdef BTLOG
|
||||
extern void dhd_dbg_bt_log_handler(dhd_pub_t *dhdp, void *data, uint datalen);
|
||||
#endif /* BTLOG */
|
||||
extern int dhd_dbg_attach(dhd_pub_t *dhdp, dbg_pullreq_t os_pullreq,
|
||||
dbg_urgent_noti_t os_urgent_notifier, void *os_priv);
|
||||
extern void dhd_dbg_detach(dhd_pub_t *dhdp);
|
||||
|
|
@ -798,9 +839,18 @@ extern void *dhd_dbg_get_priv(dhd_pub_t *dhdp);
|
|||
extern int dhd_dbg_send_urgent_evt(dhd_pub_t *dhdp, const void *data, const uint32 len);
|
||||
extern void dhd_dbg_verboselog_printf(dhd_pub_t *dhdp, prcd_event_log_hdr_t *plog_hdr,
|
||||
void *raw_event_ptr, uint32 *log_ptr, uint32 logset, uint16 block);
|
||||
int dhd_dbg_pull_from_ring(dhd_pub_t *dhdp, int ring_id, void *data, uint32 buf_len);
|
||||
int dhd_dbg_pull_from_ring(dhd_pub_t *dhdp, int ring_id, void *data, uint32 buf_len,
|
||||
int *num_entries);
|
||||
int dhd_dbg_pull_single_from_ring(dhd_pub_t *dhdp, int ring_id, void *data, uint32 buf_len,
|
||||
bool strip_header);
|
||||
#ifdef DHD_PKT_LOGGING_DBGRING
|
||||
int dhd_dbg_update_to_ring(dhd_pub_t *dhdp, void *ring, uint32 w_len);
|
||||
int dhd_dbg_pull_from_pktlog(dhd_pub_t *dhdp, int ring_id, void *data, uint32 buf_len);
|
||||
void dhd_os_dbg_urgent_pullreq(void *os_priv, int ring_id);
|
||||
#endif /* DHD_PKT_LOGGING_DBGRING */
|
||||
#ifdef DHD_DEBUGABILITY_DEBUG_DUMP
|
||||
int dhd_debug_dump_ring_push(dhd_pub_t *dhdp, int ring_id, uint32 len, void *data);
|
||||
#endif /* DHD_DEBUGABILITY_DEBUG_DUMP */
|
||||
int dhd_dbg_push_to_ring(dhd_pub_t *dhdp, int ring_id, dhd_dbg_ring_entry_t *hdr,
|
||||
void *data);
|
||||
int __dhd_dbg_get_ring_status(dhd_dbg_ring_t *ring, dhd_dbg_ring_status_t *ring_status);
|
||||
|
|
@ -816,10 +866,11 @@ extern int dhd_dbg_attach_pkt_monitor(dhd_pub_t *dhdp,
|
|||
dbg_mon_tx_status_t tx_status_mon,
|
||||
dbg_mon_rx_pkts_t rx_pkt_mon);
|
||||
extern int dhd_dbg_start_pkt_monitor(dhd_pub_t *dhdp);
|
||||
extern int dhd_dbg_monitor_tx_pkts(dhd_pub_t *dhdp, void *pkt, uint32 pktid);
|
||||
extern int dhd_dbg_monitor_tx_pkts(dhd_pub_t *dhdp, void *pkt,
|
||||
uint32 pktid, frame_type type, uint8 mgmt_acked);
|
||||
extern int dhd_dbg_monitor_tx_status(dhd_pub_t *dhdp, void *pkt,
|
||||
uint32 pktid, uint16 status);
|
||||
extern int dhd_dbg_monitor_rx_pkts(dhd_pub_t *dhdp, void *pkt);
|
||||
extern int dhd_dbg_monitor_rx_pkts(dhd_pub_t *dhdp, void *pkt, frame_type type);
|
||||
extern int dhd_dbg_stop_pkt_monitor(dhd_pub_t *dhdp);
|
||||
extern int dhd_dbg_monitor_get_tx_pkts(dhd_pub_t *dhdp, void __user *user_buf,
|
||||
uint16 req_count, uint16 *resp_count);
|
||||
|
|
@ -855,10 +906,11 @@ extern int dhd_os_dbg_get_feature(dhd_pub_t *dhdp, int32 *features);
|
|||
extern int dhd_os_dbg_attach_pkt_monitor(dhd_pub_t *dhdp);
|
||||
extern int dhd_os_dbg_start_pkt_monitor(dhd_pub_t *dhdp);
|
||||
extern int dhd_os_dbg_monitor_tx_pkts(dhd_pub_t *dhdp, void *pkt,
|
||||
uint32 pktid);
|
||||
uint32 pktid, frame_type type, uint8 mgmt_acked);
|
||||
extern int dhd_os_dbg_monitor_tx_status(dhd_pub_t *dhdp, void *pkt,
|
||||
uint32 pktid, uint16 status);
|
||||
extern int dhd_os_dbg_monitor_rx_pkts(dhd_pub_t *dhdp, void *pkt);
|
||||
extern int dhd_os_dbg_monitor_rx_pkts(dhd_pub_t *dhdp, void *pkt,
|
||||
frame_type type);
|
||||
extern int dhd_os_dbg_stop_pkt_monitor(dhd_pub_t *dhdp);
|
||||
extern int dhd_os_dbg_monitor_get_tx_pkts(dhd_pub_t *dhdp,
|
||||
void __user *user_buf, uint16 req_count, uint16 *resp_count);
|
||||
|
|
|
|||
200
drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_debug_linux.c
Executable file → Normal file
200
drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_debug_linux.c
Executable file → Normal file
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* DHD debugability Linux os layer
|
||||
*
|
||||
* Copyright (C) 2020, Broadcom.
|
||||
* Copyright (C) 2022, Broadcom.
|
||||
*
|
||||
* Unless you and Broadcom execute a separate written software license
|
||||
* agreement governing use of this software, this software is licensed to you
|
||||
|
|
@ -34,6 +34,9 @@
|
|||
|
||||
#include <net/cfg80211.h>
|
||||
#include <wl_cfgvendor.h>
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 3, 0)
|
||||
#include <linux/sched/clock.h>
|
||||
#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(6, 3, 0) */
|
||||
#include <dhd_config.h>
|
||||
|
||||
typedef void (*dbg_ring_send_sub_t)(void *ctx, const int ring_id, const void *data,
|
||||
|
|
@ -73,6 +76,7 @@ debug_data_send(dhd_pub_t *dhdp, int ring_id, const void *data, const uint32 len
|
|||
struct net_device *ndev;
|
||||
dbg_ring_send_sub_t ring_sub_send;
|
||||
ndev = dhd_linux_get_primary_netdev(dhdp);
|
||||
|
||||
if (!ndev)
|
||||
return;
|
||||
if (!VALID_RING(ring_id))
|
||||
|
|
@ -105,11 +109,21 @@ dbg_ring_poll_worker(struct work_struct *work)
|
|||
dhd_pub_t *dhdp;
|
||||
int ringid;
|
||||
dhd_dbg_ring_status_t ring_status;
|
||||
void *buf;
|
||||
void *buf, *buf_entries;
|
||||
dhd_dbg_ring_entry_pack_t *pack_hdr;
|
||||
dhd_dbg_ring_entry_t *hdr;
|
||||
uint32 buflen, rlen;
|
||||
int32 buflen, rlen, remain_buflen;
|
||||
int32 alloc_len;
|
||||
unsigned long flags;
|
||||
|
||||
BCM_REFERENCE(hdr);
|
||||
|
||||
if (!CAN_SLEEP()) {
|
||||
DHD_CONS_ONLY(("this context should be sleepable\n"));
|
||||
sched = FALSE;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
GCC_DIAGNOSTIC_PUSH_SUPPRESS_CAST();
|
||||
ring_info = container_of(d_work, linux_dbgring_info_t, work);
|
||||
GCC_DIAGNOSTIC_POP();
|
||||
|
|
@ -120,55 +134,126 @@ dbg_ring_poll_worker(struct work_struct *work)
|
|||
ring = &dhdp->dbg->dbg_rings[ringid];
|
||||
DHD_DBG_RING_LOCK(ring->lock, flags);
|
||||
dhd_dbg_get_ring_status(dhdp, ringid, &ring_status);
|
||||
DHD_DBG_RING_UNLOCK(ring->lock, flags);
|
||||
|
||||
if (ring->wp > ring->rp) {
|
||||
buflen = ring->wp - ring->rp;
|
||||
} else if (ring->wp < ring->rp) {
|
||||
buflen = ring->ring_size - ring->rp + ring->wp;
|
||||
} else {
|
||||
goto exit;
|
||||
#ifdef DHD_PKT_LOGGING_DBGRING
|
||||
if (ringid == PACKET_LOG_RING_ID) {
|
||||
struct net_device *ndev;
|
||||
ndev = dhd_linux_get_primary_netdev(dhdp);
|
||||
buflen = DBG_RING_ENTRY_SIZE;
|
||||
buflen += dhd_os_get_pktlog_dump_size(ndev);
|
||||
DHD_DBGIF(("%s: buflen: %d\n", __FUNCTION__, buflen));
|
||||
alloc_len = buflen + DBG_RING_ENTRY_PACK_SIZE;
|
||||
} else
|
||||
#endif /* DHD_PKT_LOGGING_DBGRING */
|
||||
{
|
||||
DHD_DBG_RING_LOCK(ring->lock, flags);
|
||||
if (ring->wp > ring->rp) {
|
||||
buflen = ring->wp - ring->rp;
|
||||
} else if (ring->wp < ring->rp) {
|
||||
buflen = ring->ring_size - ring->rp + ring->wp;
|
||||
} else {
|
||||
DHD_DBG_RING_UNLOCK(ring->lock, flags);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (buflen > ring->ring_size) {
|
||||
DHD_DBG_RING_UNLOCK(ring->lock, flags);
|
||||
goto exit;
|
||||
}
|
||||
DHD_DBG_RING_UNLOCK(ring->lock, flags);
|
||||
|
||||
alloc_len = NLMSG_DEFAULT_SIZE;
|
||||
}
|
||||
buf = VMALLOCZ(dhdp->osh, alloc_len);
|
||||
|
||||
if (buflen > ring->ring_size) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
buf = MALLOCZ(dhdp->osh, buflen);
|
||||
if (!buf) {
|
||||
DHD_ERROR(("%s failed to allocate read buf\n", __FUNCTION__));
|
||||
DHD_CONS_ONLY(("%s failed to allocate read buf\n", __FUNCTION__));
|
||||
sched = FALSE;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
DHD_DBG_RING_UNLOCK(ring->lock, flags);
|
||||
rlen = dhd_dbg_pull_from_ring(dhdp, ringid, buf, buflen);
|
||||
DHD_DBG_RING_LOCK(ring->lock, flags);
|
||||
pack_hdr = (dhd_dbg_ring_entry_pack_t *)buf;
|
||||
pack_hdr->magic = DBG_RING_PACK_MAGIC;
|
||||
|
||||
buf_entries = (char *)buf + sizeof(dhd_dbg_ring_entry_pack_t);
|
||||
|
||||
#ifdef DHD_PKT_LOGGING_DBGRING
|
||||
if (ringid == PACKET_LOG_RING_ID) {
|
||||
pack_hdr->num_entries = 1u;
|
||||
rlen = dhd_dbg_pull_from_pktlog(dhdp, ringid, buf_entries, buflen);
|
||||
DHD_DBGIF(("%s: rlen: %d\n", __FUNCTION__, rlen));
|
||||
hdr = (dhd_dbg_ring_entry_t *)buf_entries;
|
||||
while (rlen > 0) {
|
||||
DHD_DBG_RING_LOCK(ring->lock, flags);
|
||||
ring_status.read_bytes += (rlen - DBG_RING_ENTRY_SIZE);
|
||||
ring->stat.read_bytes += (rlen - DBG_RING_ENTRY_SIZE);
|
||||
if (ring->stat.read_bytes > ring->stat.written_bytes) {
|
||||
DHD_DBGIF(("%s READ/WRITE counter mismatched!\n", __FUNCTION__));
|
||||
ring->stat.read_bytes = ring->stat.written_bytes;
|
||||
}
|
||||
DHD_DBGIF(("%s RING%d[%s]read_bytes %d, written_bytes %d, "
|
||||
"writen_records %d\n", __FUNCTION__, ring->id, ring->name,
|
||||
ring->stat.read_bytes, ring->stat.written_bytes,
|
||||
ring->stat.written_records));
|
||||
DHD_DBG_RING_UNLOCK(ring->lock, flags);
|
||||
/* offset fw ts to host ts */
|
||||
hdr->timestamp += ring_info->tsoffset;
|
||||
debug_data_send(dhdp, ringid, pack_hdr,
|
||||
ENTRY_LENGTH(hdr) + DBG_RING_ENTRY_PACK_SIZE, ring_status);
|
||||
rlen -= ENTRY_LENGTH(hdr);
|
||||
hdr = (dhd_dbg_ring_entry_t *)((char *)hdr + ENTRY_LENGTH(hdr));
|
||||
}
|
||||
} else
|
||||
#endif /* DHD_PKT_LOGGING_DBGRING */
|
||||
{
|
||||
remain_buflen = buflen;
|
||||
while (remain_buflen > 0) {
|
||||
pack_hdr->num_entries = 0;
|
||||
memset_s(buf_entries, NLMSG_DEFAULT_SIZE - DBG_RING_ENTRY_PACK_SIZE,
|
||||
0, NLMSG_DEFAULT_SIZE - DBG_RING_ENTRY_PACK_SIZE);
|
||||
/* Returns as much as possible with the size of the passed buffer
|
||||
* rlen means the total length of multiple entries including entry hdr
|
||||
*/
|
||||
rlen = dhd_dbg_pull_from_ring(dhdp, ringid, buf_entries,
|
||||
NLMSG_DEFAULT_SIZE - DBG_RING_ENTRY_PACK_SIZE,
|
||||
&pack_hdr->num_entries);
|
||||
if (rlen <= 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
DHD_DBG_RING_LOCK(ring->lock, flags);
|
||||
ring_status.read_bytes += rlen;
|
||||
DHD_DBG_RING_UNLOCK(ring->lock, flags);
|
||||
|
||||
/* payload length includes pack_hdr size */
|
||||
debug_data_send(dhdp, ringid, pack_hdr,
|
||||
rlen + DBG_RING_ENTRY_PACK_SIZE, ring_status);
|
||||
remain_buflen -= rlen;
|
||||
}
|
||||
}
|
||||
|
||||
VMFREE(dhdp->osh, buf, alloc_len);
|
||||
|
||||
DHD_DBG_RING_LOCK(ring->lock, flags);
|
||||
if (!ring->sched_pull) {
|
||||
ring->sched_pull = TRUE;
|
||||
}
|
||||
|
||||
hdr = (dhd_dbg_ring_entry_t *)buf;
|
||||
while (rlen > 0) {
|
||||
ring_status.read_bytes += ENTRY_LENGTH(hdr);
|
||||
/* offset fw ts to host ts */
|
||||
hdr->timestamp += ring_info->tsoffset;
|
||||
debug_data_send(dhdp, ringid, hdr, ENTRY_LENGTH(hdr),
|
||||
ring_status);
|
||||
rlen -= ENTRY_LENGTH(hdr);
|
||||
hdr = (dhd_dbg_ring_entry_t *)((char *)hdr + ENTRY_LENGTH(hdr));
|
||||
}
|
||||
MFREE(dhdp->osh, buf, buflen);
|
||||
|
||||
DHD_DBG_RING_UNLOCK(ring->lock, flags);
|
||||
exit:
|
||||
if (sched) {
|
||||
/* retrigger the work at same interval */
|
||||
if ((ring_status.written_bytes == ring_status.read_bytes) &&
|
||||
(ring_info->interval)) {
|
||||
schedule_delayed_work(d_work, ring_info->interval);
|
||||
if ((ring_info->interval)) {
|
||||
if ((ring_status.written_bytes == ring_status.read_bytes) ||
|
||||
#ifdef DHD_PKT_LOGGING_DBGRING
|
||||
(ringid == PACKET_LOG_RING_ID)) {
|
||||
#else
|
||||
FALSE) {
|
||||
#endif /* DHD_PKT_LOGGING_DBGRING */
|
||||
schedule_delayed_work(d_work, ring_info->interval);
|
||||
}
|
||||
}
|
||||
}
|
||||
DHD_DBG_RING_UNLOCK(ring->lock, flags);
|
||||
|
||||
return;
|
||||
}
|
||||
|
|
@ -205,8 +290,9 @@ dhd_os_start_logging(dhd_pub_t *dhdp, char *ring_name, int log_level,
|
|||
if (!VALID_RING(ring_id))
|
||||
return BCME_UNSUPPORTED;
|
||||
|
||||
DHD_INFO(("%s , log_level : %d, time_intval : %d, threshod %d Bytes\n",
|
||||
__FUNCTION__, log_level, time_intval, threshold));
|
||||
DHD_ERROR(("%s , ring_id : %d log_level : %d, "
|
||||
"time_intval : %d, threshod %d Bytes\n",
|
||||
__FUNCTION__, ring_id, log_level, time_intval, threshold));
|
||||
|
||||
/* change the configuration */
|
||||
ret = dhd_dbg_set_configuration(dhdp, ring_id, log_level, flags, threshold);
|
||||
|
|
@ -248,8 +334,6 @@ dhd_os_reset_logging(dhd_pub_t *dhdp)
|
|||
DHD_INFO(("%s: Stop ring buffer %d\n", __FUNCTION__, ring_id));
|
||||
|
||||
ring_info = &os_priv[ring_id];
|
||||
/* cancel any pending work */
|
||||
cancel_delayed_work_sync(&ring_info->work);
|
||||
/* log level zero makes stop logging on that ring */
|
||||
ring_info->log_level = 0;
|
||||
ring_info->interval = 0;
|
||||
|
|
@ -259,6 +343,8 @@ dhd_os_reset_logging(dhd_pub_t *dhdp)
|
|||
DHD_ERROR(("dhd_set_configuration is failed : %d\n", ret));
|
||||
return ret;
|
||||
}
|
||||
/* cancel any pending work */
|
||||
cancel_delayed_work_sync(&ring_info->work);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -365,7 +451,7 @@ dhd_os_push_push_ring_data(dhd_pub_t *dhdp, int ring_id, void *data, int32 data_
|
|||
}
|
||||
#endif /* DHD_DEBUGABILITY_LOG_DUMP_RING */
|
||||
ret = dhd_dbg_push_to_ring(dhdp, ring_id, &msg_hdr, event_data);
|
||||
if (ret) {
|
||||
if (ret && ret != BCME_BUSY) {
|
||||
DHD_ERROR(("%s : failed to push data into the ring (%d) with ret(%d)\n",
|
||||
__FUNCTION__, ring_id, ret));
|
||||
}
|
||||
|
|
@ -388,9 +474,10 @@ dhd_os_dbg_start_pkt_monitor(dhd_pub_t *dhdp)
|
|||
}
|
||||
|
||||
int
|
||||
dhd_os_dbg_monitor_tx_pkts(dhd_pub_t *dhdp, void *pkt, uint32 pktid)
|
||||
dhd_os_dbg_monitor_tx_pkts(dhd_pub_t *dhdp, void *pkt, uint32 pktid,
|
||||
frame_type type, uint8 mgmt_acked)
|
||||
{
|
||||
return dhd_dbg_monitor_tx_pkts(dhdp, pkt, pktid);
|
||||
return dhd_dbg_monitor_tx_pkts(dhdp, pkt, pktid, type, mgmt_acked);
|
||||
}
|
||||
|
||||
int
|
||||
|
|
@ -401,9 +488,9 @@ dhd_os_dbg_monitor_tx_status(dhd_pub_t *dhdp, void *pkt, uint32 pktid,
|
|||
}
|
||||
|
||||
int
|
||||
dhd_os_dbg_monitor_rx_pkts(dhd_pub_t *dhdp, void *pkt)
|
||||
dhd_os_dbg_monitor_rx_pkts(dhd_pub_t *dhdp, void *pkt, frame_type type)
|
||||
{
|
||||
return dhd_dbg_monitor_rx_pkts(dhdp, pkt);
|
||||
return dhd_dbg_monitor_rx_pkts(dhdp, pkt, type);
|
||||
}
|
||||
|
||||
int
|
||||
|
|
@ -465,6 +552,9 @@ dhd_os_dbg_get_feature(dhd_pub_t *dhdp, int32 *features)
|
|||
}
|
||||
#endif /* DBG_PKT_MON */
|
||||
#endif /* DEBUGABILITY */
|
||||
#ifdef DHD_PKT_LOGGING_DBGRING
|
||||
*features |= DBG_PACKET_LOG_SUPPORTED;
|
||||
#endif /* DHD_PKT_LOGGING_DBGRING */
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -478,6 +568,14 @@ dhd_os_dbg_pullreq(void *os_priv, int ring_id)
|
|||
schedule_delayed_work(&ring_info->work, 0);
|
||||
}
|
||||
|
||||
#ifdef DHD_PKT_LOGGING_DBGRING
|
||||
void
|
||||
dhd_os_dbg_urgent_pullreq(void *os_priv, int ring_id)
|
||||
{
|
||||
dhd_os_dbg_pullreq(os_priv, ring_id);
|
||||
}
|
||||
#endif /* DHD_PKT_LOGGING_DBGRING */
|
||||
|
||||
int
|
||||
dhd_os_dbg_attach(dhd_pub_t *dhdp)
|
||||
{
|
||||
|
|
@ -486,9 +584,12 @@ dhd_os_dbg_attach(dhd_pub_t *dhdp)
|
|||
int ring_id;
|
||||
|
||||
/* os_dbg data */
|
||||
os_priv = MALLOCZ(dhdp->osh, sizeof(*os_priv) * DEBUG_RING_ID_MAX);
|
||||
if (!os_priv)
|
||||
os_priv = VMALLOCZ(dhdp->osh, sizeof(*os_priv) * DEBUG_RING_ID_MAX);
|
||||
if (!os_priv) {
|
||||
DHD_ERROR(("%s:%d: VMALLOC failed for os_priv, size %d\n", __FUNCTION__,
|
||||
__LINE__, (uint32)sizeof(*os_priv) * DEBUG_RING_ID_MAX));
|
||||
return BCME_NOMEM;
|
||||
}
|
||||
|
||||
for (ring_id = DEBUG_RING_ID_INVALID + 1; ring_id < DEBUG_RING_ID_MAX;
|
||||
ring_id++) {
|
||||
|
|
@ -499,8 +600,9 @@ dhd_os_dbg_attach(dhd_pub_t *dhdp)
|
|||
}
|
||||
|
||||
ret = dhd_dbg_attach(dhdp, dhd_os_dbg_pullreq, dhd_os_dbg_urgent_notifier, os_priv);
|
||||
if (ret)
|
||||
MFREE(dhdp->osh, os_priv, sizeof(*os_priv) * DEBUG_RING_ID_MAX);
|
||||
if (ret) {
|
||||
VMFREE(dhdp->osh, os_priv, sizeof(*os_priv) * DEBUG_RING_ID_MAX);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -522,7 +624,7 @@ dhd_os_dbg_detach(dhd_pub_t *dhdp)
|
|||
cancel_delayed_work_sync(&ring_info->work);
|
||||
}
|
||||
}
|
||||
MFREE(dhdp->osh, os_priv, sizeof(*os_priv) * DEBUG_RING_ID_MAX);
|
||||
VMFREE(dhdp->osh, os_priv, sizeof(*os_priv) * DEBUG_RING_ID_MAX);
|
||||
|
||||
return dhd_dbg_detach(dhdp);
|
||||
}
|
||||
|
|
|
|||
170
drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_event_log_filter.c
Executable file → Normal file
170
drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_event_log_filter.c
Executable file → Normal file
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* Wifi dongle status Filter and Report
|
||||
*
|
||||
* Copyright (C) 2020, Broadcom.
|
||||
* Copyright (C) 2022, Broadcom.
|
||||
*
|
||||
* Unless you and Broadcom execute a separate written software license
|
||||
* agreement governing use of this software, this software is licensed to you
|
||||
|
|
@ -63,11 +63,7 @@
|
|||
#endif /* IL_BIGENDINAN */
|
||||
|
||||
#define DHD_FILTER_ERR_INTERNAL(fmt, ...) DHD_ERROR(("EWPF-" fmt, ##__VA_ARGS__))
|
||||
#ifdef DHD_REPLACE_LOG_INFO_TO_TRACE
|
||||
#define DHD_FILTER_TRACE_INTERNAL(fmt, ...) DHD_TRACE(("EWPF-" fmt, ##__VA_ARGS__))
|
||||
#else
|
||||
#define DHD_FILTER_TRACE_INTERNAL(fmt, ...) DHD_INFO(("EWPF-" fmt, ##__VA_ARGS__))
|
||||
#endif /* DHD_REPLACE_LOG_INFO_TO_TRACE */
|
||||
|
||||
#define DHD_FILTER_ERR(x) DHD_FILTER_ERR_INTERNAL x
|
||||
#define DHD_FILTER_TRACE(x) DHD_FILTER_TRACE_INTERNAL x
|
||||
|
|
@ -92,7 +88,7 @@
|
|||
#define EWPF_SLICE_MAIN 0 /* SLICE ID for 5GHZ */
|
||||
#define EWPF_SLICE_AUX 1 /* SLICE ID for 2GHZ */
|
||||
|
||||
#define EWPF_MAX_IFACE 2 /* MAX IFACE supported, 0: STA */
|
||||
#define EWPF_MAX_IFACE 3 /* MAX IFACE supported */
|
||||
#define EWPF_MAX_EVENT 1 /* MAX EVENT counter supported */
|
||||
#define EWPF_MAX_KEY_INFO 1 /* MAX KEY INFO counter supported */
|
||||
|
||||
|
|
@ -131,6 +127,7 @@ typedef struct {
|
|||
wl_periodic_compact_cntrs_v1_t compact_cntr_v1;
|
||||
wl_periodic_compact_cntrs_v2_t compact_cntr_v2;
|
||||
wl_periodic_compact_cntrs_v3_t compact_cntr_v3;
|
||||
wl_periodic_compact_cntrs_v4_t compact_cntr_v4;
|
||||
};
|
||||
evt_hist_compact_toss_stats_v1_t hist_tx_toss_stat;
|
||||
evt_hist_compact_toss_stats_v1_t hist_rx_toss_stat;
|
||||
|
|
@ -230,7 +227,7 @@ static EWPF_tbl_t EWPF_periodic[] =
|
|||
{
|
||||
WL_STATE_COMPACT_COUNTERS,
|
||||
evt_xtlv_copy_cb,
|
||||
SLICE_INFO(compact_cntr_v3),
|
||||
SLICE_INFO(compact_cntr_v4),
|
||||
NULL
|
||||
},
|
||||
{
|
||||
|
|
@ -835,7 +832,7 @@ static int
|
|||
evt_get_last_toss_hist(uint8 *ptr, const uint8 *data, uint16 len)
|
||||
{
|
||||
bcm_xtlv_t *bcm_xtlv_desc = (bcm_xtlv_t *)data;
|
||||
wl_hist_compact_toss_stats_v2_t *ewp_stats;
|
||||
wl_hist_compact_toss_stats_v3_t *ewp_stats;
|
||||
evt_hist_compact_toss_stats_v1_t bidata_stats;
|
||||
int16 max_rcidx = EWPF_INVALID, secnd_rcidx = EWPF_INVALID;
|
||||
uint16 cur_rnidx = 0, prev_rnidx = 0;
|
||||
|
|
@ -846,21 +843,21 @@ evt_get_last_toss_hist(uint8 *ptr, const uint8 *data, uint16 len)
|
|||
return BCME_ERROR;
|
||||
}
|
||||
|
||||
if (bcm_xtlv_desc->len != sizeof(wl_hist_compact_toss_stats_v2_t)) {
|
||||
if (bcm_xtlv_desc->len != sizeof(wl_hist_compact_toss_stats_v3_t)) {
|
||||
DHD_FILTER_ERR(("%s : size is not matched %d\n", __FUNCTION__,
|
||||
bcm_xtlv_desc->len));
|
||||
return BCME_ERROR;
|
||||
}
|
||||
|
||||
ewp_stats = (wl_hist_compact_toss_stats_v2_t *)(&bcm_xtlv_desc->data[0]);
|
||||
ewp_stats = (wl_hist_compact_toss_stats_v3_t *)(&bcm_xtlv_desc->data[0]);
|
||||
if (ewp_stats->htr_type == WL_STATE_HIST_TX_TOSS_REASONS) {
|
||||
if (ewp_stats->version != WL_HIST_COMPACT_TOSS_STATS_TX_VER_2) {
|
||||
if (ewp_stats->version != WL_HIST_COMPACT_TOSS_STATS_TX_VER_3) {
|
||||
DHD_FILTER_ERR(("%s : unsupported version %d (type: %d)\n",
|
||||
__FUNCTION__, ewp_stats->version, ewp_stats->htr_type));
|
||||
return BCME_ERROR;
|
||||
}
|
||||
} else if (ewp_stats->htr_type == WL_STATE_HIST_RX_TOSS_REASONS) {
|
||||
if (ewp_stats->version != WL_HIST_COMPACT_TOSS_STATS_RX_VER_2) {
|
||||
if (ewp_stats->version != WL_HIST_COMPACT_TOSS_STATS_RX_VER_3) {
|
||||
DHD_FILTER_ERR(("%s : unsupported version %d (type: %d)\n",
|
||||
__FUNCTION__, ewp_stats->version, ewp_stats->htr_type));
|
||||
return BCME_ERROR;
|
||||
|
|
@ -888,10 +885,9 @@ evt_get_last_toss_hist(uint8 *ptr, const uint8 *data, uint16 len)
|
|||
* Need to get largest count of toss reasons
|
||||
*/
|
||||
for (idx = 0; idx < WLC_HIST_TOSS_LEN; idx ++) {
|
||||
cur_rccnt = (uint16)((ewp_stats->htr_rc[idx] &
|
||||
HIST_TOSS_RC_COUNT_MASK)>>HIST_TOSS_RC_COUNT_POS);
|
||||
cur_rccnt = (uint16)(ewp_stats->htr_rc[idx].toss_cnt);
|
||||
DHD_FILTER_TRACE(("%s: idx %d htr_rc %04x cur_rccnt %d\n",
|
||||
__FUNCTION__, idx, ewp_stats->htr_rc[idx], cur_rccnt));
|
||||
__FUNCTION__, idx, ewp_stats->htr_rc[idx].toss_reason, cur_rccnt));
|
||||
if (ewp_stats->htr_rc_ts[idx] && max_rccnt < cur_rccnt) {
|
||||
max_rccnt = cur_rccnt;
|
||||
secnd_rcidx = max_rcidx;
|
||||
|
|
@ -906,16 +902,16 @@ evt_get_last_toss_hist(uint8 *ptr, const uint8 *data, uint16 len)
|
|||
bidata_stats.version = ewp_stats->version;
|
||||
bidata_stats.htr_type = ewp_stats->htr_type;
|
||||
bidata_stats.htr_num = ewp_stats->htr_num;
|
||||
bidata_stats.htr_rn_last = ewp_stats->htr_running[cur_rnidx];
|
||||
bidata_stats.htr_rn_last = *(uint32*)(&ewp_stats->htr_running[cur_rnidx]);
|
||||
bidata_stats.htr_rn_ts_last = ewp_stats->htr_rn_ts[cur_rnidx];
|
||||
bidata_stats.htr_rn_prev = ewp_stats->htr_running[prev_rnidx];
|
||||
bidata_stats.htr_rn_prev = *(uint32*)(&ewp_stats->htr_running[prev_rnidx]);
|
||||
bidata_stats.htr_rn_ts_prev = ewp_stats->htr_rn_ts[prev_rnidx];
|
||||
if (max_rcidx != EWPF_INVALID) {
|
||||
bidata_stats.htr_rc_max = ewp_stats->htr_rc[max_rcidx];
|
||||
bidata_stats.htr_rc_max = *(uint32*)(&ewp_stats->htr_rc[max_rcidx]);
|
||||
bidata_stats.htr_rc_ts_max = ewp_stats->htr_rc_ts[max_rcidx];
|
||||
}
|
||||
if (secnd_rcidx != EWPF_INVALID) {
|
||||
bidata_stats.htr_rc_secnd = ewp_stats->htr_rc[secnd_rcidx];
|
||||
bidata_stats.htr_rc_secnd = *(uint32*)(&ewp_stats->htr_rc[secnd_rcidx]);
|
||||
bidata_stats.htr_rc_ts_secnd = ewp_stats->htr_rc_ts[secnd_rcidx];
|
||||
}
|
||||
DHD_FILTER_TRACE(("%s: ver %d type %d num %d "
|
||||
|
|
@ -1279,7 +1275,7 @@ dhd_event_log_filter_event_handler(dhd_pub_t *dhdp, prcd_event_log_hdr_t *plog_h
|
|||
#define EWP_REPORT_NAME_MAX 64
|
||||
|
||||
#ifdef DHD_EWPR_VER2
|
||||
#define EWP_REPORT_VERSION 0x20190514
|
||||
#define EWP_REPORT_VERSION 0x20200722
|
||||
#define EWP_REPORT_SET_DEFAULT 0x01
|
||||
#define EWPR_CSDCLIENT_DIFF 10
|
||||
#define EWPR_INTERVAL 3
|
||||
|
|
@ -1349,7 +1345,7 @@ typedef struct {
|
|||
uint32 *delta_list; /* IN delta values to find */
|
||||
} ewpr_lock_param_t;
|
||||
|
||||
#define MAX_MULTI_VER 3
|
||||
#define MAX_MULTI_VER 4
|
||||
typedef struct {
|
||||
uint32 version; /* VERSION for multiple version struct */
|
||||
uint32 offset; /* offset of the member at the version */
|
||||
|
|
@ -1386,7 +1382,7 @@ typedef struct {
|
|||
|
||||
/* offset defines */
|
||||
#define EWPR_CNT_VERSION_OFFSET \
|
||||
OFFSETOF(EWPF_slc_elem_t, compact_cntr_v3)
|
||||
OFFSETOF(EWPF_slc_elem_t, compact_cntr_v4)
|
||||
|
||||
#define EWPR_CNT_V1_OFFSET(a) \
|
||||
WL_PERIODIC_COMPACT_CNTRS_VER_1, \
|
||||
|
|
@ -1397,6 +1393,9 @@ typedef struct {
|
|||
#define EWPR_CNT_V3_OFFSET(a) \
|
||||
WL_PERIODIC_COMPACT_CNTRS_VER_3, \
|
||||
(OFFSETOF(EWPF_slc_elem_t, compact_cntr_v3) + OFFSETOF(wl_periodic_compact_cntrs_v3_t, a))
|
||||
#define EWPR_CNT_V4_OFFSET(a) \
|
||||
WL_PERIODIC_COMPACT_CNTRS_VER_4, \
|
||||
(OFFSETOF(EWPF_slc_elem_t, compact_cntr_v4) + OFFSETOF(wl_periodic_compact_cntrs_v4_t, a))
|
||||
#define EWPR_STAT_OFFSET(a) \
|
||||
(OFFSETOF(EWPF_ifc_elem_t, if_stat) + OFFSETOF(wl_if_stats_t, a))
|
||||
#define EWPR_INFRA_OFFSET(a) \
|
||||
|
|
@ -1434,14 +1433,16 @@ typedef struct {
|
|||
.v_info = { EWPR_CNT_VERSION_OFFSET, \
|
||||
{{EWPR_CNT_V1_OFFSET(a)}, \
|
||||
{EWPR_CNT_V2_OFFSET(a)}, \
|
||||
{EWPR_CNT_V3_OFFSET(a)}}}, \
|
||||
{EWPR_CNT_V3_OFFSET(a)}, \
|
||||
{EWPR_CNT_V4_OFFSET(a)}}}, \
|
||||
EWP_UINT32, EWP_HEX, EWP_UINT32}
|
||||
#define EWPR_SERIAL_CNT_16(a) {\
|
||||
#a, EWPF_IDX_TYPE_SLICE, TRUE, \
|
||||
.v_info = { EWPR_CNT_VERSION_OFFSET, \
|
||||
{{EWPR_CNT_V1_OFFSET(a)}, \
|
||||
{EWPR_CNT_V2_OFFSET(a)}, \
|
||||
{EWPR_CNT_V3_OFFSET(a)}}}, \
|
||||
{EWPR_CNT_V3_OFFSET(a)}, \
|
||||
{EWPR_CNT_V4_OFFSET(a)}}}, \
|
||||
EWP_UINT32, EWP_HEX, EWP_UINT16}
|
||||
#define EWPR_SERIAL_STAT(a) {\
|
||||
#a, EWPF_IDX_TYPE_IFACE, FALSE, .offset = EWPR_STAT_OFFSET(a), \
|
||||
|
|
@ -1528,10 +1529,10 @@ typedef struct {
|
|||
#define EWPR_SINGLE_USEC_TO_SEC EWPR_DISPLAY_METHOD_SINGLE, EWPF_USEC_TO_SEC
|
||||
|
||||
/* serail info type define */
|
||||
#define EWPR_SERIAL_CNT_V3_BIT(a, b, c, d) {\
|
||||
#define EWPR_SERIAL_CNT_V4_BIT(a, b, c, d) {\
|
||||
#a, EWPF_IDX_TYPE_SLICE, TRUE, \
|
||||
.v_info = { EWPR_CNT_VERSION_OFFSET, \
|
||||
{{EWPR_CNT_V3_OFFSET(a)}}}, \
|
||||
{{EWPR_CNT_V4_OFFSET(a)}}}, \
|
||||
EWP_UINT32, EWP_BIN, EWP_BIT, EWPF_INFO_ECNT, b, c, d}
|
||||
#define EWPR_SERIAL_STAT_BIT(a, b, c, d) {\
|
||||
#a, EWPF_IDX_TYPE_IFACE, FALSE, .offset = EWPR_STAT_OFFSET(a), \
|
||||
|
|
@ -1717,21 +1718,28 @@ ewpr_serial_bit_unwanted_network_default_tbl[] = {
|
|||
EWPR_SERIAL_MGMT_BIT(rxdeauth, 4, 6, EWPR_DIFF_DEFAULT),
|
||||
EWPR_SERIAL_MGMT_BIT(txaction, 7, 6, EWPR_DIFF_DEFAULT),
|
||||
EWPR_SERIAL_MGMT_BIT(rxaction, 7, 6, EWPR_DIFF_DEFAULT),
|
||||
EWPR_SERIAL_CNT_V3_BIT(txallfrm, 17, 6, EWPR_DIFF_DEFAULT),
|
||||
EWPR_SERIAL_CNT_V3_BIT(rxrsptmout, 17, 6, EWPR_DIFF_DEFAULT),
|
||||
EWPR_SERIAL_CNT_V3_BIT(rxbadplcp, 17, 6, EWPR_DIFF_DEFAULT),
|
||||
EWPR_SERIAL_CNT_V3_BIT(rxcrsglitch, 17, 6, EWPR_DIFF_DEFAULT),
|
||||
EWPR_SERIAL_CNT_V3_BIT(rxbadfcs, 17, 6, EWPR_DIFF_DEFAULT),
|
||||
EWPR_SERIAL_CNT_V3_BIT(rxbeaconmbss, 5, 6, EWPR_DIFF_DEFAULT),
|
||||
EWPR_SERIAL_CNT_V3_BIT(rxbeaconobss, 12, 6, EWPR_DIFF_DEFAULT),
|
||||
EWPR_SERIAL_CNT_V3_BIT(lqcm_report, 19, 6, EWPR_SINGLE_DEFAULT),
|
||||
EWPR_SERIAL_CNT_V3_BIT(tx_toss_cnt, 18, 6, EWPR_DIFF_DEFAULT),
|
||||
EWPR_SERIAL_CNT_V3_BIT(rx_toss_cnt, 18, 6, EWPR_DIFF_DEFAULT),
|
||||
EWPR_SERIAL_CNT_V3_BIT(rxretry, 17, 6, EWPR_DIFF_DEFAULT),
|
||||
EWPR_SERIAL_CNT_V3_BIT(rxdup, 15, 6, EWPR_DIFF_DEFAULT),
|
||||
EWPR_SERIAL_CNT_V3_BIT(chswitch_cnt, 8, 6, EWPR_DIFF_DEFAULT),
|
||||
EWPR_SERIAL_CNT_V3_BIT(pm_dur, 12, 6, EWPR_DIFF_DEFAULT),
|
||||
EWPR_SERIAL_CNT_V3_BIT(rxholes, 15, 6, EWPR_DIFF_DEFAULT),
|
||||
EWPR_SERIAL_CNT_V4_BIT(txallfrm, 17, 6, EWPR_DIFF_DEFAULT),
|
||||
EWPR_SERIAL_CNT_V4_BIT(rxrsptmout, 17, 6, EWPR_DIFF_DEFAULT),
|
||||
EWPR_SERIAL_CNT_V4_BIT(rxbadplcp, 17, 6, EWPR_DIFF_DEFAULT),
|
||||
EWPR_SERIAL_CNT_V4_BIT(rxcrsglitch, 17, 6, EWPR_DIFF_DEFAULT),
|
||||
EWPR_SERIAL_CNT_V4_BIT(rxbadfcs, 17, 6, EWPR_DIFF_DEFAULT),
|
||||
EWPR_SERIAL_CNT_V4_BIT(rxbeaconmbss, 5, 6, EWPR_DIFF_DEFAULT),
|
||||
EWPR_SERIAL_CNT_V4_BIT(rxbeaconobss, 12, 6, EWPR_DIFF_DEFAULT),
|
||||
EWPR_SERIAL_CNT_V4_BIT(lqcm_report, 19, 6, EWPR_SINGLE_DEFAULT),
|
||||
EWPR_SERIAL_CNT_V4_BIT(tx_toss_cnt, 18, 6, EWPR_DIFF_DEFAULT),
|
||||
EWPR_SERIAL_CNT_V4_BIT(rx_toss_cnt, 18, 6, EWPR_DIFF_DEFAULT),
|
||||
EWPR_SERIAL_CNT_V4_BIT(rxretry, 17, 6, EWPR_DIFF_DEFAULT),
|
||||
EWPR_SERIAL_CNT_V4_BIT(rxdup, 15, 6, EWPR_DIFF_DEFAULT),
|
||||
EWPR_SERIAL_CNT_V4_BIT(chswitch_cnt, 8, 6, EWPR_DIFF_DEFAULT),
|
||||
EWPR_SERIAL_CNT_V4_BIT(pm_dur, 12, 6, EWPR_DIFF_DEFAULT),
|
||||
EWPR_SERIAL_CNT_V4_BIT(rxholes, 15, 6, EWPR_DIFF_DEFAULT),
|
||||
EWPR_SERIAL_CNT_V4_BIT(rxundec, 16, 6, EWPR_DIFF_DEFAULT),
|
||||
EWPR_SERIAL_CNT_V4_BIT(rxundec_mcst, 16, 6, EWPR_DIFF_DEFAULT),
|
||||
EWPR_SERIAL_CNT_V4_BIT(replay, 12, 6, EWPR_DIFF_DEFAULT),
|
||||
EWPR_SERIAL_CNT_V4_BIT(replay_mcst, 12, 6, EWPR_DIFF_DEFAULT),
|
||||
EWPR_SERIAL_CNT_V4_BIT(pktfilter_discard, 16, 6, EWPR_DIFF_DEFAULT),
|
||||
EWPR_SERIAL_CNT_V4_BIT(pktfilter_forward, 16, 6, EWPR_DIFF_DEFAULT),
|
||||
EWPR_SERIAL_CNT_V4_BIT(mac_rxfilter, 16, 6, EWPR_DIFF_DEFAULT),
|
||||
EWPR_SERIAL_BTC_STAT_16_BIT(bt_dcsn_map, 16, 3, EWPR_SINGLE_DEFAULT),
|
||||
EWPR_SERIAL_BTC_STAT_16_BIT(bt_dcsn_cnt, 12, 3, EWPR_SINGLE_DEFAULT),
|
||||
EWPR_SERIAL_BTC_STAT_16_BIT(bt_a2dp_hiwat_cnt, 12, 3, EWPR_SINGLE_DEFAULT),
|
||||
|
|
@ -1783,7 +1791,7 @@ ewpr_serial_bit_unwanted_network_default_tbl[] = {
|
|||
EWPR_SERIAL_RX_TOSS_HIST_BIT(htr_rc_max, 32, 1, EWPR_SINGLE_DEFAULT),
|
||||
EWPR_SERIAL_RX_TOSS_HIST_BIT(htr_rc_ts_secnd, 32, 1, EWPR_SINGLE_DEFAULT),
|
||||
EWPR_SERIAL_RX_TOSS_HIST_BIT(htr_rc_secnd, 32, 1, EWPR_SINGLE_DEFAULT),
|
||||
EWPR_SERIAL_CPLOG_BIT(packtlog, 22, 70),
|
||||
EWPR_SERIAL_CPLOG_BIT(packtlog, 22, 50),
|
||||
EWPR_SERIAL_NONE
|
||||
};
|
||||
|
||||
|
|
@ -1817,21 +1825,28 @@ ewpr_serial_bit_assoc_fail_default_tbl[] = {
|
|||
EWPR_SERIAL_MGMT_BIT(rxdeauth, 4, 6, EWPR_DIFF_DEFAULT),
|
||||
EWPR_SERIAL_MGMT_BIT(txaction, 7, 6, EWPR_DIFF_DEFAULT),
|
||||
EWPR_SERIAL_MGMT_BIT(rxaction, 7, 6, EWPR_DIFF_DEFAULT),
|
||||
EWPR_SERIAL_CNT_V3_BIT(txallfrm, 17, 6, EWPR_DIFF_DEFAULT),
|
||||
EWPR_SERIAL_CNT_V3_BIT(rxrsptmout, 17, 6, EWPR_DIFF_DEFAULT),
|
||||
EWPR_SERIAL_CNT_V3_BIT(rxbadplcp, 17, 6, EWPR_DIFF_DEFAULT),
|
||||
EWPR_SERIAL_CNT_V3_BIT(rxcrsglitch, 17, 6, EWPR_DIFF_DEFAULT),
|
||||
EWPR_SERIAL_CNT_V3_BIT(rxbadfcs, 17, 6, EWPR_DIFF_DEFAULT),
|
||||
EWPR_SERIAL_CNT_V3_BIT(rxbeaconmbss, 5, 6, EWPR_DIFF_DEFAULT),
|
||||
EWPR_SERIAL_CNT_V3_BIT(rxbeaconobss, 12, 6, EWPR_DIFF_DEFAULT),
|
||||
EWPR_SERIAL_CNT_V3_BIT(lqcm_report, 19, 6, EWPR_SINGLE_DEFAULT),
|
||||
EWPR_SERIAL_CNT_V3_BIT(tx_toss_cnt, 18, 6, EWPR_DIFF_DEFAULT),
|
||||
EWPR_SERIAL_CNT_V3_BIT(rx_toss_cnt, 18, 6, EWPR_DIFF_DEFAULT),
|
||||
EWPR_SERIAL_CNT_V3_BIT(rxretry, 17, 6, EWPR_DIFF_DEFAULT),
|
||||
EWPR_SERIAL_CNT_V3_BIT(rxdup, 15, 6, EWPR_DIFF_DEFAULT),
|
||||
EWPR_SERIAL_CNT_V3_BIT(chswitch_cnt, 8, 6, EWPR_DIFF_DEFAULT),
|
||||
EWPR_SERIAL_CNT_V3_BIT(pm_dur, 12, 6, EWPR_DIFF_DEFAULT),
|
||||
EWPR_SERIAL_CNT_V3_BIT(rxholes, 15, 6, EWPR_DIFF_DEFAULT),
|
||||
EWPR_SERIAL_CNT_V4_BIT(txallfrm, 17, 6, EWPR_DIFF_DEFAULT),
|
||||
EWPR_SERIAL_CNT_V4_BIT(rxrsptmout, 17, 6, EWPR_DIFF_DEFAULT),
|
||||
EWPR_SERIAL_CNT_V4_BIT(rxbadplcp, 17, 6, EWPR_DIFF_DEFAULT),
|
||||
EWPR_SERIAL_CNT_V4_BIT(rxcrsglitch, 17, 6, EWPR_DIFF_DEFAULT),
|
||||
EWPR_SERIAL_CNT_V4_BIT(rxbadfcs, 17, 6, EWPR_DIFF_DEFAULT),
|
||||
EWPR_SERIAL_CNT_V4_BIT(rxbeaconmbss, 5, 6, EWPR_DIFF_DEFAULT),
|
||||
EWPR_SERIAL_CNT_V4_BIT(rxbeaconobss, 12, 6, EWPR_DIFF_DEFAULT),
|
||||
EWPR_SERIAL_CNT_V4_BIT(lqcm_report, 19, 6, EWPR_SINGLE_DEFAULT),
|
||||
EWPR_SERIAL_CNT_V4_BIT(tx_toss_cnt, 18, 6, EWPR_DIFF_DEFAULT),
|
||||
EWPR_SERIAL_CNT_V4_BIT(rx_toss_cnt, 18, 6, EWPR_DIFF_DEFAULT),
|
||||
EWPR_SERIAL_CNT_V4_BIT(rxretry, 17, 6, EWPR_DIFF_DEFAULT),
|
||||
EWPR_SERIAL_CNT_V4_BIT(rxdup, 15, 6, EWPR_DIFF_DEFAULT),
|
||||
EWPR_SERIAL_CNT_V4_BIT(chswitch_cnt, 8, 6, EWPR_DIFF_DEFAULT),
|
||||
EWPR_SERIAL_CNT_V4_BIT(pm_dur, 12, 6, EWPR_DIFF_DEFAULT),
|
||||
EWPR_SERIAL_CNT_V4_BIT(rxholes, 15, 6, EWPR_DIFF_DEFAULT),
|
||||
EWPR_SERIAL_CNT_V4_BIT(rxundec, 16, 6, EWPR_DIFF_DEFAULT),
|
||||
EWPR_SERIAL_CNT_V4_BIT(rxundec_mcst, 16, 6, EWPR_DIFF_DEFAULT),
|
||||
EWPR_SERIAL_CNT_V4_BIT(replay, 12, 6, EWPR_DIFF_DEFAULT),
|
||||
EWPR_SERIAL_CNT_V4_BIT(replay_mcst, 12, 6, EWPR_DIFF_DEFAULT),
|
||||
EWPR_SERIAL_CNT_V4_BIT(pktfilter_discard, 16, 6, EWPR_DIFF_DEFAULT),
|
||||
EWPR_SERIAL_CNT_V4_BIT(pktfilter_forward, 16, 6, EWPR_DIFF_DEFAULT),
|
||||
EWPR_SERIAL_CNT_V4_BIT(mac_rxfilter, 16, 6, EWPR_DIFF_DEFAULT),
|
||||
EWPR_SERIAL_BTC_STAT_16_BIT(bt_dcsn_map, 16, 3, EWPR_SINGLE_DEFAULT),
|
||||
EWPR_SERIAL_BTC_STAT_16_BIT(bt_dcsn_cnt, 12, 3, EWPR_SINGLE_DEFAULT),
|
||||
EWPR_SERIAL_BTC_STAT_16_BIT(bt_a2dp_hiwat_cnt, 12, 3, EWPR_SINGLE_DEFAULT),
|
||||
|
|
@ -1869,7 +1884,7 @@ ewpr_serial_bit_assoc_fail_default_tbl[] = {
|
|||
EWPR_SERIAL_RX_TOSS_HIST_BIT(htr_rc_max, 32, 1, EWPR_SINGLE_DEFAULT),
|
||||
EWPR_SERIAL_RX_TOSS_HIST_BIT(htr_rc_ts_secnd, 32, 1, EWPR_SINGLE_DEFAULT),
|
||||
EWPR_SERIAL_RX_TOSS_HIST_BIT(htr_rc_secnd, 32, 1, EWPR_SINGLE_DEFAULT),
|
||||
EWPR_SERIAL_CPLOG_BIT(packtlog, 22, 70),
|
||||
EWPR_SERIAL_CPLOG_BIT(packtlog, 22, 50),
|
||||
EWPR_SERIAL_NONE
|
||||
};
|
||||
|
||||
|
|
@ -1903,21 +1918,28 @@ ewpr_serial_bit_abnormal_disconnect_default_tbl[] = {
|
|||
EWPR_SERIAL_MGMT_BIT(rxdeauth, 4, 6, EWPR_DIFF_DEFAULT),
|
||||
EWPR_SERIAL_MGMT_BIT(txaction, 7, 6, EWPR_DIFF_DEFAULT),
|
||||
EWPR_SERIAL_MGMT_BIT(rxaction, 7, 6, EWPR_DIFF_DEFAULT),
|
||||
EWPR_SERIAL_CNT_V3_BIT(txallfrm, 17, 6, EWPR_DIFF_DEFAULT),
|
||||
EWPR_SERIAL_CNT_V3_BIT(rxrsptmout, 17, 6, EWPR_DIFF_DEFAULT),
|
||||
EWPR_SERIAL_CNT_V3_BIT(rxbadplcp, 17, 6, EWPR_DIFF_DEFAULT),
|
||||
EWPR_SERIAL_CNT_V3_BIT(rxcrsglitch, 17, 6, EWPR_DIFF_DEFAULT),
|
||||
EWPR_SERIAL_CNT_V3_BIT(rxbadfcs, 17, 6, EWPR_DIFF_DEFAULT),
|
||||
EWPR_SERIAL_CNT_V3_BIT(rxbeaconmbss, 5, 6, EWPR_DIFF_DEFAULT),
|
||||
EWPR_SERIAL_CNT_V3_BIT(rxbeaconobss, 12, 6, EWPR_DIFF_DEFAULT),
|
||||
EWPR_SERIAL_CNT_V3_BIT(lqcm_report, 19, 6, EWPR_SINGLE_DEFAULT),
|
||||
EWPR_SERIAL_CNT_V3_BIT(tx_toss_cnt, 18, 6, EWPR_DIFF_DEFAULT),
|
||||
EWPR_SERIAL_CNT_V3_BIT(rx_toss_cnt, 18, 6, EWPR_DIFF_DEFAULT),
|
||||
EWPR_SERIAL_CNT_V3_BIT(rxretry, 17, 6, EWPR_DIFF_DEFAULT),
|
||||
EWPR_SERIAL_CNT_V3_BIT(rxdup, 15, 6, EWPR_DIFF_DEFAULT),
|
||||
EWPR_SERIAL_CNT_V3_BIT(chswitch_cnt, 8, 6, EWPR_DIFF_DEFAULT),
|
||||
EWPR_SERIAL_CNT_V3_BIT(pm_dur, 12, 6, EWPR_DIFF_DEFAULT),
|
||||
EWPR_SERIAL_CNT_V3_BIT(rxholes, 15, 6, EWPR_DIFF_DEFAULT),
|
||||
EWPR_SERIAL_CNT_V4_BIT(txallfrm, 17, 6, EWPR_DIFF_DEFAULT),
|
||||
EWPR_SERIAL_CNT_V4_BIT(rxrsptmout, 17, 6, EWPR_DIFF_DEFAULT),
|
||||
EWPR_SERIAL_CNT_V4_BIT(rxbadplcp, 17, 6, EWPR_DIFF_DEFAULT),
|
||||
EWPR_SERIAL_CNT_V4_BIT(rxcrsglitch, 17, 6, EWPR_DIFF_DEFAULT),
|
||||
EWPR_SERIAL_CNT_V4_BIT(rxbadfcs, 17, 6, EWPR_DIFF_DEFAULT),
|
||||
EWPR_SERIAL_CNT_V4_BIT(rxbeaconmbss, 5, 6, EWPR_DIFF_DEFAULT),
|
||||
EWPR_SERIAL_CNT_V4_BIT(rxbeaconobss, 12, 6, EWPR_DIFF_DEFAULT),
|
||||
EWPR_SERIAL_CNT_V4_BIT(lqcm_report, 19, 6, EWPR_SINGLE_DEFAULT),
|
||||
EWPR_SERIAL_CNT_V4_BIT(tx_toss_cnt, 18, 6, EWPR_DIFF_DEFAULT),
|
||||
EWPR_SERIAL_CNT_V4_BIT(rx_toss_cnt, 18, 6, EWPR_DIFF_DEFAULT),
|
||||
EWPR_SERIAL_CNT_V4_BIT(rxretry, 17, 6, EWPR_DIFF_DEFAULT),
|
||||
EWPR_SERIAL_CNT_V4_BIT(rxdup, 15, 6, EWPR_DIFF_DEFAULT),
|
||||
EWPR_SERIAL_CNT_V4_BIT(chswitch_cnt, 8, 6, EWPR_DIFF_DEFAULT),
|
||||
EWPR_SERIAL_CNT_V4_BIT(pm_dur, 12, 6, EWPR_DIFF_DEFAULT),
|
||||
EWPR_SERIAL_CNT_V4_BIT(rxholes, 15, 6, EWPR_DIFF_DEFAULT),
|
||||
EWPR_SERIAL_CNT_V4_BIT(rxundec, 16, 6, EWPR_DIFF_DEFAULT),
|
||||
EWPR_SERIAL_CNT_V4_BIT(rxundec_mcst, 16, 6, EWPR_DIFF_DEFAULT),
|
||||
EWPR_SERIAL_CNT_V4_BIT(replay, 12, 6, EWPR_DIFF_DEFAULT),
|
||||
EWPR_SERIAL_CNT_V4_BIT(replay_mcst, 12, 6, EWPR_DIFF_DEFAULT),
|
||||
EWPR_SERIAL_CNT_V4_BIT(pktfilter_discard, 16, 6, EWPR_DIFF_DEFAULT),
|
||||
EWPR_SERIAL_CNT_V4_BIT(pktfilter_forward, 16, 6, EWPR_DIFF_DEFAULT),
|
||||
EWPR_SERIAL_CNT_V4_BIT(mac_rxfilter, 16, 6, EWPR_DIFF_DEFAULT),
|
||||
EWPR_SERIAL_BTC_STAT_16_BIT(bt_dcsn_map, 16, 3, EWPR_SINGLE_DEFAULT),
|
||||
EWPR_SERIAL_BTC_STAT_16_BIT(bt_dcsn_cnt, 12, 3, EWPR_SINGLE_DEFAULT),
|
||||
EWPR_SERIAL_BTC_STAT_16_BIT(bt_a2dp_hiwat_cnt, 12, 3, EWPR_SINGLE_DEFAULT),
|
||||
|
|
@ -1969,7 +1991,7 @@ ewpr_serial_bit_abnormal_disconnect_default_tbl[] = {
|
|||
EWPR_SERIAL_RX_TOSS_HIST_BIT(htr_rc_max, 32, 1, EWPR_SINGLE_DEFAULT),
|
||||
EWPR_SERIAL_RX_TOSS_HIST_BIT(htr_rc_ts_secnd, 32, 1, EWPR_SINGLE_DEFAULT),
|
||||
EWPR_SERIAL_RX_TOSS_HIST_BIT(htr_rc_secnd, 32, 1, EWPR_SINGLE_DEFAULT),
|
||||
EWPR_SERIAL_CPLOG_BIT(packtlog, 22, 70),
|
||||
EWPR_SERIAL_CPLOG_BIT(packtlog, 22, 50),
|
||||
EWPR_SERIAL_NONE
|
||||
};
|
||||
|
||||
|
|
|
|||
2
drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_event_log_filter.h
Executable file → Normal file
2
drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_event_log_filter.h
Executable file → Normal file
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* Wifi dongle status Filter and Report
|
||||
*
|
||||
* Copyright (C) 2020, Broadcom.
|
||||
* Copyright (C) 2022, Broadcom.
|
||||
*
|
||||
* Unless you and Broadcom execute a separate written software license
|
||||
* agreement governing use of this software, this software is licensed to you
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
* Flow rings are transmit traffic (=propagating towards antenna) related entities
|
||||
*
|
||||
*
|
||||
* Copyright (C) 2020, Broadcom.
|
||||
* Copyright (C) 2022, Broadcom.
|
||||
*
|
||||
* Unless you and Broadcom execute a separate written software license
|
||||
* agreement governing use of this software, this software is licensed to you
|
||||
|
|
@ -64,12 +64,6 @@ int dhd_flow_queue_overflow(flow_queue_t *queue, void *pkt);
|
|||
#define FLOW_QUEUE_PKT_NEXT(p) PKTLINK(p)
|
||||
#define FLOW_QUEUE_PKT_SETNEXT(p, x) PKTSETLINK((p), (x))
|
||||
|
||||
#ifdef DHD_REPLACE_LOG_INFO_TO_TRACE
|
||||
#define DHD_FLOWRING_INFO DHD_TRACE
|
||||
#else
|
||||
#define DHD_FLOWRING_INFO DHD_INFO
|
||||
#endif /* DHD_REPLACE_LOG_INFO_TO_TRACE */
|
||||
|
||||
const uint8 prio2ac[8] = { 0, 1, 1, 0, 2, 2, 3, 3 };
|
||||
const uint8 prio2tid[8] = { 0, 1, 2, 3, 4, 5, 6, 7 };
|
||||
|
||||
|
|
@ -254,7 +248,6 @@ BCMFASTPATH(dhd_flow_queue_dequeue)(dhd_pub_t *dhdp, flow_queue_t *queue)
|
|||
pkt = queue->head; /* from head */
|
||||
|
||||
if (pkt == NULL) {
|
||||
ASSERT((queue->len == 0) && (queue->tail == NULL));
|
||||
goto done;
|
||||
}
|
||||
|
||||
|
|
@ -361,11 +354,11 @@ dhd_get_max_multi_client_flow_rings(dhd_pub_t *dhdp)
|
|||
int
|
||||
dhd_flowid_map_init(dhd_pub_t *dhdp, uint16 max_tx_flow_rings)
|
||||
{
|
||||
#if defined(DHD_HTPUT_TUNABLES)
|
||||
uint16 max_normal_tx_flow_rings = max_tx_flow_rings - HTPUT_TOTAL_FLOW_RINGS;
|
||||
#else
|
||||
uint16 max_normal_tx_flow_rings = max_tx_flow_rings;
|
||||
#endif /* DHD_HTPUT_TUNABLES */
|
||||
|
||||
if (dhdp->htput_support) {
|
||||
max_normal_tx_flow_rings = max_tx_flow_rings - HTPUT_TOTAL_FLOW_RINGS;
|
||||
}
|
||||
|
||||
/* Construct a normal flowid allocator from FLOWID_RESERVED to
|
||||
* (max_normal_tx_flow_rings - 1)
|
||||
|
|
@ -377,21 +370,24 @@ dhd_flowid_map_init(dhd_pub_t *dhdp, uint16 max_tx_flow_rings)
|
|||
return BCME_NOMEM;
|
||||
}
|
||||
|
||||
#if defined(DHD_HTPUT_TUNABLES)
|
||||
if (HTPUT_TOTAL_FLOW_RINGS > 0) {
|
||||
dhdp->htput_flow_ring_start = max_normal_tx_flow_rings + FLOWID_RESERVED;
|
||||
/* Construct a htput flowid allocator from htput_flow_ring_start to
|
||||
* (htput_flow_ring_start + HTPUT_TOTAL_FLOW_RINGS - 1)
|
||||
*/
|
||||
dhdp->htput_flowid_allocator = id16_map_init(dhdp->osh, HTPUT_TOTAL_FLOW_RINGS,
|
||||
dhdp->htput_flow_ring_start);
|
||||
if (dhdp->htput_flowid_allocator == NULL) {
|
||||
DHD_ERROR(("%s: htput flowid allocator init failure\n", __FUNCTION__));
|
||||
return BCME_NOMEM;
|
||||
dhdp->htput_flowid_allocator = NULL;
|
||||
|
||||
if (dhdp->htput_support) {
|
||||
if (HTPUT_TOTAL_FLOW_RINGS > 0) {
|
||||
dhdp->htput_flow_ring_start = max_normal_tx_flow_rings + FLOWID_RESERVED;
|
||||
/* Construct a htput flowid allocator from htput_flow_ring_start to
|
||||
* (htput_flow_ring_start + HTPUT_TOTAL_FLOW_RINGS - 1)
|
||||
*/
|
||||
dhdp->htput_flowid_allocator = id16_map_init(dhdp->osh,
|
||||
HTPUT_TOTAL_FLOW_RINGS, dhdp->htput_flow_ring_start);
|
||||
if (dhdp->htput_flowid_allocator == NULL) {
|
||||
DHD_ERROR(("%s: htput flowid allocator init failure\n",
|
||||
__FUNCTION__));
|
||||
return BCME_NOMEM;
|
||||
}
|
||||
dhdp->htput_client_flow_rings = 0u;
|
||||
}
|
||||
dhdp->htput_client_flow_rings = 0u;
|
||||
}
|
||||
#endif /* !DHD_HTPUT_TUNABLES */
|
||||
|
||||
return BCME_OK;
|
||||
}
|
||||
|
|
@ -404,14 +400,13 @@ dhd_flowid_map_deinit(dhd_pub_t *dhdp)
|
|||
}
|
||||
ASSERT(dhdp->flowid_allocator == NULL);
|
||||
|
||||
#if defined(DHD_HTPUT_TUNABLES)
|
||||
if (dhdp->htput_flowid_allocator) {
|
||||
dhdp->htput_flowid_allocator = id16_map_fini(dhdp->osh,
|
||||
dhdp->htput_flowid_allocator);
|
||||
ASSERT(dhdp->htput_flowid_allocator == NULL);
|
||||
}
|
||||
dhdp->htput_client_flow_rings = 0u;
|
||||
#endif /* !DHD_HTPUT_TUNABLES */
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -508,7 +503,8 @@ dhd_flow_rings_init(dhd_pub_t *dhdp, uint32 num_h2d_rings)
|
|||
bcopy(prio2ac, dhdp->flow_prio_map, sizeof(uint8) * NUMPRIO);
|
||||
|
||||
dhdp->max_multi_client_flow_rings = dhd_get_max_multi_client_flow_rings(dhdp);
|
||||
dhdp->multi_client_flow_rings = 0U;
|
||||
|
||||
OSL_ATOMIC_INIT(dhdp->osh, &dhdp->multi_client_flow_rings);
|
||||
|
||||
#ifdef DHD_LOSSLESS_ROAMING
|
||||
dhdp->dequeue_prec_map = ALLPRIO;
|
||||
|
|
@ -608,7 +604,8 @@ void dhd_flow_rings_deinit(dhd_pub_t *dhdp)
|
|||
bzero(dhdp->flow_prio_map, sizeof(uint8) * NUMPRIO);
|
||||
|
||||
dhdp->max_multi_client_flow_rings = 0U;
|
||||
dhdp->multi_client_flow_rings = 0U;
|
||||
|
||||
OSL_ATOMIC_INIT(dhdp->osh, &dhdp->multi_client_flow_rings);
|
||||
|
||||
lock = dhdp->flowid_lock;
|
||||
dhdp->flowid_lock = NULL;
|
||||
|
|
@ -702,7 +699,8 @@ dhd_flowid_find(dhd_pub_t *dhdp, uint8 ifindex, uint8 prio, char *sa, char *da)
|
|||
}
|
||||
} else {
|
||||
|
||||
if (ETHER_ISMULTI(da)) {
|
||||
if (ETHER_ISMULTI(da) &&
|
||||
TRUE) {
|
||||
ismcast = TRUE;
|
||||
hash = 0;
|
||||
} else {
|
||||
|
|
@ -723,11 +721,7 @@ dhd_flowid_find(dhd_pub_t *dhdp, uint8 ifindex, uint8 prio, char *sa, char *da)
|
|||
}
|
||||
DHD_FLOWID_UNLOCK(dhdp->flowid_lock, flags);
|
||||
|
||||
#ifdef DHD_EFI
|
||||
DHD_TRACE(("%s: cannot find flowid\n", __FUNCTION__));
|
||||
#else
|
||||
DHD_FLOWRING_INFO(("%s: cannot find flowid\n", __FUNCTION__));
|
||||
#endif
|
||||
DHD_INFO(("%s: cannot find flowid\n", __FUNCTION__));
|
||||
return FLOWID_INVALID;
|
||||
} /* dhd_flowid_find */
|
||||
|
||||
|
|
@ -737,7 +731,13 @@ dhd_flowid_map_alloc(dhd_pub_t *dhdp, uint8 ifindex, uint8 prio, char *da)
|
|||
uint16 flowid = FLOWID_INVALID;
|
||||
ASSERT(dhdp->flowid_allocator != NULL);
|
||||
|
||||
#if defined(DHD_HTPUT_TUNABLES)
|
||||
/* P2P Connections are always 80Mhz */
|
||||
if (DHD_IF_ROLE_P2PGC(dhdp, ifindex) ||
|
||||
DHD_IF_ROLE_P2PGO(dhdp, ifindex)) {
|
||||
flowid = id16_map_alloc(dhdp->flowid_allocator);
|
||||
return flowid;
|
||||
}
|
||||
|
||||
if (dhdp->htput_flowid_allocator) {
|
||||
if (prio == HTPUT_FLOW_RING_PRIO) {
|
||||
if (DHD_IF_ROLE_GENERIC_STA(dhdp, ifindex)) {
|
||||
|
|
@ -748,7 +748,8 @@ dhd_flowid_map_alloc(dhd_pub_t *dhdp, uint8 ifindex, uint8 prio, char *da)
|
|||
* will take care assigning same for those HTPUT_PRIO packets.
|
||||
*/
|
||||
flowid = id16_map_alloc(dhdp->htput_flowid_allocator);
|
||||
} else if (DHD_IF_ROLE_MULTI_CLIENT(dhdp, ifindex) && !ETHER_ISMULTI(da)) {
|
||||
} else if (DHD_IF_ROLE_MULTI_CLIENT(dhdp, ifindex) && !ETHER_ISMULTI(da) &&
|
||||
dhd_is_sta_htput(dhdp, ifindex, (uint8 *)da)) {
|
||||
/* Use HTPUT flowrings for only HTPUT_NUM_CLIENT_FLOW_RINGS */
|
||||
if (dhdp->htput_client_flow_rings < HTPUT_NUM_CLIENT_FLOW_RINGS) {
|
||||
flowid = id16_map_alloc(dhdp->htput_flowid_allocator);
|
||||
|
|
@ -760,7 +761,6 @@ dhd_flowid_map_alloc(dhd_pub_t *dhdp, uint8 ifindex, uint8 prio, char *da)
|
|||
}
|
||||
}
|
||||
}
|
||||
#endif /* !DHD_HTPUT_TUNABLES */
|
||||
|
||||
BCM_REFERENCE(flowid);
|
||||
|
||||
|
|
@ -830,7 +830,9 @@ dhd_flowid_alloc(dhd_pub_t *dhdp, uint8 ifindex, uint8 prio, char *sa, char *da)
|
|||
} else {
|
||||
|
||||
/* For bcast/mcast assign first slot in in interface */
|
||||
hash = ETHER_ISMULTI(da) ? 0 : DHD_FLOWRING_HASHINDEX(da, prio);
|
||||
hash = (ETHER_ISMULTI(da) &&
|
||||
TRUE) ? 0 : DHD_FLOWRING_HASHINDEX(da, prio);
|
||||
|
||||
cur = if_flow_lkup[ifindex].fl_hash[hash];
|
||||
if (cur) {
|
||||
while (cur->next) {
|
||||
|
|
@ -842,7 +844,7 @@ dhd_flowid_alloc(dhd_pub_t *dhdp, uint8 ifindex, uint8 prio, char *sa, char *da)
|
|||
}
|
||||
DHD_FLOWID_UNLOCK(dhdp->flowid_lock, flags);
|
||||
|
||||
DHD_FLOWRING_INFO(("%s: allocated flowid %d\n", __FUNCTION__, fl_hash_node->flowid));
|
||||
DHD_INFO(("%s: allocated flowid %d\n", __FUNCTION__, fl_hash_node->flowid));
|
||||
|
||||
if (fl_hash_node->flowid > dhdp->max_tx_flowid) {
|
||||
DHD_ERROR(("%s: flowid=%d max_tx_flowid=%d ifindex=%d prio=%d role=%d\n",
|
||||
|
|
@ -881,7 +883,7 @@ dhd_flowid_lookup(dhd_pub_t *dhdp, uint8 ifindex,
|
|||
|
||||
id = dhd_flowid_find(dhdp, ifindex, prio, sa, da);
|
||||
|
||||
if (id == FLOWID_INVALID) {
|
||||
if (id == FLOWID_INVALID || (id > dhdp->max_tx_flowid)) {
|
||||
bool if_role_multi_client;
|
||||
if_flow_lkup_t *if_flow_lkup;
|
||||
if_flow_lkup = (if_flow_lkup_t *)dhdp->if_flow_lkup;
|
||||
|
|
@ -895,9 +897,11 @@ dhd_flowid_lookup(dhd_pub_t *dhdp, uint8 ifindex,
|
|||
/* Abort Flowring creation if multi client flowrings crossed the threshold */
|
||||
#ifdef DHD_LIMIT_MULTI_CLIENT_FLOWRINGS
|
||||
if (if_role_multi_client &&
|
||||
(dhdp->multi_client_flow_rings >= dhdp->max_multi_client_flow_rings)) {
|
||||
(OSL_ATOMIC_READ(dhdp->osh, &dhdp->multi_client_flow_rings) >=
|
||||
dhdp->max_multi_client_flow_rings)) {
|
||||
DHD_ERROR_RLMT(("%s: Max multi client flow rings reached: %d:%d\n",
|
||||
__FUNCTION__, dhdp->multi_client_flow_rings,
|
||||
__FUNCTION__,
|
||||
OSL_ATOMIC_READ(dhdp->osh, &dhdp->multi_client_flow_rings),
|
||||
dhdp->max_multi_client_flow_rings));
|
||||
return BCME_ERROR;
|
||||
}
|
||||
|
|
@ -923,7 +927,7 @@ dhd_flowid_lookup(dhd_pub_t *dhdp, uint8 ifindex,
|
|||
|
||||
/* Only after flowid alloc, increment multi_client_flow_rings */
|
||||
if (if_role_multi_client) {
|
||||
dhdp->multi_client_flow_rings++;
|
||||
OSL_ATOMIC_INC(dhdp->osh, &dhdp->multi_client_flow_rings);
|
||||
}
|
||||
|
||||
/* register this flowid in dhd_pub */
|
||||
|
|
@ -1095,7 +1099,7 @@ BCMFASTPATH(dhd_flowid_update)(dhd_pub_t *dhdp, uint8 ifindex, uint8 prio, void
|
|||
return BCME_ERROR;
|
||||
}
|
||||
|
||||
DHD_FLOWRING_INFO(("%s: prio %d flowid %d\n", __FUNCTION__, prio, flowid));
|
||||
DHD_INFO(("%s: prio %d flowid %d\n", __FUNCTION__, prio, flowid));
|
||||
|
||||
/* Tag the packet with flowid */
|
||||
DHD_PKT_SET_FLOWID(pktbuf, flowid);
|
||||
|
|
@ -1105,7 +1109,6 @@ BCMFASTPATH(dhd_flowid_update)(dhd_pub_t *dhdp, uint8 ifindex, uint8 prio, void
|
|||
static void
|
||||
dhd_flowid_map_free(dhd_pub_t *dhdp, uint8 ifindex, uint16 flowid)
|
||||
{
|
||||
#if defined(DHD_HTPUT_TUNABLES)
|
||||
if (dhdp->htput_flowid_allocator) {
|
||||
if (DHD_IS_FLOWID_HTPUT(dhdp, flowid)) {
|
||||
id16_map_free(dhdp->htput_flowid_allocator, flowid);
|
||||
|
|
@ -1116,7 +1119,6 @@ dhd_flowid_map_free(dhd_pub_t *dhdp, uint8 ifindex, uint16 flowid)
|
|||
return;
|
||||
}
|
||||
}
|
||||
#endif /* !DHD_HTPUT_TUNABLES */
|
||||
|
||||
id16_map_free(dhdp->flowid_allocator, flowid);
|
||||
|
||||
|
|
@ -1169,15 +1171,19 @@ dhd_flowid_free(dhd_pub_t *dhdp, uint8 ifindex, uint16 flowid)
|
|||
|
||||
/* Decrement multi_client_flow_rings */
|
||||
if (if_role_multi_client) {
|
||||
dhdp->multi_client_flow_rings--;
|
||||
if (OSL_ATOMIC_READ(dhdp->osh,
|
||||
&dhdp->multi_client_flow_rings)) {
|
||||
OSL_ATOMIC_DEC(dhdp->osh,
|
||||
&dhdp->multi_client_flow_rings);
|
||||
}
|
||||
}
|
||||
|
||||
/* deregister flowid from dhd_pub. */
|
||||
dhd_del_flowid(dhdp, ifindex, flowid);
|
||||
|
||||
dhd_flowid_map_free(dhdp, ifindex, flowid);
|
||||
DHD_FLOWID_UNLOCK(dhdp->flowid_lock, flags);
|
||||
MFREE(dhdp->osh, cur, sizeof(flow_hash_info_t));
|
||||
DHD_FLOWID_UNLOCK(dhdp->flowid_lock, flags);
|
||||
|
||||
return;
|
||||
}
|
||||
|
|
@ -1219,6 +1225,50 @@ dhd_flow_rings_delete(dhd_pub_t *dhdp, uint8 ifindex)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
dhd_update_multicilent_flow_rings(dhd_pub_t *dhdp, uint8 ifindex, bool increment)
|
||||
{
|
||||
uint32 id;
|
||||
flow_ring_table_t *flow_ring_table;
|
||||
|
||||
DHD_ERROR(("%s: ifindex %u\n", __FUNCTION__, ifindex));
|
||||
|
||||
ASSERT(ifindex < DHD_MAX_IFS);
|
||||
if (ifindex >= DHD_MAX_IFS)
|
||||
return;
|
||||
|
||||
if (!dhdp->flow_ring_table)
|
||||
return;
|
||||
|
||||
flow_ring_table = (flow_ring_table_t *)dhdp->flow_ring_table;
|
||||
for (id = 0; id < dhdp->num_h2d_rings; id++) {
|
||||
if (flow_ring_table[id].active &&
|
||||
(flow_ring_table[id].flow_info.ifindex == ifindex) &&
|
||||
(flow_ring_table[id].status == FLOW_RING_STATUS_OPEN)) {
|
||||
if (increment) {
|
||||
if (OSL_ATOMIC_READ(dhdp->osh, &dhdp->multi_client_flow_rings) <
|
||||
dhdp->max_multi_client_flow_rings) {
|
||||
OSL_ATOMIC_INC(dhdp->osh, &dhdp->multi_client_flow_rings);
|
||||
} else {
|
||||
DHD_ERROR(("%s: multi_client_flow_rings:%u"
|
||||
" reached max:%d\n", __FUNCTION__,
|
||||
OSL_ATOMIC_READ(dhdp->osh,
|
||||
&dhdp->multi_client_flow_rings),
|
||||
dhdp->max_multi_client_flow_rings));
|
||||
}
|
||||
} else {
|
||||
if (OSL_ATOMIC_READ(dhdp->osh, &dhdp->multi_client_flow_rings)) {
|
||||
OSL_ATOMIC_DEC(dhdp->osh, &dhdp->multi_client_flow_rings);
|
||||
} else {
|
||||
DHD_ERROR(("%s: multi_client_flow_rings:%u"
|
||||
" reached ZERO\n", __FUNCTION__,
|
||||
OSL_ATOMIC_READ(dhdp->osh,
|
||||
&dhdp->multi_client_flow_rings)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
void
|
||||
dhd_flow_rings_flush(dhd_pub_t *dhdp, uint8 ifindex)
|
||||
{
|
||||
|
|
@ -1252,7 +1302,7 @@ dhd_flow_rings_delete_for_peer(dhd_pub_t *dhdp, uint8 ifindex, char *addr)
|
|||
uint32 id;
|
||||
flow_ring_table_t *flow_ring_table;
|
||||
|
||||
DHD_ERROR(("%s: ifindex %u\n", __FUNCTION__, ifindex));
|
||||
DHD_INFO(("%s: ifindex %u\n", __FUNCTION__, ifindex));
|
||||
|
||||
ASSERT(ifindex < DHD_MAX_IFS);
|
||||
if (ifindex >= DHD_MAX_IFS)
|
||||
|
|
@ -1277,7 +1327,7 @@ dhd_flow_rings_delete_for_peer(dhd_pub_t *dhdp, uint8 ifindex, char *addr)
|
|||
(!memcmp(flow_ring_table[id].flow_info.da, addr, ETHER_ADDR_LEN)) &&
|
||||
((flow_ring_table[id].status == FLOW_RING_STATUS_OPEN) ||
|
||||
(flow_ring_table[id].status == FLOW_RING_STATUS_CREATE_PENDING))) {
|
||||
DHD_ERROR(("%s: deleting flowid %d\n",
|
||||
DHD_INFO(("%s: deleting flowid %d\n",
|
||||
__FUNCTION__, flow_ring_table[id].flowid));
|
||||
dhd_bus_flow_ring_delete_request(dhdp->bus,
|
||||
(void *) &flow_ring_table[id]);
|
||||
|
|
@ -1308,8 +1358,15 @@ dhd_update_interface_flow_info(dhd_pub_t *dhdp, uint8 ifindex,
|
|||
if_flow_lkup = (if_flow_lkup_t *)dhdp->if_flow_lkup;
|
||||
|
||||
if (op == WLC_E_IF_ADD || op == WLC_E_IF_CHANGE) {
|
||||
|
||||
DHD_ERROR(("%s: ifindex:%d previous role:%d new role:%d\n",
|
||||
__FUNCTION__, ifindex, if_flow_lkup[ifindex].role, role));
|
||||
if_flow_lkup[ifindex].role = role;
|
||||
#ifdef PCIE_FULL_DONGLE
|
||||
if (op == WLC_E_IF_CHANGE) {
|
||||
bool increment = DHD_IF_ROLE_MULTI_CLIENT(dhdp, ifindex);
|
||||
dhd_update_multicilent_flow_rings(dhdp, ifindex, increment);
|
||||
}
|
||||
#endif /* PCIE_FULL_DONGLE */
|
||||
|
||||
if (role == WLC_E_IF_ROLE_WDS) {
|
||||
/**
|
||||
|
|
@ -1452,48 +1509,3 @@ dhd_active_tx_flowring_bkpq_len(dhd_pub_t *dhd)
|
|||
DHD_FLOWRING_LIST_UNLOCK(bus->dhd->flowring_list_lock, list_lock_flags);
|
||||
return active_tx_flowring_qlen;
|
||||
}
|
||||
|
||||
#ifdef DHD_AWDL
|
||||
/**
|
||||
* Handle/Intercept awdl peer op IOVAR fired by user
|
||||
* buf = NULL means delete all peers in awdl interface
|
||||
*/
|
||||
void
|
||||
dhd_awdl_peer_op(dhd_pub_t *dhdp, uint8 ifindex, void *buf, uint32 buflen)
|
||||
{
|
||||
awdl_peer_op_t *peer = (awdl_peer_op_t *)buf;
|
||||
DHD_TRACE(("%s\n", __FUNCTION__));
|
||||
|
||||
ASSERT(ifindex < DHD_MAX_IFS);
|
||||
if (ifindex >= DHD_MAX_IFS)
|
||||
return;
|
||||
if (!buf) {
|
||||
/* Delete all peers in awdl interface */
|
||||
if_flow_lkup_t *if_flow_lkup;
|
||||
if_flow_lkup = (if_flow_lkup_t *)dhdp->if_flow_lkup;
|
||||
if (if_flow_lkup[ifindex].role != WLC_E_IF_ROLE_AWDL) {
|
||||
DHD_ERROR(("%s: Iinterface %d is not a awdl peer \n",
|
||||
__FUNCTION__, ifindex));
|
||||
return;
|
||||
}
|
||||
dhd_flow_rings_delete(dhdp, ifindex);
|
||||
return;
|
||||
}
|
||||
/* Parse awdl_peer_op info now */
|
||||
if (buflen < sizeof(awdl_peer_op_t)) {
|
||||
DHD_ERROR(("%s: cannot handle awdl_peer_op add/del\n", __FUNCTION__));
|
||||
return;
|
||||
}
|
||||
/**
|
||||
* Only flowring deletion is handled here
|
||||
* Flowring addition is taken care in dhd_flowid_lookup
|
||||
*/
|
||||
if (peer->opcode == AWDL_PEER_OP_DEL) {
|
||||
dhd_del_sta(dhdp, ifindex, &peer->addr.octet[0]);
|
||||
dhd_flow_rings_delete_for_peer(dhdp, ifindex, (char *)&peer->addr.octet[0]);
|
||||
} else if (peer->opcode == AWDL_PEER_OP_ADD) {
|
||||
dhd_findadd_sta(dhdp, ifindex, &peer->addr.octet[0]);
|
||||
}
|
||||
return;
|
||||
}
|
||||
#endif /* DHD_AWDL */
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
* Provides type definitions and function prototypes used to create, delete and manage flow rings at
|
||||
* high level.
|
||||
*
|
||||
* Copyright (C) 2020, Broadcom.
|
||||
* Copyright (C) 2022, Broadcom.
|
||||
*
|
||||
* Unless you and Broadcom execute a separate written software license
|
||||
* agreement governing use of this software, this software is licensed to you
|
||||
|
|
@ -58,47 +58,19 @@
|
|||
#endif /* IDLE_TX_FLOW_MGMT */
|
||||
#define FLOW_RING_STATUS_STA_FREEING 7
|
||||
|
||||
#if defined(DHD_HTPUT_TUNABLES)
|
||||
#define HTPUT_FLOW_RING_PRIO PRIO_8021D_BE
|
||||
#define HTPUT_NUM_STA_FLOW_RINGS 1u
|
||||
#define HTPUT_NUM_CLIENT_FLOW_RINGS 3u
|
||||
#define HTPUT_TOTAL_FLOW_RINGS (HTPUT_NUM_STA_FLOW_RINGS + HTPUT_NUM_CLIENT_FLOW_RINGS)
|
||||
#define DHD_IS_FLOWID_HTPUT(pub, flowid) \
|
||||
((flowid >= (pub)->htput_flow_ring_start) && \
|
||||
(flowid < ((pub)->htput_flow_ring_start + HTPUT_TOTAL_FLOW_RINGS)))
|
||||
#endif /* DHD_HTPUT_TUNABLES */
|
||||
((pub)->htput_support && (flowid >= (pub)->htput_flow_ring_start) && \
|
||||
((uint16)flowid < ((pub)->htput_flow_ring_start + HTPUT_TOTAL_FLOW_RINGS)))
|
||||
|
||||
#if defined(FLOW_RING_PREALLOC)
|
||||
#define MAX_FLOW_RINGS 64
|
||||
#endif /* FLOW_RING_PREALLOC */
|
||||
|
||||
#ifdef DHD_EFI
|
||||
/*
|
||||
* Each lbuf is of size 2048 bytes. But the last 112 bytes is occupied for lbuf header.
|
||||
* Since lbuf is crucial data structure we want to avoid operations very close to lbuf.
|
||||
* so providing a pad of 136 bytes. so lbuf and pad together is 248 bytes.
|
||||
*
|
||||
* So the maximum usable lbuf size is 1800 bytes.
|
||||
*
|
||||
* These 1800 bytes is utilized for below purposes.
|
||||
*
|
||||
* 1. FW operating in mode2 requires 98 bytes for extra headers
|
||||
* like SNAP, PLCP etc. Whereas FW operating in mode4 requires 70 bytes.
|
||||
* So in EFI DHD we will consider 98 bytes which fits for chips operating in both mode2 and mode4.
|
||||
*
|
||||
* 2. For TPUT tests in EFI user can request a maximum payload of 1500 bytes.
|
||||
* To add ethernet header and TPUT header etc we are reserving 100bytes. So 1600 bytes are utilized
|
||||
* for headers and payload.
|
||||
*
|
||||
* so 1698(98 + 1600) bytes by are consumed by 1 and 2.
|
||||
* So we still have 112 bytes which can be utilized
|
||||
* if FW needs buffer for more headers in future.
|
||||
*
|
||||
* --Update-- 13Jul2018 (above comments preserved for history)
|
||||
* 3. In case of 11ax chips more headroom is required, FW requires a min. of 1920 bytes for Rx
|
||||
* buffers, or it will trap. Therefore bumping up the size to 1920 bytes. Which leaves
|
||||
* only 16 bytes pad between data and lbuf header ! Further size increase may not be possible !!
|
||||
*/
|
||||
#define DHD_FLOWRING_RX_BUFPOST_PKTSZ 1920
|
||||
#else
|
||||
#define DHD_FLOWRING_RX_BUFPOST_PKTSZ 2048
|
||||
#endif /* DHD_EFI */
|
||||
|
||||
#define DHD_FLOWRING_RX_BUFPOST_PKTSZ_MAX 4096
|
||||
|
||||
|
|
@ -127,16 +99,9 @@
|
|||
#define DHD_IF_ROLE_GENERIC_STA(pub, idx) \
|
||||
(DHD_IF_ROLE_STA(pub, idx) || DHD_IF_ROLE_P2PGC(pub, idx) || DHD_IF_ROLE_WDS(pub, idx))
|
||||
|
||||
#ifdef DHD_AWDL
|
||||
#define DHD_IF_ROLE_AWDL(pub, idx) (DHD_IF_ROLE(pub, idx) == WLC_E_IF_ROLE_AWDL)
|
||||
#define DHD_IF_ROLE_MULTI_CLIENT(pub, idx) \
|
||||
(DHD_IF_ROLE_AP(pub, idx) || DHD_IF_ROLE_P2PGO(pub, idx) || DHD_IF_ROLE_AWDL(pub, idx) ||\
|
||||
DHD_IF_ROLE_NAN(pub, idx))
|
||||
#else
|
||||
#define DHD_IF_ROLE_MULTI_CLIENT(pub, idx) \
|
||||
(DHD_IF_ROLE_AP(pub, idx) || DHD_IF_ROLE_P2PGO(pub, idx) ||\
|
||||
DHD_IF_ROLE_NAN(pub, idx))
|
||||
#endif /* DHD_AWDL */
|
||||
|
||||
#define DHD_FLOW_RING(dhdp, flowid) \
|
||||
(flow_ring_node_t *)&(((flow_ring_node_t *)((dhdp)->flow_ring_table))[flowid])
|
||||
|
|
@ -272,9 +237,6 @@ typedef struct flow_ring_node {
|
|||
/* counter to decide if this particlur flow is stuck or not */
|
||||
uint32 stuck_count;
|
||||
#endif /* DEVICE_TX_STUCK_DETECT */
|
||||
#ifdef DHD_HP2P
|
||||
bool hp2p_ring;
|
||||
#endif /* DHD_HP2P */
|
||||
} flow_ring_node_t;
|
||||
|
||||
typedef flow_ring_node_t flow_ring_table_t;
|
||||
|
|
@ -327,6 +289,8 @@ extern int dhd_flowid_find_by_ifidx(dhd_pub_t *dhdp, uint8 ifidex, uint16 flowid
|
|||
extern void dhd_flowid_free(dhd_pub_t *dhdp, uint8 ifindex, uint16 flowid);
|
||||
|
||||
extern void dhd_flow_rings_delete(dhd_pub_t *dhdp, uint8 ifindex);
|
||||
extern void dhd_update_multicilent_flow_rings(dhd_pub_t *dhdp, uint8 ifindex,
|
||||
bool increment);
|
||||
extern void dhd_flow_rings_flush(dhd_pub_t *dhdp, uint8 ifindex);
|
||||
|
||||
extern void dhd_flow_rings_delete_for_peer(dhd_pub_t *dhdp, uint8 ifindex,
|
||||
|
|
@ -342,10 +306,5 @@ extern int dhd_update_interface_link_status(dhd_pub_t *dhdp, uint8 ifindex,
|
|||
extern int dhd_flow_prio_map(dhd_pub_t *dhd, uint8 *map, bool set);
|
||||
extern int dhd_update_flow_prio_map(dhd_pub_t *dhdp, uint8 map);
|
||||
extern uint32 dhd_active_tx_flowring_bkpq_len(dhd_pub_t *dhdp);
|
||||
#ifdef DHD_AWDL
|
||||
/* DHD handler for awdl peer op IOVAR */
|
||||
extern void dhd_awdl_peer_op(dhd_pub_t *dhdp, uint8 ifindex,
|
||||
void *buf, uint32 buflen);
|
||||
#endif /* DHD_AWDL */
|
||||
extern uint8 dhd_flow_rings_ifindex2role(dhd_pub_t *dhdp, uint8 ifindex);
|
||||
#endif /* _dhd_flowrings_h_ */
|
||||
|
|
|
|||
|
|
@ -1,563 +0,0 @@
|
|||
/*
|
||||
* Firmware trace handling on the DHD side. Kernel thread reads the trace data and writes
|
||||
* to the file and implements various utility functions.
|
||||
*
|
||||
* Broadcom Proprietary and Confidential. Copyright (C) 2020,
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* This is UNPUBLISHED PROPRIETARY SOURCE CODE of Broadcom;
|
||||
* the contents of this file may not be disclosed to third parties,
|
||||
* copied or duplicated in any form, in whole or in part, without
|
||||
* the prior written permission of Broadcom.
|
||||
*
|
||||
*
|
||||
* <<Broadcom-WL-IPTag/Proprietary:>>
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#ifdef BCMINTERNAL
|
||||
|
||||
#ifdef DHD_FWTRACE
|
||||
|
||||
#include <typedefs.h>
|
||||
#include <osl.h>
|
||||
|
||||
#include <bcmutils.h>
|
||||
#include <bcmendian.h>
|
||||
|
||||
#include <dngl_stats.h>
|
||||
#include <dhd.h>
|
||||
#include <dhd_proto.h>
|
||||
#include <dhd_dbg.h>
|
||||
#include <dhd_debug.h>
|
||||
|
||||
#include <dhd_fwtrace.h>
|
||||
|
||||
static int fwtrace_write_to_file(uint8 *buf, uint16 buf_len, dhd_pub_t *dhdp);
|
||||
static int fwtrace_close_file(dhd_pub_t *dhdp);
|
||||
static int fwtrace_open_file(uint32 fw_trace_enabled, dhd_pub_t *dhdp);
|
||||
static fwtrace_buf_t *fwtrace_get_trace_data_ptr(dhd_pub_t *dhdp);
|
||||
static void fwtrace_free_trace_buf(dhd_pub_t *dhdp);
|
||||
|
||||
typedef struct fwtrace_info {
|
||||
struct file *fw_trace_fp;
|
||||
int file_index;
|
||||
int part_index;
|
||||
int trace_buf_index;
|
||||
int trace_buf_count;
|
||||
uint16 overflow_counter;
|
||||
|
||||
char trace_file[TRACE_FILE_NAME_LEN];
|
||||
|
||||
fwtrace_buf_t *trace_data_ptr;
|
||||
|
||||
uint16 prev_seq;
|
||||
|
||||
uint32 fwtrace_enable; /* Enable firmware tracing and the
|
||||
* trace file management.
|
||||
*/
|
||||
struct mutex fwtrace_lock; /* Synchronization between the
|
||||
* ioctl and the kernel thread.
|
||||
*/
|
||||
dhd_dma_buf_t fwtrace_buf; /* firmware trace buffer */
|
||||
} fwtrace_info_t;
|
||||
|
||||
int
|
||||
dhd_fwtrace_attach(dhd_pub_t *dhdp)
|
||||
{
|
||||
fwtrace_info_t *fwtrace_info;
|
||||
|
||||
/* Allocate prot structure */
|
||||
if (!(fwtrace_info = (fwtrace_info_t *)VMALLOCZ(dhdp->osh, sizeof(*fwtrace_info)))) {
|
||||
DHD_ERROR(("%s: kmalloc failed\n", __FUNCTION__));
|
||||
return (BCME_NOMEM);
|
||||
}
|
||||
|
||||
bzero(fwtrace_info, sizeof(*fwtrace_info));
|
||||
dhdp->fwtrace_info = fwtrace_info;
|
||||
|
||||
mutex_init(&dhdp->fwtrace_info->fwtrace_lock);
|
||||
|
||||
DHD_INFO(("allocated DHD fwtrace\n"));
|
||||
|
||||
return BCME_OK;
|
||||
}
|
||||
|
||||
int
|
||||
dhd_fwtrace_detach(dhd_pub_t *dhdp)
|
||||
{
|
||||
fwtrace_info_t *fwtrace_info;
|
||||
|
||||
DHD_TRACE(("%s: %d\n", __FUNCTION__, __LINE__));
|
||||
|
||||
if (!dhdp) {
|
||||
return BCME_OK;
|
||||
}
|
||||
|
||||
if (!dhdp->fwtrace_info) {
|
||||
return BCME_OK;
|
||||
}
|
||||
|
||||
fwtrace_info = dhdp->fwtrace_info;
|
||||
|
||||
dhd_dma_buf_free(dhdp, &dhdp->fwtrace_info->fwtrace_buf);
|
||||
|
||||
/* close the file if valid */
|
||||
if (!(IS_ERR_OR_NULL(dhdp->fwtrace_info->fw_trace_fp))) {
|
||||
(void) filp_close(dhdp->fwtrace_info->fw_trace_fp, 0);
|
||||
}
|
||||
|
||||
mutex_destroy(&dhdp->fwtrace_info->fwtrace_lock);
|
||||
|
||||
VMFREE(dhdp->osh, fwtrace_info, sizeof(*fwtrace_info));
|
||||
|
||||
dhdp->fwtrace_info = NULL;
|
||||
|
||||
DHD_INFO(("Deallocated DHD fwtrace_info\n"));
|
||||
|
||||
return (BCME_OK);
|
||||
}
|
||||
|
||||
uint16
|
||||
get_fw_trace_overflow_counter(dhd_pub_t *dhdp)
|
||||
{
|
||||
return (dhdp->fwtrace_info->overflow_counter);
|
||||
}
|
||||
|
||||
void
|
||||
process_fw_trace_data(dhd_pub_t *dhdp)
|
||||
{
|
||||
fwtrace_info_t *fwtrace_info = dhdp->fwtrace_info;
|
||||
uint16 length;
|
||||
uint16 incoming_seq;
|
||||
uint32 trace_buf_index = fwtrace_info->trace_buf_index;
|
||||
fwtrace_buf_t * trace_buf;
|
||||
fwtrace_buf_t * curr_buf;
|
||||
|
||||
mutex_lock(&fwtrace_info->fwtrace_lock);
|
||||
|
||||
if (fwtrace_info->fw_trace_fp == NULL) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
if ((trace_buf = fwtrace_get_trace_data_ptr(dhdp)) == NULL) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
do {
|
||||
curr_buf = trace_buf + trace_buf_index;
|
||||
|
||||
length = curr_buf->info.length;
|
||||
/* If the incoming length is 0, means nothing is updated by the firmware */
|
||||
if (length == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
incoming_seq = curr_buf->info.seq_num;
|
||||
|
||||
if (((uint16)(fwtrace_info->prev_seq + 1) != incoming_seq) &&
|
||||
length != sizeof(*curr_buf)) {
|
||||
DHD_ERROR(("*** invalid trace len idx = %u, length = %u, "
|
||||
"cur seq = %u, in-seq = %u \n",
|
||||
trace_buf_index, length,
|
||||
fwtrace_info->prev_seq, incoming_seq));
|
||||
break;
|
||||
}
|
||||
|
||||
DHD_TRACE(("*** TRACE BUS: IDX:%d, in-seq:%d(prev-%d), ptr:%p(%llu), len:%d\n",
|
||||
trace_buf_index, incoming_seq, fwtrace_info->prev_seq,
|
||||
curr_buf, (uint64)curr_buf, length));
|
||||
|
||||
/* Write trace data to a file */
|
||||
if (fwtrace_write_to_file((uint8 *) curr_buf, length, dhdp) != BCME_OK) {
|
||||
DHD_ERROR(("*** fwtrace_write_to_file has failed \n"));
|
||||
break;
|
||||
}
|
||||
|
||||
/* Reset length after consuming the fwtrace data */
|
||||
curr_buf->info.length = 0;
|
||||
|
||||
if ((fwtrace_info->prev_seq + 1) != incoming_seq) {
|
||||
DHD_ERROR(("*** seq mismatch, index = %u, length = %u, "
|
||||
"cur seq = %u, in-seq = %u \n",
|
||||
trace_buf_index, length,
|
||||
fwtrace_info->prev_seq, incoming_seq));
|
||||
}
|
||||
fwtrace_info->prev_seq = incoming_seq;
|
||||
|
||||
trace_buf_index++;
|
||||
trace_buf_index &= (fwtrace_info->trace_buf_count - 1u);
|
||||
fwtrace_info->trace_buf_index = trace_buf_index;
|
||||
} while (true);
|
||||
|
||||
done:
|
||||
mutex_unlock(&fwtrace_info->fwtrace_lock);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Write the incoming trace data to a file. The maximum file size is 1MB. After that
|
||||
* the trace data is saved into a new file.
|
||||
*/
|
||||
static int
|
||||
fwtrace_write_to_file(uint8 *buf, uint16 buf_len, dhd_pub_t *dhdp)
|
||||
{
|
||||
fwtrace_info_t *fwtrace_info = dhdp->fwtrace_info;
|
||||
int ret_val = BCME_OK;
|
||||
int ret_val_1 = 0;
|
||||
mm_segment_t old_fs;
|
||||
loff_t pos = 0;
|
||||
struct kstat stat;
|
||||
int error;
|
||||
|
||||
/* Change to KERNEL_DS address limit */
|
||||
old_fs = get_fs();
|
||||
set_fs(KERNEL_DS);
|
||||
|
||||
if (buf == NULL) {
|
||||
ret_val = BCME_ERROR;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (IS_ERR_OR_NULL(fwtrace_info->fw_trace_fp)) {
|
||||
ret_val = BCME_ERROR;
|
||||
goto done;
|
||||
}
|
||||
|
||||
//
|
||||
// Get the file size
|
||||
// if the size + buf_len > TRACE_FILE_SIZE, then write to a different file.
|
||||
//
|
||||
error = vfs_stat(fwtrace_info->trace_file, &stat);
|
||||
if (error) {
|
||||
DHD_ERROR(("vfs_stat has failed with error code = %d\n", error));
|
||||
goto done;
|
||||
}
|
||||
|
||||
if ((int) stat.size + buf_len > TRACE_FILE_SIZE) {
|
||||
fwtrace_close_file(dhdp);
|
||||
(fwtrace_info->part_index)++;
|
||||
fwtrace_open_file(TRUE, dhdp);
|
||||
}
|
||||
|
||||
pos = fwtrace_info->fw_trace_fp->f_pos;
|
||||
/* Write buf to file */
|
||||
ret_val_1 = vfs_write(fwtrace_info->fw_trace_fp,
|
||||
(char *) buf, (uint32) buf_len, &pos);
|
||||
if (ret_val_1 < 0) {
|
||||
DHD_ERROR(("write file error, err = %d\n", ret_val_1));
|
||||
ret_val = BCME_ERROR;
|
||||
goto done;
|
||||
}
|
||||
fwtrace_info->fw_trace_fp->f_pos = pos;
|
||||
|
||||
/* Sync file from filesystem to physical media */
|
||||
ret_val_1 = vfs_fsync(fwtrace_info->fw_trace_fp, 0);
|
||||
if (ret_val_1 < 0) {
|
||||
DHD_ERROR(("sync file error, error = %d\n", ret_val_1));
|
||||
ret_val = BCME_ERROR;
|
||||
goto done;
|
||||
}
|
||||
|
||||
done:
|
||||
/* restore previous address limit */
|
||||
set_fs(old_fs);
|
||||
return (ret_val);
|
||||
}
|
||||
|
||||
/*
|
||||
* Start the trace, gets called from the ioctl handler.
|
||||
*/
|
||||
int
|
||||
fw_trace_start(dhd_pub_t *dhdp, uint32 fw_trace_enabled)
|
||||
{
|
||||
int ret_val = BCME_OK;
|
||||
|
||||
(dhdp->fwtrace_info->file_index)++;
|
||||
dhdp->fwtrace_info->part_index = 1;
|
||||
|
||||
dhdp->fwtrace_info->trace_buf_index = 0;
|
||||
|
||||
mutex_lock(&dhdp->fwtrace_info->fwtrace_lock);
|
||||
ret_val = fwtrace_open_file(fw_trace_enabled, dhdp);
|
||||
if (ret_val == BCME_OK) {
|
||||
dhdp->fwtrace_info->fwtrace_enable = fw_trace_enabled;
|
||||
}
|
||||
mutex_unlock(&dhdp->fwtrace_info->fwtrace_lock);
|
||||
|
||||
return (ret_val);
|
||||
}
|
||||
|
||||
/*
|
||||
* Stop the trace collection and close the file descriptor.
|
||||
*/
|
||||
int
|
||||
fw_trace_stop(dhd_pub_t *dhdp)
|
||||
{
|
||||
int ret_val = BCME_OK;
|
||||
|
||||
/* Check to see if there is any trace data */
|
||||
process_fw_trace_data(dhdp);
|
||||
|
||||
mutex_lock(&dhdp->fwtrace_info->fwtrace_lock); /* acquire lock */
|
||||
/* flush the trace buffer */
|
||||
ret_val = fwtrace_close_file(dhdp);
|
||||
|
||||
/* free the trace buffer */
|
||||
fwtrace_free_trace_buf(dhdp);
|
||||
mutex_unlock(&dhdp->fwtrace_info->fwtrace_lock); /* release the lock */
|
||||
|
||||
return (ret_val);
|
||||
}
|
||||
|
||||
/*
|
||||
* The trace file format is: fw_trace_w_part_x_y_z
|
||||
* where w is the file index, x is the part index,
|
||||
* y is in seconds and z is in milliseconds
|
||||
*
|
||||
* fw_trace_1_part_1_1539298163209110
|
||||
* fw_trace_1_part_2_1539298194739003 etc.
|
||||
*
|
||||
*/
|
||||
static int
|
||||
fwtrace_open_file(uint32 fw_trace_enabled, dhd_pub_t *dhdp)
|
||||
{
|
||||
fwtrace_info_t *fwtrace_info = dhdp->fwtrace_info;
|
||||
int ret_val = BCME_OK;
|
||||
uint32 file_mode;
|
||||
char ts_str[DEBUG_DUMP_TIME_BUF_LEN];
|
||||
|
||||
if (fw_trace_enabled) {
|
||||
if (!(IS_ERR_OR_NULL(fwtrace_info->fw_trace_fp))) {
|
||||
(void) filp_close(fwtrace_info->fw_trace_fp, 0);
|
||||
}
|
||||
|
||||
DHD_INFO((" *** Creating the trace file \n"));
|
||||
|
||||
file_mode = O_CREAT | O_WRONLY | O_SYNC;
|
||||
clear_debug_dump_time(ts_str);
|
||||
get_debug_dump_time(ts_str);
|
||||
|
||||
snprintf(fwtrace_info->trace_file,
|
||||
sizeof(fwtrace_info->trace_file),
|
||||
"%sfw_trace_%d_part_%d_%x_%s",
|
||||
DHD_COMMON_DUMP_PATH, fwtrace_info->file_index,
|
||||
fwtrace_info->part_index,
|
||||
dhd_bus_get_bp_base(dhdp),
|
||||
ts_str);
|
||||
|
||||
fwtrace_info->fw_trace_fp =
|
||||
filp_open(fwtrace_info->trace_file, file_mode, 0664);
|
||||
|
||||
if (IS_ERR(fwtrace_info->fw_trace_fp)) {
|
||||
DHD_ERROR(("Unable to create the fw trace file file: %s\n",
|
||||
fwtrace_info->trace_file));
|
||||
ret_val = BCME_ERROR;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
done:
|
||||
return (ret_val);
|
||||
}
|
||||
|
||||
static int
|
||||
fwtrace_close_file(dhd_pub_t *dhdp)
|
||||
{
|
||||
int ret_val = BCME_OK;
|
||||
|
||||
if (!(IS_ERR_OR_NULL(dhdp->fwtrace_info->fw_trace_fp))) {
|
||||
(void) filp_close(dhdp->fwtrace_info->fw_trace_fp, 0);
|
||||
}
|
||||
|
||||
dhdp->fwtrace_info->fw_trace_fp = NULL;
|
||||
|
||||
return (ret_val);
|
||||
}
|
||||
|
||||
#define FWTRACE_HADDR_PARAMS_SIZE 256u
|
||||
#define FW_TRACE_FLUSH 0x8u /* bit 3 */
|
||||
|
||||
static int send_fw_trace_val(dhd_pub_t *dhdp, int val);
|
||||
|
||||
/*
|
||||
* Initialize FWTRACE.
|
||||
* Allocate trace buffer and open trace file.
|
||||
*/
|
||||
int
|
||||
fwtrace_init(dhd_pub_t *dhdp)
|
||||
{
|
||||
int ret_val = BCME_OK;
|
||||
fwtrace_hostaddr_info_t host_buf_info;
|
||||
|
||||
if (dhdp->fwtrace_info->fwtrace_buf.va != NULL) {
|
||||
/* Already initialized */
|
||||
goto done;
|
||||
}
|
||||
|
||||
ret_val = fwtrace_get_haddr(dhdp, &host_buf_info);
|
||||
|
||||
if (ret_val != BCME_OK) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
DHD_INFO(("dhd_get_trace_haddr: addr = %llx, len = %u\n",
|
||||
host_buf_info.haddr.u64, host_buf_info.num_bufs));
|
||||
|
||||
/* Initialize and setup the file */
|
||||
ret_val = fw_trace_start(dhdp, TRUE);
|
||||
|
||||
done:
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
/*
|
||||
* Process the fwtrace set command to enable/disable firmware tracing.
|
||||
* Always, enable preceeds with disable.
|
||||
*/
|
||||
int
|
||||
handle_set_fwtrace(dhd_pub_t *dhdp, uint32 val)
|
||||
{
|
||||
int ret, ret_val = BCME_OK;
|
||||
|
||||
/* On set, consider only lower two bytes for now */
|
||||
dhdp->fwtrace_info->fwtrace_enable = (val & 0xFFFF);
|
||||
|
||||
if (val & FW_TRACE_FLUSH) { /* only flush the trace buffer */
|
||||
if ((ret_val = send_fw_trace_val(dhdp, val)) != BCME_OK) {
|
||||
goto done;
|
||||
}
|
||||
} else if (val == 0) { /* disable the tracing */
|
||||
/* Disable the trace in the firmware */
|
||||
if ((ret_val = send_fw_trace_val(dhdp, val)) != BCME_OK) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* cleanup in the driver */
|
||||
fw_trace_stop(dhdp);
|
||||
} else { /* enable the tracing */
|
||||
fwtrace_hostaddr_info_t haddr_info;
|
||||
|
||||
ret_val = fwtrace_init(dhdp);
|
||||
if (ret_val != BCME_OK) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
if ((ret_val = fwtrace_get_haddr(dhdp, &haddr_info)) != BCME_OK) {
|
||||
DHD_ERROR(("%s: set dhd_iovar has failed for "
|
||||
"fw_trace_haddr, "
|
||||
"ret=%d\n", __FUNCTION__, ret_val));
|
||||
goto done;
|
||||
}
|
||||
|
||||
ret = dhd_iovar(dhdp, 0, "dngl:fwtrace_haddr",
|
||||
(char *) &haddr_info, sizeof(haddr_info),
|
||||
NULL, 0, TRUE);
|
||||
if (ret < 0) {
|
||||
DHD_ERROR(("%s: set dhd_iovar has failed for "
|
||||
"fwtrace_haddr, "
|
||||
"ret=%d\n", __FUNCTION__, ret));
|
||||
ret_val = BCME_NOMEM;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Finaly, enable the trace in the firmware */
|
||||
if ((ret_val = send_fw_trace_val(dhdp, val)) != BCME_OK) {
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
done:
|
||||
return (ret_val);
|
||||
}
|
||||
|
||||
/*
|
||||
* Send dngl:fwtrace IOVAR to the firmware.
|
||||
*/
|
||||
|
||||
static int
|
||||
send_fw_trace_val(dhd_pub_t *dhdp, int val)
|
||||
{
|
||||
int ret_val = BCME_OK;
|
||||
|
||||
if ((ret_val = dhd_iovar(dhdp, 0, "dngl:fwtrace", (char *)&val, sizeof(val),
|
||||
NULL, 0, TRUE)) < 0) {
|
||||
DHD_ERROR(("%s: set dhd_iovar has failed fwtrace, "
|
||||
"ret=%d\n", __FUNCTION__, ret_val));
|
||||
}
|
||||
|
||||
return (ret_val);
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns the virual address for the firmware trace buffer.
|
||||
* DHD monitors this buffer for an update from the firmware.
|
||||
*/
|
||||
static fwtrace_buf_t *
|
||||
fwtrace_get_trace_data_ptr(dhd_pub_t *dhdp)
|
||||
{
|
||||
return ((fwtrace_buf_t *) dhdp->fwtrace_info->fwtrace_buf.va);
|
||||
}
|
||||
|
||||
int
|
||||
fwtrace_get_haddr(dhd_pub_t *dhdp, fwtrace_hostaddr_info_t *haddr_info)
|
||||
{
|
||||
int ret_val = BCME_NOMEM;
|
||||
int num_host_buffers = FWTRACE_NUM_HOST_BUFFERS;
|
||||
|
||||
if (haddr_info == NULL) {
|
||||
ret_val = BCME_BADARG;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (dhdp->fwtrace_info->fwtrace_buf.va != NULL) {
|
||||
/* Use the existing buffer and send to the firmware */
|
||||
haddr_info->haddr.u64 = HTOL64(*(uint64 *)
|
||||
&dhdp->fwtrace_info->fwtrace_buf.pa);
|
||||
haddr_info->num_bufs = dhdp->fwtrace_info->trace_buf_count;
|
||||
haddr_info->buf_len = sizeof(fwtrace_buf_t);
|
||||
ret_val = BCME_OK;
|
||||
goto done;
|
||||
}
|
||||
|
||||
do {
|
||||
/* Initialize firmware trace buffer */
|
||||
if (dhd_dma_buf_alloc(dhdp, &dhdp->fwtrace_info->fwtrace_buf,
|
||||
sizeof(fwtrace_buf_t) * num_host_buffers) == BCME_OK) {
|
||||
dhdp->fwtrace_info->trace_buf_count = num_host_buffers;
|
||||
ret_val = BCME_OK;
|
||||
break;
|
||||
}
|
||||
|
||||
DHD_ERROR(("%s: Allocing %d buffers of size %lu bytes failed\n",
|
||||
__FUNCTION__, num_host_buffers,
|
||||
sizeof(fwtrace_buf_t) * num_host_buffers));
|
||||
|
||||
/* Retry with smaller numbers */
|
||||
num_host_buffers >>= 1;
|
||||
} while (num_host_buffers > 0);
|
||||
|
||||
haddr_info->haddr.u64 = HTOL64(*(uint64 *)&dhdp->fwtrace_info->fwtrace_buf.pa);
|
||||
haddr_info->num_bufs = num_host_buffers;
|
||||
haddr_info->buf_len = sizeof(fwtrace_buf_t);
|
||||
|
||||
DHD_INFO(("Firmware trace buffer, host address = %llx, count = %u \n",
|
||||
haddr_info->haddr.u64,
|
||||
haddr_info->num_bufs));
|
||||
done:
|
||||
return (ret_val);
|
||||
}
|
||||
|
||||
/*
|
||||
* Frees the host buffer.
|
||||
*/
|
||||
static void
|
||||
fwtrace_free_trace_buf(dhd_pub_t *dhdp)
|
||||
{
|
||||
dhd_dma_buf_free(dhdp, &dhdp->fwtrace_info->fwtrace_buf);
|
||||
return;
|
||||
}
|
||||
|
||||
#endif /* DHD_FWTRACE */
|
||||
|
||||
#endif /* BCMINTERNAL */
|
||||
|
|
@ -1,55 +0,0 @@
|
|||
/*
|
||||
* Data structures required for the firmware tracing support on Linux.
|
||||
*
|
||||
* Broadcom Proprietary and Confidential. Copyright (C) 2020,
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* This is UNPUBLISHED PROPRIETARY SOURCE CODE of Broadcom;
|
||||
* the contents of this file may not be disclosed to third parties,
|
||||
* copied or duplicated in any form, in whole or in part, without
|
||||
* the prior written permission of Broadcom.
|
||||
*
|
||||
*
|
||||
* <<Broadcom-WL-IPTag/Proprietary:>>
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#ifndef _DHD_FWTRACE_H
|
||||
#define _DHD_FWTRACE_H
|
||||
|
||||
#ifdef BCMINTERNAL
|
||||
#ifdef DHD_FWTRACE /* firmware tracing */
|
||||
|
||||
#include <dngl_stats.h>
|
||||
#include <dhd.h>
|
||||
#include <dhd_proto.h>
|
||||
#include <dhd_dbg.h>
|
||||
#include <dhd_debug.h>
|
||||
#include <dhd_fwtrace.h>
|
||||
|
||||
#include <linux/mutex.h>
|
||||
#include <bcm_fwtrace.h>
|
||||
|
||||
#define TRACE_FILE_NAME_LEN 128u /* bytes */
|
||||
#define TRACE_FILE_SIZE (1024u * 1024u) /* Trace file size is 1 MB */
|
||||
|
||||
/* Prototypes */
|
||||
void dhd_event_logtrace_enqueue_fwtrace(dhd_pub_t *dhdp);
|
||||
int dhd_fwtrace_attach(dhd_pub_t *dhdinfo);
|
||||
int dhd_fwtrace_detach(dhd_pub_t *dhdinfo);
|
||||
|
||||
void process_fw_trace_data(dhd_pub_t *dhdp);
|
||||
uint32 dhd_bus_get_bp_base(dhd_pub_t *dhdp);
|
||||
int fwtrace_init(dhd_pub_t *dhdp);
|
||||
int fw_trace_start(dhd_pub_t *dhdp, uint32 fw_trace_enabled);
|
||||
int fw_trace_stop(dhd_pub_t *dhdp);
|
||||
int handle_set_fwtrace(dhd_pub_t *dhdp, uint32 val);
|
||||
uint16 get_fw_trace_overflow_counter(dhd_pub_t *dhdp);
|
||||
int fwtrace_get_haddr(dhd_pub_t *dhdp, fwtrace_hostaddr_info_t *haddr_info);
|
||||
|
||||
#endif /* DHD_FWTRACE */
|
||||
|
||||
#endif /* BCMINTERNAL */
|
||||
|
||||
#endif /* _DHD_FWTRACE_H */
|
||||
|
|
@ -1,24 +1,19 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
|
||||
#include <osl.h>
|
||||
#include <dhd_linux.h>
|
||||
#include <linux/gpio.h>
|
||||
#ifdef BCMDHD_DTS
|
||||
#include <linux/of_gpio.h>
|
||||
#endif
|
||||
#ifdef BCMDHD_PLATDEV
|
||||
#include <linux/platform_device.h>
|
||||
#endif
|
||||
#ifdef CUSTOMER_HW_ROCKCHIP
|
||||
#include <linux/rfkill-wlan.h>
|
||||
#endif
|
||||
|
||||
#if defined(BUS_POWER_RESTORE) && defined(BCMSDIO)
|
||||
#include <linux/mmc/core.h>
|
||||
#include <linux/mmc/card.h>
|
||||
#include <linux/mmc/host.h>
|
||||
#include <linux/mmc/sdio_func.h>
|
||||
#endif /* defined(BUS_POWER_RESTORE) && defined(BCMSDIO) */
|
||||
|
||||
#ifdef CONFIG_DHD_USE_STATIC_BUF
|
||||
#ifdef DHD_STATIC_IN_DRIVER
|
||||
extern int dhd_static_buf_init(void);
|
||||
extern void dhd_static_buf_exit(void);
|
||||
#endif /* DHD_STATIC_IN_DRIVER */
|
||||
#ifdef BCMDHD_MDRIVER
|
||||
#if defined(BCMDHD_MDRIVER) && !defined(DHD_STATIC_IN_DRIVER)
|
||||
extern void *dhd_wlan_mem_prealloc(uint bus_type, int index,
|
||||
int section, unsigned long size);
|
||||
#else
|
||||
|
|
@ -33,7 +28,7 @@ extern void *dhd_wlan_mem_prealloc(int section, unsigned long size);
|
|||
|
||||
#ifdef BCMDHD_DTS
|
||||
/* This is sample code in dts file.
|
||||
bcmdhd {
|
||||
bcmdhd_wlan {
|
||||
compatible = "android,bcmdhd_wlan";
|
||||
gpio_wl_reg_on = <&gpio GPIOH_4 GPIO_ACTIVE_HIGH>;
|
||||
gpio_wl_host_wake = <&gpio GPIOZ_15 GPIO_ACTIVE_HIGH>;
|
||||
|
|
@ -62,19 +57,11 @@ dhd_wlan_set_power(int on, wifi_adapter_info_t *adapter)
|
|||
#ifdef CUSTOMER_HW_ROCKCHIP
|
||||
rockchip_wifi_power(1);
|
||||
#ifdef BCMPCIE
|
||||
//rk_pcie_power_on_atu_fixup();
|
||||
// rk_pcie_power_on_atu_fixup();
|
||||
#endif
|
||||
#endif
|
||||
#ifdef BUS_POWER_RESTORE
|
||||
#ifdef BCMSDIO
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 32) && LINUX_VERSION_CODE < KERNEL_VERSION(4, 19, 0)
|
||||
if (adapter->sdio_func && adapter->sdio_func->card && adapter->sdio_func->card->host) {
|
||||
mdelay(100);
|
||||
printf("======== mmc_power_restore_host! ========\n");
|
||||
mmc_power_restore_host(adapter->sdio_func->card->host);
|
||||
}
|
||||
#endif
|
||||
#elif defined(BCMPCIE)
|
||||
#ifdef BCMPCIE
|
||||
if (adapter->pci_dev) {
|
||||
mdelay(100);
|
||||
printf("======== pci_set_power_state PCI_D0! ========\n");
|
||||
|
|
@ -90,17 +77,9 @@ dhd_wlan_set_power(int on, wifi_adapter_info_t *adapter)
|
|||
#endif /* BCMPCIE */
|
||||
#endif /* BUS_POWER_RESTORE */
|
||||
/* Lets customer power to get stable */
|
||||
mdelay(100);
|
||||
} else {
|
||||
#ifdef BUS_POWER_RESTORE
|
||||
#ifdef BCMSDIO
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 32) && LINUX_VERSION_CODE < KERNEL_VERSION(4, 19, 0)
|
||||
if (adapter->sdio_func && adapter->sdio_func->card && adapter->sdio_func->card->host) {
|
||||
printf("======== mmc_power_save_host! ========\n");
|
||||
mmc_power_save_host(adapter->sdio_func->card->host);
|
||||
}
|
||||
#endif
|
||||
#elif defined(BCMPCIE)
|
||||
#ifdef BCMPCIE
|
||||
if (adapter->pci_dev) {
|
||||
printf("======== pci_set_power_state PCI_D3hot! ========\n");
|
||||
pci_save_state(adapter->pci_dev);
|
||||
|
|
@ -127,16 +106,17 @@ dhd_wlan_set_power(int on, wifi_adapter_info_t *adapter)
|
|||
return err;
|
||||
}
|
||||
|
||||
static int dhd_wlan_set_reset(int onoff)
|
||||
static int
|
||||
dhd_wlan_set_reset(int onoff)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dhd_wlan_set_carddetect(int present)
|
||||
static int
|
||||
dhd_wlan_set_carddetect(int present)
|
||||
{
|
||||
int err = 0;
|
||||
|
||||
#if !defined(BUS_POWER_RESTORE)
|
||||
if (present) {
|
||||
#if defined(BCMSDIO)
|
||||
printf("======== Card detection to detect SDIO card! ========\n");
|
||||
|
|
@ -156,20 +136,20 @@ static int dhd_wlan_set_carddetect(int present)
|
|||
err = sdhci_force_presence_change(&sdmmc_channel, 0);
|
||||
#endif /* CUSTOMER_HW_PLATFORM */
|
||||
#ifdef CUSTOMER_HW_ROCKCHIP
|
||||
rockchip_wifi_set_carddetect(0);
|
||||
rockchip_wifi_set_carddetect(0);
|
||||
#endif
|
||||
#elif defined(BCMPCIE)
|
||||
printf("======== Card detection to remove PCIE card! ========\n");
|
||||
#endif
|
||||
}
|
||||
#endif /* BUS_POWER_RESTORE */
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int dhd_wlan_get_mac_addr(unsigned char *buf, int ifidx)
|
||||
static int
|
||||
dhd_wlan_get_mac_addr(unsigned char *buf, int ifidx)
|
||||
{
|
||||
int err = 0;
|
||||
int err = -1;
|
||||
|
||||
if (ifidx == 1) {
|
||||
#ifdef EXAMPLE_GET_MAC
|
||||
|
|
@ -265,16 +245,17 @@ struct wifi_platform_data dhd_wlan_control = {
|
|||
.get_country_code = dhd_wlan_get_country_code,
|
||||
};
|
||||
|
||||
int dhd_wlan_init_gpio(wifi_adapter_info_t *adapter)
|
||||
static int
|
||||
dhd_wlan_init_gpio(wifi_adapter_info_t *adapter)
|
||||
{
|
||||
#ifdef BCMDHD_DTS
|
||||
char wlan_node[32];
|
||||
struct device_node *root_node = NULL;
|
||||
#endif
|
||||
int err = 0;
|
||||
int gpio_wl_reg_on;
|
||||
int gpio_wl_reg_on = -1;
|
||||
#ifdef CUSTOMER_OOB
|
||||
int gpio_wl_host_wake;
|
||||
int gpio_wl_host_wake = -1;
|
||||
int host_oob_irq = -1;
|
||||
uint host_oob_irq_flags = 0;
|
||||
#ifdef CUSTOMER_HW_ROCKCHIP
|
||||
|
|
@ -288,9 +269,19 @@ int dhd_wlan_init_gpio(wifi_adapter_info_t *adapter)
|
|||
* WL_REG_ON and WL_HOST_WAKE.
|
||||
*/
|
||||
#ifdef BCMDHD_DTS
|
||||
#ifdef BCMDHD_PLATDEV
|
||||
if (adapter->pdev) {
|
||||
root_node = adapter->pdev->dev.of_node;
|
||||
strcpy(wlan_node, root_node->name);
|
||||
} else {
|
||||
printf("%s: adapter->pdev is NULL\n", __FUNCTION__);
|
||||
return -1;
|
||||
}
|
||||
#else
|
||||
strcpy(wlan_node, DHD_DT_COMPAT_ENTRY);
|
||||
printf("======== Get GPIO from DTS(%s) ========\n", wlan_node);
|
||||
root_node = of_find_compatible_node(NULL, NULL, wlan_node);
|
||||
#endif
|
||||
printf("======== Get GPIO from DTS(%s) ========\n", wlan_node);
|
||||
if (root_node) {
|
||||
gpio_wl_reg_on = of_get_named_gpio(root_node, GPIO_WL_REG_ON_PROPNAME, 0);
|
||||
#ifdef CUSTOMER_OOB
|
||||
|
|
@ -308,8 +299,8 @@ int dhd_wlan_init_gpio(wifi_adapter_info_t *adapter)
|
|||
if (gpio_wl_reg_on >= 0) {
|
||||
err = gpio_request(gpio_wl_reg_on, "WL_REG_ON");
|
||||
if (err < 0) {
|
||||
printf("%s: gpio_request(%d) for WL_REG_ON failed\n",
|
||||
__FUNCTION__, gpio_wl_reg_on);
|
||||
printf("%s: gpio_request(%d) for WL_REG_ON failed %d\n",
|
||||
__FUNCTION__, gpio_wl_reg_on, err);
|
||||
gpio_wl_reg_on = -1;
|
||||
}
|
||||
}
|
||||
|
|
@ -319,22 +310,22 @@ int dhd_wlan_init_gpio(wifi_adapter_info_t *adapter)
|
|||
if (gpio_wl_host_wake >= 0) {
|
||||
err = gpio_request(gpio_wl_host_wake, "bcmdhd");
|
||||
if (err < 0) {
|
||||
printf("%s: gpio_request(%d) for WL_HOST_WAKE failed\n",
|
||||
__FUNCTION__, gpio_wl_host_wake);
|
||||
printf("%s: gpio_request(%d) for WL_HOST_WAKE failed %d\n",
|
||||
__FUNCTION__, gpio_wl_host_wake, err);
|
||||
return -1;
|
||||
}
|
||||
adapter->gpio_wl_host_wake = gpio_wl_host_wake;
|
||||
err = gpio_direction_input(gpio_wl_host_wake);
|
||||
if (err < 0) {
|
||||
printf("%s: gpio_direction_input(%d) for WL_HOST_WAKE failed\n",
|
||||
__FUNCTION__, gpio_wl_host_wake);
|
||||
printf("%s: gpio_direction_input(%d) for WL_HOST_WAKE failed %d\n",
|
||||
__FUNCTION__, gpio_wl_host_wake, err);
|
||||
gpio_free(gpio_wl_host_wake);
|
||||
return -1;
|
||||
}
|
||||
host_oob_irq = gpio_to_irq(gpio_wl_host_wake);
|
||||
if (host_oob_irq < 0) {
|
||||
printf("%s: gpio_to_irq(%d) for WL_HOST_WAKE failed\n",
|
||||
__FUNCTION__, gpio_wl_host_wake);
|
||||
printf("%s: gpio_to_irq(%d) for WL_HOST_WAKE failed %d\n",
|
||||
__FUNCTION__, gpio_wl_host_wake, host_oob_irq);
|
||||
gpio_free(gpio_wl_host_wake);
|
||||
return -1;
|
||||
}
|
||||
|
|
@ -374,7 +365,8 @@ int dhd_wlan_init_gpio(wifi_adapter_info_t *adapter)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void dhd_wlan_deinit_gpio(wifi_adapter_info_t *adapter)
|
||||
static void
|
||||
dhd_wlan_deinit_gpio(wifi_adapter_info_t *adapter)
|
||||
{
|
||||
int gpio_wl_reg_on = adapter->gpio_wl_reg_on;
|
||||
#ifdef CUSTOMER_OOB
|
||||
|
|
@ -384,42 +376,74 @@ static void dhd_wlan_deinit_gpio(wifi_adapter_info_t *adapter)
|
|||
if (gpio_wl_reg_on >= 0) {
|
||||
printf("%s: gpio_free(WL_REG_ON %d)\n", __FUNCTION__, gpio_wl_reg_on);
|
||||
gpio_free(gpio_wl_reg_on);
|
||||
gpio_wl_reg_on = -1;
|
||||
adapter->gpio_wl_reg_on = -1;
|
||||
}
|
||||
#ifdef CUSTOMER_OOB
|
||||
if (gpio_wl_host_wake >= 0) {
|
||||
printf("%s: gpio_free(WL_HOST_WAKE %d)\n", __FUNCTION__, gpio_wl_host_wake);
|
||||
gpio_free(gpio_wl_host_wake);
|
||||
gpio_wl_host_wake = -1;
|
||||
adapter->gpio_wl_host_wake = -1;
|
||||
}
|
||||
#endif /* CUSTOMER_OOB */
|
||||
}
|
||||
|
||||
int dhd_wlan_init_plat_data(wifi_adapter_info_t *adapter)
|
||||
#if defined(BCMDHD_MDRIVER)
|
||||
static void
|
||||
dhd_wlan_init_adapter(wifi_adapter_info_t *adapter)
|
||||
{
|
||||
#ifdef ADAPTER_IDX
|
||||
if (ADAPTER_IDX == 0) {
|
||||
adapter->bus_num = 1;
|
||||
adapter->slot_num = 1;
|
||||
} else if (ADAPTER_IDX == 1) {
|
||||
adapter->bus_num = 2;
|
||||
adapter->slot_num = 1;
|
||||
}
|
||||
adapter->index = ADAPTER_IDX;
|
||||
#ifdef BCMSDIO
|
||||
adapter->bus_type = SDIO_BUS;
|
||||
#elif defined(BCMPCIE)
|
||||
adapter->bus_type = PCI_BUS;
|
||||
#elif defined(BCMDBUS)
|
||||
adapter->bus_type = USB_BUS;
|
||||
#endif
|
||||
printf("bus_type=%d, bus_num=%d, slot_num=%d\n",
|
||||
adapter->bus_type, adapter->bus_num, adapter->slot_num);
|
||||
#endif /* ADAPTER_IDX */
|
||||
|
||||
#ifdef DHD_STATIC_IN_DRIVER
|
||||
adapter->index = 0;
|
||||
#elif !defined(ADAPTER_IDX)
|
||||
#ifdef BCMSDIO
|
||||
adapter->index = 0;
|
||||
#elif defined(BCMPCIE)
|
||||
adapter->index = 1;
|
||||
#elif defined(BCMDBUS)
|
||||
adapter->index = 2;
|
||||
#endif
|
||||
#endif /* DHD_STATIC_IN_DRIVER */
|
||||
}
|
||||
#endif /* BCMDHD_MDRIVER */
|
||||
|
||||
int
|
||||
dhd_wlan_init_plat_data(wifi_adapter_info_t *adapter)
|
||||
{
|
||||
int err = 0;
|
||||
|
||||
printf("======== %s ========\n", __FUNCTION__);
|
||||
if (adapter->index == -1) {
|
||||
adapter->index = 0;
|
||||
}
|
||||
#ifdef BCMDHD_MDRIVER
|
||||
dhd_wlan_init_adapter(adapter);
|
||||
#endif /* BCMDHD_MDRIVER */
|
||||
|
||||
err = dhd_wlan_init_gpio(adapter);
|
||||
if (err)
|
||||
goto exit;
|
||||
|
||||
#ifdef DHD_STATIC_IN_DRIVER
|
||||
err = dhd_static_buf_init();
|
||||
#endif
|
||||
|
||||
exit:
|
||||
return err;
|
||||
}
|
||||
|
||||
void dhd_wlan_deinit_plat_data(wifi_adapter_info_t *adapter)
|
||||
void
|
||||
dhd_wlan_deinit_plat_data(wifi_adapter_info_t *adapter)
|
||||
{
|
||||
printf("======== %s ========\n", __FUNCTION__);
|
||||
#ifdef DHD_STATIC_IN_DRIVER
|
||||
dhd_static_buf_exit();
|
||||
#endif
|
||||
dhd_wlan_deinit_gpio(adapter);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* IP Packet Parser Module.
|
||||
*
|
||||
* Copyright (C) 2020, Broadcom.
|
||||
* Copyright (C) 2022, Broadcom.
|
||||
*
|
||||
* Unless you and Broadcom execute a separate written software license
|
||||
* agreement governing use of this software, this software is licensed to you
|
||||
|
|
@ -31,6 +31,7 @@
|
|||
#include <bcmip.h>
|
||||
#include <bcmendian.h>
|
||||
|
||||
#include <dhd.h>
|
||||
#include <dhd_dbg.h>
|
||||
|
||||
#include <dhd_ip.h>
|
||||
|
|
@ -976,6 +977,11 @@ dhd_tcpdata_info_get(dhd_pub_t *dhdp, void *pkt)
|
|||
cur_framelen -= ETHER_HDR_LEN;
|
||||
|
||||
ASSERT(cur_framelen >= IPV4_MIN_HEADER_LEN);
|
||||
if (cur_framelen < IPV4_MIN_HEADER_LEN) {
|
||||
DHD_TRACE(("%s %d: cur_framelen(%d) < IPV4_MIN_HEADER_LEN\n", __FUNCTION__,
|
||||
__LINE__, cur_framelen));
|
||||
goto exit;
|
||||
}
|
||||
|
||||
ip_hdr_len = IPV4_HLEN(ip_hdr);
|
||||
if (IP_VER(ip_hdr) != IP_VER_4 || IPV4_PROT(ip_hdr) != IP_PROT_TCP) {
|
||||
|
|
@ -988,6 +994,11 @@ dhd_tcpdata_info_get(dhd_pub_t *dhdp, void *pkt)
|
|||
cur_framelen -= ip_hdr_len;
|
||||
|
||||
ASSERT(cur_framelen >= TCP_MIN_HEADER_LEN);
|
||||
if (cur_framelen < TCP_MIN_HEADER_LEN) {
|
||||
DHD_TRACE(("%s %d: cur_framelen is less than TCP_MIN_HEADER_LEN\n",
|
||||
__FUNCTION__, __LINE__));
|
||||
goto exit;
|
||||
}
|
||||
|
||||
DHD_TRACE(("%s %d: TCP pkt!\n", __FUNCTION__, __LINE__));
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
*
|
||||
* Provides type definitions and function prototypes used to parse ip packet.
|
||||
*
|
||||
* Copyright (C) 2020, Broadcom.
|
||||
* Copyright (C) 2022, Broadcom.
|
||||
*
|
||||
* Unless you and Broadcom execute a separate written software license
|
||||
* agreement governing use of this software, this software is licensed to you
|
||||
|
|
@ -62,10 +62,10 @@ extern tcp_hdr_flag_t dhd_tcpdata_get_flag(dhd_pub_t *dhdp, void *pkt);
|
|||
|
||||
/* Max number of TCP streams that have own src/dst IP addrs and TCP ports */
|
||||
#ifndef TCPACK_INFO_MAXNUM
|
||||
#define TCPACK_INFO_MAXNUM 4
|
||||
#define TCPACK_INFO_MAXNUM 40
|
||||
#endif
|
||||
#ifndef TCPDATA_INFO_MAXNUM
|
||||
#define TCPDATA_INFO_MAXNUM 4
|
||||
#define TCPDATA_INFO_MAXNUM 40
|
||||
#endif
|
||||
#define TCPDATA_PSH_INFO_MAXNUM (8 * TCPDATA_INFO_MAXNUM)
|
||||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* DHD Linux header file (dhd_linux exports for cfg80211 and other components)
|
||||
*
|
||||
* Copyright (C) 2020, Broadcom.
|
||||
* Copyright (C) 2022, Broadcom.
|
||||
*
|
||||
* Unless you and Broadcom execute a separate written software license
|
||||
* agreement governing use of this software, this software is licensed to you
|
||||
|
|
@ -35,6 +35,9 @@
|
|||
#include <linux/init.h>
|
||||
#include <linux/fs.h>
|
||||
#include <dngl_stats.h>
|
||||
#ifdef DHD_LOG_DUMP
|
||||
#include <dhd_log_dump.h>
|
||||
#endif
|
||||
#include <dhd.h>
|
||||
#ifdef DHD_WMF
|
||||
#include <dhd_wmf_linux.h>
|
||||
|
|
@ -55,6 +58,14 @@
|
|||
#include <etd.h>
|
||||
#endif /* PCIE_FULL_DONGLE */
|
||||
|
||||
#ifdef CONFIG_IRQ_HISTORY
|
||||
#include <linux/power/irq_history.h>
|
||||
#endif /* CONFIG_IRQ_HISTORY */
|
||||
|
||||
#if defined(OEM_ANDROID)
|
||||
#include <linux/nl80211.h>
|
||||
#endif /* OEM_ANDROID */
|
||||
|
||||
#ifdef WL_MONITOR
|
||||
#ifdef HOST_RADIOTAP_CONV
|
||||
#include <bcmwifi_monitor.h>
|
||||
|
|
@ -67,9 +78,9 @@
|
|||
/* dongle status */
|
||||
enum wifi_adapter_status {
|
||||
WIFI_STATUS_POWER_ON = 0,
|
||||
WIFI_STATUS_ATTACH,
|
||||
WIFI_STATUS_FW_READY,
|
||||
WIFI_STATUS_DETTACH
|
||||
WIFI_STATUS_NET_ATTACHED,
|
||||
WIFI_STATUS_BUS_DISCONNECTED
|
||||
};
|
||||
#define wifi_chk_adapter_status(adapter, stat) (test_bit(stat, &(adapter)->status))
|
||||
#define wifi_get_adapter_status(adapter, stat) (test_bit(stat, &(adapter)->status))
|
||||
|
|
@ -77,9 +88,149 @@ enum wifi_adapter_status {
|
|||
#define wifi_clr_adapter_status(adapter, stat) (clear_bit(stat, &(adapter)->status))
|
||||
#define wifi_chg_adapter_status(adapter, stat) (change_bit(stat, &(adapter)->status))
|
||||
|
||||
#ifdef DHD_COREDUMP
|
||||
#define PC_FOUND_BIT 0x01
|
||||
#define LR_FOUND_BIT 0x02
|
||||
#define ALL_ADDR_VAL (PC_FOUND_BIT | LR_FOUND_BIT)
|
||||
#define READ_NUM_BYTES 1000
|
||||
#define DHD_FUNC_STR_LEN 80
|
||||
|
||||
#define DHD_COREDUMP_MAGIC 0xDDCEDACF
|
||||
#define TLV_TYPE_LENGTH_SIZE (8u)
|
||||
/* coredump is composed as following TLV format.
|
||||
* Type(32bit) | Length(32bit) | Value(x bit)
|
||||
* e.g) socram type | length | socram dump
|
||||
* sssr core1 type | length | sssr core1 dump
|
||||
* ...
|
||||
*/
|
||||
enum coredump_types {
|
||||
DHD_COREDUMP_TYPE_SSSRDUMP_CORE0_BEFORE = 0,
|
||||
DHD_COREDUMP_TYPE_SSSRDUMP_CORE0_AFTER,
|
||||
DHD_COREDUMP_TYPE_SSSRDUMP_CORE1_BEFORE,
|
||||
DHD_COREDUMP_TYPE_SSSRDUMP_CORE1_AFTER,
|
||||
DHD_COREDUMP_TYPE_SSSRDUMP_CORE2_BEFORE,
|
||||
DHD_COREDUMP_TYPE_SSSRDUMP_CORE2_AFTER,
|
||||
DHD_COREDUMP_TYPE_SSSRDUMP_DIG_BEFORE,
|
||||
DHD_COREDUMP_TYPE_SSSRDUMP_DIG_AFTER,
|
||||
DHD_COREDUMP_TYPE_SOCRAMDUMP
|
||||
};
|
||||
|
||||
#ifdef DHD_SSSR_DUMP
|
||||
typedef struct dhd_coredump {
|
||||
uint32 type;
|
||||
uint32 length;
|
||||
void *bufptr;
|
||||
} dhd_coredump_t;
|
||||
#endif /* DHD_SSSR_DUMP */
|
||||
#endif /* DHD_COREDUMP */
|
||||
|
||||
#ifdef BCMDBUS
|
||||
#define DBUS_NRXQ 50
|
||||
#define DBUS_NTXQ 100
|
||||
#endif /* BCMDBUS */
|
||||
|
||||
#ifdef DHD_WAKE_RX_STATUS
|
||||
#define ETHER_ICMP6_HEADER 20
|
||||
#define ETHER_IPV6_SADDR (ETHER_ICMP6_HEADER + 2)
|
||||
#define ETHER_IPV6_DAADR (ETHER_IPV6_SADDR + IPV6_ADDR_LEN)
|
||||
#define ETHER_ICMPV6_TYPE (ETHER_IPV6_DAADR + IPV6_ADDR_LEN)
|
||||
#endif /* DHD_WAKE_RX_STATUS */
|
||||
|
||||
#ifdef SUPPORT_AP_POWERSAVE
|
||||
#define RXCHAIN_PWRSAVE_PPS 10
|
||||
#define RXCHAIN_PWRSAVE_QUIET_TIME 10
|
||||
#define RXCHAIN_PWRSAVE_STAS_ASSOC_CHECK 0
|
||||
#endif /* SUPPORT_AP_POWERSAVE */
|
||||
|
||||
#define DHD_REGISTRATION_TIMEOUT 12000 /* msec : allowed time to finished dhd registration */
|
||||
#define DHD_FW_READY_TIMEOUT 5000 /* msec : allowed time to finished fw download */
|
||||
|
||||
/* FW initialised value for ocl_rssi_threshold */
|
||||
#define FW_OCL_RSSI_THRESH_INITVAL -75
|
||||
|
||||
#if defined(DHD_TRACE_WAKE_LOCK)
|
||||
typedef enum dhd_wklock_type {
|
||||
DHD_WAKE_LOCK,
|
||||
DHD_WAKE_UNLOCK,
|
||||
DHD_WAIVE_LOCK,
|
||||
DHD_RESTORE_LOCK
|
||||
} dhd_wklock_t;
|
||||
|
||||
struct wk_trace_record {
|
||||
unsigned long addr; /* Address of the instruction */
|
||||
dhd_wklock_t lock_type; /* lock_type */
|
||||
unsigned long long counter; /* counter information */
|
||||
struct hlist_node wklock_node; /* hash node */
|
||||
};
|
||||
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 7, 0))
|
||||
#define HASH_ADD(hashtable, node, key) \
|
||||
do { \
|
||||
hash_add(hashtable, node, key); \
|
||||
} while (0);
|
||||
#else
|
||||
#define HASH_ADD(hashtable, node, key) \
|
||||
do { \
|
||||
int index = hash_long(key, ilog2(ARRAY_SIZE(hashtable))); \
|
||||
hlist_add_head(node, &hashtable[index]); \
|
||||
} while (0);
|
||||
#endif /* KERNEL_VER < KERNEL_VERSION(3, 7, 0) */
|
||||
|
||||
#define STORE_WKLOCK_RECORD(wklock_type) \
|
||||
do { \
|
||||
struct wk_trace_record *wklock_info = NULL; \
|
||||
unsigned long func_addr = (unsigned long)__builtin_return_address(0); \
|
||||
wklock_info = find_wklock_entry(func_addr); \
|
||||
if (wklock_info) { \
|
||||
if (wklock_type == DHD_WAIVE_LOCK || wklock_type == DHD_RESTORE_LOCK) { \
|
||||
wklock_info->counter = dhd->wakelock_counter; \
|
||||
} else { \
|
||||
wklock_info->counter++; \
|
||||
} \
|
||||
} else { \
|
||||
wklock_info = kzalloc(sizeof(*wklock_info), GFP_ATOMIC); \
|
||||
if (!wklock_info) {\
|
||||
DHD_ERROR(("Can't allocate wk_trace_record \n")); \
|
||||
} else { \
|
||||
wklock_info->addr = func_addr; \
|
||||
wklock_info->lock_type = wklock_type; \
|
||||
if (wklock_type == DHD_WAIVE_LOCK || \
|
||||
wklock_type == DHD_RESTORE_LOCK) { \
|
||||
wklock_info->counter = dhd->wakelock_counter; \
|
||||
} else { \
|
||||
wklock_info->counter++; \
|
||||
} \
|
||||
HASH_ADD(wklock_history, &wklock_info->wklock_node, func_addr); \
|
||||
} \
|
||||
} \
|
||||
} while (0);
|
||||
|
||||
#else
|
||||
#define STORE_WKLOCK_RECORD(wklock_type)
|
||||
#endif /* DHD_TRACE_WAKE_LOCK */
|
||||
|
||||
#ifdef ENABLE_ADAPTIVE_SCHED
|
||||
#define DEFAULT_CPUFREQ_THRESH 1000000 /* threshold frequency : 1000000 = 1GHz */
|
||||
#ifndef CUSTOM_CPUFREQ_THRESH
|
||||
#define CUSTOM_CPUFREQ_THRESH DEFAULT_CPUFREQ_THRESH
|
||||
#endif /* CUSTOM_CPUFREQ_THRESH */
|
||||
#endif /* ENABLE_ADAPTIVE_SCHED */
|
||||
|
||||
/* enable HOSTIP cache update from the host side when an eth0:N is up */
|
||||
#define AOE_IP_ALIAS_SUPPORT 1
|
||||
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0) && defined(DHD_TCP_LIMIT_OUTPUT)
|
||||
#ifndef DHD_TCP_LIMIT_OUTPUT_BYTES
|
||||
#define DHD_TCP_LIMIT_OUTPUT_BYTES (4 * 1024 * 1024)
|
||||
#endif /* DHD_TCP_LIMIT_OUTPUT_BYTES */
|
||||
#ifndef TCP_DEFAULT_LIMIT_OUTPUT
|
||||
#define TCP_DEFAULT_LIMIT_OUTPUT (256 * 1024)
|
||||
#endif /* TSQ_DEFAULT_LIMIT_OUTPUT */
|
||||
#endif /* LINUX_VERSION_CODE > 4.19.0 && DHD_TCP_LIMIT_OUTPUT */
|
||||
|
||||
#define DHD_MEMDUMP_TYPE_STR_LEN 32
|
||||
#define DHD_MEMDUMP_PATH_STR_LEN 128
|
||||
|
||||
typedef struct wifi_adapter_info {
|
||||
const char *name;
|
||||
uint irq_num;
|
||||
|
|
@ -99,7 +250,7 @@ typedef struct wifi_adapter_info {
|
|||
#endif
|
||||
wait_queue_head_t status_event;
|
||||
unsigned long status;
|
||||
#if defined (BT_OVER_SDIO)
|
||||
#if defined(BT_OVER_SDIO)
|
||||
const char *btfw_path;
|
||||
#endif /* defined (BT_OVER_SDIO) */
|
||||
#if defined(BCMSDIO)
|
||||
|
|
@ -109,9 +260,12 @@ typedef struct wifi_adapter_info {
|
|||
struct pci_dev *pci_dev;
|
||||
struct pci_saved_state *pci_saved_state;
|
||||
#endif /* BCMPCIE */
|
||||
#ifdef BCMDHD_PLATDEV
|
||||
struct platform_device *pdev;
|
||||
#endif /* BCMDHD_PLATDEV */
|
||||
} wifi_adapter_info_t;
|
||||
|
||||
#if defined(CONFIG_WIFI_CONTROL_FUNC) || defined(CUSTOMER_HW4)
|
||||
#if defined(CONFIG_WIFI_CONTROL_FUNC)
|
||||
#include <linux/wlan_plat.h>
|
||||
#else
|
||||
#include <dhd_plat.h>
|
||||
|
|
@ -134,6 +288,7 @@ typedef struct dhd_sta {
|
|||
#ifdef DHD_WMF
|
||||
struct dhd_sta *psta_prim; /* primary index of psta interface */
|
||||
#endif /* DHD_WMF */
|
||||
chanspec_t chanspec; /* sta chanspec info */
|
||||
} dhd_sta_t;
|
||||
typedef dhd_sta_t dhd_sta_pool_t;
|
||||
|
||||
|
|
@ -204,12 +359,6 @@ typedef struct dhd_tx_lb_pkttag_fr {
|
|||
#define dtohchanspec(i) (i)
|
||||
#endif /* IL_BIGENDINA */
|
||||
|
||||
#if defined(DHD_TCP_WINSIZE_ADJUST)
|
||||
#define MIN_TCP_WIN_SIZE 18000
|
||||
#define WIN_SIZE_SCALE_FACTOR 2
|
||||
#define MAX_TARGET_PORTS 5
|
||||
#endif /* DHD_TCP_WINSIZE_ADJUST */
|
||||
|
||||
#ifdef BLOCK_IPV6_PACKET
|
||||
#define HEX_PREF_STR "0x"
|
||||
#define UNI_FILTER_STR "010000000000"
|
||||
|
|
@ -230,35 +379,6 @@ extern int dhd_get_suspend_bcn_li_dtim(dhd_pub_t *dhd, int *dtim_period, int *bc
|
|||
extern int dhd_get_suspend_bcn_li_dtim(dhd_pub_t *dhd);
|
||||
#endif /* OEM_ANDROID && BCMPCIE */
|
||||
|
||||
#ifdef CUSTOMER_HW4
|
||||
#ifdef MIMO_ANT_SETTING
|
||||
#ifdef DHD_EXPORT_CNTL_FILE
|
||||
extern unsigned long antsel;
|
||||
#endif /* DHD_EXPORT_CNTL_FILE */
|
||||
extern int dhd_sel_ant_from_file(dhd_pub_t *dhd);
|
||||
#endif /* MIMO_ANT_SETTING */
|
||||
#ifdef WRITE_WLANINFO
|
||||
#define MAX_VERSION_LEN 512
|
||||
#ifdef DHD_EXPORT_CNTL_FILE
|
||||
extern char version_info[MAX_VERSION_LEN];
|
||||
#endif /* DHD_EXPORT_CNTL_FILE */
|
||||
extern uint32 sec_save_wlinfo(char *firm_ver, char *dhd_ver, char *nvram_p, char *clm_ver);
|
||||
#endif /* WRITE_WLANINFO */
|
||||
#ifdef LOGTRACE_FROM_FILE
|
||||
extern int dhd_logtrace_from_file(dhd_pub_t *dhd);
|
||||
#ifdef DHD_EXPORT_CNTL_FILE
|
||||
extern unsigned long logtrace_val;
|
||||
#endif /* DHD_EXPORT_CNTL_FILE */
|
||||
#endif /* LOGTRACE_FROM_FILE */
|
||||
#ifdef GEN_SOFTAP_INFO_FILE
|
||||
#define SOFTAP_INFO_BUF_SZ 512
|
||||
#ifdef DHD_EXPORT_CNTL_FILE
|
||||
extern char softapinfostr[SOFTAP_INFO_BUF_SZ];
|
||||
#endif /* DHD_EXPORT_CNTL_FILE */
|
||||
extern uint32 sec_save_softap_info(void);
|
||||
#endif /* GEN_SOFTAP_INFO_FILE */
|
||||
#endif /* CUSTOMER_HW4 */
|
||||
|
||||
#ifdef DHD_SEND_HANG_PRIVCMD_ERRORS
|
||||
extern uint32 report_hang_privcmd_err;
|
||||
#endif /* DHD_SEND_HANG_PRIVCMD_ERRORS */
|
||||
|
|
@ -272,65 +392,6 @@ extern void dhd_bus_getidletime(dhd_pub_t *dhdp, int* idle_time);
|
|||
void traffic_mgmt_pkt_set_prio(dhd_pub_t *dhdp, void * pktbuf);
|
||||
#endif /* BCM_ROUTER_DHD */
|
||||
|
||||
#ifdef DHD_LOG_DUMP
|
||||
/* 0: DLD_BUF_TYPE_GENERAL, 1: DLD_BUF_TYPE_PRESERVE
|
||||
* 2: DLD_BUF_TYPE_SPECIAL
|
||||
*/
|
||||
#define DLD_BUFFER_NUM 3
|
||||
|
||||
#ifndef CUSTOM_LOG_DUMP_BUFSIZE_MB
|
||||
#define CUSTOM_LOG_DUMP_BUFSIZE_MB 4 /* DHD_LOG_DUMP_BUF_SIZE 4 MB static memory in kernel */
|
||||
#endif /* CUSTOM_LOG_DUMP_BUFSIZE_MB */
|
||||
|
||||
#define LOG_DUMP_TOTAL_BUFSIZE (1024 * 1024 * CUSTOM_LOG_DUMP_BUFSIZE_MB)
|
||||
|
||||
/*
|
||||
* Below are different sections that use the prealloced buffer
|
||||
* and sum of the sizes of these should not cross LOG_DUMP_TOTAL_BUFSIZE
|
||||
*/
|
||||
#ifdef EWP_BCM_TRACE
|
||||
#define LOG_DUMP_GENERAL_MAX_BUFSIZE (192 * 1024 * CUSTOM_LOG_DUMP_BUFSIZE_MB)
|
||||
#define LOG_DUMP_BCM_TRACE_MAX_BUFSIZE (64 * 1024 * CUSTOM_LOG_DUMP_BUFSIZE_MB)
|
||||
#else
|
||||
#define LOG_DUMP_GENERAL_MAX_BUFSIZE (256 * 1024 * CUSTOM_LOG_DUMP_BUFSIZE_MB)
|
||||
#define LOG_DUMP_BCM_TRACE_MAX_BUFSIZE 0
|
||||
#endif /* EWP_BCM_TRACE */
|
||||
#define LOG_DUMP_PRESERVE_MAX_BUFSIZE (128 * 1024 * CUSTOM_LOG_DUMP_BUFSIZE_MB)
|
||||
#define LOG_DUMP_ECNTRS_MAX_BUFSIZE (256 * 1024 * CUSTOM_LOG_DUMP_BUFSIZE_MB)
|
||||
#define LOG_DUMP_RTT_MAX_BUFSIZE (256 * 1024 * CUSTOM_LOG_DUMP_BUFSIZE_MB)
|
||||
#define LOG_DUMP_FILTER_MAX_BUFSIZE (128 * 1024 * CUSTOM_LOG_DUMP_BUFSIZE_MB)
|
||||
|
||||
#if LOG_DUMP_TOTAL_BUFSIZE < \
|
||||
(LOG_DUMP_GENERAL_MAX_BUFSIZE + LOG_DUMP_PRESERVE_MAX_BUFSIZE + \
|
||||
LOG_DUMP_ECNTRS_MAX_BUFSIZE + LOG_DUMP_RTT_MAX_BUFSIZE + \
|
||||
LOG_DUMP_BCM_TRACE_MAX_BUFSIZE + LOG_DUMP_FILTER_MAX_BUFSIZE)
|
||||
#error "LOG_DUMP_TOTAL_BUFSIZE is lesser than sum of all rings"
|
||||
#endif
|
||||
|
||||
/* Special buffer is allocated as separately in prealloc */
|
||||
#define LOG_DUMP_SPECIAL_MAX_BUFSIZE (8 * 1024)
|
||||
|
||||
#define LOG_DUMP_MAX_FILESIZE (8 *1024 * 1024) /* 8 MB default */
|
||||
|
||||
#ifdef CONFIG_LOG_BUF_SHIFT
|
||||
/* 15% of kernel log buf size, if for example klog buf size is 512KB
|
||||
* 15% of 512KB ~= 80KB
|
||||
*/
|
||||
#define LOG_DUMP_KERNEL_TAIL_FLUSH_SIZE \
|
||||
(15 * ((1 << CONFIG_LOG_BUF_SHIFT)/100))
|
||||
#endif /* CONFIG_LOG_BUF_SHIFT */
|
||||
|
||||
#define LOG_DUMP_COOKIE_BUFSIZE 1024u
|
||||
typedef struct {
|
||||
char *hdr_str;
|
||||
log_dump_section_type_t sec_type;
|
||||
} dld_hdr_t;
|
||||
|
||||
#define DHD_PRINT_BUF_NAME_LEN 30
|
||||
void dhd_get_debug_dump_len(void *handle, struct sk_buff *skb, void *event_info, u8 event);
|
||||
void cfgvendor_log_dump_len(dhd_pub_t *dhdp, log_dump_type_t *type, struct sk_buff *skb);
|
||||
#endif /* DHD_LOG_DUMP */
|
||||
|
||||
typedef struct dhd_if_event {
|
||||
struct list_head list;
|
||||
wl_event_data_if_t event;
|
||||
|
|
@ -454,20 +515,24 @@ struct dhd_rx_tx_work {
|
|||
#endif /* DHD_PCIE_NATIVE_RUNTIMEPM */
|
||||
|
||||
#ifdef FILTER_IE
|
||||
#ifdef DHD_LINUX_STD_FW_API
|
||||
#define FILTER_IE_PATH "filter_ie"
|
||||
#else
|
||||
#define FILTER_IE_PATH "/vendor/etc/wifi/filter_ie"
|
||||
#endif /* DHD_LINUX_STD_FW_API */
|
||||
#define FILTER_IE_BUFSZ 1024 /* ioc buffsize for FILTER_IE */
|
||||
#define FILE_BLOCK_READ_SIZE 256
|
||||
#define WL_FILTER_IE_IOV_HDR_SIZE OFFSETOF(wl_filter_ie_iov_v1_t, tlvs)
|
||||
#endif /* FILTER_IE */
|
||||
|
||||
#define NULL_CHECK(p, s, err) \
|
||||
do { \
|
||||
if (!(p)) { \
|
||||
printk("NULL POINTER (%s) : %s\n", __FUNCTION__, (s)); \
|
||||
err = BCME_ERROR; \
|
||||
return err; \
|
||||
} \
|
||||
} while (0)
|
||||
do { \
|
||||
if (!(p)) { \
|
||||
DHD_ERROR(("NULL POINTER (%s) : %s\n", __FUNCTION__, (s))); \
|
||||
err = BCME_ERROR; \
|
||||
return err; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
int dhd_wifi_platform_register_drv(void);
|
||||
void dhd_wifi_platform_unregister_drv(void);
|
||||
|
|
@ -505,22 +570,40 @@ void dhd_update_psta_interface_for_sta(dhd_pub_t *dhdp, char* ifname,
|
|||
void* mac_addr, void* event_data);
|
||||
#endif /* DHD_WMF */
|
||||
|
||||
#if defined (BT_OVER_SDIO)
|
||||
#if defined(BT_OVER_SDIO)
|
||||
int dhd_net_bus_get(struct net_device *dev);
|
||||
int dhd_net_bus_put(struct net_device *dev);
|
||||
#endif /* BT_OVER_SDIO */
|
||||
#if defined(WLADPS) || defined(WLADPS_PRIVATE_CMD)
|
||||
#if defined(WLADPS)
|
||||
#define ADPS_ENABLE 1
|
||||
#define ADPS_DISABLE 0
|
||||
#define ADPS_MODE_PM2_ONLY 3
|
||||
|
||||
int dhd_enable_adps(dhd_pub_t *dhd, uint8 on);
|
||||
#endif /* WLADPS || WLADPS_PRIVATE_CMD */
|
||||
#endif
|
||||
#ifdef DHDTCPSYNC_FLOOD_BLK
|
||||
extern void dhd_reset_tcpsync_info_by_ifp(dhd_if_t *ifp);
|
||||
extern void dhd_reset_tcpsync_info_by_dev(struct net_device *dev);
|
||||
#endif /* DHDTCPSYNC_FLOOD_BLK */
|
||||
extern void dhd_set_del_in_progress(dhd_pub_t *dhdp, struct net_device * ndev);
|
||||
extern void dhd_clear_del_in_progress(dhd_pub_t *dhdp, struct net_device * ndev);
|
||||
#ifdef PCIE_FULL_DONGLE
|
||||
extern void dhd_net_del_flowrings_sta(dhd_pub_t * dhd, struct net_device * ndev);
|
||||
#endif /* PCIE_FULL_DONGLE */
|
||||
int dhd_get_fw_capabilities(dhd_pub_t * dhd);
|
||||
#ifdef BCMDBUS
|
||||
int dhd_dbus_txdata(dhd_pub_t *dhdp, void *pktbuf);
|
||||
#endif
|
||||
void dhd_event_logtrace_enqueue(dhd_pub_t *dhdp, int ifidx, void *pktbuf);
|
||||
#if defined(SUPPORT_MULTIPLE_NVRAM) || defined(SUPPORT_MULTIPLE_CLMBLOB)
|
||||
int dhd_get_platform_naming_for_nvram_clmblob_file(download_type_t component, char* file_name);
|
||||
#ifdef USE_CID_CHECK
|
||||
void dhd_set_platform_ext_name_for_chip_version(char* chip_version);
|
||||
#endif /* USE_CID_CHECK */
|
||||
#endif /* SUPPORT_MULTIPLE_NVRAM || SUPPORT_MULTIPLE_CLMBLOB */
|
||||
void dhd_netif_rx_ni(struct sk_buff * skb);
|
||||
#if defined(DBG_PKT_MON) && !defined(PCIE_FULL_DONGLE)
|
||||
extern bool dhd_80211_mon_pkt(dhd_pub_t *dhdp, void *pkt, int ifidx);
|
||||
#endif /* DBG_PKT_MON */
|
||||
|
||||
#endif /* __DHD_LINUX_H__ */
|
||||
|
|
|
|||
1284
drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_linux_exportfs.c
Executable file → Normal file
1284
drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_linux_exportfs.c
Executable file → Normal file
File diff suppressed because it is too large
Load Diff
|
|
@ -2,7 +2,7 @@
|
|||
* Broadcom Dongle Host Driver (DHD), Linux-specific network interface
|
||||
* Basically selected code segments from usb-cdc.c and usb-rndis.c
|
||||
*
|
||||
* Copyright (C) 2020, Broadcom.
|
||||
* Copyright (C) 2022, Broadcom.
|
||||
*
|
||||
* Unless you and Broadcom execute a separate written software license
|
||||
* agreement governing use of this software, this software is licensed to you
|
||||
|
|
@ -35,12 +35,6 @@ extern dhd_pub_t* g_dhd_pub;
|
|||
#define DHD_NAPI_LATENCY_SIZE (sizeof(uint64) * DHD_NUM_NAPI_LATENCY_ROWS)
|
||||
#endif /* DHD_LB_STATS */
|
||||
|
||||
#ifdef DHD_REPLACE_LOG_INFO_TO_TRACE
|
||||
#define DHD_LB_INFO DHD_TRACE
|
||||
#else
|
||||
#define DHD_LB_INFO DHD_INFO
|
||||
#endif /* DHD_REPLACE_LOG_INFO_TO_TRACE */
|
||||
|
||||
void
|
||||
dhd_lb_set_default_cpus(dhd_info_t *dhd)
|
||||
{
|
||||
|
|
@ -173,8 +167,22 @@ void dhd_select_cpu_candidacy(dhd_info_t *dhd)
|
|||
* cpumask_next returns >= nr_cpu_ids
|
||||
*/
|
||||
tx_cpu = cpumask_next(napi_cpu, dhd->cpumask_primary_new);
|
||||
if (tx_cpu >= nr_cpu_ids)
|
||||
tx_cpu = 0;
|
||||
if (tx_cpu >= nr_cpu_ids) {
|
||||
/* If no CPU is available for tx processing in primary CPUs,
|
||||
* choose the same CPU with net_tx_cpu
|
||||
* in case net_tx_cpu is in primary CPUs.
|
||||
*/
|
||||
cpumask_and(dhd->cpumask_primary_new, dhd->cpumask_primary,
|
||||
dhd->cpumask_curr_avail);
|
||||
|
||||
if (cpumask_test_cpu(net_tx_cpu, dhd->cpumask_primary_new)) {
|
||||
tx_cpu = net_tx_cpu;
|
||||
DHD_INFO(("%s If no CPU is for tx cpu, use net_tx_cpu %d\n",
|
||||
__FUNCTION__, net_tx_cpu));
|
||||
} else {
|
||||
tx_cpu = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DHD_INFO(("%s After primary CPU check napi_cpu %d tx_cpu %d\n",
|
||||
|
|
@ -200,24 +208,31 @@ void dhd_select_cpu_candidacy(dhd_info_t *dhd)
|
|||
} else if (tx_cpu == 0) {
|
||||
tx_cpu = cpumask_first(dhd->cpumask_secondary_new);
|
||||
}
|
||||
|
||||
/* If no CPU was available for tx processing, choose CPU 0 */
|
||||
if (tx_cpu >= nr_cpu_ids)
|
||||
tx_cpu = 0;
|
||||
}
|
||||
|
||||
if ((primary_available_cpus == 0) &&
|
||||
(secondary_available_cpus == 0)) {
|
||||
/* No CPUs available from primary or secondary mask */
|
||||
napi_cpu = 1;
|
||||
tx_cpu = 2;
|
||||
tx_cpu = napi_cpu = nr_cpu_ids - 1;
|
||||
}
|
||||
|
||||
DHD_INFO(("%s After secondary CPU check napi_cpu %d tx_cpu %d\n",
|
||||
__FUNCTION__, napi_cpu, tx_cpu));
|
||||
/* If no CPU was available for napi processing, choose CPU 0 */
|
||||
if (napi_cpu >= nr_cpu_ids)
|
||||
napi_cpu = 0;
|
||||
|
||||
ASSERT(napi_cpu < nr_cpu_ids);
|
||||
ASSERT(tx_cpu < nr_cpu_ids);
|
||||
/* If no CPU was available for tx processing, choose CPU 0 */
|
||||
if (tx_cpu >= nr_cpu_ids)
|
||||
tx_cpu = 0;
|
||||
|
||||
DHD_INFO(("%s After secondary CPU check napi_cpu %d tx_cpu %d nr cpu ids %d\n",
|
||||
__FUNCTION__, napi_cpu, tx_cpu, nr_cpu_ids));
|
||||
|
||||
if (!cpu_online(napi_cpu)) {
|
||||
napi_cpu = 0;
|
||||
}
|
||||
if (!cpu_online(tx_cpu)) {
|
||||
tx_cpu = 0;
|
||||
}
|
||||
|
||||
atomic_set(&dhd->rx_napi_cpu, napi_cpu);
|
||||
atomic_set(&dhd->tx_cpu, tx_cpu);
|
||||
|
|
@ -237,6 +252,12 @@ int dhd_cpu_startup_callback(unsigned int cpu)
|
|||
{
|
||||
dhd_info_t *dhd = g_dhd_pub->info;
|
||||
|
||||
if (!dhd || !(dhd->dhd_state & DHD_ATTACH_STATE_LB_ATTACH_DONE)) {
|
||||
DHD_ERROR(("%s(): LB data is not initialized yet.\n",
|
||||
__FUNCTION__));
|
||||
return 0;
|
||||
}
|
||||
|
||||
DHD_INFO(("%s(): \r\n cpu:%d", __FUNCTION__, cpu));
|
||||
DHD_LB_STATS_INCR(dhd->cpu_online_cnt[cpu]);
|
||||
cpumask_set_cpu(cpu, dhd->cpumask_curr_avail);
|
||||
|
|
@ -249,6 +270,12 @@ int dhd_cpu_teardown_callback(unsigned int cpu)
|
|||
{
|
||||
dhd_info_t *dhd = g_dhd_pub->info;
|
||||
|
||||
if (!dhd || !(dhd->dhd_state & DHD_ATTACH_STATE_LB_ATTACH_DONE)) {
|
||||
DHD_ERROR(("%s(): LB data is not initialized yet.\n",
|
||||
__FUNCTION__));
|
||||
return 0;
|
||||
}
|
||||
|
||||
DHD_INFO(("%s(): \r\n cpu:%d", __FUNCTION__, cpu));
|
||||
DHD_LB_STATS_INCR(dhd->cpu_offline_cnt[cpu]);
|
||||
cpumask_clear_cpu(cpu, dhd->cpumask_curr_avail);
|
||||
|
|
@ -299,14 +326,13 @@ dhd_cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu)
|
|||
|
||||
int dhd_register_cpuhp_callback(dhd_info_t *dhd)
|
||||
{
|
||||
int cpuhp_ret = 0;
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0))
|
||||
cpuhp_ret = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "dhd",
|
||||
dhd->dhd_cpuhp_state = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "dhd",
|
||||
dhd_cpu_startup_callback, dhd_cpu_teardown_callback);
|
||||
|
||||
if (cpuhp_ret < 0) {
|
||||
if (dhd->dhd_cpuhp_state < 0) {
|
||||
DHD_ERROR(("%s(): cpuhp_setup_state failed %d RX LB won't happen \r\n",
|
||||
__FUNCTION__, cpuhp_ret));
|
||||
__FUNCTION__, dhd->dhd_cpuhp_state));
|
||||
}
|
||||
#else
|
||||
/*
|
||||
|
|
@ -317,7 +343,7 @@ int dhd_register_cpuhp_callback(dhd_info_t *dhd)
|
|||
dhd->cpu_notifier.notifier_call = dhd_cpu_callback;
|
||||
register_hotcpu_notifier(&dhd->cpu_notifier); /* Register a callback */
|
||||
#endif /* LINUX_VERSION_CODE < 4.10.0 */
|
||||
return cpuhp_ret;
|
||||
return dhd->dhd_cpuhp_state;
|
||||
}
|
||||
|
||||
int dhd_unregister_cpuhp_callback(dhd_info_t *dhd)
|
||||
|
|
@ -325,12 +351,14 @@ int dhd_unregister_cpuhp_callback(dhd_info_t *dhd)
|
|||
int ret = 0;
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0))
|
||||
/* Don't want to call tear down while unregistering */
|
||||
cpuhp_remove_state_nocalls(CPUHP_AP_ONLINE_DYN);
|
||||
if (dhd->dhd_cpuhp_state >= 0) {
|
||||
cpuhp_remove_state_nocalls(dhd->dhd_cpuhp_state);
|
||||
}
|
||||
#else
|
||||
if (dhd->cpu_notifier.notifier_call != NULL) {
|
||||
unregister_cpu_notifier(&dhd->cpu_notifier);
|
||||
}
|
||||
#endif
|
||||
#endif /* LINUX_VERSION_CODE < 4.10.0 */
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -647,7 +675,7 @@ void dhd_lb_stats_dump_cpu_array(struct bcmstrbuf *strbuf, uint32 *p)
|
|||
uint64 dhd_lb_mem_usage(dhd_pub_t *dhdp, struct bcmstrbuf *strbuf)
|
||||
{
|
||||
dhd_info_t *dhd;
|
||||
uint16 rxbufpost_sz;
|
||||
uint16 rxbufpost_alloc_sz;
|
||||
uint16 rx_post_active = 0;
|
||||
uint16 rx_cmpl_active = 0;
|
||||
uint64 rx_path_memory_usage = 0;
|
||||
|
|
@ -663,28 +691,30 @@ uint64 dhd_lb_mem_usage(dhd_pub_t *dhdp, struct bcmstrbuf *strbuf)
|
|||
DHD_ERROR(("%s(): DHD pointer is NULL \n", __FUNCTION__));
|
||||
return 0;
|
||||
}
|
||||
rxbufpost_sz = dhd_prot_get_rxbufpost_sz(dhdp);
|
||||
if (rxbufpost_sz == 0) {
|
||||
rxbufpost_sz = DHD_FLOWRING_RX_BUFPOST_PKTSZ;
|
||||
rxbufpost_alloc_sz = dhd_prot_get_rxbufpost_alloc_sz(dhdp);
|
||||
if (rxbufpost_alloc_sz == 0) {
|
||||
rxbufpost_alloc_sz = DHD_FLOWRING_RX_BUFPOST_PKTSZ;
|
||||
}
|
||||
rx_path_memory_usage = rxbufpost_sz * (skb_queue_len(&dhd->rx_pend_queue) +
|
||||
rx_path_memory_usage = rxbufpost_alloc_sz * (skb_queue_len(&dhd->rx_emerge_queue) +
|
||||
skb_queue_len(&dhd->rx_pend_queue) +
|
||||
skb_queue_len(&dhd->rx_napi_queue) +
|
||||
skb_queue_len(&dhd->rx_process_queue));
|
||||
rx_post_active = dhd_prot_get_h2d_rx_post_active(dhdp);
|
||||
if (rx_post_active != 0) {
|
||||
rx_path_memory_usage += (rxbufpost_sz * rx_post_active);
|
||||
rx_path_memory_usage += (rxbufpost_alloc_sz * rx_post_active);
|
||||
}
|
||||
|
||||
rx_cmpl_active = dhd_prot_get_d2h_rx_cpln_active(dhdp);
|
||||
if (rx_cmpl_active != 0) {
|
||||
rx_path_memory_usage += (rxbufpost_sz * rx_cmpl_active);
|
||||
rx_path_memory_usage += (rxbufpost_alloc_sz * rx_cmpl_active);
|
||||
}
|
||||
|
||||
dhdp->rxpath_mem = rx_path_memory_usage;
|
||||
bcm_bprintf(strbuf, "\nrxbufpost_sz: %d rx_post_active: %d rx_cmpl_active: %d "
|
||||
"pend_queue_len: %d napi_queue_len: %d process_queue_len: %d\n",
|
||||
rxbufpost_sz, rx_post_active, rx_cmpl_active,
|
||||
skb_queue_len(&dhd->rx_pend_queue),
|
||||
bcm_bprintf(strbuf, "\nrxbufpost_alloc_sz: %d rx_post_active: %d rx_cmpl_active: %d "
|
||||
"emerge_queue_len: %d pend_queue_len: %d napi_queue_len: %d"
|
||||
" process_queue_len: %d\n",
|
||||
rxbufpost_alloc_sz, rx_post_active, rx_cmpl_active,
|
||||
skb_queue_len(&dhd->rx_emerge_queue), skb_queue_len(&dhd->rx_pend_queue),
|
||||
skb_queue_len(&dhd->rx_napi_queue), skb_queue_len(&dhd->rx_process_queue));
|
||||
bcm_bprintf(strbuf, "DHD rx-path memory_usage: %llubytes %lluKB \n",
|
||||
rx_path_memory_usage, (rx_path_memory_usage/ 1024));
|
||||
|
|
@ -708,6 +738,7 @@ void dhd_lb_stats_dump(dhd_pub_t *dhdp, struct bcmstrbuf *strbuf)
|
|||
return;
|
||||
}
|
||||
|
||||
bcm_bprintf(strbuf, "\nLoad Balancing/NAPI stats:\n==========================\n");
|
||||
bcm_bprintf(strbuf, "\ncpu_online_cnt:\n");
|
||||
dhd_lb_stats_dump_cpu_array(strbuf, dhd->cpu_online_cnt);
|
||||
|
||||
|
|
@ -731,6 +762,13 @@ void dhd_lb_stats_dump(dhd_pub_t *dhdp, struct bcmstrbuf *strbuf)
|
|||
dhd_lb_stats_dump_histo(dhdp, strbuf, dhd->napi_rx_hist);
|
||||
bcm_bprintf(strbuf, "\nNAPI poll latency stats ie from napi schedule to napi execution\n");
|
||||
dhd_lb_stats_dump_napi_latency(dhdp, strbuf, dhd->napi_latency);
|
||||
|
||||
bcm_bprintf(strbuf, "\nlb_rxp_stop_thr_hitcnt: %llu lb_rxp_strt_thr_hitcnt: %llu"
|
||||
" rx_dma_stall_hc_ignore_cnt: %llu\n",
|
||||
dhdp->lb_rxp_stop_thr_hitcnt, dhdp->lb_rxp_strt_thr_hitcnt,
|
||||
dhdp->rx_dma_stall_hc_ignore_cnt);
|
||||
bcm_bprintf(strbuf, "\nlb_rxp_napi_sched_cnt: %llu lb_rxp_napi_omplete_cnt: %llu\n",
|
||||
dhdp->lb_rxp_napi_sched_cnt, dhdp->lb_rxp_napi_complete_cnt);
|
||||
#endif /* DHD_LB_RXP */
|
||||
|
||||
#ifdef DHD_LB_TXP
|
||||
|
|
@ -740,6 +778,7 @@ void dhd_lb_stats_dump(dhd_pub_t *dhdp, struct bcmstrbuf *strbuf)
|
|||
bcm_bprintf(strbuf, "\ntx_start_percpu_run_cnt:\n");
|
||||
dhd_lb_stats_dump_cpu_array(strbuf, dhd->tx_start_percpu_run_cnt);
|
||||
#endif /* DHD_LB_TXP */
|
||||
bcm_bprintf(strbuf, "\n");
|
||||
}
|
||||
|
||||
void dhd_lb_stats_update_napi_latency(uint64 *bin, uint32 latency)
|
||||
|
|
@ -986,7 +1025,7 @@ dhd_napi_poll(struct napi_struct *napi, int budget)
|
|||
napi_latency = (uint32)(OSL_SYSUPTIME_US() - dhd->napi_schedule_time);
|
||||
dhd_lb_stats_update_napi_latency(dhd->napi_latency, napi_latency);
|
||||
#endif /* DHD_LB_STATS */
|
||||
DHD_LB_INFO(("%s napi_queue<%d> budget<%d>\n",
|
||||
DHD_INFO(("%s napi_queue<%d> budget<%d>\n",
|
||||
__FUNCTION__, skb_queue_len(&dhd->rx_napi_queue), budget));
|
||||
|
||||
/*
|
||||
|
|
@ -1008,7 +1047,7 @@ dhd_napi_poll(struct napi_struct *napi, int budget)
|
|||
|
||||
ifid = DHD_PKTTAG_IFID((dhd_pkttag_fr_t *)PKTTAG(skb));
|
||||
|
||||
DHD_LB_INFO(("%s dhd_rx_frame pkt<%p> ifid<%d>\n",
|
||||
DHD_INFO(("%s dhd_rx_frame pkt<%p> ifid<%d>\n",
|
||||
__FUNCTION__, skb, ifid));
|
||||
|
||||
dhd_rx_frame(&dhd->pub, ifid, skb, pkt_count, chan);
|
||||
|
|
@ -1032,7 +1071,7 @@ dhd_napi_poll(struct napi_struct *napi, int budget)
|
|||
}
|
||||
DHD_LB_STATS_UPDATE_NAPI_HISTO(&dhd->pub, processed);
|
||||
|
||||
DHD_LB_INFO(("%s processed %d\n", __FUNCTION__, processed));
|
||||
DHD_INFO(("%s processed %d\n", __FUNCTION__, processed));
|
||||
|
||||
/*
|
||||
* Signal napi complete only when no more packets are processed and
|
||||
|
|
@ -1076,6 +1115,21 @@ dhd_napi_schedule(void *info)
|
|||
DHD_INFO(("%s rx_napi_struct<%p> on cpu<%d>\n",
|
||||
__FUNCTION__, &dhd->rx_napi_struct, atomic_read(&dhd->rx_napi_cpu)));
|
||||
|
||||
/* On Android platform, napi prevention during suspend in progress causes
|
||||
* rx performance drop of ~5Mbs(SWWLAN-349763).
|
||||
* So, excludes this prevention for Android platform.
|
||||
*/
|
||||
#ifndef OEM_ANDROID
|
||||
DHD_GENERAL_LOCK(&dhd->pub, flags);
|
||||
|
||||
if (DHD_BUS_BUSY_CHECK_SUSPEND_IN_PROGRESS(&dhd->pub)) {
|
||||
DHD_GENERAL_UNLOCK(&dhd->pub, flags);
|
||||
return;
|
||||
}
|
||||
|
||||
DHD_GENERAL_UNLOCK(&dhd->pub, flags);
|
||||
#endif /* OEM_ANDROID */
|
||||
|
||||
/* add napi_struct to softnet data poll list and raise NET_RX_SOFTIRQ */
|
||||
if (napi_schedule_prep(&dhd->rx_napi_struct)) {
|
||||
|
||||
|
|
@ -1104,31 +1158,6 @@ dhd_napi_schedule(void *info)
|
|||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* dhd_napi_schedule_on - API to schedule on a desired CPU core a NET_RX_SOFTIRQ
|
||||
* action after placing the dhd's rx_process napi object in the the remote CPU's
|
||||
* softnet data's poll_list.
|
||||
*
|
||||
* @dhd: dhd_info which has the rx_process napi object
|
||||
* @on_cpu: desired remote CPU id
|
||||
*/
|
||||
static INLINE int
|
||||
dhd_napi_schedule_on(dhd_info_t *dhd, int on_cpu)
|
||||
{
|
||||
int wait = 0; /* asynchronous IPI */
|
||||
DHD_INFO(("%s dhd<%p> napi<%p> on_cpu<%d>\n",
|
||||
__FUNCTION__, dhd, &dhd->rx_napi_struct, on_cpu));
|
||||
|
||||
if (smp_call_function_single(on_cpu, dhd_napi_schedule, dhd, wait)) {
|
||||
DHD_ERROR(("%s smp_call_function_single on_cpu<%d> failed\n",
|
||||
__FUNCTION__, on_cpu));
|
||||
}
|
||||
|
||||
DHD_LB_STATS_INCR(dhd->napi_sched_cnt);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Call get_online_cpus/put_online_cpus around dhd_napi_schedule_on
|
||||
* Why should we do this?
|
||||
|
|
@ -1186,7 +1215,7 @@ dhd_lb_rx_napi_dispatch(dhd_pub_t *dhdp)
|
|||
return;
|
||||
}
|
||||
|
||||
DHD_LB_INFO(("%s append napi_queue<%d> pend_queue<%d>\n", __FUNCTION__,
|
||||
DHD_INFO(("%s append napi_queue<%d> pend_queue<%d>\n", __FUNCTION__,
|
||||
skb_queue_len(&dhd->rx_napi_queue), skb_queue_len(&dhd->rx_pend_queue)));
|
||||
|
||||
/* append the producer's queue of packets to the napi's rx process queue */
|
||||
|
|
@ -1236,7 +1265,7 @@ dhd_lb_rx_napi_dispatch(dhd_pub_t *dhdp)
|
|||
|
||||
}
|
||||
|
||||
DHD_LB_INFO(("%s : schedule to curr_cpu : %d, rx_napi_cpu : %d\n",
|
||||
DHD_INFO(("%s : schedule to curr_cpu : %d, rx_napi_cpu : %d\n",
|
||||
__FUNCTION__, curr_cpu, rx_napi_cpu));
|
||||
dhd_work_schedule_on(&dhd->rx_napi_dispatcher_work, rx_napi_cpu);
|
||||
DHD_LB_STATS_INCR(dhd->napi_sched_cnt);
|
||||
|
|
@ -1244,6 +1273,26 @@ dhd_lb_rx_napi_dispatch(dhd_pub_t *dhdp)
|
|||
put_cpu();
|
||||
}
|
||||
|
||||
/**
|
||||
* dhd_rx_emerge_enqueue - Enqueue the packet into the ememrgency queue for repost
|
||||
*/
|
||||
void
|
||||
dhd_rx_emerge_enqueue(dhd_pub_t *dhdp, void *pkt)
|
||||
{
|
||||
dhd_info_t *dhd = dhdp->info;
|
||||
skb_queue_tail(&dhd->rx_emerge_queue, pkt);
|
||||
}
|
||||
|
||||
/**
|
||||
* dhd_rx_emerge_dequeue - Deueue the packet from the emergency queue for repost
|
||||
*/
|
||||
void *
|
||||
dhd_rx_emerge_dequeue(dhd_pub_t *dhdp)
|
||||
{
|
||||
dhd_info_t *dhd = dhdp->info;
|
||||
return skb_dequeue(&dhd->rx_emerge_queue);
|
||||
}
|
||||
|
||||
/**
|
||||
* dhd_lb_rx_pkt_enqueue - Enqueue the packet into the producer's queue
|
||||
*/
|
||||
|
|
@ -1252,7 +1301,7 @@ dhd_lb_rx_pkt_enqueue(dhd_pub_t *dhdp, void *pkt, int ifidx)
|
|||
{
|
||||
dhd_info_t *dhd = dhdp->info;
|
||||
|
||||
DHD_LB_INFO(("%s enqueue pkt<%p> ifidx<%d> pend_queue<%d>\n", __FUNCTION__,
|
||||
DHD_INFO(("%s enqueue pkt<%p> ifidx<%d> pend_queue<%d>\n", __FUNCTION__,
|
||||
pkt, ifidx, skb_queue_len(&dhd->rx_pend_queue)));
|
||||
DHD_PKTTAG_SET_IFID((dhd_pkttag_fr_t *)PKTTAG(pkt), ifidx);
|
||||
__skb_queue_tail(&dhd->rx_pend_queue, pkt);
|
||||
|
|
@ -1304,7 +1353,9 @@ BCMFASTPATH(dhd_lb_sendpkt)(dhd_info_t *dhd, struct net_device *net,
|
|||
#endif /* DHD_LB_TXP */
|
||||
|
||||
#ifdef DHD_LB_TXP
|
||||
#ifndef DHD_LB_TXBOUND
|
||||
#define DHD_LB_TXBOUND 64
|
||||
#endif
|
||||
/*
|
||||
* Function that performs the TX processing on a given CPU
|
||||
*/
|
||||
|
|
@ -1351,7 +1402,7 @@ dhd_lb_tx_process(dhd_info_t *dhd)
|
|||
|
||||
} while (1);
|
||||
|
||||
DHD_LB_INFO(("%s(): Processed %d packets \r\n", __FUNCTION__, cnt));
|
||||
DHD_INFO(("%s(): Processed %d packets \r\n", __FUNCTION__, cnt));
|
||||
|
||||
return resched;
|
||||
}
|
||||
|
|
@ -1369,7 +1420,7 @@ dhd_lb_tx_handler(unsigned long data)
|
|||
#endif /* DHD_LB_TXP */
|
||||
#endif /* DHD_LB */
|
||||
|
||||
#if defined(DHD_CONTROL_PCIE_CPUCORE_WIFI_TURNON)
|
||||
#if defined(SET_PCIE_IRQ_CPU_CORE) || defined(DHD_CONTROL_PCIE_CPUCORE_WIFI_TURNON)
|
||||
void
|
||||
dhd_irq_set_affinity(dhd_pub_t *dhdp, const struct cpumask *cpumask)
|
||||
{
|
||||
|
|
@ -1399,4 +1450,77 @@ dhd_irq_set_affinity(dhd_pub_t *dhdp, const struct cpumask *cpumask)
|
|||
DHD_ERROR(("%s : irq set affinity is failed cpu:0x%lx\n",
|
||||
__FUNCTION__, *cpumask_bits(cpumask)));
|
||||
}
|
||||
#endif /* DHD_CONTROL_PCIE_CPUCORE_WIFI_TURNON */
|
||||
#endif /* SET_PCIE_IRQ_CPU_CORE || DHD_CONTROL_PCIE_CPUCORE_WIFI_TURNON */
|
||||
|
||||
#ifdef SET_PCIE_IRQ_CPU_CORE
|
||||
void
|
||||
dhd_set_irq_cpucore(dhd_pub_t *dhdp, int affinity_cmd)
|
||||
{
|
||||
#if defined(DHD_LB) && defined(DHD_LB_HOST_CTRL)
|
||||
struct dhd_info *dhd = NULL;
|
||||
#endif /* DHD_LB && DHD_LB_HOST_CTRL */
|
||||
|
||||
if (!dhdp) {
|
||||
DHD_ERROR(("%s : dhd is NULL\n", __FUNCTION__));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!dhdp->bus) {
|
||||
DHD_ERROR(("%s : dhd->bus is NULL\n", __FUNCTION__));
|
||||
return;
|
||||
}
|
||||
|
||||
if (affinity_cmd < DHD_AFFINITY_OFF || affinity_cmd > DHD_AFFINITY_LAST) {
|
||||
DHD_ERROR(("Wrong Affinity cmds:%d, %s\n", affinity_cmd, __FUNCTION__));
|
||||
return;
|
||||
}
|
||||
|
||||
DHD_ERROR(("Enter %s, PCIe affinity cmd=0x%x\n", __FUNCTION__, affinity_cmd));
|
||||
|
||||
#if defined(DHD_LB) && defined(DHD_LB_HOST_CTRL)
|
||||
dhd = dhdp->info;
|
||||
|
||||
if (affinity_cmd == DHD_AFFINITY_OFF) {
|
||||
dhd->permitted_primary_cpu = FALSE;
|
||||
} else if (affinity_cmd == DHD_AFFINITY_TPUT_150MBPS ||
|
||||
affinity_cmd == DHD_AFFINITY_TPUT_300MBPS) {
|
||||
dhd->permitted_primary_cpu = TRUE;
|
||||
}
|
||||
dhd_select_cpu_candidacy(dhd);
|
||||
/*
|
||||
* It needs to NAPI disable -> enable to raise NET_RX napi CPU core
|
||||
* during Rx traffic
|
||||
* NET_RX does not move to NAPI CPU core if continusly calling napi polling
|
||||
* function
|
||||
*/
|
||||
napi_disable(&dhd->rx_napi_struct);
|
||||
napi_enable(&dhd->rx_napi_struct);
|
||||
#endif /* DHD_LB && DHD_LB_HOST_CTRL */
|
||||
|
||||
/*
|
||||
irq_set_affinity() assign dedicated CPU core PCIe interrupt
|
||||
If dedicated CPU core is not on-line,
|
||||
PCIe interrupt scheduled on CPU core 0
|
||||
*/
|
||||
switch (affinity_cmd) {
|
||||
case DHD_AFFINITY_OFF:
|
||||
#if defined(DHD_LB) && defined(DHD_LB_HOST_CTRL)
|
||||
dhd_irq_set_affinity(dhdp, dhdp->info->cpumask_secondary);
|
||||
#endif /* DHD_LB && DHD_LB_HOST_CTRL */
|
||||
break;
|
||||
case DHD_AFFINITY_TPUT_150MBPS:
|
||||
dhd_irq_set_affinity(dhdp, dhdp->info->cpumask_primary);
|
||||
break;
|
||||
case DHD_AFFINITY_TPUT_300MBPS:
|
||||
#ifdef CONFIG_ARCH_EXYNOS
|
||||
dhd_irq_set_affinity(dhdp, cpumask_of(PCIE_IRQ_CPU_CORE));
|
||||
#else
|
||||
dhd_irq_set_affinity(dhdp, dhdp->info->cpumask_primary);
|
||||
#endif /* CONFIG_ARCH_EXYNOS */
|
||||
break;
|
||||
default:
|
||||
DHD_ERROR(("%s, Unknown PCIe affinity cmd=0x%x\n",
|
||||
__FUNCTION__, affinity_cmd));
|
||||
}
|
||||
}
|
||||
#endif /* SET_PCIE_IRQ_CPU_CORE */
|
||||
|
|
|
|||
311
drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_linux_pktdump.c
Executable file → Normal file
311
drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_linux_pktdump.c
Executable file → Normal file
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* Packet dump helper functions
|
||||
*
|
||||
* Copyright (C) 2020, Broadcom.
|
||||
* Copyright (C) 2022, Broadcom.
|
||||
*
|
||||
* Unless you and Broadcom execute a separate written software license
|
||||
* agreement governing use of this software, this software is licensed to you
|
||||
|
|
@ -37,7 +37,13 @@
|
|||
#include <bcmdhcp.h>
|
||||
#include <bcmarp.h>
|
||||
#include <bcmicmp.h>
|
||||
#include <bcmigmp.h>
|
||||
#include <dhd_linux_pktdump.h>
|
||||
#ifdef WL_CFGVENDOR_CUST_ADVLOG
|
||||
#include <wl_cfg80211.h>
|
||||
#include <wl_cfgvendor.h>
|
||||
#include <dhd_flowring.h>
|
||||
#endif /* WL_CFGVENDOR_CUST_ADVLOG */
|
||||
#include <dhd_config.h>
|
||||
#include <wl_android.h>
|
||||
|
||||
|
|
@ -168,16 +174,27 @@ static const char pkt_cnt_msg[][20] = {
|
|||
};
|
||||
#endif
|
||||
|
||||
static const char tx_pktfate[][30] = {
|
||||
"TX_PKT_FATE_ACKED", /* 0: WLFC_CTL_PKTFLAG_DISCARD */
|
||||
"TX_PKT_FATE_FW_QUEUED", /* 1: WLFC_CTL_PKTFLAG_D11SUPPRESS */
|
||||
"TX_PKT_FATE_FW_QUEUED", /* 2: WLFC_CTL_PKTFLAG_WLSUPPRESS */
|
||||
"TX_PKT_FATE_FW_DROP_INVALID", /* 3: WLFC_CTL_PKTFLAG_TOSSED_BYWLC */
|
||||
"TX_PKT_FATE_SENT", /* 4: WLFC_CTL_PKTFLAG_DISCARD_NOACK */
|
||||
"TX_PKT_FATE_FW_DROP_OTHER", /* 5: WLFC_CTL_PKTFLAG_SUPPRESS_ACKED */
|
||||
"TX_PKT_FATE_FW_DROP_EXPTIME", /* 6: WLFC_CTL_PKTFLAG_EXPIRED */
|
||||
"TX_PKT_FATE_FW_DROP_OTHER", /* 7: WLFC_CTL_PKTFLAG_DROPPED */
|
||||
"TX_PKT_FATE_FW_PKT_FREE", /* 8: WLFC_CTL_PKTFLAG_MKTFREE */
|
||||
#if defined(DHD_DNS_DUMP) || defined(DHD_ARP_DUMP) || defined(DHD_ICMP_DUMP) || \
|
||||
defined(DHD_DHCP_DUMP) || defined(DHD_8021X_DUMP) || defined(DHD_PKTDUMP_ROAM)
|
||||
#define DHD_PKTFATE_STR_MAX 30
|
||||
#define DHD_PKTFATE_EX_STR_MAX 10
|
||||
typedef struct dhd_tx_pktfate_entry {
|
||||
const char reason[DHD_PKTFATE_STR_MAX];
|
||||
const char ex[DHD_PKTFATE_EX_STR_MAX];
|
||||
} dhd_tx_pktfate_entry_t;
|
||||
|
||||
static dhd_tx_pktfate_entry_t tx_pktfate[] = {
|
||||
{"TX_PKT_FATE_ACKED", "ACK"}, /* 0: WLFC_CTL_PKTFLAG_DISCARD */
|
||||
{"TX_PKT_FATE_FW_D11SUPPRESS", "TX_FAIL"}, /* 1: WLFC_CTL_PKTFLAG_D11SUPPRESS */
|
||||
{"TX_PKT_FATE_FW_WLSUPPRESS", "TX_FAIL"}, /* 2: WLFC_CTL_PKTFLAG_WLSUPPRESS */
|
||||
{"TX_PKT_FATE_FW_TOSSED_BYWLC", "TX_FAIL"}, /* 3: WLFC_CTL_PKTFLAG_TOSSED_BYWLC */
|
||||
{"TX_PKT_FATE_SENT_NOACK", "NO_ACK"}, /* 4: WLFC_CTL_PKTFLAG_DISCARD_NOACK */
|
||||
{"TX_PKT_FATE_FW_SUPPRESS_ACKED", "TX_FAIL"}, /* 5: WLFC_CTL_PKTFLAG_SUPPRESS_ACKED */
|
||||
{"TX_PKT_FATE_FW_DROP_EXPTIME", "TX_FAIL"}, /* 6: WLFC_CTL_PKTFLAG_EXPIRED */
|
||||
{"TX_PKT_FATE_FW_DROP_OTHER", "TX_FAIL"}, /* 7: WLFC_CTL_PKTFLAG_DROPPED */
|
||||
{"TX_PKT_FATE_FW_PKT_FREE", "TX_FAIL"}, /* 8: WLFC_CTL_PKTFLAG_MKTFREE */
|
||||
{"TX_PKT_FATE_FW_MAX_SUP_RETR", "TX_FAIL"}, /* 9: WLFC_CTL_PKTFLAG_MAX_SUP_RETR */
|
||||
{"TX_PKT_FATE_FW_FORCED_EXPIRED", "TX_FAIL"}, /* 10: WLFC_CTL_PKTFLAG_FORCED_EXPIRED */
|
||||
};
|
||||
|
||||
#define DBGREPLAY " Replay Counter: %02x%02x%02x%02x%02x%02x%02x%02x"
|
||||
|
|
@ -191,10 +208,17 @@ static const char tx_pktfate[][30] = {
|
|||
((const eapol_key_hdr_t *)(key))->replay[7]
|
||||
#define TXFATE_FMT " TX_PKTHASH:0x%X TX_PKT_FATE:%s"
|
||||
#define TX_PKTHASH(pkthash) ((pkthash) ? (*pkthash) : (0))
|
||||
#define TX_FATE_STR(fate) (((*fate) <= (WLFC_CTL_PKTFLAG_MKTFREE)) ? \
|
||||
(tx_pktfate[(*fate)]) : "TX_PKT_FATE_FW_DROP_OTHER")
|
||||
#define TX_FATE_STR(fate) (((*fate) <= (WLFC_CTL_PKTFLAG_FORCED_EXPIRED)) ? \
|
||||
(tx_pktfate[(*fate)].reason) : "TX_PKT_FATE_UNKNOWN")
|
||||
#define TX_FATE_STR_EX(fate) (((*fate) <= (WLFC_CTL_PKTFLAG_FORCED_EXPIRED)) ? \
|
||||
(tx_pktfate[(*fate)].ex) : NULL)
|
||||
#define TX_FATE(fate) ((fate) ? (TX_FATE_STR(fate)) : "N/A")
|
||||
#define TX_FATE_EX(fate) ((fate) ? (TX_FATE_STR_EX(fate)) : NULL)
|
||||
#define TX_FATE_ACKED(fate) ((fate) ? ((*fate) == (WLFC_CTL_PKTFLAG_DISCARD)) : (0))
|
||||
#endif /*
|
||||
* DHD_DNS_DUMP || DHD_ARP_DUMP || DHD_ICMP_DUMP ||
|
||||
* DHD_DHCP_DUMP || DHD_8021X_DUMP || DHD_PKTDUMP_ROAM
|
||||
*/
|
||||
|
||||
#define EAP_PRINT(x, args...) \
|
||||
do { \
|
||||
|
|
@ -1075,6 +1099,7 @@ typedef struct bootp_fmt {
|
|||
static const uint8 bootp_magic_cookie[4] = { 99, 130, 83, 99 };
|
||||
|
||||
#ifdef DHD_DHCP_DUMP
|
||||
#if defined(DHD_DHCP_DUMP) || defined(WL_CFGVENDOR_CUST_ADVLOG)
|
||||
#define DHCP_MSGTYPE_DISCOVER 1
|
||||
#define DHCP_MSGTYPE_OFFER 2
|
||||
#define DHCP_MSGTYPE_REQUEST 3
|
||||
|
|
@ -1083,6 +1108,7 @@ static const uint8 bootp_magic_cookie[4] = { 99, 130, 83, 99 };
|
|||
#define DHCP_MSGTYPE_NAK 6
|
||||
#define DHCP_MSGTYPE_RELEASE 7
|
||||
#define DHCP_MSGTYPE_INFORM 8
|
||||
#endif /* DHD_DHCP_DUMP || WL_CFGVENDOR_CUST_ADVLOG */
|
||||
|
||||
#define DHCP_PRINT(str) \
|
||||
do { \
|
||||
|
|
@ -1098,15 +1124,26 @@ static const uint8 bootp_magic_cookie[4] = { 99, 130, 83, 99 };
|
|||
} \
|
||||
} while (0)
|
||||
|
||||
static char dhcp_ops[][10] = {
|
||||
#define MAX_DHCP_OPS_STR 3
|
||||
#define MAX_DHCP_TYPES_STR 9
|
||||
|
||||
static char dhcp_ops[MAX_DHCP_OPS_STR][10] = {
|
||||
"NA", "REQUEST", "REPLY"
|
||||
};
|
||||
static char dhcp_types[][10] = {
|
||||
static char dhcp_types[MAX_DHCP_TYPES_STR][10] = {
|
||||
"NA", "DISCOVER", "OFFER", "REQUEST", "DECLINE", "ACK", "NAK", "RELEASE", "INFORM"
|
||||
};
|
||||
|
||||
#define DHCP_OPS_STR(ops) ((ops < MAX_DHCP_OPS_STR) ? \
|
||||
(dhcp_ops[ops]) : "UNKNOWN_DHCP_OPS")
|
||||
#define DHCP_TYPES_STR(type) ((type < MAX_DHCP_TYPES_STR) ? \
|
||||
(dhcp_types[type]) : "UNKNOWN_DHCP_TYPE")
|
||||
|
||||
#ifdef DHD_STATUS_LOGGING
|
||||
static const int dhcp_types_stat[9] = {
|
||||
#define MAX_DHCP_TYPES_STAT 9
|
||||
#define DHCP_TYPES_STAT(type) ((type < MAX_DHCP_TYPES_STAT) ? \
|
||||
(dhcp_types_stat[type]) : ST(INVALID))
|
||||
static const int dhcp_types_stat[MAX_DHCP_TYPES_STAT] = {
|
||||
ST(INVALID), ST(DHCP_DISCOVER), ST(DHCP_OFFER), ST(DHCP_REQUEST),
|
||||
ST(DHCP_DECLINE), ST(DHCP_ACK), ST(DHCP_NAK), ST(DHCP_RELEASE),
|
||||
ST(DHCP_INFORM)
|
||||
|
|
@ -1120,7 +1157,8 @@ dhd_dhcp_dump(dhd_pub_t *dhdp, int ifidx, uint8 *pktdata, bool tx,
|
|||
bootp_fmt_t *b = (bootp_fmt_t *)&pktdata[ETHER_HDR_LEN];
|
||||
struct ipv4_hdr *iph = &b->iph;
|
||||
uint8 *ptr, *opt, *end = (uint8 *) b + ntohs(b->iph.tot_len);
|
||||
int dhcp_type = 0, len, opt_len;
|
||||
uint8 dhcp_type = 0;
|
||||
int len, opt_len;
|
||||
char *ifname = NULL, *typestr = NULL, *opstr = NULL;
|
||||
bool cond;
|
||||
char sabuf[20]="", dabuf[20]="";
|
||||
|
|
@ -1156,9 +1194,9 @@ dhd_dhcp_dump(dhd_pub_t *dhdp, int ifidx, uint8 *pktdata, bool tx,
|
|||
if (*opt == DHCP_OPT_MSGTYPE) {
|
||||
if (opt[1]) {
|
||||
dhcp_type = opt[2];
|
||||
typestr = dhcp_types[dhcp_type];
|
||||
opstr = dhcp_ops[b->op];
|
||||
DHD_STATLOG_DATA(dhdp, dhcp_types_stat[dhcp_type],
|
||||
typestr = DHCP_TYPES_STR(dhcp_type);
|
||||
opstr = DHCP_OPS_STR(b->op);
|
||||
DHD_STATLOG_DATA(dhdp, DHCP_TYPES_STAT(dhcp_type),
|
||||
ifidx, tx, cond);
|
||||
DHCP_PRINT("DHCP");
|
||||
break;
|
||||
|
|
@ -1186,6 +1224,23 @@ dhd_check_icmp(uint8 *pktdata)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
bool
|
||||
dhd_check_icmpv6(uint8 *pktdata, uint32 plen)
|
||||
{
|
||||
uint8 *pkt = (uint8 *)&pktdata[ETHER_HDR_LEN];
|
||||
struct ipv6_hdr *ip6h = (struct ipv6_hdr *)pkt;
|
||||
|
||||
if (IPV6_PROT(ip6h) != IP_PROT_ICMP6) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* check header length */
|
||||
if (plen <= IPV6_MIN_HLEN) {
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#ifdef DHD_ICMP_DUMP
|
||||
#define ICMP_TYPE_DEST_UNREACH 3
|
||||
#define ICMP_ECHO_SEQ_OFFSET 6
|
||||
|
|
@ -1577,6 +1632,222 @@ dhd_trx_pkt_dump(dhd_pub_t *dhdp, int ifidx, uint8 *pktdata, uint32 pktlen, bool
|
|||
}
|
||||
#endif /* DHD_RX_DUMP */
|
||||
|
||||
#ifdef WL_CFGVENDOR_CUST_ADVLOG
|
||||
typedef struct dhd_advlog_arr_map_entry {
|
||||
uint32 avglog_type;
|
||||
dhd_advlog_map_entry_t *arr;
|
||||
uint32 arr_len;
|
||||
} dhd_advlog_arr_map_entry_t;
|
||||
|
||||
typedef enum dhd_advlog_type {
|
||||
DHD_ADVLOG_DHCP_TX = 0,
|
||||
DHD_ADVLOG_DHCP_RX = 1,
|
||||
DHD_ADVLOG_EAP = 2,
|
||||
DHD_ADVLOG_EAPOL = 3,
|
||||
DHD_ADVLOG_LAST = 4
|
||||
} dhd_advlog_type_t;
|
||||
|
||||
static dhd_advlog_map_entry_t eap_type_map[] = {
|
||||
{EAP_TYPE_IDENT, "Identity"},
|
||||
{EAP_TYPE_TLS, "TLS"},
|
||||
{EAP_TYPE_LEAP, "LEAP"},
|
||||
{EAP_TYPE_TTLS, "TTLS"},
|
||||
{EAP_TYPE_AKA, "AKA"},
|
||||
{EAP_TYPE_PEAP, "PEAP"},
|
||||
{EAP_TYPE_FAST, "FAST"},
|
||||
{EAP_TYPE_PSK, "PSK"},
|
||||
{EAP_TYPE_AKAP, "AKAP"},
|
||||
};
|
||||
|
||||
static dhd_advlog_map_entry_t eap_advlog_map[] = {
|
||||
{EAP_CODE_REQUEST, "[EAP] REQ type=%s len=%d"},
|
||||
{EAP_CODE_RESPONSE, "[EAP] RESP type=%s len=%d tx_status=%s"},
|
||||
{EAP_CODE_SUCCESS, "[EAP] SUCC"},
|
||||
{EAP_CODE_FAILURE, "[EAP] FAIL"},
|
||||
};
|
||||
|
||||
static dhd_advlog_map_entry_t dhcp_tx_advlog_map[] = {
|
||||
{DHCP_MSGTYPE_DISCOVER, "[DHCP] DISCOVER tx_status=%s"},
|
||||
{DHCP_MSGTYPE_REQUEST, "[DHCP] REQUEST tx_status=%s"},
|
||||
};
|
||||
|
||||
static dhd_advlog_map_entry_t dhcp_rx_advlog_map[] = {
|
||||
{DHCP_MSGTYPE_OFFER, "[DHCP] OFFER"},
|
||||
{DHCP_MSGTYPE_ACK, "[DHCP] ACK"},
|
||||
{DHCP_MSGTYPE_NAK, "[DHCP] NAK"},
|
||||
};
|
||||
|
||||
static dhd_advlog_map_entry_t eapol_advlog_map[] = {
|
||||
{EAPOL_4WAY_M1, "[EAPOL] 4WAY M1"},
|
||||
{EAPOL_4WAY_M2, "[EAPOL] 4WAY M2 tx_status=%s"},
|
||||
{EAPOL_4WAY_M3, "[EAPOL] 4WAY M3"},
|
||||
{EAPOL_4WAY_M4, "[EAPOL] 4WAY M4 tx_status=%s"},
|
||||
{EAPOL_GROUPKEY_M1, "[EAPOL] GTK M1"},
|
||||
{EAPOL_GROUPKEY_M2, "[EAPOL] GTK M2 tx_status=%s"},
|
||||
};
|
||||
|
||||
static dhd_advlog_arr_map_entry_t advlog_map_arr[] = {
|
||||
{DHD_ADVLOG_DHCP_TX, dhcp_tx_advlog_map, ARRAY_SIZE(dhcp_tx_advlog_map)},
|
||||
{DHD_ADVLOG_DHCP_RX, dhcp_rx_advlog_map, ARRAY_SIZE(dhcp_rx_advlog_map)},
|
||||
{DHD_ADVLOG_EAP, eap_advlog_map, ARRAY_SIZE(eap_advlog_map)},
|
||||
{DHD_ADVLOG_EAPOL, eapol_advlog_map, ARRAY_SIZE(eapol_advlog_map)},
|
||||
};
|
||||
|
||||
const char* get_advlog_val(dhd_advlog_map_entry_t *arr, uint32 arr_len, int tag)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < arr_len; i++) {
|
||||
if (tag == arr[i].key) {
|
||||
return arr[i].val;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int get_dhcp_type(uint8 *pktdata)
|
||||
{
|
||||
bootp_fmt_t *b = (bootp_fmt_t *)&pktdata[ETHER_HDR_LEN];
|
||||
uint8 *ptr, *opt, *end = (uint8 *) b + ntohs(b->iph.tot_len);
|
||||
int dhcp_type = 0, len, opt_len;
|
||||
|
||||
len = ntohs(b->udph.len) - sizeof(struct bcmudp_hdr);
|
||||
opt_len = len - (sizeof(*b) - sizeof(struct ipv4_hdr) -
|
||||
sizeof(struct bcmudp_hdr) - sizeof(b->options));
|
||||
|
||||
/* parse bootp options */
|
||||
if (opt_len >= BOOTP_MAGIC_COOKIE_LEN &&
|
||||
!memcmp(b->options, bootp_magic_cookie, BOOTP_MAGIC_COOKIE_LEN)) {
|
||||
ptr = &b->options[BOOTP_MAGIC_COOKIE_LEN];
|
||||
while (ptr < end && *ptr != 0xff) {
|
||||
opt = ptr++;
|
||||
if (*opt == 0) {
|
||||
continue;
|
||||
}
|
||||
ptr += *ptr + 1;
|
||||
if (ptr >= end) {
|
||||
break;
|
||||
}
|
||||
if (*opt == DHCP_OPT_MSGTYPE) {
|
||||
if (opt[1]) {
|
||||
dhcp_type = opt[2];
|
||||
return dhcp_type;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return BCME_ERROR;
|
||||
}
|
||||
|
||||
static int dhd_send_supp(uint32 avglog_type, int arg_tag, int arg_type, uint32 pktlen,
|
||||
bool tx, uint16 *pktfate)
|
||||
{
|
||||
const char *type_str = NULL;
|
||||
const char *fmt_str = NULL;
|
||||
dhd_advlog_map_entry_t *fmt_arr;
|
||||
uint32 fmt_arr_len;
|
||||
|
||||
if (avglog_type >= DHD_ADVLOG_LAST) {
|
||||
DHD_ERROR(("%s incorrect array index type:%d tag:%d\n",
|
||||
__func__, avglog_type, arg_tag));
|
||||
return BCME_ERROR;
|
||||
}
|
||||
if ((arg_type && !pktlen) || (!arg_type && pktlen)) {
|
||||
DHD_ERROR(("%s Not expected value pair type:%d tag:%d pktlen:%u\n",
|
||||
__func__, avglog_type, arg_tag, pktlen));
|
||||
return BCME_ERROR;
|
||||
}
|
||||
if (arg_tag <= 0) {
|
||||
DHD_ERROR(("%s Invalid tag number type:%d tag:%d\n",
|
||||
__func__, avglog_type, arg_tag));
|
||||
return BCME_ERROR;
|
||||
}
|
||||
|
||||
/* Get the format string corresponding to the type */
|
||||
fmt_arr = advlog_map_arr[avglog_type].arr;
|
||||
fmt_arr_len = advlog_map_arr[avglog_type].arr_len;
|
||||
fmt_str = get_advlog_val(fmt_arr, fmt_arr_len, arg_tag);
|
||||
if (!fmt_str) {
|
||||
DHD_ERROR(("%s map arr not found type:%d tag:%d\n",
|
||||
__func__, avglog_type, arg_tag));
|
||||
return BCME_ERROR;
|
||||
}
|
||||
|
||||
/* EAP REQ/RESP */
|
||||
if (arg_type && pktlen) {
|
||||
/* Get Identity/PEAP/FAST/etc string */
|
||||
type_str = get_advlog_val(eap_type_map, ARRAY_SIZE(eap_type_map), arg_type);
|
||||
if (!type_str) {
|
||||
DHD_ERROR(("%s type string not found type:%d tag:%d\n",
|
||||
__func__, avglog_type, arg_tag));
|
||||
return BCME_ERROR;
|
||||
}
|
||||
if (tx && pktfate) {
|
||||
/* EAP RESP */
|
||||
SUPP_ADVLOG((fmt_str, type_str, pktlen, TX_FATE_EX(pktfate)));
|
||||
} else if (!tx) {
|
||||
/* EAP REQ */
|
||||
SUPP_ADVLOG((fmt_str, type_str, pktlen));
|
||||
}
|
||||
} else {
|
||||
if (tx && pktfate) {
|
||||
/* EAPOL M2/M4, GTK M2, DHCP DISC/REQ */
|
||||
SUPP_ADVLOG((fmt_str, TX_FATE_EX(pktfate)));
|
||||
} else if (!tx) {
|
||||
/* EAPOL M1/M3, GTK M1, DHCP OFFER/ACK/NAK, EAP SUCC/FAIL */
|
||||
SUPP_ADVLOG((fmt_str));
|
||||
}
|
||||
}
|
||||
return BCME_OK;
|
||||
}
|
||||
|
||||
void dhd_send_supp_dhcp(dhd_pub_t *dhdp, int ifidx, uint8 *pktdata, bool tx, uint16 *pktfate)
|
||||
{
|
||||
uint32 advlog_type;
|
||||
|
||||
/* Advanced Logging supports only STA mode */
|
||||
if (!DHD_IF_ROLE_STA(dhdp, ifidx)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (tx) {
|
||||
advlog_type = DHD_ADVLOG_DHCP_TX;
|
||||
} else {
|
||||
advlog_type = DHD_ADVLOG_DHCP_RX;
|
||||
}
|
||||
dhd_send_supp(advlog_type, get_dhcp_type(pktdata), 0, 0, tx, pktfate);
|
||||
}
|
||||
|
||||
void dhd_send_supp_eap(dhd_pub_t *dhdp, int ifidx, uint8 *pktdata, uint32 pktlen,
|
||||
bool tx, uint16 *pktfate)
|
||||
{
|
||||
eapol_header_t *eapol_hdr;
|
||||
eap_header_fmt_t *eap_hdr;
|
||||
uint16 len = 0;
|
||||
uint8 type = 0;
|
||||
|
||||
/* Advanced Logging supports only STA mode */
|
||||
if (!DHD_IF_ROLE_STA(dhdp, ifidx)) {
|
||||
return;
|
||||
}
|
||||
|
||||
eapol_hdr = (eapol_header_t *)pktdata;
|
||||
eap_hdr = (eap_header_fmt_t *)(eapol_hdr->body);
|
||||
|
||||
if (eapol_hdr->type == EAP_PACKET) {
|
||||
/* EAP SUCC/FAIL has no arg to print */
|
||||
if (eap_hdr->code != EAP_CODE_SUCCESS &&
|
||||
eap_hdr->code != EAP_CODE_FAILURE) {
|
||||
type = eap_hdr->type;
|
||||
len = ntoh16(eap_hdr->len);
|
||||
}
|
||||
dhd_send_supp(DHD_ADVLOG_EAP, eap_hdr->code, type, len, tx, pktfate);
|
||||
} else if (eapol_hdr->type == EAPOL_KEY) {
|
||||
dhd_send_supp(DHD_ADVLOG_EAPOL, dhd_is_4way_msg(pktdata),
|
||||
0, 0, tx, pktfate);
|
||||
}
|
||||
}
|
||||
#endif /* WL_CFGVENDOR_CUST_ADVLOG */
|
||||
|
||||
#ifdef BCMPCIE
|
||||
static bool
|
||||
dhd_is_eapol_pkt(dhd_pub_t *dhd, uint8 *pktdata, uint32 pktlen)
|
||||
|
|
|
|||
29
drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_linux_pktdump.h
Executable file → Normal file
29
drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_linux_pktdump.h
Executable file → Normal file
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* Header file for the Packet dump helper functions
|
||||
*
|
||||
* Copyright (C) 2020, Broadcom.
|
||||
* Copyright (C) 2022, Broadcom.
|
||||
*
|
||||
* Unless you and Broadcom execute a separate written software license
|
||||
* agreement governing use of this software, this software is licensed to you
|
||||
|
|
@ -51,11 +51,31 @@ enum pkt_type {
|
|||
PKT_TYPE_DATA = 0,
|
||||
PKT_TYPE_DHCP = 1,
|
||||
PKT_TYPE_ICMP = 2,
|
||||
PKT_TYPE_DNS = 3,
|
||||
PKT_TYPE_ARP = 4,
|
||||
PKT_TYPE_EAP = 5
|
||||
PKT_TYPE_ICMPV6 = 3,
|
||||
PKT_TYPE_DNS = 4,
|
||||
PKT_TYPE_ARP = 5,
|
||||
PKT_TYPE_EAP = 6,
|
||||
PKT_TYPE_IGMP = 7
|
||||
};
|
||||
|
||||
#ifdef WL_CFGVENDOR_CUST_ADVLOG
|
||||
#define DHD_ADVLOG_FMT_MAX 256u
|
||||
typedef struct dhd_advlog_map_entry {
|
||||
uint32 key;
|
||||
const char val[DHD_ADVLOG_FMT_MAX];
|
||||
} dhd_advlog_map_entry_t;
|
||||
|
||||
extern void dhd_send_supp_dhcp(dhd_pub_t *dhdp, int ifidx, uint8 *pktdata,
|
||||
bool tx, uint16 *pktfate);
|
||||
extern void dhd_send_supp_eap(dhd_pub_t *dhdp, int ifidx, uint8 *pktdata, uint32 pktlen,
|
||||
bool tx, uint16 *pktfate);
|
||||
#else
|
||||
static INLINE void dhd_send_supp_dhcp(dhd_pub_t *dhdp, int ifidx, uint8 *pktdata,
|
||||
bool tx, uint16 *pktfate) {}
|
||||
static INLINE void dhd_send_supp_eap(dhd_pub_t *dhdp, int ifidx, uint8 *pktdata,
|
||||
uint32 pktlen, bool tx, uint16 *pktfate) {}
|
||||
#endif /* WL_CFGVENDOR_CUST_ADVLOG */
|
||||
|
||||
extern msg_eapol_t dhd_is_4way_msg(uint8 *pktdata);
|
||||
extern void dhd_dump_pkt(dhd_pub_t *dhd, int ifidx, uint8 *pktdata,
|
||||
uint32 pktlen, bool tx, uint32 *pkthash, uint16 *pktfate);
|
||||
|
|
@ -131,5 +151,6 @@ extern bool dhd_check_ip_prot(uint8 *pktdata, uint16 ether_type);
|
|||
extern bool dhd_check_arp(uint8 *pktdata, uint16 ether_type);
|
||||
extern bool dhd_check_dhcp(uint8 *pktdata);
|
||||
extern bool dhd_check_icmp(uint8 *pktdata);
|
||||
extern bool dhd_check_icmpv6(uint8 *pktdata, uint32 plen);
|
||||
extern bool dhd_check_dns(uint8 *pktdata);
|
||||
#endif /* __DHD_LINUX_PKTDUMP_H_ */
|
||||
|
|
|
|||
348
drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_linux_platdev.c
Executable file → Normal file
348
drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_linux_platdev.c
Executable file → Normal file
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* Linux platform device for DHD WLAN adapter
|
||||
*
|
||||
* Copyright (C) 2020, Broadcom.
|
||||
* Copyright (C) 2022, Broadcom.
|
||||
*
|
||||
* Unless you and Broadcom execute a separate written software license
|
||||
* agreement governing use of this software, this software is licensed to you
|
||||
|
|
@ -37,20 +37,16 @@
|
|||
#if defined(OEM_ANDROID)
|
||||
#include <wl_android.h>
|
||||
#endif
|
||||
#if defined(CONFIG_WIFI_CONTROL_FUNC) || defined(CUSTOMER_HW4)
|
||||
#include <linux/wlan_plat.h>
|
||||
#else
|
||||
#include <dhd_plat.h>
|
||||
#if defined(CONFIG_WIFI_CONTROL_FUNC)
|
||||
#include <linux/wlan_plat.h>
|
||||
#endif /* CONFIG_WIFI_CONTROL_FUNC */
|
||||
#ifdef BCMDBUS
|
||||
#include <dbus.h>
|
||||
#endif
|
||||
#ifdef CONFIG_DTS
|
||||
#include<linux/regulator/consumer.h>
|
||||
#include<linux/of_gpio.h>
|
||||
#endif /* CONFIG_DTS */
|
||||
|
||||
#if defined(CUSTOMER_HW)
|
||||
#if defined(CUSTOMER_HW) || defined(BCMDHD_PLATDEV)
|
||||
extern int dhd_wlan_init_plat_data(wifi_adapter_info_t *adapter);
|
||||
extern void dhd_wlan_deinit_plat_data(wifi_adapter_info_t *adapter);
|
||||
#endif /* CUSTOMER_HW */
|
||||
|
|
@ -59,6 +55,11 @@ extern void dhd_wlan_deinit_plat_data(wifi_adapter_info_t *adapter);
|
|||
#define WIFI_PLAT_NAME2 "bcm4329_wlan"
|
||||
#define WIFI_PLAT_EXT "bcmdhd_wifi_platform"
|
||||
|
||||
#if defined(SUPPORT_MULTIPLE_BOARD_REVISION)
|
||||
#include <linux/of.h>
|
||||
extern char* dhd_get_device_dt_name(void);
|
||||
#endif /* SUPPORT_MULTIPLE_BOARD_REVISION */
|
||||
|
||||
#ifdef DHD_WIFI_SHUTDOWN
|
||||
extern void wifi_plat_dev_drv_shutdown(struct platform_device *pdev);
|
||||
#endif
|
||||
|
|
@ -88,7 +89,7 @@ static bool dts_enabled = FALSE;
|
|||
#pragma GCC diagnostic ignored "-Wmissing-field-initializers"
|
||||
#endif
|
||||
struct resource dhd_wlan_resources = {0};
|
||||
struct wifi_platform_data dhd_wlan_control = {0};
|
||||
extern struct wifi_platform_data dhd_wlan_control;
|
||||
#if defined(STRICT_GCC_WARNINGS) && defined(__GNUC__)
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
|
@ -99,14 +100,15 @@ static int dhd_wifi_platform_load(void);
|
|||
|
||||
extern void* wl_cfg80211_get_dhdp(struct net_device *dev);
|
||||
|
||||
#ifdef BCMDHD_MODULAR
|
||||
// modify for compatibility
|
||||
#if defined(BCMDHD_MODULAR) && defined(BOARD_MODULAR_INIT)
|
||||
//extern int dhd_wlan_init(void);
|
||||
//extern int dhd_wlan_deinit(void);
|
||||
#ifdef WBRC
|
||||
extern int wbrc_init(void);
|
||||
extern void wbrc_exit(void);
|
||||
#endif /* WBRC */
|
||||
#endif /* BCMDHD_MODULAR */
|
||||
#endif /* defined(BCMDHD_MODULAR) && defined(BOARD_MODULAR_INIT) */
|
||||
|
||||
#ifdef ENABLE_4335BT_WAR
|
||||
extern int bcm_bt_lock(int cookie);
|
||||
|
|
@ -118,6 +120,18 @@ static int lock_cookie_wifi = 'W' | 'i'<<8 | 'F'<<16 | 'i'<<24; /* cookie is "Wi
|
|||
extern bool check_bcm4335_rev(void);
|
||||
#endif /* BCM4335_XTAL_WAR */
|
||||
|
||||
#if defined(CONFIG_X86)
|
||||
#define PCIE_RC_VENDOR_ID 0x8086
|
||||
#define PCIE_RC_DEVICE_ID 0x9c1a
|
||||
#elif defined(CONFIG_ARCH_TEGRA)
|
||||
#define PCIE_RC_VENDOR_ID 0x14e4
|
||||
#define PCIE_RC_DEVICE_ID 0x4347
|
||||
#else /* CONFIG_ARCH_TEGRA */
|
||||
/* Dummy defn */
|
||||
#define PCIE_RC_VENDOR_ID 0xffff
|
||||
#define PCIE_RC_DEVICE_ID 0xffff
|
||||
#endif /* CONFIG_X86 */
|
||||
|
||||
wifi_adapter_info_t* dhd_wifi_platform_attach_adapter(uint32 bus_type,
|
||||
uint32 bus_num, uint32 slot_num, unsigned long status)
|
||||
{
|
||||
|
|
@ -131,7 +145,7 @@ wifi_adapter_info_t* dhd_wifi_platform_attach_adapter(uint32 bus_type,
|
|||
if ((adapter->bus_type == -1 || adapter->bus_type == bus_type) &&
|
||||
(adapter->bus_num == -1 || adapter->bus_num == bus_num) &&
|
||||
(adapter->slot_num == -1 || adapter->slot_num == slot_num)
|
||||
#if defined(ENABLE_INSMOD_NO_FW_LOAD)
|
||||
#if defined(ENABLE_INSMOD_NO_FW_LOAD) && !defined(ENABLE_INSMOD_NO_POWER_OFF)
|
||||
&& (wifi_chk_adapter_status(adapter, status))
|
||||
#endif
|
||||
) {
|
||||
|
|
@ -161,6 +175,10 @@ wifi_adapter_info_t* dhd_wifi_platform_get_adapter(uint32 bus_type, uint32 bus_n
|
|||
return NULL;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_WIFI_CONTROL_FUNC) && defined(CONFIG_DHD_USE_STATIC_BUF)
|
||||
extern void *dhd_wlan_mem_prealloc(int section, unsigned long size);
|
||||
#endif /* CONFIG_WIFI_CONTROL_FUNC && CONFIG_DHD_USE_STATIC_BUF */
|
||||
|
||||
void* wifi_platform_prealloc(wifi_adapter_info_t *adapter, int section, unsigned long size)
|
||||
{
|
||||
void *alloc_ptr = NULL;
|
||||
|
|
@ -170,10 +188,14 @@ void* wifi_platform_prealloc(wifi_adapter_info_t *adapter, int section, unsigned
|
|||
return NULL;
|
||||
plat_data = adapter->wifi_plat_data;
|
||||
if (plat_data->mem_prealloc) {
|
||||
#ifdef BCMDHD_MDRIVER
|
||||
#if defined(BCMDHD_MDRIVER) && !defined(DHD_STATIC_IN_DRIVER)
|
||||
alloc_ptr = plat_data->mem_prealloc(adapter->bus_type, adapter->index, section, size);
|
||||
#else
|
||||
#if defined(CONFIG_WIFI_CONTROL_FUNC) && defined(CONFIG_DHD_USE_STATIC_BUF)
|
||||
alloc_ptr = dhd_wlan_mem_prealloc(section, size);
|
||||
#else
|
||||
alloc_ptr = plat_data->mem_prealloc(section, size);
|
||||
#endif
|
||||
#endif
|
||||
if (alloc_ptr) {
|
||||
DHD_INFO(("success alloc section %d\n", section));
|
||||
|
|
@ -260,11 +282,17 @@ int wifi_platform_set_power(wifi_adapter_info_t *adapter, bool on, unsigned long
|
|||
}
|
||||
#endif /* ENABLE_4335BT_WAR */
|
||||
|
||||
#ifdef CONFIG_WIFI_CONTROL_FUNC
|
||||
err = plat_data->set_power(on);
|
||||
#else
|
||||
err = plat_data->set_power(on, adapter);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (msec && !err)
|
||||
if (msec && !err) {
|
||||
OSL_SLEEP(msec);
|
||||
DHD_ERROR(("%s = %d, sleep done: %lu msec\n", __FUNCTION__, on, msec));
|
||||
}
|
||||
|
||||
if (on && !err)
|
||||
is_power_on = TRUE;
|
||||
|
|
@ -310,7 +338,11 @@ int wifi_platform_get_mac_addr(wifi_adapter_info_t *adapter, unsigned char *buf,
|
|||
return -EINVAL;
|
||||
plat_data = adapter->wifi_plat_data;
|
||||
if (plat_data->get_mac_addr) {
|
||||
#ifdef CONFIG_WIFI_CONTROL_FUNC
|
||||
return plat_data->get_mac_addr(buf);
|
||||
#else
|
||||
return plat_data->get_mac_addr(buf, ifidx);
|
||||
#endif
|
||||
}
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
|
@ -381,6 +413,14 @@ static int wifi_plat_dev_drv_probe(struct platform_device *pdev)
|
|||
adapter->wifi_plat_data = (void *)&dhd_wlan_control;
|
||||
#endif
|
||||
|
||||
#ifdef BCMDHD_PLATDEV
|
||||
adapter->pdev = pdev;
|
||||
wifi_plat_dev_probe_ret = dhd_wlan_init_plat_data(adapter);
|
||||
if (!wifi_plat_dev_probe_ret)
|
||||
wifi_plat_dev_probe_ret = dhd_wifi_platform_load();
|
||||
return wifi_plat_dev_probe_ret;
|
||||
#endif
|
||||
|
||||
resource = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "bcmdhd_wlan_irq");
|
||||
if (resource == NULL)
|
||||
resource = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "bcm4329_wlan_irq");
|
||||
|
|
@ -452,6 +492,9 @@ static int wifi_plat_dev_drv_remove(struct platform_device *pdev)
|
|||
#ifdef CONFIG_DTS
|
||||
regulator_put(wifi_regulator);
|
||||
#endif /* CONFIG_DTS */
|
||||
#ifdef BCMDHD_PLATDEV
|
||||
dhd_wlan_deinit_plat_data(adapter);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -518,9 +561,10 @@ static int wifi_platdev_match(struct device *dev, const void *data)
|
|||
static int wifi_platdev_match(struct device *dev, void *data)
|
||||
#endif /* LINUX_VER >= 5.3.0 */
|
||||
{
|
||||
char *name = (char*)data;
|
||||
char *name = NULL;
|
||||
const struct platform_device *pdev;
|
||||
GCC_DIAGNOSTIC_PUSH_SUPPRESS_CAST();
|
||||
name = (char*)data;
|
||||
pdev = to_platform_device(dev);
|
||||
GCC_DIAGNOSTIC_POP();
|
||||
|
||||
|
|
@ -544,12 +588,16 @@ static int wifi_ctrlfunc_register_drv(void)
|
|||
dev2 = bus_find_device(&platform_bus_type, NULL, WIFI_PLAT_NAME2, wifi_platdev_match);
|
||||
#endif
|
||||
|
||||
#ifdef BCMDHD_MODULAR
|
||||
// dhd_wlan_init();
|
||||
// modify for compaibility
|
||||
#if defined(BCMDHD_MODULAR) && defined(BOARD_MODULAR_INIT)
|
||||
// if ((err = dhd_wlan_init())) {
|
||||
// DHD_ERROR(("%s: dhd_wlan_init() failed(%d)\n", __FUNCTION__, err));
|
||||
// return err;
|
||||
// }
|
||||
#ifdef WBRC
|
||||
wbrc_init();
|
||||
#endif /* WBRC */
|
||||
#endif /* BCMDHD_MODULAR */
|
||||
#endif /* defined(BCMDHD_MODULAR) && defined(BOARD_MODULAR_INIT) */
|
||||
|
||||
#if !defined(CONFIG_DTS) && !defined(CUSTOMER_HW)
|
||||
if (!dts_enabled) {
|
||||
|
|
@ -569,16 +617,7 @@ static int wifi_ctrlfunc_register_drv(void)
|
|||
return -ENOMEM;
|
||||
}
|
||||
adapter->name = "DHD generic adapter";
|
||||
adapter->index = -1;
|
||||
#if defined(BCMDHD_MDRIVER) && !defined(DHD_STATIC_IN_DRIVER)
|
||||
#ifdef BCMSDIO
|
||||
adapter->index = 0;
|
||||
#elif defined(BCMPCIE)
|
||||
adapter->index = 1;
|
||||
#elif defined(BCMDBUS)
|
||||
adapter->index = 2;
|
||||
#endif
|
||||
#endif
|
||||
adapter->bus_type = -1;
|
||||
adapter->bus_num = -1;
|
||||
adapter->slot_num = -1;
|
||||
|
|
@ -586,6 +625,11 @@ static int wifi_ctrlfunc_register_drv(void)
|
|||
is_power_on = FALSE;
|
||||
wifi_plat_dev_probe_ret = 0;
|
||||
dhd_wifi_platdata = kzalloc(sizeof(bcmdhd_wifi_platdata_t), GFP_KERNEL);
|
||||
if (dhd_wifi_platdata == NULL) {
|
||||
DHD_ERROR(("%s:dhd_wifi_platdata alloc failed", __FUNCTION__));
|
||||
kfree(adapter);
|
||||
return -ENOMEM;
|
||||
}
|
||||
dhd_wifi_platdata->num_adapters = 1;
|
||||
dhd_wifi_platdata->adapters = adapter;
|
||||
init_waitqueue_head(&adapter->status_event);
|
||||
|
|
@ -657,6 +701,11 @@ void wifi_ctrlfunc_unregister_drv(void)
|
|||
if (dev2)
|
||||
platform_driver_unregister(&wifi_platform_dev_driver_legacy);
|
||||
#endif
|
||||
|
||||
if (!dhd_wifi_platdata) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (dts_enabled) {
|
||||
adapter = &dhd_wifi_platdata->adapters[0];
|
||||
if (is_power_on) {
|
||||
|
|
@ -664,24 +713,30 @@ void wifi_ctrlfunc_unregister_drv(void)
|
|||
}
|
||||
wifi_platform_bus_enumerate(adapter, FALSE);
|
||||
}
|
||||
#ifdef BCMDHD_MODULAR
|
||||
// modify for compaibility
|
||||
#if defined(BCMDHD_MODULAR) && defined(BOARD_MODULAR_INIT)
|
||||
// dhd_wlan_deinit();
|
||||
osl_static_mem_deinit(NULL, NULL);
|
||||
#ifdef WBRC
|
||||
wbrc_exit();
|
||||
#endif /* WBRC */
|
||||
#endif /* BCMDHD_MODULAR */
|
||||
|
||||
#endif /* defined(BCMDHD_MODULAR) && defined(BOARD_MODULAR_INIT) */
|
||||
#endif /* !defined(CONFIG_DTS) */
|
||||
|
||||
#if defined(CUSTOMER_HW)
|
||||
dhd_wlan_deinit_plat_data(adapter);
|
||||
#endif
|
||||
|
||||
kfree(dhd_wifi_platdata->adapters);
|
||||
dhd_wifi_platdata->adapters = NULL;
|
||||
dhd_wifi_platdata->num_adapters = 0;
|
||||
kfree(dhd_wifi_platdata);
|
||||
dhd_wifi_platdata = NULL;
|
||||
done:
|
||||
if (dhd_wifi_platdata && dhd_wifi_platdata->adapters) {
|
||||
kfree(dhd_wifi_platdata->adapters);
|
||||
dhd_wifi_platdata->adapters = NULL;
|
||||
dhd_wifi_platdata->num_adapters = 0;
|
||||
}
|
||||
if (dhd_wifi_platdata) {
|
||||
kfree(dhd_wifi_platdata);
|
||||
dhd_wifi_platdata = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef CUSTOMER_HW
|
||||
|
|
@ -759,25 +814,31 @@ int dhd_wifi_platform_register_drv(void)
|
|||
#ifdef BCMPCIE
|
||||
static int dhd_wifi_platform_load_pcie(void)
|
||||
{
|
||||
int err = 0;
|
||||
int i;
|
||||
int err;
|
||||
int retry;
|
||||
wifi_adapter_info_t *adapter;
|
||||
|
||||
BCM_REFERENCE(i);
|
||||
BCM_REFERENCE(adapter);
|
||||
|
||||
if (dhd_wifi_platdata == NULL) {
|
||||
/* XXX For x86 Bringup PC or BRIX */
|
||||
err = dhd_bus_register();
|
||||
} else {
|
||||
if (dhd_wifi_platdata) {
|
||||
/* enumerate PCIe RC */
|
||||
for (i = 0; i < dhd_wifi_platdata->num_adapters; i++) {
|
||||
adapter = &dhd_wifi_platdata->adapters[i];
|
||||
err = wifi_platform_bus_enumerate(adapter, TRUE);
|
||||
if (err) {
|
||||
DHD_ERROR(("failed to enumerate bus %s err=%d",
|
||||
adapter->name, err));
|
||||
return err;
|
||||
}
|
||||
}
|
||||
#ifdef DHD_SUPPORT_HDM
|
||||
if (dhd_download_fw_on_driverload || hdm_trigger_init) {
|
||||
if (dhd_download_fw_on_driverload || hdm_trigger_init)
|
||||
#else
|
||||
if (dhd_download_fw_on_driverload) {
|
||||
if (dhd_download_fw_on_driverload)
|
||||
#endif /* DHD_SUPPORT_HDM */
|
||||
{
|
||||
/* power up all adapters */
|
||||
for (i = 0; i < dhd_wifi_platdata->num_adapters; i++) {
|
||||
int retry = POWERUP_MAX_RETRY;
|
||||
retry = POWERUP_MAX_RETRY;
|
||||
adapter = &dhd_wifi_platdata->adapters[i];
|
||||
|
||||
DHD_ERROR(("Power-up adapter '%s'\n", adapter->name));
|
||||
|
|
@ -798,17 +859,17 @@ static int dhd_wifi_platform_load_pcie(void)
|
|||
wifi_platform_set_power(adapter,
|
||||
FALSE, WIFI_TURNOFF_DELAY);
|
||||
continue;
|
||||
}
|
||||
|
||||
err = wifi_platform_bus_enumerate(adapter, TRUE);
|
||||
if (err) {
|
||||
DHD_ERROR(("failed to enumerate bus %s, "
|
||||
"%d retry left\n",
|
||||
adapter->name, retry));
|
||||
wifi_platform_set_power(adapter, FALSE,
|
||||
WIFI_TURNOFF_DELAY);
|
||||
} else {
|
||||
err = wifi_platform_bus_enumerate(adapter, TRUE);
|
||||
if (err) {
|
||||
DHD_ERROR(("failed to enumerate bus %s, "
|
||||
"%d retry left\n",
|
||||
adapter->name, retry));
|
||||
wifi_platform_set_power(adapter, FALSE,
|
||||
WIFI_TURNOFF_DELAY);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
} while (retry--);
|
||||
|
||||
|
|
@ -819,19 +880,18 @@ static int dhd_wifi_platform_load_pcie(void)
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
err = dhd_bus_register();
|
||||
|
||||
if (err) {
|
||||
DHD_ERROR(("%s: pcie_register_driver failed\n", __FUNCTION__));
|
||||
if (dhd_download_fw_on_driverload) {
|
||||
/* power down all adapters */
|
||||
for (i = 0; i < dhd_wifi_platdata->num_adapters; i++) {
|
||||
adapter = &dhd_wifi_platdata->adapters[i];
|
||||
wifi_platform_bus_enumerate(adapter, FALSE);
|
||||
wifi_platform_set_power(adapter,
|
||||
FALSE, WIFI_TURNOFF_DELAY);
|
||||
}
|
||||
err = dhd_bus_register();
|
||||
if (err) {
|
||||
DHD_ERROR(("%s: dhd_bus_register failed err=%d\n", __FUNCTION__, err));
|
||||
if (dhd_wifi_platdata && dhd_download_fw_on_driverload) {
|
||||
/* power down all adapters */
|
||||
for (i = 0; i < dhd_wifi_platdata->num_adapters; i++) {
|
||||
adapter = &dhd_wifi_platdata->adapters[i];
|
||||
wifi_platform_bus_enumerate(adapter, FALSE);
|
||||
wifi_platform_set_power(adapter,
|
||||
FALSE, WIFI_TURNOFF_DELAY);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -896,7 +956,9 @@ static int dhd_wifi_platform_load_sdio(void)
|
|||
for (i = 0; i < dhd_wifi_platdata->num_adapters; i++) {
|
||||
bool chip_up = FALSE;
|
||||
int retry = POWERUP_MAX_RETRY;
|
||||
#ifndef DHD_INSMOD_NOWAIT
|
||||
struct semaphore dhd_chipup_sem;
|
||||
#endif
|
||||
|
||||
adapter = &dhd_wifi_platdata->adapters[i];
|
||||
|
||||
|
|
@ -907,6 +969,18 @@ static int dhd_wifi_platform_load_sdio(void)
|
|||
adapter->bus_type, adapter->bus_num, adapter->slot_num));
|
||||
|
||||
do {
|
||||
#ifdef DHD_INSMOD_NOWAIT
|
||||
err = wifi_platform_set_power(adapter, TRUE, WIFI_TURNON_DELAY);
|
||||
if (err) {
|
||||
DHD_ERROR(("%s: wifi pwr on error ! \n", __FUNCTION__));
|
||||
wifi_platform_set_power(adapter, FALSE, WIFI_TURNOFF_DELAY);
|
||||
continue;
|
||||
} else {
|
||||
wifi_platform_bus_enumerate(adapter, TRUE);
|
||||
chip_up = TRUE;
|
||||
break;
|
||||
}
|
||||
#else
|
||||
sema_init(&dhd_chipup_sem, 0);
|
||||
err = dhd_bus_reg_sdio_notify(&dhd_chipup_sem);
|
||||
if (err) {
|
||||
|
|
@ -935,6 +1009,7 @@ static int dhd_wifi_platform_load_sdio(void)
|
|||
dhd_bus_unreg_sdio_notify();
|
||||
wifi_platform_set_power(adapter, FALSE, WIFI_TURNOFF_DELAY);
|
||||
wifi_platform_bus_enumerate(adapter, FALSE);
|
||||
#endif
|
||||
} while (retry--);
|
||||
|
||||
if (!chip_up) {
|
||||
|
|
@ -951,6 +1026,7 @@ static int dhd_wifi_platform_load_sdio(void)
|
|||
goto fail;
|
||||
}
|
||||
|
||||
#ifndef DHD_INSMOD_NOWAIT
|
||||
/*
|
||||
* Wait till MMC sdio_register_driver callback called and made driver attach.
|
||||
* It's needed to make sync up exit from dhd insmod and
|
||||
|
|
@ -962,6 +1038,7 @@ static int dhd_wifi_platform_load_sdio(void)
|
|||
dhd_bus_unregister();
|
||||
goto fail;
|
||||
}
|
||||
#endif
|
||||
|
||||
return err;
|
||||
|
||||
|
|
@ -994,16 +1071,15 @@ static int dhd_wifi_platform_load_usb(void)
|
|||
wifi_adapter_info_t *adapter;
|
||||
s32 timeout = -1;
|
||||
int i;
|
||||
enum wifi_adapter_status wait_status;
|
||||
#endif
|
||||
|
||||
#if !defined(DHD_PRELOAD)
|
||||
#if !defined(DHD_PRELOAD) && !defined(ENABLE_INSMOD_NO_POWER_OFF)
|
||||
/* power down all adapters */
|
||||
for (i = 0; i < dhd_wifi_platdata->num_adapters; i++) {
|
||||
adapter = &dhd_wifi_platdata->adapters[i];
|
||||
wifi_platform_set_power(adapter, FALSE, 0);
|
||||
if (err) {
|
||||
DHD_ERROR(("failed to wifi_platform_set_power on %s\n", adapter->name));
|
||||
DHD_ERROR(("failed to wifi_platform_set_power off %s\n", adapter->name));
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
|
|
@ -1030,12 +1106,8 @@ static int dhd_wifi_platform_load_usb(void)
|
|||
DHD_ERROR(("failed to wifi_platform_set_power on %s\n", adapter->name));
|
||||
goto fail;
|
||||
}
|
||||
if (dhd_download_fw_on_driverload)
|
||||
wait_status = WIFI_STATUS_ATTACH;
|
||||
else
|
||||
wait_status = WIFI_STATUS_DETTACH;
|
||||
timeout = wait_event_interruptible_timeout(adapter->status_event,
|
||||
wifi_get_adapter_status(adapter, wait_status),
|
||||
wifi_get_adapter_status(adapter, WIFI_STATUS_NET_ATTACHED),
|
||||
msecs_to_jiffies(DHD_REGISTRATION_TIMEOUT));
|
||||
if (timeout <= 0) {
|
||||
err = -1;
|
||||
|
|
@ -1095,3 +1167,127 @@ end:
|
|||
|
||||
return err;
|
||||
}
|
||||
|
||||
#if defined(SUPPORT_MULTIPLE_BOARD_REVISION)
|
||||
void
|
||||
concate_custom_board_revision(char *nv_path)
|
||||
{
|
||||
uint32 board_revision = 0;
|
||||
struct device_node *root_node = NULL;
|
||||
char* wlan_node = NULL;
|
||||
|
||||
if (!nv_path) {
|
||||
DHD_ERROR(("nv_path is null\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
wlan_node = dhd_get_device_dt_name();
|
||||
if (!wlan_node) {
|
||||
DHD_ERROR(("Failed to dt name\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
root_node = of_find_compatible_node(NULL, NULL, wlan_node);
|
||||
if (!root_node) {
|
||||
DHD_ERROR(("Failed to get device node\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (of_property_read_u32(root_node, "nvram-ES", &board_revision)) {
|
||||
DHD_ERROR(("No board revision property in dtsi\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
DHD_INFO(("Board revision:%d\n", board_revision));
|
||||
|
||||
if (board_revision == 1) {
|
||||
strcat(nv_path, "_ES10");
|
||||
DHD_INFO(("Mached Board revision ES10: nvram name:%s\n", nv_path));
|
||||
}
|
||||
|
||||
}
|
||||
#endif /* SUPPORT_MULTIPLE_BOARD_REVISION */
|
||||
|
||||
/* Weak functions that can be overridden in Platform specific implementation */
|
||||
char* __attribute__ ((weak)) dhd_get_device_dt_name(void)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
uint32 __attribute__ ((weak)) dhd_plat_get_info_size(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int __attribute__ ((weak)) dhd_plat_pcie_register_event(void *plat_info,
|
||||
struct pci_dev *pdev, dhd_pcie_event_cb_t pfn)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void __attribute__ ((weak)) dhd_plat_pcie_deregister_event(void *plat_info)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
void __attribute__ ((weak)) dhd_plat_l1ss_ctrl(bool ctrl)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
void __attribute__ ((weak)) dhd_plat_l1_exit_io(void)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
void __attribute__ ((weak)) dhd_plat_l1_exit(void)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
void __attribute__ ((weak)) dhd_plat_report_bh_sched(void *plat_info, int resched)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int __attribute__ ((weak)) dhd_plat_pcie_suspend(void *plat_info)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int __attribute__ ((weak)) dhd_plat_pcie_resume(void *plat_info)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void __attribute__ ((weak)) dhd_plat_pcie_register_dump(void *plat_info)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
void __attribute__ ((weak)) dhd_plat_pin_dbg_show(void *plat_info)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
uint32 __attribute__ ((weak)) dhd_plat_get_rc_vendor_id(void)
|
||||
{
|
||||
return PCIE_RC_VENDOR_ID;
|
||||
}
|
||||
|
||||
uint32 __attribute__ ((weak)) dhd_plat_get_rc_device_id(void)
|
||||
{
|
||||
return PCIE_RC_DEVICE_ID;
|
||||
}
|
||||
|
||||
uint16 __attribute__ ((weak)) dhd_plat_align_rxbuf_size(uint16 rxbufpost_sz)
|
||||
{
|
||||
return rxbufpost_sz;
|
||||
}
|
||||
|
||||
int
|
||||
__attribute__ ((weak)) dhd_get_platform_naming_for_nvram_clmblob_file(download_type_t component,
|
||||
char *file_name)
|
||||
{
|
||||
return BCME_ERROR;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* DHD Linux header file - contains private structure definition of the Linux specific layer
|
||||
*
|
||||
* Copyright (C) 2020, Broadcom.
|
||||
* Copyright (C) 2022, Broadcom.
|
||||
*
|
||||
* Unless you and Broadcom execute a separate written software license
|
||||
* agreement governing use of this software, this software is licensed to you
|
||||
|
|
@ -41,7 +41,6 @@
|
|||
#ifdef CONFIG_HAS_WAKELOCK
|
||||
#include <linux/pm_wakeup.h>
|
||||
#endif /* CONFIG_HAS_WAKELOCK */
|
||||
#include <linux/wakelock.h>
|
||||
#include <dngl_stats.h>
|
||||
#include <dhd.h>
|
||||
#include <dhd_dbg.h>
|
||||
|
|
@ -54,9 +53,15 @@
|
|||
#include <dhd_flowring.h>
|
||||
#endif /* PCIE_FULL_DONGLE */
|
||||
|
||||
#ifdef DHD_QOS_ON_SOCK_FLOW
|
||||
struct dhd_sock_qos_info;
|
||||
#endif /* DHD_QOS_ON_SOCK_FLOW */
|
||||
#ifdef RX_PKT_POOL
|
||||
#define RX_PKTPOOL_RESCHED_DELAY_MS 500u
|
||||
#define RX_PKTPOOL_FETCH_MAX_ATTEMPTS 10u
|
||||
typedef struct pkt_pool {
|
||||
struct sk_buff_head skb_q ____cacheline_aligned;
|
||||
uint32 max_size;
|
||||
uint16 rxbuf_sz;
|
||||
} pkt_pool_t;
|
||||
#endif /* RX_PKT_POOL */
|
||||
|
||||
/*
|
||||
* Do not include this header except for the dhd_linux.c dhd_linux_sysfs.c
|
||||
|
|
@ -74,8 +79,9 @@ typedef struct dhd_info {
|
|||
wifi_adapter_info_t *adapter; /* adapter information, interrupt, fw path etc. */
|
||||
char fw_path[PATH_MAX]; /* path to firmware image */
|
||||
char nv_path[PATH_MAX]; /* path to nvram vars file */
|
||||
char clm_path[PATH_MAX]; /* path to clm vars file */
|
||||
char clm_path[PATH_MAX]; /* path to CLM data */
|
||||
char conf_path[PATH_MAX]; /* path to config vars file */
|
||||
char sig_path[PATH_MAX]; /* path to rtecdc.sig file */
|
||||
#ifdef DHD_UCODE_DOWNLOAD
|
||||
char uc_path[PATH_MAX]; /* path to ucode image */
|
||||
#endif /* DHD_UCODE_DOWNLOAD */
|
||||
|
|
@ -96,18 +102,10 @@ typedef struct dhd_info {
|
|||
wait_queue_head_t d3ack_wait;
|
||||
wait_queue_head_t dhd_bus_busy_state_wait;
|
||||
wait_queue_head_t dmaxfer_wait;
|
||||
#ifdef BT_OVER_PCIE
|
||||
wait_queue_head_t quiesce_wait;
|
||||
#endif /* BT_OVER_PCIE */
|
||||
uint32 default_wd_interval;
|
||||
|
||||
timer_list_compat_t timer;
|
||||
bool wd_timer_valid;
|
||||
#ifdef DHD_PCIE_RUNTIMEPM
|
||||
timer_list_compat_t rpm_timer;
|
||||
bool rpm_timer_valid;
|
||||
tsk_ctl_t thr_rpm_ctl;
|
||||
#endif /* DHD_PCIE_RUNTIMEPM */
|
||||
struct tasklet_struct tasklet;
|
||||
spinlock_t sdlock;
|
||||
spinlock_t txqlock;
|
||||
|
|
@ -129,32 +127,35 @@ typedef struct dhd_info {
|
|||
|
||||
/* Wakelocks */
|
||||
#if defined(CONFIG_HAS_WAKELOCK)
|
||||
struct wakeup_source wl_wifi; /* Wifi wakelock */
|
||||
struct wakeup_source wl_rxwake; /* Wifi rx wakelock */
|
||||
struct wakeup_source wl_ctrlwake; /* Wifi ctrl wakelock */
|
||||
struct wakeup_source wl_wdwake; /* Wifi wd wakelock */
|
||||
struct wakeup_source wl_evtwake; /* Wifi event wakelock */
|
||||
struct wakeup_source wl_pmwake; /* Wifi pm handler wakelock */
|
||||
struct wakeup_source wl_txflwake; /* Wifi tx flow wakelock */
|
||||
struct wakeup_source *wl_wifi; /* Wifi wakelock */
|
||||
struct wakeup_source *wl_rxwake; /* Wifi rx wakelock */
|
||||
struct wakeup_source *wl_ctrlwake; /* Wifi ctrl wakelock */
|
||||
struct wakeup_source *wl_wdwake; /* Wifi wd wakelock */
|
||||
struct wakeup_source *wl_evtwake; /* Wifi event wakelock */
|
||||
struct wakeup_source *wl_pmwake; /* Wifi pm handler wakelock */
|
||||
struct wakeup_source *wl_txflwake; /* Wifi tx flow wakelock */
|
||||
#ifdef BCMPCIE_OOB_HOST_WAKE
|
||||
struct wakeup_source wl_intrwake; /* Host wakeup wakelock */
|
||||
struct wakeup_source *wl_intrwake; /* Host wakeup wakelock */
|
||||
#endif /* BCMPCIE_OOB_HOST_WAKE */
|
||||
#ifdef DHD_USE_SCAN_WAKELOCK
|
||||
struct wakeup_source wl_scanwake; /* Wifi scan wakelock */
|
||||
struct wakeup_source *wl_scanwake; /* Wifi scan wakelock */
|
||||
#endif /* DHD_USE_SCAN_WAKELOCK */
|
||||
struct wakeup_source wl_nanwake; /* NAN wakelock */
|
||||
struct wakeup_source *wl_nanwake; /* NAN wakelock */
|
||||
#endif /* CONFIG_HAS_WAKELOCK */
|
||||
|
||||
struct wake_lock rx_wakelock;
|
||||
#if defined(OEM_ANDROID)
|
||||
/* net_device interface lock, prevent race conditions among net_dev interface
|
||||
* calls and wifi_on or wifi_off
|
||||
*/
|
||||
struct mutex dhd_net_if_mutex;
|
||||
struct mutex dhd_suspend_mutex;
|
||||
#if defined(PKT_FILTER_SUPPORT) && defined(APF)
|
||||
#if defined(APF)
|
||||
struct mutex dhd_apf_mutex;
|
||||
#endif /* PKT_FILTER_SUPPORT && APF */
|
||||
#endif /* APF */
|
||||
#else
|
||||
#if defined(APF)
|
||||
struct mutex dhd_apf_mutex;
|
||||
#endif /* APF */
|
||||
#endif /* OEM_ANDROID */
|
||||
spinlock_t wakelock_spinlock;
|
||||
spinlock_t wakelock_evt_spinlock;
|
||||
|
|
@ -254,6 +255,11 @@ typedef struct dhd_info {
|
|||
struct work_struct tx_dispatcher_work;
|
||||
struct work_struct rx_compl_dispatcher_work;
|
||||
|
||||
/* Emergency queue to hold pkts when flow control is enabled and
|
||||
* same pkts will be posted back to the dongle till flow control is disabled.
|
||||
*/
|
||||
struct sk_buff_head rx_emerge_queue ____cacheline_aligned;
|
||||
|
||||
/* Number of times DPC Tasklet ran */
|
||||
uint32 dhd_dpc_cnt;
|
||||
/* Number of times NAPI processing got scheduled */
|
||||
|
|
@ -352,7 +358,12 @@ typedef struct dhd_info {
|
|||
uint32 *rxc_hist[HIST_BIN_SIZE];
|
||||
struct kobject dhd_lb_kobj;
|
||||
bool dhd_lb_candidacy_override;
|
||||
enum cpuhp_state dhd_cpuhp_state;
|
||||
#endif /* DHD_LB */
|
||||
|
||||
/* DPC bounds sysfs */
|
||||
struct kobject dhd_dpc_bounds_kobj;
|
||||
|
||||
#if defined(DNGL_AXI_ERROR_LOGGING) && defined(DHD_USE_WQ_FOR_DNGL_AXI_ERROR)
|
||||
struct work_struct axi_error_dispatcher_work;
|
||||
#endif /* DNGL_AXI_ERROR_LOGGING && DHD_USE_WQ_FOR_DNGL_AXI_ERROR */
|
||||
|
|
@ -364,24 +375,20 @@ typedef struct dhd_info {
|
|||
#endif /* DHD_USE_KTHREAD_FOR_LOGTRACE */
|
||||
#endif /* SHOW_LOGTRACE */
|
||||
|
||||
#ifdef BTLOG
|
||||
struct work_struct bt_log_dispatcher_work;
|
||||
#endif /* SHOW_LOGTRACE */
|
||||
#ifdef EWP_EDL
|
||||
struct delayed_work edl_dispatcher_work;
|
||||
#endif
|
||||
#if defined(WLAN_ACCEL_BOOT)
|
||||
int fs_check_retry;
|
||||
struct delayed_work wl_accel_work;
|
||||
bool wl_accel_force_reg_on;
|
||||
bool wl_accel_boot_on_done;
|
||||
#endif
|
||||
#if defined(BCM_DNGL_EMBEDIMAGE) || defined(BCM_REQUEST_FW)
|
||||
#if defined(BCMDBUS)
|
||||
struct task_struct *fw_download_task;
|
||||
struct semaphore fw_download_lock;
|
||||
bool fw_download_thread_exit;
|
||||
#endif /* BCMDBUS */
|
||||
#endif /* defined(BCM_DNGL_EMBEDIMAGE) || defined(BCM_REQUEST_FW) */
|
||||
uint32 flag_kobj; /* Add for duplicate kobj processing */
|
||||
struct kobject dhd_kobj;
|
||||
timer_list_compat_t timesync_timer;
|
||||
#if defined(BT_OVER_SDIO)
|
||||
|
|
@ -397,7 +404,7 @@ typedef struct dhd_info {
|
|||
uint host_radiotap_conv;
|
||||
#endif /* HOST_RADIOTAP_CONV */
|
||||
#endif /* WL_MONITOR */
|
||||
#if defined (BT_OVER_SDIO)
|
||||
#if defined(BT_OVER_SDIO)
|
||||
struct mutex bus_user_lock; /* lock for sdio bus apis shared between WLAN & BT */
|
||||
int bus_user_count; /* User counts of sdio bus shared between WLAN & BT */
|
||||
#endif /* BT_OVER_SDIO */
|
||||
|
|
@ -408,27 +415,13 @@ typedef struct dhd_info {
|
|||
struct workqueue_struct *tx_wq;
|
||||
struct workqueue_struct *rx_wq;
|
||||
#endif /* DHD_PCIE_NATIVE_RUNTIMEPM */
|
||||
#ifdef BTLOG
|
||||
struct sk_buff_head bt_log_queue ____cacheline_aligned;
|
||||
#endif /* BTLOG */
|
||||
#ifdef PCIE_INB_DW
|
||||
wait_queue_head_t ds_exit_wait;
|
||||
#endif /* PCIE_INB_DW */
|
||||
#ifdef DHD_DEBUG_UART
|
||||
bool duart_execute;
|
||||
#endif /* DHD_DEBUG_UART */
|
||||
#ifdef BT_OVER_PCIE
|
||||
struct mutex quiesce_flr_lock;
|
||||
struct mutex quiesce_lock;
|
||||
enum dhd_bus_quiesce_state dhd_quiesce_state;
|
||||
#endif /* BT_OVER_PCIE */
|
||||
struct mutex logdump_lock;
|
||||
#if defined(GDB_PROXY) && defined(PCIE_FULL_DONGLE) && defined(BCMINTERNAL)
|
||||
/* Root directory for GDB Proxy's (proc)fs files, used by first (default) interface */
|
||||
struct proc_dir_entry *gdb_proxy_fs_root;
|
||||
/* Name of procfs root directory */
|
||||
char gdb_proxy_fs_root_name[100];
|
||||
#endif /* defined(GDB_PROXY) && defined(PCIE_FULL_DONGLE) && defined(BCMINTERNAL) */
|
||||
#if defined(DHD_MQ) && defined(DHD_MQ_STATS)
|
||||
uint64 pktcnt_qac_histo[MQ_MAX_QUEUES][AC_COUNT];
|
||||
uint64 pktcnt_per_ac[AC_COUNT];
|
||||
|
|
@ -436,19 +429,35 @@ typedef struct dhd_info {
|
|||
#endif /* DHD_MQ && DHD_MQ_STATS */
|
||||
/* indicates mem_dump was scheduled as work queue or called directly */
|
||||
bool scheduled_memdump;
|
||||
#ifdef DHD_PKTTS
|
||||
bool latency; /* pktts enab flag */
|
||||
pktts_flow_t config[PKTTS_CONFIG_MAX]; /* pktts user config */
|
||||
#endif /* DHD_PKTTS */
|
||||
struct work_struct dhd_hang_process_work;
|
||||
#ifdef DHD_HP2P
|
||||
spinlock_t hp2p_lock;
|
||||
#endif /* DHD_HP2P */
|
||||
#ifdef DHD_QOS_ON_SOCK_FLOW
|
||||
struct dhd_sock_qos_info *psk_qos;
|
||||
#ifdef WL_CFGVENDOR_SEND_ALERT_EVENT
|
||||
struct work_struct dhd_alert_process_work;
|
||||
#endif /* WL_CFGVENDOR_SEND_ALERT_EVENT */
|
||||
#ifdef RX_PKT_POOL
|
||||
pkt_pool_t rx_pkt_pool;
|
||||
tsk_ctl_t rx_pktpool_thread;
|
||||
#endif
|
||||
#if defined(DHD_FILE_DUMP_EVENT) && defined(DHD_FW_COREDUMP)
|
||||
osl_atomic_t dump_status;
|
||||
struct work_struct dhd_dump_proc_work;
|
||||
#endif /* DHD_FILE_DUMP_EVENT && DHD_FW_COREDUMP */
|
||||
} dhd_info_t;
|
||||
|
||||
/** priv_link is the link between netdev and the dhdif and dhd_info structs. */
|
||||
typedef struct dhd_dev_priv {
|
||||
dhd_info_t * dhd; /* cached pointer to dhd_info in netdevice priv */
|
||||
dhd_if_t * ifp; /* cached pointer to dhd_if in netdevice priv */
|
||||
int ifidx; /* interface index */
|
||||
void * lkup;
|
||||
} dhd_dev_priv_t;
|
||||
|
||||
#define DHD_DEV_PRIV_SIZE (sizeof(dhd_dev_priv_t))
|
||||
#define DHD_DEV_PRIV(dev) ((dhd_dev_priv_t *)DEV_PRIV(dev))
|
||||
#define DHD_DEV_INFO(dev) (((dhd_dev_priv_t *)DEV_PRIV(dev))->dhd)
|
||||
#define DHD_DEV_IFP(dev) (((dhd_dev_priv_t *)DEV_PRIV(dev))->ifp)
|
||||
#define DHD_DEV_IFIDX(dev) (((dhd_dev_priv_t *)DEV_PRIV(dev))->ifidx)
|
||||
#define DHD_DEV_LKUP(dev) (((dhd_dev_priv_t *)DEV_PRIV(dev))->lkup)
|
||||
|
||||
#ifdef WL_MONITOR
|
||||
#define MONPKT_EXTRA_LEN 48u
|
||||
#endif /* WL_MONITOR */
|
||||
|
|
@ -495,21 +504,42 @@ int dhd_register_cpuhp_callback(dhd_info_t *dhd);
|
|||
int dhd_unregister_cpuhp_callback(dhd_info_t *dhd);
|
||||
#endif /* DHD_LB */
|
||||
|
||||
#if defined(DHD_CONTROL_PCIE_CPUCORE_WIFI_TURNON)
|
||||
#ifdef RX_PKT_POOL
|
||||
void dhd_rx_pktpool_init(dhd_info_t *dhd);
|
||||
void dhd_rx_pktpool_deinit(dhd_info_t *dhd);
|
||||
#endif /* RX_PKT_POOL */
|
||||
|
||||
#if defined(SET_PCIE_IRQ_CPU_CORE) || defined(DHD_CONTROL_PCIE_CPUCORE_WIFI_TURNON)
|
||||
void dhd_irq_set_affinity(dhd_pub_t *dhdp, const struct cpumask *cpumask);
|
||||
#endif /* DHD_CONTROL_PCIE_CPUCORE_WIFI_TURNON */
|
||||
#endif /* SET_PCIE_IRQ_CPU_CORE || DHD_CONTROL_PCIE_CPUCORE_WIFI_TURNON */
|
||||
|
||||
void dhd_flush_logtrace_process(dhd_info_t *dhd);
|
||||
|
||||
#ifdef DHD_SSSR_DUMP
|
||||
extern uint sssr_enab;
|
||||
extern uint fis_enab;
|
||||
#endif /* DHD_SSSR_DUMP */
|
||||
|
||||
#if defined(ANDROID_VERSION) && (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0))
|
||||
#define WAKELOCK_BACKPORT
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_HAS_WAKELOCK
|
||||
enum {
|
||||
WAKE_LOCK_SUSPEND, /* Prevent suspend */
|
||||
WAKE_LOCK_TYPE_COUNT
|
||||
};
|
||||
#define dhd_wake_lock_init(wakeup_source, type, name) wakeup_source_add(wakeup_source)
|
||||
#define dhd_wake_lock_destroy(wakeup_source) wakeup_source_remove(wakeup_source)
|
||||
#if ((LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0)) || defined(WAKELOCK_BACKPORT))
|
||||
#define dhd_wake_lock_init(wakeup_source, dev, name) \
|
||||
do { \
|
||||
wakeup_source = wakeup_source_register(dev, name); \
|
||||
} while (0);
|
||||
#else
|
||||
#define dhd_wake_lock_init(wakeup_source, dev, name) \
|
||||
do { \
|
||||
wakeup_source = wakeup_source_register(name); \
|
||||
} while (0);
|
||||
#endif /* LINUX_VERSION >= 5.4.0 */
|
||||
#define dhd_wake_lock_destroy(wakeup_source) \
|
||||
do { \
|
||||
wakeup_source_unregister(wakeup_source); \
|
||||
} while (0);
|
||||
#define dhd_wake_lock(wakeup_source) __pm_stay_awake(wakeup_source)
|
||||
#define dhd_wake_unlock(wakeup_source) __pm_relax(wakeup_source)
|
||||
#define dhd_wake_lock_active(wakeup_source) ((wakeup_source)->active)
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* Expose some of the kernel scheduler routines
|
||||
*
|
||||
* Copyright (C) 2020, Broadcom.
|
||||
* Copyright (C) 2022, Broadcom.
|
||||
*
|
||||
* Unless you and Broadcom execute a separate written software license
|
||||
* agreement governing use of this software, this software is licensed to you
|
||||
|
|
@ -31,11 +31,24 @@
|
|||
int setScheduler(struct task_struct *p, int policy, struct sched_param *param)
|
||||
{
|
||||
int rc = 0;
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 9, 0))
|
||||
sched_set_fifo_low(p);
|
||||
#else
|
||||
|
||||
#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 9, 0))
|
||||
rc = sched_setscheduler(p, policy, param);
|
||||
#endif
|
||||
#else
|
||||
switch (policy) {
|
||||
case SCHED_FIFO:
|
||||
sched_set_fifo(p);
|
||||
break;
|
||||
case SCHED_RR:
|
||||
sched_set_fifo_low(p);
|
||||
break;
|
||||
case SCHED_NORMAL:
|
||||
default:
|
||||
sched_set_normal(p, PRIO_TO_NICE(param->sched_priority));
|
||||
break;
|
||||
}
|
||||
#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(5, 9, 0)) */
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
64
drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_linux_sock_qos.h
Executable file → Normal file
64
drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_linux_sock_qos.h
Executable file → Normal file
|
|
@ -4,7 +4,7 @@
|
|||
* Provides type definitions and function prototypes to call into
|
||||
* DHD's QOS on Socket Flow module.
|
||||
*
|
||||
* Copyright (C) 2020, Broadcom.
|
||||
* Copyright (C) 2022, Broadcom.
|
||||
*
|
||||
* Unless you and Broadcom execute a separate written software license
|
||||
* agreement governing use of this software, this software is licensed to you
|
||||
|
|
@ -32,87 +32,45 @@
|
|||
|
||||
struct dhd_sock_flow_info;
|
||||
|
||||
#if defined(DHD_QOS_ON_SOCK_FLOW)
|
||||
#define QOS_SAMPLING_INTVL_MS 100
|
||||
/* Feature Enabed original implementation */
|
||||
int dhd_init_sock_flows_buf(dhd_info_t *dhd, uint watchdog_ms);
|
||||
int dhd_deinit_sock_flows_buf(dhd_info_t *dhd);
|
||||
void dhd_update_sock_flows(dhd_info_t *dhd, struct sk_buff *skb);
|
||||
void dhd_analyze_sock_flows(dhd_info_t *dhd, uint32 watchdog_ms);
|
||||
|
||||
/* sysfs call backs */
|
||||
unsigned long dhd_sock_qos_get_status(dhd_info_t *dhd);
|
||||
void dhd_sock_qos_set_status(dhd_info_t *dhd, unsigned long on_off);
|
||||
ssize_t dhd_sock_qos_show_stats(dhd_info_t *dhd, char *buf, ssize_t sz);
|
||||
void dhd_sock_qos_clear_stats(dhd_info_t *dhd);
|
||||
unsigned long dhd_sock_qos_get_force_upgrade(dhd_info_t *dhd);
|
||||
void dhd_sock_qos_set_force_upgrade(dhd_info_t *dhd, unsigned long force_upgrade);
|
||||
int dhd_sock_qos_get_numfl_upgrd_thresh(dhd_info_t *dhd);
|
||||
void dhd_sock_qos_set_numfl_upgrd_thresh(dhd_info_t *dhd, int upgrade_thresh);
|
||||
void dhd_sock_qos_get_avgpktsize_thresh(dhd_info_t *dhd,
|
||||
unsigned long *avgpktsize_low,
|
||||
unsigned long *avgpktsize_high);
|
||||
void dhd_sock_qos_set_avgpktsize_thresh(dhd_info_t *dhd,
|
||||
unsigned long avgpktsize_low,
|
||||
unsigned long avgpktsize_high);
|
||||
void dhd_sock_qos_get_numpkts_thresh(dhd_info_t *dhd,
|
||||
unsigned long *numpkts_low,
|
||||
unsigned long *numpkts_high);
|
||||
void dhd_sock_qos_set_numpkts_thresh(dhd_info_t *dhd,
|
||||
unsigned long numpkts_low,
|
||||
unsigned long numpkts_high);
|
||||
void dhd_sock_qos_get_detectcnt_thresh(dhd_info_t *dhd,
|
||||
unsigned char *detectcnt_inc,
|
||||
unsigned char *detectcnt_dec);
|
||||
void dhd_sock_qos_set_detectcnt_thresh(dhd_info_t *dhd,
|
||||
unsigned char detectcnt_inc,
|
||||
unsigned char detectcnt_dec);
|
||||
int dhd_sock_qos_get_detectcnt_upgrd_thresh(dhd_info_t *dhd);
|
||||
void dhd_sock_qos_set_detectcnt_upgrd_thresh(dhd_info_t *dhd,
|
||||
unsigned char detect_upgrd_thresh);
|
||||
int dhd_sock_qos_get_maxfl(dhd_info_t *dhd);
|
||||
void dhd_sock_qos_set_maxfl(dhd_info_t *dhd, unsigned int maxfl);
|
||||
|
||||
/* Update from Bus Layer */
|
||||
void dhd_sock_qos_update_bus_flowid(dhd_info_t *dhd, void *pktbuf,
|
||||
uint32 bus_flow_id);
|
||||
|
||||
#else
|
||||
/* Feature Disabled dummy implementations */
|
||||
|
||||
inline int dhd_init_sock_flows_buf(dhd_info_t *dhd, uint watchdog_ms)
|
||||
static inline int
|
||||
dhd_init_sock_flows_buf(dhd_info_t *dhd, uint watchdog_ms)
|
||||
{
|
||||
BCM_REFERENCE(dhd);
|
||||
return BCME_UNSUPPORTED;
|
||||
}
|
||||
|
||||
inline int dhd_deinit_sock_flows_buf(dhd_info_t *dhd)
|
||||
static inline int
|
||||
dhd_deinit_sock_flows_buf(dhd_info_t *dhd)
|
||||
{
|
||||
BCM_REFERENCE(dhd);
|
||||
return BCME_UNSUPPORTED;
|
||||
}
|
||||
|
||||
inline void dhd_update_sock_flows(dhd_info_t *dhd, struct sk_buff *skb)
|
||||
static inline void
|
||||
dhd_update_sock_flows(dhd_info_t *dhd, struct sk_buff *skb)
|
||||
{
|
||||
BCM_REFERENCE(dhd);
|
||||
BCM_REFERENCE(skb);
|
||||
return;
|
||||
}
|
||||
|
||||
inline void dhd_analyze_sock_flows(dhd_info_t *dhd, uint32 watchdog_ms)
|
||||
static inline void
|
||||
dhd_analyze_sock_flows(dhd_info_t *dhd, uint32 watchdog_ms)
|
||||
{
|
||||
BCM_REFERENCE(dhd);
|
||||
BCM_REFERENCE(dhd_watchdog_ms);
|
||||
return;
|
||||
}
|
||||
|
||||
inline void dhd_sock_qos_update_bus_flowid(dhd_info_t *dhd, void *pktbuf,
|
||||
static inline void
|
||||
dhd_sock_qos_update_bus_flowid(dhd_info_t *dhd, void *pktbuf,
|
||||
uint32 bus_flow_id)
|
||||
{
|
||||
BCM_REFERENCE(dhd);
|
||||
BCM_REFERENCE(pktbuf);
|
||||
BCM_REFERENCE(bus_flow_id);
|
||||
}
|
||||
#endif /* End of !DHD_QOS_ON_SOCK_FLOW */
|
||||
|
||||
#endif /* _DHD_LINUX_TPA_H_ */
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* Broadcom Dongle Host Driver (DHD),
|
||||
* Linux-specific network interface for transmit(tx) path
|
||||
*
|
||||
* Copyright (C) 2022, Broadcom.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*
|
||||
* <<Broadcom-WL-IPTag/Open:>>
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#ifndef _dhd_linux_tx_h_
|
||||
#define _dhd_linux_tx_h_
|
||||
void dhd_tx_stop_queues(struct net_device *net);
|
||||
void dhd_tx_start_queues(struct net_device *net);
|
||||
int BCMFASTPATH(__dhd_sendpkt)(dhd_pub_t *dhdp, int ifidx, void *pktbuf);
|
||||
int BCMFASTPATH(dhd_sendpkt)(dhd_pub_t *dhdp, int ifidx, void *pktbuf);
|
||||
#ifdef DHD_MQ
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
|
||||
uint16
|
||||
BCMFASTPATH(dhd_select_queue)(struct net_device *net, struct sk_buff *skb,
|
||||
void *accel_priv, select_queue_fallback_t fallback);
|
||||
#else
|
||||
uint16
|
||||
BCMFASTPATH(dhd_select_queue)(struct net_device *net, struct sk_buff *skb);
|
||||
#endif /* LINUX_VERSION_CODE */
|
||||
#endif /* DHD_MQ */
|
||||
netdev_tx_t BCMFASTPATH(dhd_start_xmit)(struct sk_buff *skb, struct net_device *net);
|
||||
void dhd_txflowcontrol(dhd_pub_t *dhdp, int ifidx, bool state);
|
||||
void dhd_txcomplete(dhd_pub_t *dhdp, void *txp, bool success);
|
||||
void dhd_os_tx_completion_wake(dhd_pub_t *dhd);
|
||||
void dhd_os_sdlock_txq(dhd_pub_t *pub);
|
||||
void dhd_os_sdunlock_txq(dhd_pub_t *pub);
|
||||
#endif /* _dhd_linux_tx_h_ */
|
||||
|
|
@ -2,7 +2,7 @@
|
|||
* Broadcom Dongle Host Driver (DHD), Generic work queue framework
|
||||
* Generic interface to handle dhd deferred work events
|
||||
*
|
||||
* Copyright (C) 2020, Broadcom.
|
||||
* Copyright (C) 2022, Broadcom.
|
||||
*
|
||||
* Unless you and Broadcom execute a separate written software license
|
||||
* agreement governing use of this software, this software is licensed to you
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
* Broadcom Dongle Host Driver (DHD), Generic work queue framework
|
||||
* Generic interface to handle dhd deferred work events
|
||||
*
|
||||
* Copyright (C) 2020, Broadcom.
|
||||
* Copyright (C) 2022, Broadcom.
|
||||
*
|
||||
* Unless you and Broadcom execute a separate written software license
|
||||
* agreement governing use of this software, this software is licensed to you
|
||||
|
|
@ -47,15 +47,14 @@ enum _wq_event {
|
|||
DHD_WQ_WORK_GET_BIGDATA_AP,
|
||||
DHD_WQ_WORK_SOC_RAM_DUMP,
|
||||
DHD_WQ_WORK_SOC_RAM_COLLECT,
|
||||
#ifdef DHD_ERPOM
|
||||
DHD_WQ_WORK_ERROR_RECOVERY,
|
||||
#endif /* DHD_ERPOM */
|
||||
DHD_WQ_WORK_H2D_CONSOLE_TIME_STAMP_MATCH,
|
||||
DHD_WQ_WORK_AXI_ERROR_DUMP,
|
||||
DHD_WQ_WORK_CTO_RECOVERY,
|
||||
#ifdef DHD_UPDATE_INTF_MAC
|
||||
DHD_WQ_WORK_IF_UPDATE,
|
||||
#endif /* DHD_UPDATE_INTF_MAC */
|
||||
DHD_WQ_WORK_AML_IOVAR,
|
||||
DHD_WQ_WORK_NDEV_UPD_FEATURES,
|
||||
DHD_MAX_WQ_EVENTS
|
||||
};
|
||||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,402 @@
|
|||
/*
|
||||
* log_dump - debugability support for dumping logs to file - header file
|
||||
*
|
||||
* Copyright (C) 2022, Broadcom.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*
|
||||
* <<Broadcom-WL-IPTag/Open:>>
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#ifndef __DHD_LOG_DUMP_H__
|
||||
#define __DHD_LOG_DUMP_H__
|
||||
|
||||
#ifdef DHD_LOG_DUMP
|
||||
|
||||
#include <dhd.h>
|
||||
|
||||
#define LOG_DUMP_MAGIC 0xDEB3DEB3
|
||||
#ifdef EWP_ECNTRS_LOGGING
|
||||
#define ECNTR_RING_ID 0xECDB
|
||||
#define ECNTR_RING_NAME "ewp_ecntr_ring"
|
||||
#endif /* EWP_ECNTRS_LOGGING */
|
||||
|
||||
#ifdef EWP_RTT_LOGGING
|
||||
#define RTT_RING_ID 0xADCD
|
||||
#define RTT_RING_NAME "ewp_rtt_ring"
|
||||
#endif /* EWP_ECNTRS_LOGGING */
|
||||
|
||||
#ifdef EWP_BCM_TRACE
|
||||
#define BCM_TRACE_RING_ID 0xBCBC
|
||||
#define BCM_TRACE_RING_NAME "ewp_bcm_trace_ring"
|
||||
#endif /* EWP_BCM_TRACE */
|
||||
|
||||
#define DHD_LOG_DUMP_MAX_TEMP_BUFFER_SIZE 512
|
||||
#define DHD_LOG_DUMP_MAX_TAIL_FLUSH_SIZE (80 * 1024)
|
||||
#define DHD_LOG_DUMP_TS_MULTIPLIER_VALUE 60
|
||||
#define DHD_LOG_DUMP_TS_FMT_YYMMDDHHMMSSMSMS "%02d-%02d-%02d/%02d:%02d:%02d.%04lu"
|
||||
#define DHD_LOG_DUMP_TS_FMT_YYMMDDHHMMSS "%02d%02d%02d%02d%02d%02d"
|
||||
#define DHD_DEBUG_DUMP_TYPE "debug_dump"
|
||||
#define DEBUG_DUMP_TRIGGER_INTERVAL_SEC 4
|
||||
|
||||
#ifndef _DHD_LOG_DUMP_DEFINITIONS_
|
||||
#define _DHD_LOG_DUMP_DEFINITIONS_
|
||||
#define GENERAL_LOG_HDR "\n-------------------- General log ---------------------------\n"
|
||||
#define PRESERVE_LOG_HDR "\n-------------------- Preserve log ---------------------------\n"
|
||||
#define SPECIAL_LOG_HDR "\n-------------------- Special log ---------------------------\n"
|
||||
#define DHD_DUMP_LOG_HDR "\n-------------------- 'dhd dump' log -----------------------\n"
|
||||
#define EXT_TRAP_LOG_HDR "\n-------------------- Extended trap data -------------------\n"
|
||||
#define HEALTH_CHK_LOG_HDR "\n-------------------- Health check data --------------------\n"
|
||||
#ifdef DHD_DUMP_PCIE_RINGS
|
||||
#define RING_DUMP_HDR "\n-------------------- Ring dump --------------------\n"
|
||||
#endif /* DHD_DUMP_PCIE_RINGS */
|
||||
#define DHD_LOG_DUMP_DLD(fmt, ...) \
|
||||
dhd_log_dump_write(DLD_BUF_TYPE_GENERAL, NULL, 0, fmt, ##__VA_ARGS__)
|
||||
#define DHD_LOG_DUMP_DLD_EX(fmt, ...) \
|
||||
dhd_log_dump_write(DLD_BUF_TYPE_SPECIAL, NULL, 0, fmt, ##__VA_ARGS__)
|
||||
#define DHD_LOG_DUMP_DLD_PRSRV(fmt, ...) \
|
||||
dhd_log_dump_write(DLD_BUF_TYPE_PRESERVE, NULL, 0, fmt, ##__VA_ARGS__)
|
||||
#endif /* !_DHD_LOG_DUMP_DEFINITIONS_ */
|
||||
|
||||
#ifndef DHD_LOG_DUMP_RING_DEFINITIONS
|
||||
#define DHD_LOG_DUMP_RING_DEFINITIONS
|
||||
#ifdef DHD_DEBUGABILITY_LOG_DUMP_RING
|
||||
/* Enabled DHD_DEBUGABILITY_LOG_DUMP_RING */
|
||||
#define DHD_DBG_RING(fmt, ...) \
|
||||
dhd_dbg_ring_write(DRIVER_LOG_RING_ID, NULL, 0, fmt, ##__VA_ARGS__)
|
||||
#define DHD_DBG_RING_EX(fmt, ...) \
|
||||
dhd_dbg_ring_write(FW_VERBOSE_RING_ID, NULL, 0, fmt, ##__VA_ARGS__)
|
||||
#define DHD_DBG_RING_ROAM(fmt, ...) \
|
||||
dhd_dbg_ring_write(ROAM_STATS_RING_ID, NULL, 0, fmt, ##__VA_ARGS__)
|
||||
|
||||
#define DHD_LOG_DUMP_WRITE DHD_DBG_RING
|
||||
#define DHD_LOG_DUMP_WRITE_EX DHD_DBG_RING_EX
|
||||
#define DHD_LOG_DUMP_WRITE_PRSRV DHD_DBG_RING_EX
|
||||
#define DHD_LOG_DUMP_WRITE_ROAM DHD_DBG_RING_ROAM
|
||||
|
||||
#define DHD_PREFIX_TS "[%s][%s] ", \
|
||||
OSL_GET_RTCTIME(), dhd_log_dump_get_timestamp()
|
||||
#define DHD_PREFIX_TS_FN "[%s][%s] %s: ", \
|
||||
OSL_GET_RTCTIME(), dhd_log_dump_get_timestamp(), __func__
|
||||
#define DHD_LOG_DUMP_WRITE_TS DHD_DBG_RING(DHD_PREFIX_TS)
|
||||
#define DHD_LOG_DUMP_WRITE_TS_FN DHD_DBG_RING(DHD_PREFIX_TS_FN)
|
||||
#define DHD_LOG_DUMP_WRITE_EX_TS DHD_DBG_RING_EX(DHD_PREFIX_TS)
|
||||
#define DHD_LOG_DUMP_WRITE_EX_TS_FN DHD_DBG_RING_EX(DHD_PREFIX_TS_FN)
|
||||
#define DHD_LOG_DUMP_WRITE_PRSRV_TS DHD_DBG_RING_EX(DHD_PREFIX_TS)
|
||||
#define DHD_LOG_DUMP_WRITE_PRSRV_TS_FN DHD_DBG_RING_EX(DHD_PREFIX_TS_FN)
|
||||
#define DHD_LOG_DUMP_WRITE_ROAM_TS DHD_DBG_RING_ROAM(DHD_PREFIX_TS)
|
||||
#define DHD_LOG_DUMP_WRITE_ROAM_TS_FN DHD_DBG_RING_ROAM(DHD_PREFIX_TS_FN)
|
||||
#else
|
||||
/* Not enabled DHD_DEBUGABILITY_LOG_DUMP_RING */
|
||||
#define DHD_LOG_DUMP_WRITE DHD_LOG_DUMP_DLD
|
||||
#define DHD_LOG_DUMP_WRITE_EX DHD_LOG_DUMP_DLD_EX
|
||||
#define DHD_LOG_DUMP_WRITE_PRSRV DHD_LOG_DUMP_DLD_PRSRV
|
||||
#define DHD_LOG_DUMP_WRITE_ROAM DHD_LOG_DUMP_DLD
|
||||
|
||||
#define DHD_PREFIX_TS "[%s]: ", dhd_log_dump_get_timestamp()
|
||||
#define DHD_PREFIX_TS_FN "[%s] %s: ", dhd_log_dump_get_timestamp(), __func__
|
||||
#define DHD_LOG_DUMP_WRITE_TS DHD_LOG_DUMP_DLD(DHD_PREFIX_TS)
|
||||
#define DHD_LOG_DUMP_WRITE_TS_FN DHD_LOG_DUMP_DLD(DHD_PREFIX_TS_FN)
|
||||
#define DHD_LOG_DUMP_WRITE_EX_TS DHD_LOG_DUMP_DLD_EX(DHD_PREFIX_TS)
|
||||
#define DHD_LOG_DUMP_WRITE_EX_TS_FN DHD_LOG_DUMP_DLD_EX(DHD_PREFIX_TS_FN)
|
||||
#define DHD_LOG_DUMP_WRITE_PRSRV_TS DHD_LOG_DUMP_DLD_PRSRV(DHD_PREFIX_TS)
|
||||
#define DHD_LOG_DUMP_WRITE_PRSRV_TS_FN DHD_LOG_DUMP_DLD_PRSRV(DHD_PREFIX_TS_FN)
|
||||
#define DHD_LOG_DUMP_WRITE_ROAM_TS DHD_LOG_DUMP_DLD(DHD_PREFIX_TS)
|
||||
#define DHD_LOG_DUMP_WRITE_ROAM_TS_FN DHD_LOG_DUMP_DLD(DHD_PREFIX_TS_FN)
|
||||
#endif /* DHD_DEBUGABILITY_LOG_DUMP_RING */
|
||||
#endif /* DHD_LOG_DUMP_RING_DEFINITIONS */
|
||||
|
||||
#define CONCISE_DUMP_BUFLEN 32 * 1024
|
||||
#define ECNTRS_LOG_HDR "\n-------------------- Ecounters log --------------------------\n"
|
||||
#ifdef DHD_STATUS_LOGGING
|
||||
#define STATUS_LOG_HDR "\n-------------------- Status log -----------------------\n"
|
||||
#endif /* DHD_STATUS_LOGGING */
|
||||
#define RTT_LOG_HDR "\n-------------------- RTT log --------------------------\n"
|
||||
#define BCM_TRACE_LOG_HDR "\n-------------------- BCM Trace log --------------------------\n"
|
||||
#define COOKIE_LOG_HDR "\n-------------------- Cookie List ----------------------------\n"
|
||||
#define DHD_PKTID_MAP_LOG_HDR "\n---------------- PKTID MAP log -----------------------\n"
|
||||
#define DHD_PKTID_UNMAP_LOG_HDR "\n------------------ PKTID UNMAP log -----------------------\n"
|
||||
#define PKTID_LOG_DUMP_FMT \
|
||||
"\nIndex \t\tTimestamp \tPktaddr(PA) \tPktid \tSize \tPkttype\n(Current=%d)\n"
|
||||
|
||||
/* 0: DLD_BUF_TYPE_GENERAL, 1: DLD_BUF_TYPE_PRESERVE
|
||||
* 2: DLD_BUF_TYPE_SPECIAL
|
||||
*/
|
||||
#define DLD_BUFFER_NUM 3
|
||||
|
||||
#ifndef CUSTOM_LOG_DUMP_BUFSIZE_MB
|
||||
#define CUSTOM_LOG_DUMP_BUFSIZE_MB 4 /* DHD_LOG_DUMP_BUF_SIZE 4 MB static memory in kernel */
|
||||
#endif /* CUSTOM_LOG_DUMP_BUFSIZE_MB */
|
||||
|
||||
#define LOG_DUMP_TOTAL_BUFSIZE (1024 * 1024 * CUSTOM_LOG_DUMP_BUFSIZE_MB)
|
||||
|
||||
/*
|
||||
* Below are different sections that use the prealloced buffer
|
||||
* and sum of the sizes of these should not cross LOG_DUMP_TOTAL_BUFSIZE
|
||||
*/
|
||||
#ifdef EWP_BCM_TRACE
|
||||
#define LOG_DUMP_GENERAL_MAX_BUFSIZE (192 * 1024 * CUSTOM_LOG_DUMP_BUFSIZE_MB)
|
||||
#define LOG_DUMP_BCM_TRACE_MAX_BUFSIZE (64 * 1024 * CUSTOM_LOG_DUMP_BUFSIZE_MB)
|
||||
#else
|
||||
#define LOG_DUMP_GENERAL_MAX_BUFSIZE (256 * 1024 * CUSTOM_LOG_DUMP_BUFSIZE_MB)
|
||||
#define LOG_DUMP_BCM_TRACE_MAX_BUFSIZE 0
|
||||
#endif /* EWP_BCM_TRACE */
|
||||
#define LOG_DUMP_PRESERVE_MAX_BUFSIZE (128 * 1024 * CUSTOM_LOG_DUMP_BUFSIZE_MB)
|
||||
#define LOG_DUMP_ECNTRS_MAX_BUFSIZE (256 * 1024 * CUSTOM_LOG_DUMP_BUFSIZE_MB)
|
||||
#define LOG_DUMP_RTT_MAX_BUFSIZE (256 * 1024 * CUSTOM_LOG_DUMP_BUFSIZE_MB)
|
||||
#define LOG_DUMP_FILTER_MAX_BUFSIZE (128 * 1024 * CUSTOM_LOG_DUMP_BUFSIZE_MB)
|
||||
|
||||
#if LOG_DUMP_TOTAL_BUFSIZE < (LOG_DUMP_GENERAL_MAX_BUFSIZE + \
|
||||
LOG_DUMP_PRESERVE_MAX_BUFSIZE + LOG_DUMP_ECNTRS_MAX_BUFSIZE + LOG_DUMP_RTT_MAX_BUFSIZE \
|
||||
+ LOG_DUMP_BCM_TRACE_MAX_BUFSIZE + LOG_DUMP_FILTER_MAX_BUFSIZE)
|
||||
#error "LOG_DUMP_TOTAL_BUFSIZE is lesser than sum of all rings"
|
||||
#endif
|
||||
|
||||
/* Special buffer is allocated as separately in prealloc */
|
||||
#define LOG_DUMP_SPECIAL_MAX_BUFSIZE (8 * 1024)
|
||||
|
||||
#define LOG_DUMP_MAX_FILESIZE (8 *1024 * 1024) /* 8 MB default */
|
||||
|
||||
#ifdef CONFIG_LOG_BUF_SHIFT
|
||||
/* 15% of kernel log buf size, if for example klog buf size is 512KB
|
||||
* 15% of 512KB ~= 80KB
|
||||
*/
|
||||
#define LOG_DUMP_KERNEL_TAIL_FLUSH_SIZE \
|
||||
(15 * ((1 << CONFIG_LOG_BUF_SHIFT)/100))
|
||||
#endif /* CONFIG_LOG_BUF_SHIFT */
|
||||
|
||||
#define LOG_DUMP_COOKIE_BUFSIZE 1024u
|
||||
#define DHD_PRINT_BUF_NAME_LEN 30
|
||||
|
||||
#ifdef DHD_SSSR_DUMP
|
||||
#define DUMP_SSSR_ATTR_START 2
|
||||
#define DUMP_SSSR_ATTR_COUNT 10
|
||||
|
||||
typedef enum {
|
||||
SSSR_C0_D11_BEFORE = 0,
|
||||
SSSR_C0_D11_AFTER = 1,
|
||||
SSSR_C1_D11_BEFORE = 2,
|
||||
SSSR_C1_D11_AFTER = 3,
|
||||
SSSR_C2_D11_BEFORE = 4,
|
||||
SSSR_C2_D11_AFTER = 5,
|
||||
SSSR_DIG_BEFORE = 6,
|
||||
SSSR_DIG_AFTER = 7
|
||||
} EWP_SSSR_DUMP;
|
||||
#endif /* DHD_SSSR_DUMP */
|
||||
|
||||
typedef enum {
|
||||
DLD_BUF_TYPE_GENERAL = 0,
|
||||
DLD_BUF_TYPE_PRESERVE = 1,
|
||||
DLD_BUF_TYPE_SPECIAL = 2,
|
||||
DLD_BUF_TYPE_ECNTRS = 3,
|
||||
DLD_BUF_TYPE_FILTER = 4,
|
||||
DLD_BUF_TYPE_ALL = 5
|
||||
} log_dump_type_t;
|
||||
|
||||
/*
|
||||
* XXX: Always add new enums at the end to compatible with parser,
|
||||
* also add new section in split_ret of EWP_config.py
|
||||
*/
|
||||
typedef enum {
|
||||
LOG_DUMP_SECTION_GENERAL = 0,
|
||||
LOG_DUMP_SECTION_ECNTRS,
|
||||
LOG_DUMP_SECTION_SPECIAL,
|
||||
LOG_DUMP_SECTION_DHD_DUMP,
|
||||
LOG_DUMP_SECTION_EXT_TRAP,
|
||||
LOG_DUMP_SECTION_HEALTH_CHK,
|
||||
LOG_DUMP_SECTION_PRESERVE,
|
||||
LOG_DUMP_SECTION_COOKIE,
|
||||
LOG_DUMP_SECTION_RING,
|
||||
LOG_DUMP_SECTION_STATUS,
|
||||
LOG_DUMP_SECTION_RTT,
|
||||
LOG_DUMP_SECTION_BCM_TRACE,
|
||||
LOG_DUMP_SECTION_PKTID_MAP_LOG,
|
||||
LOG_DUMP_SECTION_PKTID_UNMAP_LOG,
|
||||
LOG_DUMP_SECTION_TIMESTAMP,
|
||||
LOG_DUMP_SECTION_MAX
|
||||
} log_dump_section_type_t;
|
||||
|
||||
/* Each section in the debug_dump log file shall begin with a header */
|
||||
typedef struct {
|
||||
uint32 magic; /* 0xDEB3DEB3 */
|
||||
uint32 type; /* of type log_dump_section_type_t */
|
||||
uint64 timestamp;
|
||||
uint32 length; /* length of the section that follows */
|
||||
} log_dump_section_hdr_t;
|
||||
|
||||
#ifdef DHD_DEBUGABILITY_LOG_DUMP_RING
|
||||
struct dhd_dbg_ring_buf
|
||||
{
|
||||
void *dhd_pub;
|
||||
};
|
||||
extern struct dhd_dbg_ring_buf g_ring_buf;
|
||||
#endif /* DHD_DEBUGABILITY_LOG_DUMP_RING */
|
||||
|
||||
typedef struct dhd_debug_dump_ring_entry {
|
||||
log_dump_section_type_t type;
|
||||
uint32 debug_dump_ring;
|
||||
} dhd_debug_dump_ring_entry_t;
|
||||
|
||||
/* below structure describe ring buffer. */
|
||||
struct dhd_log_dump_buf
|
||||
{
|
||||
#if defined(LINUX) || defined(linux) || defined(ANDROID) || defined(OEM_ANDROID)
|
||||
spinlock_t lock;
|
||||
#endif
|
||||
void *dhd_pub;
|
||||
unsigned int enable;
|
||||
unsigned int wraparound;
|
||||
unsigned long max;
|
||||
unsigned int remain;
|
||||
char* present;
|
||||
char* front;
|
||||
char* buffer;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
char *hdr_str;
|
||||
log_dump_section_type_t sec_type;
|
||||
} dld_hdr_t;
|
||||
|
||||
extern void dhd_log_dump_write(int type, char *binary_data,
|
||||
int binary_len, const char *fmt, ...);
|
||||
void dhd_schedule_log_dump(dhd_pub_t *dhdp, void *type);
|
||||
void dhd_log_dump_trigger(dhd_pub_t *dhdp, int subcmd);
|
||||
void dhd_log_dump_vendor_trigger(dhd_pub_t *dhd_pub);
|
||||
|
||||
#ifdef DHD_DEBUGABILITY_DEBUG_DUMP
|
||||
int dhd_debug_dump_get_ring_num(int sec_type);
|
||||
#endif /* DHD_DEBUGABILITY_DEBUG_DUMP */
|
||||
int dhd_log_dump_ring_to_file(dhd_pub_t *dhdp, void *ring_ptr, void *file,
|
||||
unsigned long *file_posn, log_dump_section_hdr_t *sec_hdr, char *text_hdr,
|
||||
uint32 sec_type);
|
||||
int dhd_dump_debug_ring(dhd_pub_t *dhdp, void *ring_ptr, const void *user_buf,
|
||||
log_dump_section_hdr_t *sec_hdr, char *text_hdr, int buflen, uint32 sec_type);
|
||||
int dhd_log_dump_cookie_to_file(dhd_pub_t *dhdp, void *fp,
|
||||
const void *user_buf, unsigned long *f_pos);
|
||||
int dhd_log_dump_cookie(dhd_pub_t *dhdp, const void *user_buf);
|
||||
uint32 dhd_log_dump_cookie_len(dhd_pub_t *dhdp);
|
||||
int dhd_logdump_cookie_init(dhd_pub_t *dhdp, uint8 *buf, uint32 buf_size);
|
||||
void dhd_logdump_cookie_deinit(dhd_pub_t *dhdp);
|
||||
void dhd_logdump_cookie_save(dhd_pub_t *dhdp, char *cookie, char *type);
|
||||
int dhd_logdump_cookie_get(dhd_pub_t *dhdp, char *ret_cookie, uint32 buf_size);
|
||||
int dhd_logdump_cookie_count(dhd_pub_t *dhdp);
|
||||
int dhd_get_dld_log_dump(void *dev, dhd_pub_t *dhdp, const void *user_buf, void *fp,
|
||||
uint32 len, int type, void *pos);
|
||||
#if defined(BCMPCIE)
|
||||
int dhd_print_ext_trap_data(void *dev, dhd_pub_t *dhdp, const void *user_buf,
|
||||
void *fp, uint32 len, void *pos);
|
||||
uint32 dhd_get_ext_trap_len(void *ndev, dhd_pub_t *dhdp);
|
||||
#endif /* BCMPCIE */
|
||||
int dhd_print_dump_data(void *dev, dhd_pub_t *dhdp, const void *user_buf,
|
||||
void *fp, uint32 len, void *pos);
|
||||
int dhd_print_cookie_data(void *dev, dhd_pub_t *dhdp, const void *user_buf,
|
||||
void *fp, uint32 len, void *pos);
|
||||
int dhd_print_health_chk_data(void *dev, dhd_pub_t *dhdp, const void *user_buf,
|
||||
void *fp, uint32 len, void *pos);
|
||||
int dhd_print_time_str(const void *user_buf, void *fp, uint32 len, void *pos);
|
||||
#ifdef DHD_DUMP_PCIE_RINGS
|
||||
int dhd_print_flowring_data(void *dev, dhd_pub_t *dhdp, const void *user_buf,
|
||||
void *fp, uint32 len, void *pos);
|
||||
uint32 dhd_get_flowring_len(void *ndev, dhd_pub_t *dhdp);
|
||||
#endif /* DHD_DUMP_PCIE_RINGS */
|
||||
#ifdef DHD_STATUS_LOGGING
|
||||
extern int dhd_print_status_log_data(void *dev, dhd_pub_t *dhdp,
|
||||
const void *user_buf, void *fp, uint32 len, void *pos);
|
||||
extern uint32 dhd_get_status_log_len(void *ndev, dhd_pub_t *dhdp);
|
||||
#endif /* DHD_STATUS_LOGGING */
|
||||
#ifdef DHD_MAP_PKTID_LOGGING
|
||||
extern uint32 dhd_pktid_buf_len(dhd_pub_t *dhd, bool is_map);
|
||||
extern int dhd_print_pktid_map_log_data(void *dev, dhd_pub_t *dhdp,
|
||||
const void *user_buf, void *fp, uint32 len, void *pos, bool is_map);
|
||||
extern int dhd_write_pktid_log_dump(dhd_pub_t *dhdp, const void *user_buf,
|
||||
void *fp, uint32 len, unsigned long *pos, bool is_map);
|
||||
extern uint32 dhd_get_pktid_map_logging_len(void *ndev, dhd_pub_t *dhdp, bool is_map);
|
||||
#endif /* DHD_MAP_PKTID_LOGGING */
|
||||
int dhd_print_ecntrs_data(void *dev, dhd_pub_t *dhdp, const void *user_buf,
|
||||
void *fp, uint32 len, void *pos);
|
||||
int dhd_print_rtt_data(void *dev, dhd_pub_t *dhdp, const void *user_buf,
|
||||
void *fp, uint32 len, void *pos);
|
||||
int dhd_get_debug_dump_file_name(void *dev, dhd_pub_t *dhdp,
|
||||
char *dump_path, int size);
|
||||
uint32 dhd_get_time_str_len(void);
|
||||
uint32 dhd_get_health_chk_len(void *ndev, dhd_pub_t *dhdp);
|
||||
uint32 dhd_get_dhd_dump_len(void *ndev, dhd_pub_t *dhdp);
|
||||
uint32 dhd_get_cookie_log_len(void *ndev, dhd_pub_t *dhdp);
|
||||
uint32 dhd_get_ecntrs_len(void *ndev, dhd_pub_t *dhdp);
|
||||
uint32 dhd_get_rtt_len(void *ndev, dhd_pub_t *dhdp);
|
||||
uint32 dhd_get_dld_len(int log_type);
|
||||
void dhd_init_sec_hdr(log_dump_section_hdr_t *sec_hdr);
|
||||
extern char *dhd_log_dump_get_timestamp(void);
|
||||
bool dhd_log_dump_ecntr_enabled(void);
|
||||
bool dhd_log_dump_rtt_enabled(void);
|
||||
void dhd_nla_put_sssr_dump_len(void *ndev, uint32 *arr_len);
|
||||
int dhd_get_debug_dump(void *dev, const void *user_buf, uint32 len, int type);
|
||||
#ifdef DHD_SSSR_DUMP_BEFORE_SR
|
||||
int
|
||||
dhd_sssr_dump_d11_buf_before(void *dev, const void *user_buf, uint32 len, int core);
|
||||
int
|
||||
dhd_sssr_dump_dig_buf_before(void *dev, const void *user_buf, uint32 len);
|
||||
#endif /* DHD_SSSR_DUMP_BEFORE_SR */
|
||||
int
|
||||
dhd_sssr_dump_d11_buf_after(void *dev, const void *user_buf, uint32 len, int core);
|
||||
int
|
||||
dhd_sssr_dump_dig_buf_after(void *dev, const void *user_buf, uint32 len);
|
||||
#ifdef DHD_PKT_LOGGING
|
||||
extern int dhd_os_get_pktlog_dump(void *dev, const void *user_buf, uint32 len);
|
||||
extern spinlock_t* dhd_os_get_pktlog_lock(dhd_pub_t *dhdp);
|
||||
extern uint32 dhd_os_get_pktlog_dump_size(struct net_device *dev);
|
||||
extern void dhd_os_get_pktlogdump_filename(struct net_device *dev, char *dump_path, int len);
|
||||
#endif /* DHD_PKT_LOGGING */
|
||||
|
||||
#ifdef DNGL_AXI_ERROR_LOGGING
|
||||
extern int dhd_os_get_axi_error_dump(void *dev, const void *user_buf, uint32 len);
|
||||
extern int dhd_os_get_axi_error_dump_size(struct net_device *dev);
|
||||
extern void dhd_os_get_axi_error_filename(struct net_device *dev, char *dump_path, int len);
|
||||
#endif /* DNGL_AXI_ERROR_LOGGING */
|
||||
|
||||
#ifdef DHD_DEBUGABILITY_DEBUG_DUMP
|
||||
extern int dhd_debug_dump_to_ring(dhd_pub_t *dhdp);
|
||||
#endif /* DHD_DEBUGABILITY_DEBUG_DUMP */
|
||||
|
||||
extern char *dhd_log_dump_get_timestamp(void);
|
||||
extern void dhd_dbg_ring_write(int type, char *binary_data,
|
||||
int binary_len, const char *fmt, ...);
|
||||
|
||||
void dhd_log_dump_init(dhd_pub_t *dhd);
|
||||
void dhd_log_dump_deinit(dhd_pub_t *dhd);
|
||||
void dhd_log_dump(void *handle, void *event_info, uint8 event);
|
||||
int do_dhd_log_dump(dhd_pub_t *dhdp, log_dump_type_t *type);
|
||||
void dhd_print_buf_addr(dhd_pub_t *dhdp, char *name, void *buf, unsigned int size);
|
||||
void dhd_log_dump_buf_addr(dhd_pub_t *dhdp, log_dump_type_t *type);
|
||||
int dhd_log_flush(dhd_pub_t *dhdp, log_dump_type_t *type);
|
||||
|
||||
extern void get_debug_dump_time(char *str);
|
||||
extern void clear_debug_dump_time(char *str);
|
||||
#if defined(WL_CFGVENDOR_SEND_HANG_EVENT) || defined(DHD_PKT_LOGGING)
|
||||
extern void copy_debug_dump_time(char *dest, char *src);
|
||||
#endif
|
||||
|
||||
void dhd_get_debug_dump_len(void *handle, struct sk_buff *skb, void *event_info, uint8 event);
|
||||
void cfgvendor_log_dump_len(dhd_pub_t *dhdp, log_dump_type_t *type, struct sk_buff *skb);
|
||||
#ifdef DHD_IOVAR_LOG_FILTER_DUMP
|
||||
bool dhd_iovar_log_dump_check(dhd_pub_t *dhd_pub, uint32 cmd, char *msg);
|
||||
#endif /* DHD_IOVAR_LOG_FILTER_DUMP */
|
||||
#endif /* DHD_LOG_DUMP */
|
||||
|
||||
#endif /* !__DHD_LOG_DUMP_H__ */
|
||||
|
|
@ -1,746 +0,0 @@
|
|||
/* D11 macdbg functions for Broadcom 802.11abgn
|
||||
* Networking Adapter Device Drivers.
|
||||
*
|
||||
* Broadcom Proprietary and Confidential. Copyright (C) 2020,
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* This is UNPUBLISHED PROPRIETARY SOURCE CODE of Broadcom;
|
||||
* the contents of this file may not be disclosed to third parties,
|
||||
* copied or duplicated in any form, in whole or in part, without
|
||||
* the prior written permission of Broadcom.
|
||||
*
|
||||
*
|
||||
* <<Broadcom-WL-IPTag/Proprietary:>>
|
||||
*
|
||||
* $Id: dhd_macdbg.c 670412 2016-11-15 20:01:18Z shinuk $
|
||||
*/
|
||||
|
||||
#ifdef BCMDBG
|
||||
#include <typedefs.h>
|
||||
#include <osl.h>
|
||||
|
||||
#include <bcmutils.h>
|
||||
#include <dhd_dbg.h>
|
||||
#include <dhd_macdbg.h>
|
||||
#include "d11reglist_proto.h"
|
||||
#include "dhdioctl.h"
|
||||
#include <sdiovar.h>
|
||||
|
||||
#ifdef BCMDBUS
|
||||
#include <dbus.h>
|
||||
#define BUS_IOVAR_OP(a, b, c, d, e, f, g) dbus_iovar_op(a->dbus, b, c, d, e, f, g)
|
||||
#else
|
||||
#include <dhd_bus.h>
|
||||
#define BUS_IOVAR_OP dhd_bus_iovar_op
|
||||
#endif
|
||||
|
||||
typedef struct _macdbg_info_t {
|
||||
dhd_pub_t *dhdp;
|
||||
d11regs_list_t *pd11regs;
|
||||
uint16 d11regs_sz;
|
||||
d11regs_list_t *pd11regs_x;
|
||||
uint16 d11regsx_sz;
|
||||
svmp_list_t *psvmpmems;
|
||||
uint16 svmpmems_sz;
|
||||
} macdbg_info_t;
|
||||
|
||||
#define SVMPLIST_HARDCODE
|
||||
|
||||
int
|
||||
dhd_macdbg_attach(dhd_pub_t *dhdp)
|
||||
{
|
||||
macdbg_info_t *macdbg_info = MALLOCZ(dhdp->osh, sizeof(*macdbg_info));
|
||||
#ifdef SVMPLIST_HARDCODE
|
||||
svmp_list_t svmpmems[] = {
|
||||
{0x20000, 256},
|
||||
{0x21e10, 16},
|
||||
{0x20300, 16},
|
||||
{0x20700, 16},
|
||||
{0x20b00, 16},
|
||||
{0x20be0, 16},
|
||||
{0x20bff, 16},
|
||||
{0xc000, 32},
|
||||
{0xe000, 32},
|
||||
{0x10000, 0x8000},
|
||||
{0x18000, 0x8000}
|
||||
};
|
||||
#endif /* SVMPLIST_HARDCODE */
|
||||
|
||||
if (macdbg_info == NULL) {
|
||||
return BCME_NOMEM;
|
||||
}
|
||||
dhdp->macdbg_info = macdbg_info;
|
||||
macdbg_info->dhdp = dhdp;
|
||||
|
||||
#ifdef SVMPLIST_HARDCODE
|
||||
macdbg_info->psvmpmems = MALLOCZ(dhdp->osh, sizeof(svmpmems));
|
||||
if (macdbg_info->psvmpmems == NULL) {
|
||||
return BCME_NOMEM;
|
||||
}
|
||||
|
||||
macdbg_info->svmpmems_sz = ARRAYSIZE(svmpmems);
|
||||
memcpy(macdbg_info->psvmpmems, svmpmems, sizeof(svmpmems));
|
||||
|
||||
DHD_ERROR(("%s: psvmpmems %p svmpmems_sz %d\n",
|
||||
__FUNCTION__, macdbg_info->psvmpmems, macdbg_info->svmpmems_sz));
|
||||
#endif
|
||||
return BCME_OK;
|
||||
}
|
||||
|
||||
void
|
||||
dhd_macdbg_detach(dhd_pub_t *dhdp)
|
||||
{
|
||||
macdbg_info_t *macdbg_info = dhdp->macdbg_info;
|
||||
ASSERT(macdbg_info);
|
||||
|
||||
if (macdbg_info->pd11regs) {
|
||||
ASSERT(macdbg_info->d11regs_sz > 0);
|
||||
MFREE(dhdp->osh, macdbg_info->pd11regs,
|
||||
(macdbg_info->d11regs_sz * sizeof(macdbg_info->pd11regs[0])));
|
||||
macdbg_info->d11regs_sz = 0;
|
||||
}
|
||||
if (macdbg_info->pd11regs_x) {
|
||||
ASSERT(macdbg_info->d11regsx_sz > 0);
|
||||
MFREE(dhdp->osh, macdbg_info->pd11regs_x,
|
||||
(macdbg_info->d11regsx_sz * sizeof(macdbg_info->pd11regs_x[0])));
|
||||
macdbg_info->d11regsx_sz = 0;
|
||||
}
|
||||
if (macdbg_info->psvmpmems) {
|
||||
ASSERT(macdbg_info->svmpmems_sz > 0);
|
||||
MFREE(dhdp->osh, macdbg_info->psvmpmems,
|
||||
(macdbg_info->svmpmems_sz * sizeof(macdbg_info->psvmpmems[0])));
|
||||
macdbg_info->svmpmems_sz = 0;
|
||||
}
|
||||
MFREE(dhdp->osh, macdbg_info, sizeof(*macdbg_info));
|
||||
}
|
||||
|
||||
void
|
||||
dhd_macdbg_event_handler(dhd_pub_t *dhdp, uint32 reason,
|
||||
uint8 *event_data, uint32 datalen)
|
||||
{
|
||||
d11regs_list_t *pd11regs;
|
||||
macdbg_info_t *macdbg_info = dhdp->macdbg_info;
|
||||
uint d11regs_sz;
|
||||
|
||||
DHD_TRACE(("%s: reason %d datalen %d\n", __FUNCTION__, reason, datalen));
|
||||
switch (reason) {
|
||||
case WLC_E_MACDBG_LIST_PSMX:
|
||||
/* Fall through */
|
||||
case WLC_E_MACDBG_LIST_PSM:
|
||||
pd11regs = MALLOCZ(dhdp->osh, datalen);
|
||||
if (pd11regs == NULL) {
|
||||
DHD_ERROR(("%s: NOMEM for len %d\n", __FUNCTION__, datalen));
|
||||
return;
|
||||
}
|
||||
memcpy(pd11regs, event_data, datalen);
|
||||
d11regs_sz = datalen / sizeof(pd11regs[0]);
|
||||
DHD_ERROR(("%s: d11regs %p d11regs_sz %d\n",
|
||||
__FUNCTION__, pd11regs, d11regs_sz));
|
||||
if (reason == WLC_E_MACDBG_LIST_PSM) {
|
||||
macdbg_info->pd11regs = pd11regs;
|
||||
macdbg_info->d11regs_sz = (uint16)d11regs_sz;
|
||||
} else {
|
||||
macdbg_info->pd11regs_x = pd11regs;
|
||||
macdbg_info->d11regsx_sz = (uint16)d11regs_sz;
|
||||
}
|
||||
break;
|
||||
case WLC_E_MACDBG_REGALL:
|
||||
#ifdef LINUX
|
||||
/* Schedule to work queue as this context could be ISR */
|
||||
dhd_schedule_macdbg_dump(dhdp);
|
||||
#else
|
||||
/* Dump PSMr */
|
||||
(void) dhd_macdbg_dumpmac(dhdp, NULL, 0, NULL, FALSE);
|
||||
/* Dump PSMx */
|
||||
(void) dhd_macdbg_dumpmac(dhdp, NULL, 0, NULL, TRUE);
|
||||
/* Dump SVMP mems */
|
||||
(void) dhd_macdbg_dumpsvmp(dhdp, NULL, 0, NULL);
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
DHD_ERROR(("%s: Unknown reason %d\n",
|
||||
__FUNCTION__, reason));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
static uint16
|
||||
_dhd_get_ihr16(macdbg_info_t *macdbg_info, uint16 addr, struct bcmstrbuf *b, bool verbose)
|
||||
{
|
||||
sdreg_t sdreg;
|
||||
uint16 val;
|
||||
|
||||
sdreg.func = 2;
|
||||
sdreg.offset = (0x1000 | addr);
|
||||
BUS_IOVAR_OP(macdbg_info->dhdp, "sbreg",
|
||||
&sdreg, sizeof(sdreg), &val, sizeof(val), IOV_GET);
|
||||
if (verbose) {
|
||||
if (b) {
|
||||
bcm_bprintf(b, "DEBUG: IHR16: read 0x%08x, size 2, value 0x%04x\n",
|
||||
(addr + 0x18001000), val);
|
||||
} else {
|
||||
printf("DEBUG: IHR16: read 0x%08x, size 2, value 0x%04x\n",
|
||||
(addr + 0x18001000), val);
|
||||
}
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
static uint32
|
||||
_dhd_get_ihr32(macdbg_info_t *macdbg_info, uint16 addr, struct bcmstrbuf *b, bool verbose)
|
||||
{
|
||||
sdreg_t sdreg;
|
||||
uint32 val;
|
||||
|
||||
sdreg.func = 4;
|
||||
sdreg.offset = (0x1000 | addr);
|
||||
BUS_IOVAR_OP(macdbg_info->dhdp, "sbreg",
|
||||
&sdreg, sizeof(sdreg), &val, sizeof(val), IOV_GET);
|
||||
if (verbose) {
|
||||
if (b) {
|
||||
bcm_bprintf(b, "DEBUG: IHR32: read 0x%08x, size 4, value 0x%08x\n",
|
||||
(addr + 0x18001000), val);
|
||||
} else {
|
||||
printf("DEBUG: IHR32: read 0x%08x, size 4, value 0x%08x\n",
|
||||
(addr + 0x18001000), val);
|
||||
}
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
static void
|
||||
_dhd_set_ihr16(macdbg_info_t *macdbg_info, uint16 addr, uint16 val,
|
||||
struct bcmstrbuf *b, bool verbose)
|
||||
{
|
||||
sdreg_t sdreg;
|
||||
|
||||
sdreg.func = 2;
|
||||
sdreg.offset = (0x1000 | addr);
|
||||
sdreg.value = val;
|
||||
|
||||
if (verbose) {
|
||||
if (b) {
|
||||
bcm_bprintf(b, "DEBUG: IHR16: write 0x%08x, size 2, value 0x%04x\n",
|
||||
(addr + 0x18001000), val);
|
||||
} else {
|
||||
printf("DEBUG: IHR16: write 0x%08x, size 2, value 0x%04x\n",
|
||||
(addr + 0x18001000), val);
|
||||
}
|
||||
}
|
||||
BUS_IOVAR_OP(macdbg_info->dhdp, "sbreg",
|
||||
NULL, 0, &sdreg, sizeof(sdreg), IOV_SET);
|
||||
}
|
||||
|
||||
static void
|
||||
_dhd_set_ihr32(macdbg_info_t *macdbg_info, uint16 addr, uint32 val,
|
||||
struct bcmstrbuf *b, bool verbose)
|
||||
{
|
||||
sdreg_t sdreg;
|
||||
|
||||
sdreg.func = 4;
|
||||
sdreg.offset = (0x1000 | addr);
|
||||
sdreg.value = val;
|
||||
|
||||
if (verbose) {
|
||||
if (b) {
|
||||
bcm_bprintf(b, "DEBUG: IHR32: write 0x%08x, size 4, value 0x%08x\n",
|
||||
(addr + 0x18001000), val);
|
||||
} else {
|
||||
printf("DEBUG: IHR32: write 0x%08x, size 4, value 0x%08x\n",
|
||||
(addr + 0x18001000), val);
|
||||
}
|
||||
}
|
||||
BUS_IOVAR_OP(macdbg_info->dhdp, "sbreg",
|
||||
NULL, 0, &sdreg, sizeof(sdreg), IOV_SET);
|
||||
}
|
||||
|
||||
static uint32
|
||||
_dhd_get_d11obj32(macdbg_info_t *macdbg_info, uint16 objaddr, uint32 sel,
|
||||
struct bcmstrbuf *b, bool verbose)
|
||||
{
|
||||
uint32 val;
|
||||
sdreg_t sdreg;
|
||||
sdreg.func = 4; // 4bytes by default.
|
||||
sdreg.offset = 0x1160;
|
||||
|
||||
if (objaddr == 0xffff) {
|
||||
if (verbose) {
|
||||
goto objaddr_read;
|
||||
} else {
|
||||
goto objdata_read;
|
||||
}
|
||||
}
|
||||
|
||||
if (objaddr & 0x3) {
|
||||
printf("%s: ERROR! Invalid addr 0x%x\n", __FUNCTION__, objaddr);
|
||||
}
|
||||
|
||||
sdreg.value = (sel | (objaddr >> 2));
|
||||
|
||||
if (verbose) {
|
||||
if (b) {
|
||||
bcm_bprintf(b, "DEBUG: %s: Indirect: write 0x%08x, size %d, value 0x%08x\n",
|
||||
(sel & 0x00020000) ? "SCR":"SHM",
|
||||
(sdreg.offset + 0x18000000), sdreg.func, sdreg.value);
|
||||
} else {
|
||||
printf("DEBUG: %s: Indirect: write 0x%08x, size %d, value 0x%08x\n",
|
||||
(sel & 0x00020000) ? "SCR":"SHM",
|
||||
(sdreg.offset + 0x18000000), sdreg.func, sdreg.value);
|
||||
}
|
||||
}
|
||||
BUS_IOVAR_OP(macdbg_info->dhdp, "sbreg",
|
||||
NULL, 0, &sdreg, sizeof(sdreg), IOV_SET);
|
||||
|
||||
objaddr_read:
|
||||
/* Give some time to obj addr register */
|
||||
BUS_IOVAR_OP(macdbg_info->dhdp, "sbreg",
|
||||
&sdreg, sizeof(sdreg), &val, sizeof(val), IOV_GET);
|
||||
if (verbose) {
|
||||
if (b) {
|
||||
bcm_bprintf(b, "DEBUG: %s: Indirect: Read 0x%08x, size %d, value 0x%08x\n",
|
||||
(sel & 0x00020000) ? "SCR":"SHM",
|
||||
(sdreg.offset + 0x18000000), sdreg.func, val);
|
||||
} else {
|
||||
printf("DEBUG: %s: Indirect: Read 0x%08x, size %d, value 0x%08x\n",
|
||||
(sel & 0x00020000) ? "SCR":"SHM",
|
||||
(sdreg.offset + 0x18000000), sdreg.func, val);
|
||||
}
|
||||
}
|
||||
|
||||
objdata_read:
|
||||
sdreg.offset = 0x1164;
|
||||
BUS_IOVAR_OP(macdbg_info->dhdp, "sbreg",
|
||||
&sdreg, sizeof(sdreg), &val, sizeof(val), IOV_GET);
|
||||
if (verbose) {
|
||||
if (b) {
|
||||
bcm_bprintf(b, "DEBUG: %s: Indirect: Read 0x%08x, size %d, value 0x%04x\n",
|
||||
(sel & 0x00020000) ? "SCR":"SHM",
|
||||
(sdreg.offset + 0x18000000), sdreg.func, val);
|
||||
} else {
|
||||
printf("DEBUG: %s: Indirect: Read 0x%08x, size %d, value 0x%04x\n",
|
||||
(sel & 0x00020000) ? "SCR":"SHM",
|
||||
(sdreg.offset + 0x18000000), sdreg.func, val);
|
||||
}
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
static uint16
|
||||
_dhd_get_d11obj16(macdbg_info_t *macdbg_info, uint16 objaddr,
|
||||
uint32 sel, d11obj_cache_t *obj_cache, struct bcmstrbuf *b, bool verbose)
|
||||
{
|
||||
uint32 val;
|
||||
if (obj_cache && obj_cache->cache_valid && ((obj_cache->sel ^ sel) & (0xffffff)) == 0) {
|
||||
if (obj_cache->addr32 == (objaddr & ~0x3)) {
|
||||
/* XXX: Same objaddr read as the previous one */
|
||||
if (verbose) {
|
||||
if (b) {
|
||||
bcm_bprintf(b, "DEBUG: %s: Read cache value: "
|
||||
"addr32 0x%04x, sel 0x%08x, value 0x%08x\n",
|
||||
(sel & 0x00020000) ? "SCR":"SHM",
|
||||
obj_cache->addr32, obj_cache->sel, obj_cache->val);
|
||||
} else {
|
||||
printf("DEBUG: %s: Read cache value: "
|
||||
"addr32 0x%04x, sel 0x%08x, value 0x%08x\n",
|
||||
(sel & 0x00020000) ? "SCR":"SHM",
|
||||
obj_cache->addr32, obj_cache->sel, obj_cache->val);
|
||||
}
|
||||
}
|
||||
val = obj_cache->val;
|
||||
goto exit;
|
||||
} else if ((obj_cache->sel & 0x02000000) &&
|
||||
(obj_cache->addr32 + 4 == (objaddr & ~0x3))) {
|
||||
/* XXX: objaddr is auto incrementing, so just read objdata */
|
||||
if (verbose) {
|
||||
if (b) {
|
||||
bcm_bprintf(b, "DEBUG: %s: Read objdata only: "
|
||||
"addr32 0x%04x, sel 0x%08x, value 0x%08x\n",
|
||||
(sel & 0x00020000) ? "SCR":"SHM",
|
||||
obj_cache->addr32, obj_cache->sel, obj_cache->val);
|
||||
} else {
|
||||
printf("DEBUG: %s: Read objdata only: "
|
||||
"addr32 0x%04x, sel 0x%08x, value 0x%08x\n",
|
||||
(sel & 0x00020000) ? "SCR":"SHM",
|
||||
obj_cache->addr32, obj_cache->sel, obj_cache->val);
|
||||
}
|
||||
}
|
||||
val = _dhd_get_d11obj32(macdbg_info, 0xffff, sel, b, verbose);
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
val = _dhd_get_d11obj32(macdbg_info, (objaddr & ~0x2), sel, b, verbose);
|
||||
exit:
|
||||
if (obj_cache) {
|
||||
obj_cache->addr32 = (objaddr & ~0x3);
|
||||
obj_cache->sel = sel;
|
||||
obj_cache->val = val;
|
||||
obj_cache->cache_valid = TRUE;
|
||||
}
|
||||
return (uint16)((objaddr & 0x2) ? (val >> 16) : val);
|
||||
}
|
||||
|
||||
static int
|
||||
_dhd_print_d11reg(macdbg_info_t *macdbg_info, int idx, int type, uint16 addr, struct bcmstrbuf *b,
|
||||
d11obj_cache_t *obj_cache, bool verbose)
|
||||
{
|
||||
const char *regname[D11REG_TYPE_MAX] = D11REGTYPENAME;
|
||||
uint32 val;
|
||||
|
||||
if (type == D11REG_TYPE_IHR32) {
|
||||
if ((addr & 0x3)) {
|
||||
printf("%s: ERROR! Invalid addr 0x%x\n", __FUNCTION__, addr);
|
||||
addr &= ~0x3;
|
||||
}
|
||||
val = _dhd_get_ihr32(macdbg_info, addr, b, verbose);
|
||||
if (b) {
|
||||
bcm_bprintf(b, "%-3d %s 0x%-4x = 0x%-8x\n",
|
||||
idx, regname[type], addr, val);
|
||||
} else {
|
||||
printf("%-3d %s 0x%-4x = 0x%-8x\n",
|
||||
idx, regname[type], addr, val);
|
||||
}
|
||||
} else {
|
||||
switch (type) {
|
||||
case D11REG_TYPE_IHR16: {
|
||||
if ((addr & 0x1)) {
|
||||
printf("%s: ERROR! Invalid addr 0x%x\n", __FUNCTION__, addr);
|
||||
addr &= ~0x1;
|
||||
}
|
||||
val = _dhd_get_ihr16(macdbg_info, addr, b, verbose);
|
||||
break;
|
||||
}
|
||||
case D11REG_TYPE_IHRX16:
|
||||
val = _dhd_get_d11obj16(macdbg_info, (addr - 0x400) << 1, 0x020b0000,
|
||||
obj_cache, b, verbose);
|
||||
break;
|
||||
case D11REG_TYPE_SCR:
|
||||
val = _dhd_get_d11obj16(macdbg_info, addr << 2, 0x02020000,
|
||||
obj_cache, b, verbose);
|
||||
break;
|
||||
case D11REG_TYPE_SCRX:
|
||||
val = _dhd_get_d11obj16(macdbg_info, addr << 2, 0x020a0000,
|
||||
obj_cache, b, verbose);
|
||||
break;
|
||||
case D11REG_TYPE_SHM:
|
||||
val = _dhd_get_d11obj16(macdbg_info, addr, 0x02010000,
|
||||
obj_cache, b, verbose);
|
||||
break;
|
||||
case D11REG_TYPE_SHMX:
|
||||
val = _dhd_get_d11obj16(macdbg_info, addr, 0x02090000,
|
||||
obj_cache, b, verbose);
|
||||
break;
|
||||
default:
|
||||
printf("Unrecognized type %d!\n", type);
|
||||
return 0;
|
||||
}
|
||||
if (b) {
|
||||
bcm_bprintf(b, "%-3d %s 0x%-4x = 0x%-4x\n",
|
||||
idx, regname[type], addr, val);
|
||||
} else {
|
||||
printf("%-3d %s 0x%-4x = 0x%-4x\n",
|
||||
idx, regname[type], addr, val);
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
_dhd_print_d11regs(macdbg_info_t *macdbg_info, d11regs_list_t *pregs,
|
||||
int start_idx, struct bcmstrbuf *b, bool verbose)
|
||||
{
|
||||
uint16 addr;
|
||||
int idx = 0;
|
||||
d11obj_cache_t obj_cache = {0, 0, 0, FALSE};
|
||||
|
||||
addr = pregs->addr;
|
||||
if (pregs->type >= D11REG_TYPE_MAX) {
|
||||
printf("%s: wrong type %d\n", __FUNCTION__, pregs->type);
|
||||
return 0;
|
||||
}
|
||||
if (pregs->bitmap) {
|
||||
while (pregs->bitmap) {
|
||||
if (pregs->bitmap && (pregs->bitmap & 0x1)) {
|
||||
_dhd_print_d11reg(macdbg_info, (idx + start_idx), pregs->type,
|
||||
addr, b, &obj_cache, verbose);
|
||||
idx++;
|
||||
}
|
||||
pregs->bitmap = pregs->bitmap >> 1;
|
||||
addr += pregs->step;
|
||||
}
|
||||
} else {
|
||||
for (; idx < pregs->cnt; idx++) {
|
||||
_dhd_print_d11reg(macdbg_info, (idx + start_idx), pregs->type,
|
||||
addr, b, &obj_cache, verbose);
|
||||
addr += pregs->step;
|
||||
}
|
||||
}
|
||||
return idx;
|
||||
}
|
||||
|
||||
static int
|
||||
_dhd_pd11regs_bylist(macdbg_info_t *macdbg_info, d11regs_list_t *reglist,
|
||||
uint16 reglist_sz, struct bcmstrbuf *b)
|
||||
{
|
||||
uint i, idx = 0;
|
||||
|
||||
if (reglist != NULL && reglist_sz > 0) {
|
||||
for (i = 0; i < reglist_sz; i++) {
|
||||
DHD_TRACE(("%s %d %p %d\n", __FUNCTION__, __LINE__,
|
||||
®list[i], reglist_sz));
|
||||
idx += _dhd_print_d11regs(macdbg_info, ®list[i], idx, b, FALSE);
|
||||
}
|
||||
}
|
||||
return idx;
|
||||
}
|
||||
|
||||
int
|
||||
dhd_macdbg_dumpmac(dhd_pub_t *dhdp, char *buf, int buflen,
|
||||
int *outbuflen, bool dump_x)
|
||||
{
|
||||
macdbg_info_t *macdbg_info = dhdp->macdbg_info;
|
||||
struct bcmstrbuf *b = NULL;
|
||||
struct bcmstrbuf bcmstrbuf;
|
||||
uint cnt = 0;
|
||||
|
||||
DHD_TRACE(("%s %d %p %d %p %d %p %d\n", __FUNCTION__, __LINE__,
|
||||
buf, buflen, macdbg_info->pd11regs, macdbg_info->d11regs_sz,
|
||||
macdbg_info->pd11regs_x, macdbg_info->d11regsx_sz));
|
||||
|
||||
if (buf && buflen > 0) {
|
||||
bcm_binit(&bcmstrbuf, buf, buflen);
|
||||
b = &bcmstrbuf;
|
||||
}
|
||||
if (!dump_x) {
|
||||
/* Dump PSMr */
|
||||
cnt += _dhd_pd11regs_bylist(macdbg_info, macdbg_info->pd11regs,
|
||||
macdbg_info->d11regs_sz, b);
|
||||
} else {
|
||||
/* Dump PSMx */
|
||||
cnt += _dhd_pd11regs_bylist(macdbg_info, macdbg_info->pd11regs_x,
|
||||
macdbg_info->d11regsx_sz, b);
|
||||
}
|
||||
|
||||
if (b && outbuflen) {
|
||||
if ((uint)buflen > BCMSTRBUF_LEN(b)) {
|
||||
*outbuflen = buflen - BCMSTRBUF_LEN(b);
|
||||
} else {
|
||||
DHD_ERROR(("%s: buflen insufficient!\n", __FUNCTION__));
|
||||
*outbuflen = buflen;
|
||||
/* Do not return buftooshort to allow printing macregs we have got */
|
||||
}
|
||||
}
|
||||
|
||||
return ((cnt > 0) ? BCME_OK : BCME_UNSUPPORTED);
|
||||
}
|
||||
|
||||
int
|
||||
dhd_macdbg_pd11regs(dhd_pub_t *dhdp, char *params, int plen, char *buf, int buflen)
|
||||
{
|
||||
macdbg_info_t *macdbg_info = dhdp->macdbg_info;
|
||||
dhd_pd11regs_param *pd11regs = (void *)params;
|
||||
dhd_pd11regs_buf *pd11regs_buf = (void *)buf;
|
||||
uint16 start_idx;
|
||||
bool verbose;
|
||||
d11regs_list_t reglist;
|
||||
struct bcmstrbuf *b = NULL;
|
||||
struct bcmstrbuf bcmstrbuf;
|
||||
|
||||
start_idx = pd11regs->start_idx;
|
||||
verbose = pd11regs->verbose;
|
||||
memcpy(®list, pd11regs->plist, sizeof(reglist));
|
||||
memset(buf, '\0', buflen);
|
||||
bcm_binit(&bcmstrbuf, (char *)(pd11regs_buf->pbuf),
|
||||
(buflen - OFFSETOF(dhd_pd11regs_buf, pbuf)));
|
||||
b = &bcmstrbuf;
|
||||
pd11regs_buf->idx = (uint16)_dhd_print_d11regs(macdbg_info, ®list,
|
||||
start_idx, b, verbose);
|
||||
|
||||
return ((pd11regs_buf->idx > 0) ? BCME_OK : BCME_ERROR);
|
||||
}
|
||||
|
||||
int
|
||||
dhd_macdbg_reglist(dhd_pub_t *dhdp, char *buf, int buflen)
|
||||
{
|
||||
int err, desc_idx = 0;
|
||||
dhd_maclist_t *maclist = (dhd_maclist_t *)buf;
|
||||
macdbg_info_t *macdbg_info = dhdp->macdbg_info;
|
||||
void *xtlvbuf_p = maclist->plist;
|
||||
uint16 xtlvbuflen = (uint16)buflen;
|
||||
xtlv_desc_t xtlv_desc[] = {
|
||||
{0, 0, NULL},
|
||||
{0, 0, NULL},
|
||||
{0, 0, NULL},
|
||||
{0, 0, NULL}
|
||||
};
|
||||
|
||||
if (!macdbg_info->pd11regs) {
|
||||
err = BCME_NOTFOUND;
|
||||
goto exit;
|
||||
}
|
||||
ASSERT(macdbg_info->d11regs_sz > 0);
|
||||
xtlv_desc[desc_idx].type = DHD_MACLIST_XTLV_R;
|
||||
xtlv_desc[desc_idx].len =
|
||||
macdbg_info->d11regs_sz * (uint16)sizeof(*(macdbg_info->pd11regs));
|
||||
xtlv_desc[desc_idx].ptr = macdbg_info->pd11regs;
|
||||
desc_idx++;
|
||||
|
||||
if (macdbg_info->pd11regs_x) {
|
||||
ASSERT(macdbg_info->d11regsx_sz);
|
||||
xtlv_desc[desc_idx].type = DHD_MACLIST_XTLV_X;
|
||||
xtlv_desc[desc_idx].len = macdbg_info->d11regsx_sz *
|
||||
(uint16)sizeof(*(macdbg_info->pd11regs_x));
|
||||
xtlv_desc[desc_idx].ptr = macdbg_info->pd11regs_x;
|
||||
desc_idx++;
|
||||
}
|
||||
|
||||
if (macdbg_info->psvmpmems) {
|
||||
ASSERT(macdbg_info->svmpmems_sz);
|
||||
xtlv_desc[desc_idx].type = DHD_SVMPLIST_XTLV;
|
||||
xtlv_desc[desc_idx].len = macdbg_info->svmpmems_sz *
|
||||
(uint16)sizeof(*(macdbg_info->psvmpmems));
|
||||
xtlv_desc[desc_idx].ptr = macdbg_info->psvmpmems;
|
||||
desc_idx++;
|
||||
}
|
||||
|
||||
err = bcm_pack_xtlv_buf_from_mem((uint8 **)&xtlvbuf_p, &xtlvbuflen,
|
||||
xtlv_desc, BCM_XTLV_OPTION_ALIGN32);
|
||||
|
||||
maclist->version = 0; /* No version control for now anyway */
|
||||
maclist->bytes_len = (buflen - xtlvbuflen);
|
||||
|
||||
exit:
|
||||
return err;
|
||||
}
|
||||
|
||||
static int
|
||||
_dhd_print_svmps(macdbg_info_t *macdbg_info, svmp_list_t *psvmp,
|
||||
int start_idx, struct bcmstrbuf *b, bool verbose)
|
||||
{
|
||||
int idx;
|
||||
uint32 addr, mem_id, offset, prev_mem_id, prev_offset;
|
||||
uint16 cnt, val;
|
||||
|
||||
BCM_REFERENCE(start_idx);
|
||||
|
||||
/* Set tbl ID and tbl offset. */
|
||||
_dhd_set_ihr32(macdbg_info, 0x3fc, 0x30000d, b, verbose);
|
||||
_dhd_set_ihr32(macdbg_info, 0x3fc, 0x8000000e, b, verbose);
|
||||
|
||||
addr = psvmp->addr;
|
||||
cnt = psvmp->cnt;
|
||||
|
||||
/* In validate previous mem_id and offset */
|
||||
prev_mem_id = (uint32)(-1);
|
||||
prev_offset = (uint32)(-1);
|
||||
|
||||
for (idx = 0; idx < cnt; idx++, addr++) {
|
||||
mem_id = (addr >> 15);
|
||||
offset = (addr & 0x7fff) >> 1;
|
||||
|
||||
if (mem_id != prev_mem_id) {
|
||||
/* Set mem_id */
|
||||
_dhd_set_ihr32(macdbg_info, 0x3fc, ((mem_id & 0xffff0000) | 0x10),
|
||||
b, verbose);
|
||||
_dhd_set_ihr32(macdbg_info, 0x3fc, ((mem_id << 16) | 0xf),
|
||||
b, verbose);
|
||||
}
|
||||
|
||||
if (offset != prev_offset) {
|
||||
/* XXX: Is this needed?
|
||||
* _dhd_set_ihr32(macdbg_info, 0x3fc, 0x30000d, b, verbose);
|
||||
*/
|
||||
/* svmp offset */
|
||||
_dhd_set_ihr32(macdbg_info, 0x3fc, ((offset << 16) | 0xe),
|
||||
b, verbose);
|
||||
}
|
||||
/* Read hi or lo */
|
||||
_dhd_set_ihr16(macdbg_info, 0x3fc, ((addr & 0x1) ? 0x10 : 0xf), b, verbose);
|
||||
val = _dhd_get_ihr16(macdbg_info, 0x3fe, b, verbose);
|
||||
if (b) {
|
||||
bcm_bprintf(b, "0x%-4x 0x%-4x\n",
|
||||
addr, val);
|
||||
|
||||
} else {
|
||||
printf("0x%-4x 0x%-4x\n",
|
||||
addr, val);
|
||||
}
|
||||
prev_mem_id = mem_id;
|
||||
prev_offset = offset;
|
||||
}
|
||||
return idx;
|
||||
}
|
||||
|
||||
static int
|
||||
_dhd_psvmps_bylist(macdbg_info_t *macdbg_info, svmp_list_t *svmplist,
|
||||
uint16 svmplist_sz, struct bcmstrbuf *b)
|
||||
{
|
||||
uint i, idx = 0;
|
||||
|
||||
if (svmplist != NULL && svmplist_sz > 0) {
|
||||
for (i = 0; i < svmplist_sz; i++) {
|
||||
DHD_TRACE(("%s %d %p %d\n", __FUNCTION__, __LINE__,
|
||||
&svmplist[i], svmplist_sz));
|
||||
idx += _dhd_print_svmps(macdbg_info, &svmplist[i], idx, b, FALSE);
|
||||
}
|
||||
}
|
||||
return idx;
|
||||
}
|
||||
|
||||
int
|
||||
dhd_macdbg_dumpsvmp(dhd_pub_t *dhdp, char *buf, int buflen,
|
||||
int *outbuflen)
|
||||
{
|
||||
macdbg_info_t *macdbg_info = dhdp->macdbg_info;
|
||||
struct bcmstrbuf *b = NULL;
|
||||
struct bcmstrbuf bcmstrbuf;
|
||||
uint cnt = 0;
|
||||
|
||||
DHD_TRACE(("%s %d %p %d %p %d\n", __FUNCTION__, __LINE__,
|
||||
buf, buflen, macdbg_info->psvmpmems, macdbg_info->svmpmems_sz));
|
||||
|
||||
if (buf && buflen > 0) {
|
||||
bcm_binit(&bcmstrbuf, buf, buflen);
|
||||
b = &bcmstrbuf;
|
||||
}
|
||||
cnt = _dhd_psvmps_bylist(macdbg_info, macdbg_info->psvmpmems,
|
||||
macdbg_info->svmpmems_sz, b);
|
||||
|
||||
if (b && outbuflen) {
|
||||
if ((uint)buflen > BCMSTRBUF_LEN(b)) {
|
||||
*outbuflen = buflen - BCMSTRBUF_LEN(b);
|
||||
} else {
|
||||
DHD_ERROR(("%s: buflen insufficient!\n", __FUNCTION__));
|
||||
*outbuflen = buflen;
|
||||
/* Do not return buftooshort to allow printing macregs we have got */
|
||||
}
|
||||
}
|
||||
|
||||
return ((cnt > 0) ? BCME_OK : BCME_UNSUPPORTED);
|
||||
}
|
||||
|
||||
int
|
||||
dhd_macdbg_psvmpmems(dhd_pub_t *dhdp, char *params, int plen, char *buf, int buflen)
|
||||
{
|
||||
macdbg_info_t *macdbg_info = dhdp->macdbg_info;
|
||||
dhd_pd11regs_param *pd11regs = (void *)params;
|
||||
dhd_pd11regs_buf *pd11regs_buf = (void *)buf;
|
||||
uint16 start_idx;
|
||||
bool verbose;
|
||||
svmp_list_t reglist;
|
||||
struct bcmstrbuf *b = NULL;
|
||||
struct bcmstrbuf bcmstrbuf;
|
||||
|
||||
start_idx = pd11regs->start_idx;
|
||||
verbose = pd11regs->verbose;
|
||||
memcpy(®list, pd11regs->plist, sizeof(reglist));
|
||||
memset(buf, '\0', buflen);
|
||||
bcm_binit(&bcmstrbuf, (char *)(pd11regs_buf->pbuf),
|
||||
(buflen - OFFSETOF(dhd_pd11regs_buf, pbuf)));
|
||||
b = &bcmstrbuf;
|
||||
pd11regs_buf->idx = (uint16)_dhd_print_svmps(macdbg_info, ®list,
|
||||
start_idx, b, verbose);
|
||||
|
||||
return ((pd11regs_buf->idx > 0) ? BCME_OK : BCME_ERROR);
|
||||
}
|
||||
|
||||
#endif /* BCMDBG */
|
||||
|
|
@ -1,34 +0,0 @@
|
|||
/* D11 macdbg function prototypes for Broadcom 802.11abgn
|
||||
* Networking Adapter Device Drivers.
|
||||
*
|
||||
* Broadcom Proprietary and Confidential. Copyright (C) 2020,
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* This is UNPUBLISHED PROPRIETARY SOURCE CODE of Broadcom;
|
||||
* the contents of this file may not be disclosed to third parties,
|
||||
* copied or duplicated in any form, in whole or in part, without
|
||||
* the prior written permission of Broadcom.
|
||||
*
|
||||
*
|
||||
* <<Broadcom-WL-IPTag/Proprietary:>>
|
||||
*
|
||||
* $Id: dhd_macdbg.h 649388 2016-07-15 22:54:42Z shinuk $
|
||||
*/
|
||||
|
||||
#ifndef _dhd_macdbg_h_
|
||||
#define _dhd_macdbg_h_
|
||||
#ifdef BCMDBG
|
||||
#include <dngl_stats.h>
|
||||
#include <dhd.h>
|
||||
|
||||
extern int dhd_macdbg_attach(dhd_pub_t *dhdp);
|
||||
extern void dhd_macdbg_detach(dhd_pub_t *dhdp);
|
||||
extern void dhd_macdbg_event_handler(dhd_pub_t *dhdp, uint32 reason,
|
||||
uint8 *event_data, uint32 datalen);
|
||||
extern int dhd_macdbg_dumpmac(dhd_pub_t *dhdp, char *buf, int buflen, int *outbuflen, bool dump_x);
|
||||
extern int dhd_macdbg_pd11regs(dhd_pub_t *dhdp, char *params, int plen, char *buf, int buflen);
|
||||
extern int dhd_macdbg_reglist(dhd_pub_t *dhdp, char *buf, int buflen);
|
||||
extern int dhd_macdbg_dumpsvmp(dhd_pub_t *dhdp, char *buf, int buflen, int *outbuflen);
|
||||
extern int dhd_macdbg_psvmpmems(dhd_pub_t *dhdp, char *params, int plen, char *buf, int buflen);
|
||||
#endif /* BCMDBG */
|
||||
#endif /* _dhd_macdbg_h_ */
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* DHD debugability support
|
||||
*
|
||||
* Copyright (C) 2020, Broadcom.
|
||||
* Copyright (C) 2022, Broadcom.
|
||||
*
|
||||
* Unless you and Broadcom execute a separate written software license
|
||||
* agreement governing use of this software, this software is licensed to you
|
||||
|
|
@ -20,7 +20,7 @@
|
|||
*
|
||||
* <<Broadcom-WL-IPTag/Open:>>
|
||||
*
|
||||
* $Id: dhd_mschdbg.c 639872 2016-05-25 05:39:30Z sjadhav $
|
||||
* $Id: dhd_mschdbg.c 639872 2016-05-25 05:39:30Z $
|
||||
*/
|
||||
#ifdef SHOW_LOGTRACE
|
||||
#include <typedefs.h>
|
||||
|
|
@ -47,17 +47,17 @@ static const char *head_log = "";
|
|||
} \
|
||||
} while (0)
|
||||
|
||||
#ifdef DHD_EFI
|
||||
#if defined(CUSTOM_PREFIX)
|
||||
#define MSCH_EVENT(args) \
|
||||
do { \
|
||||
if (dhd_msg_level & DHD_EVENT_VAL) { \
|
||||
DHD_LOG_DUMP_WRITE_FW("[%s]: ", dhd_log_dump_get_timestamp()); \
|
||||
DHD_LOG_DUMP_WRITE_FW args; \
|
||||
DBG_PRINT_SYSTEM_TIME; \
|
||||
pr_cont args; \
|
||||
} \
|
||||
} while (0)
|
||||
#else
|
||||
#define MSCH_EVENT(args) do {if (dhd_msg_level & DHD_EVENT_VAL) printf args;} while (0)
|
||||
#endif /* DHD_EFI */
|
||||
#endif
|
||||
|
||||
static uint64 solt_start_time[4], req_start_time[4], profiler_start_time[4];
|
||||
static uint32 solt_chanspec[4] = {0, }, req_start[4] = {0, };
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* DHD debugability header file
|
||||
*
|
||||
* Copyright (C) 2020, Broadcom.
|
||||
* Copyright (C) 2022, Broadcom.
|
||||
*
|
||||
* Unless you and Broadcom execute a separate written software license
|
||||
* agreement governing use of this software, this software is licensed to you
|
||||
|
|
@ -20,7 +20,7 @@
|
|||
*
|
||||
* <<Broadcom-WL-IPTag/Open:>>
|
||||
*
|
||||
* $Id: dhd_mschdbg.h 571265 2015-07-14 20:50:18Z eccopark $
|
||||
* $Id: dhd_mschdbg.h 571265 2015-07-14 20:50:18Z $
|
||||
*/
|
||||
|
||||
#ifndef _dhd_mschdbg_h_
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* Linux DHD Bus Module for PCIE
|
||||
*
|
||||
* Copyright (C) 2020, Broadcom.
|
||||
* Copyright (C) 2022, Broadcom.
|
||||
*
|
||||
* Unless you and Broadcom execute a separate written software license
|
||||
* agreement governing use of this software, this software is licensed to you
|
||||
|
|
@ -28,28 +28,8 @@
|
|||
|
||||
#include <bcmpcie.h>
|
||||
#include <hnd_cons.h>
|
||||
#include <fwpkg_utils.h>
|
||||
#include <dhd_linux.h>
|
||||
#ifdef SUPPORT_LINKDOWN_RECOVERY
|
||||
#ifdef CONFIG_ARCH_MSM
|
||||
#ifdef CONFIG_PCI_MSM
|
||||
#include <linux/msm_pcie.h>
|
||||
#else
|
||||
#include <mach/msm_pcie.h>
|
||||
#endif /* CONFIG_PCI_MSM */
|
||||
#endif /* CONFIG_ARCH_MSM */
|
||||
#ifdef CONFIG_ARCH_EXYNOS
|
||||
#ifndef SUPPORT_EXYNOS7420
|
||||
#include <linux/exynos-pci-noti.h>
|
||||
extern int exynos_pcie_register_event(struct exynos_pcie_register_event *reg);
|
||||
extern int exynos_pcie_deregister_event(struct exynos_pcie_register_event *reg);
|
||||
#endif /* !SUPPORT_EXYNOS7420 */
|
||||
#endif /* CONFIG_ARCH_EXYNOS */
|
||||
#endif /* SUPPORT_LINKDOWN_RECOVERY */
|
||||
|
||||
#ifdef DHD_PCIE_RUNTIMEPM
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/wait.h>
|
||||
#endif /* DHD_PCIE_RUNTIMEPM */
|
||||
|
||||
/* defines */
|
||||
#define PCIE_SHARED_VERSION PCIE_SHARED_VERSION_7
|
||||
|
|
@ -65,19 +45,6 @@ extern int exynos_pcie_deregister_event(struct exynos_pcie_register_event *reg);
|
|||
#define REMAP_ENAB(bus) ((bus)->remap)
|
||||
#define REMAP_ISADDR(bus, a) (((a) >= ((bus)->orig_ramsize)) && ((a) < ((bus)->ramsize)))
|
||||
|
||||
#ifdef SUPPORT_LINKDOWN_RECOVERY
|
||||
#ifdef CONFIG_ARCH_MSM
|
||||
#define struct_pcie_notify struct msm_pcie_notify
|
||||
#define struct_pcie_register_event struct msm_pcie_register_event
|
||||
#endif /* CONFIG_ARCH_MSM */
|
||||
#ifdef CONFIG_ARCH_EXYNOS
|
||||
#ifndef SUPPORT_EXYNOS7420
|
||||
#define struct_pcie_notify struct exynos_pcie_notify
|
||||
#define struct_pcie_register_event struct exynos_pcie_register_event
|
||||
#endif /* !SUPPORT_EXYNOS7420 */
|
||||
#endif /* CONFIG_ARCH_EXYNOS */
|
||||
#endif /* SUPPORT_LINKDOWN_RECOVERY */
|
||||
|
||||
#define MAX_DHD_TX_FLOWS 320
|
||||
|
||||
/* user defined data structures */
|
||||
|
|
@ -186,7 +153,7 @@ typedef struct _dhd_ds_trace_t {
|
|||
|
||||
#define PCIE_FASTLPO_ENABLED(buscorerev) \
|
||||
((buscorerev == 66) || (buscorerev == 67) || (buscorerev == 68) || \
|
||||
(buscorerev == 70) || (buscorerev == 72))
|
||||
(buscorerev == 70) || (buscorerev == 72) || (buscorerev == 76))
|
||||
|
||||
/*
|
||||
* HW JIRA - CRWLPCIEGEN2-672
|
||||
|
|
@ -264,6 +231,16 @@ typedef struct _dhd_flow_ring_status_trace_t {
|
|||
} dhd_frs_trace_t;
|
||||
#endif /* DHD_FLOW_RING_STATUS_TRACE */
|
||||
|
||||
typedef enum dhd_pcie_link_state {
|
||||
DHD_PCIE_ALL_GOOD = 0,
|
||||
DHD_PCIE_LINK_DOWN = 1,
|
||||
DHD_PCIE_COMMON_BP_DOWN = 2,
|
||||
DHD_PCIE_WLAN_BP_DOWN = 3
|
||||
} dhd_pcie_link_state_type_t;
|
||||
|
||||
/* Max length of filename in IOVAR or in module parameter */
|
||||
#define DHD_MAX_PATH 2048u
|
||||
|
||||
/** Instantiated once for each hardware (dongle) instance that this DHD manages */
|
||||
typedef struct dhd_bus {
|
||||
dhd_pub_t *dhd; /**< pointer to per hardware (dongle) unique instance */
|
||||
|
|
@ -271,9 +248,6 @@ typedef struct dhd_bus {
|
|||
struct pci_dev *rc_dev; /* pci RC device handle */
|
||||
struct pci_dev *dev; /* pci device handle */
|
||||
#endif /* !defined(NDIS) */
|
||||
#ifdef DHD_EFI
|
||||
void *pcie_dev;
|
||||
#endif
|
||||
dll_t flowring_active_list; /* constructed list of tx flowring queues */
|
||||
#ifdef IDLE_TX_FLOW_MGMT
|
||||
uint64 active_list_last_process_ts;
|
||||
|
|
@ -349,14 +323,6 @@ typedef struct dhd_bus {
|
|||
uint32 curr_bar1_win; /* current PCIEBar1Window setting */
|
||||
osl_t *osh;
|
||||
uint32 nvram_csm; /* Nvram checksum */
|
||||
#ifdef BCMINTERNAL
|
||||
bool msi_sim;
|
||||
uchar *msi_sim_addr;
|
||||
dmaaddr_t msi_sim_phys;
|
||||
dhd_dma_buf_t hostfw_buf; /* Host offload firmware buffer */
|
||||
uint32 hostfw_base; /* FW assumed base of host offload mem */
|
||||
uint32 bp_base; /* adjusted bp base of host offload mem */
|
||||
#endif /* BCMINTERNAL */
|
||||
uint16 pollrate;
|
||||
uint16 polltick;
|
||||
|
||||
|
|
@ -403,25 +369,8 @@ typedef struct dhd_bus {
|
|||
bool irq_registered;
|
||||
bool d2h_intr_method;
|
||||
bool d2h_intr_control;
|
||||
#ifdef SUPPORT_LINKDOWN_RECOVERY
|
||||
#if defined(CONFIG_ARCH_MSM) || (defined(CONFIG_ARCH_EXYNOS) && \
|
||||
!defined(SUPPORT_EXYNOS7420))
|
||||
#ifdef CONFIG_ARCH_MSM
|
||||
uint8 no_cfg_restore;
|
||||
#endif /* CONFIG_ARCH_MSM */
|
||||
struct_pcie_register_event pcie_event;
|
||||
#endif /* CONFIG_ARCH_MSM || CONFIG_ARCH_EXYNOS && !SUPPORT_EXYNOS7420 */
|
||||
bool read_shm_fail;
|
||||
#endif /* SUPPORT_LINKDOWN_RECOVERY */
|
||||
int32 idletime; /* Control for activity timeout */
|
||||
bool rpm_enabled;
|
||||
#ifdef DHD_PCIE_RUNTIMEPM
|
||||
int32 idlecount; /* Activity timeout counter */
|
||||
int32 bus_wake; /* For wake up the bus */
|
||||
bool runtime_resume_done; /* For check runtime suspend end */
|
||||
struct mutex pm_lock; /* Synchronize for system PM & runtime PM */
|
||||
wait_queue_head_t rpm_queue; /* wait-queue for bus wake up */
|
||||
#endif /* DHD_PCIE_RUNTIMEPM */
|
||||
uint32 d3_inform_cnt;
|
||||
uint32 d0_inform_cnt;
|
||||
uint32 d0_inform_in_use_cnt;
|
||||
|
|
@ -455,14 +404,14 @@ typedef struct dhd_bus {
|
|||
dhd_ds_trace_t ds_trace[MAX_DS_TRACE_SIZE];
|
||||
uint32 ds_trace_count;
|
||||
uint32 hostready_count; /* Number of hostready issued */
|
||||
#if defined(PCIE_OOB) || defined (BCMPCIE_OOB_HOST_WAKE)
|
||||
#if defined(PCIE_OOB) || defined(BCMPCIE_OOB_HOST_WAKE)
|
||||
bool oob_presuspend;
|
||||
#endif /* PCIE_OOB || BCMPCIE_OOB_HOST_WAKE */
|
||||
dhdpcie_config_save_t saved_config;
|
||||
ulong resume_intr_enable_count;
|
||||
ulong dpc_intr_enable_count;
|
||||
ulong isr_intr_disable_count;
|
||||
ulong suspend_intr_disable_count;
|
||||
ulong host_irq_enable_count;
|
||||
ulong host_irq_disable_count;
|
||||
ulong dngl_intmask_disable_count;
|
||||
ulong dngl_intmask_enable_count;
|
||||
ulong dpc_return_busdown_count;
|
||||
ulong non_ours_irq_count;
|
||||
#ifdef BCMPCIE_OOB_HOST_WAKE
|
||||
|
|
@ -475,6 +424,7 @@ typedef struct dhd_bus {
|
|||
uint64 last_oob_irq_disable_time;
|
||||
#endif /* BCMPCIE_OOB_HOST_WAKE */
|
||||
uint64 isr_entry_time;
|
||||
uint64 prev_isr_entry_time;
|
||||
uint64 isr_exit_time;
|
||||
uint64 isr_sched_dpc_time;
|
||||
uint64 rpm_sched_dpc_time;
|
||||
|
|
@ -482,6 +432,7 @@ typedef struct dhd_bus {
|
|||
uint64 dpc_exit_time;
|
||||
uint64 resched_dpc_time;
|
||||
uint64 last_d3_inform_time;
|
||||
uint64 last_d3_ack_time;
|
||||
uint64 last_process_ctrlbuf_time;
|
||||
uint64 last_process_flowring_time;
|
||||
uint64 last_process_txcpl_time;
|
||||
|
|
@ -493,6 +444,16 @@ typedef struct dhd_bus {
|
|||
uint64 last_resume_start_time;
|
||||
uint64 last_resume_end_time;
|
||||
uint64 last_non_ours_irq_time;
|
||||
uint64 dpc_time_usec;
|
||||
uint64 *dpc_time_histo;
|
||||
uint64 ctrl_cpl_post_time_usec;
|
||||
uint64 *ctrl_cpl_post_time_histo;
|
||||
uint64 tx_post_time_usec;
|
||||
uint64 *tx_post_time_histo;
|
||||
uint64 tx_cpl_time_usec;
|
||||
uint64 *tx_cpl_time_histo;
|
||||
uint64 rx_cpl_post_time_usec;
|
||||
uint64 *rx_cpl_post_time_histo;
|
||||
bool hwa_enabled;
|
||||
bool idma_enabled;
|
||||
bool ifrm_enabled;
|
||||
|
|
@ -518,9 +479,6 @@ typedef struct dhd_bus {
|
|||
#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 */
|
||||
#if defined(PCIE_INB_DW)
|
||||
bool calc_ds_exit_latency;
|
||||
bool deep_sleep; /* Indicates deep_sleep set or unset by the DHD IOVAR deep_sleep */
|
||||
|
|
@ -536,6 +494,8 @@ typedef struct dhd_bus {
|
|||
uint32 gdb_proxy_last_id;
|
||||
/* True if firmware was started in bootloader mode */
|
||||
bool gdb_proxy_bootloader_mode;
|
||||
/* Counter incremented at each generated memory dump */
|
||||
uint32 gdb_proxy_mem_dump_count;
|
||||
#endif /* GDB_PROXY */
|
||||
uint8 dma_chan;
|
||||
|
||||
|
|
@ -560,7 +520,7 @@ typedef struct dhd_bus {
|
|||
uint32 fw_memmap_download_addr; /* Dongle address of FWS memory-info download */
|
||||
uint32 fw_memmap_download_len; /* Length in bytes of FWS memory-info download */
|
||||
|
||||
char fwsig_filename[DHD_FILENAME_MAX]; /* Name of FW signature file */
|
||||
char fwsig_filename[DHD_MAX_PATH]; /* Name of FW signature file */
|
||||
char bootloader_filename[DHD_FILENAME_MAX]; /* Name of bootloader image file */
|
||||
uint32 bootloader_addr; /* Dongle address of bootloader download */
|
||||
bool force_bt_quiesce; /* send bt_quiesce command to BT driver. */
|
||||
|
|
@ -576,12 +536,9 @@ typedef struct dhd_bus {
|
|||
#ifdef BCMSLTGT
|
||||
int xtalfreq; /* Xtal frequency used for htclkratio calculation */
|
||||
uint32 ilp_tick; /* ILP ticks per second read from pmutimer */
|
||||
uint32 xtal_ratio; /* xtal ticks per 4 ILP ticks read from pmu_xtalfreq */
|
||||
uint32 alp_to_ilp_ratio; /* ALP ticks per ILP ticks read from pmu_xtalfreq */
|
||||
uint32 xtal_to_alp_ratio; /* xtal to ALP ratio which can change from chip to chip */
|
||||
#endif /* BCMSLTGT */
|
||||
#ifdef BT_OVER_PCIE
|
||||
/* whether the chip is in BT over PCIE mode or not */
|
||||
bool btop_mode;
|
||||
#endif /* BT_OVER_PCIE */
|
||||
uint16 hp2p_txcpl_max_items;
|
||||
uint16 hp2p_rxcpl_max_items;
|
||||
/* PCIE coherent status */
|
||||
|
|
@ -591,8 +548,27 @@ typedef struct dhd_bus {
|
|||
uint64 rd_shared_pass_time;
|
||||
uint32 hwa_mem_base;
|
||||
uint32 hwa_mem_size;
|
||||
dhd_pcie_link_state_type_t link_state;
|
||||
bool dar_err_set;
|
||||
uint32 ptm_ctrl_reg;
|
||||
fwpkg_info_t fwpkg; /* combined fw package info structure */
|
||||
bool lpm_mode; /* lpm enabled */
|
||||
bool lpm_keep_in_reset; /* during LPM keep in FLR, if FLR force is enabled */
|
||||
bool lpm_mem_kill; /* kill WLAN memories in LPM */
|
||||
bool lpm_force_flr; /* Force F0 FLR on WLAN when in LPM */
|
||||
uint32 lpbk_xfer_data_pattern_type; /* data Pattern type DMA lpbk */
|
||||
} dhd_bus_t;
|
||||
|
||||
#define LPBK_DMA_XFER_DTPTRN_DEFAULT 0
|
||||
#define LPBK_DMA_XFER_DTPTRN_0x00 1
|
||||
#define LPBK_DMA_XFER_DTPTRN_0xFF 2
|
||||
#define LPBK_DMA_XFER_DTPTRN_0x55 3
|
||||
#define LPBK_DMA_XFER_DTPTRN_0xAA 4
|
||||
|
||||
#define LPM_MODE_LPM_ALL 0x1
|
||||
#define LPM_MODE_NO_MEMKILL 0x010
|
||||
#define LPM_MODE_NO_FLR 0x100
|
||||
|
||||
#ifdef DHD_MSI_SUPPORT
|
||||
extern uint enable_msi;
|
||||
#endif /* DHD_MSI_SUPPORT */
|
||||
|
|
@ -759,6 +735,7 @@ extern int dhdpcie_disable_irq_nosync(dhd_bus_t *bus);
|
|||
extern int dhdpcie_enable_irq(dhd_bus_t *bus);
|
||||
|
||||
extern void dhd_bus_dump_dar_registers(struct dhd_bus *bus);
|
||||
extern void dhd_bus_dump_imp_cfg_registers(struct dhd_bus *bus);
|
||||
|
||||
#if defined(linux) || defined(LINUX)
|
||||
extern uint32 dhdpcie_rc_config_read(dhd_bus_t *bus, uint offset);
|
||||
|
|
@ -767,6 +744,7 @@ extern uint32 dhdpcie_rc_access_cap(dhd_bus_t *bus, int cap, uint offset, bool i
|
|||
extern uint32 dhdpcie_ep_access_cap(dhd_bus_t *bus, int cap, uint offset, bool is_ext,
|
||||
bool is_write, uint32 writeval);
|
||||
extern uint32 dhd_debug_get_rc_linkcap(dhd_bus_t *bus);
|
||||
extern void dhdpcie_enable_irq_loop(dhd_bus_t *bus);
|
||||
#else
|
||||
static INLINE uint32 dhdpcie_rc_config_read(dhd_bus_t *bus, uint offset) { return 0;}
|
||||
static INLINE uint32 dhdpcie_rc_access_cap(dhd_bus_t *bus, int cap, uint offset, bool is_ext,
|
||||
|
|
@ -774,7 +752,8 @@ static INLINE uint32 dhdpcie_rc_access_cap(dhd_bus_t *bus, int cap, uint offset,
|
|||
static INLINE uint32 dhdpcie_ep_access_cap(dhd_bus_t *bus, int cap, uint offset, bool is_ext,
|
||||
bool is_write, uint32 writeval) { return -1;}
|
||||
static INLINE uint32 dhd_debug_get_rc_linkcap(dhd_bus_t *bus) { return -1;}
|
||||
#endif
|
||||
static INLINE void dhdpcie_enable_irq_loop(dhd_bus_t *bus) { return; }
|
||||
#endif /* LINUX || linux */
|
||||
#if defined(linux) || defined(LINUX)
|
||||
extern int dhdpcie_start_host_dev(dhd_bus_t *bus);
|
||||
extern int dhdpcie_stop_host_dev(dhd_bus_t *bus);
|
||||
|
|
@ -794,9 +773,10 @@ uint32 dhdpcie_os_rtcm32(dhd_bus_t *bus, ulong offset);
|
|||
void dhdpcie_os_wtcm64(dhd_bus_t *bus, ulong offset, uint64 data);
|
||||
uint64 dhdpcie_os_rtcm64(dhd_bus_t *bus, ulong offset);
|
||||
#endif
|
||||
extern void dhd_dpc_kill(dhd_pub_t *dhdp);
|
||||
#endif /* LINUX || linux */
|
||||
|
||||
#if defined(linux) || defined(LINUX) || defined(DHD_EFI)
|
||||
#if defined(linux) || defined(LINUX)
|
||||
extern int dhdpcie_enable_device(dhd_bus_t *bus);
|
||||
#endif
|
||||
|
||||
|
|
@ -807,6 +787,9 @@ extern void dhdpcie_oob_intr_set(dhd_bus_t *bus, bool enable);
|
|||
extern int dhdpcie_get_oob_irq_num(struct dhd_bus *bus);
|
||||
extern int dhdpcie_get_oob_irq_status(struct dhd_bus *bus);
|
||||
extern int dhdpcie_get_oob_irq_level(void);
|
||||
#ifdef PRINT_WAKEUP_GPIO_STATUS
|
||||
extern int dhdpcie_get_oob_gpio_number(void);
|
||||
#endif /* PRINT_WAKEUP_GPIO_STATUS */
|
||||
#endif /* BCMPCIE_OOB_HOST_WAKE */
|
||||
#ifdef PCIE_OOB
|
||||
extern void dhd_oob_set_bt_reg_on(struct dhd_bus *bus, bool val);
|
||||
|
|
@ -819,93 +802,14 @@ extern void dhd_os_ib_set_device_wake(struct dhd_bus *bus, bool val);
|
|||
extern void dhd_bus_doorbell_timeout_reset(struct dhd_bus *bus);
|
||||
#endif /* defined(PCIE_OOB) || defined(PCIE_INB_DW) */
|
||||
|
||||
#if defined(linux) || defined(LINUX)
|
||||
/* XXX: SWWLAN-82173 Making PCIe RC D3cold by force during system PM
|
||||
* exynos_pcie_pm_suspend : RC goes to suspend status & assert PERST
|
||||
* exynos_pcie_pm_resume : de-assert PERST & RC goes to resume status
|
||||
*/
|
||||
#if defined(CONFIG_ARCH_EXYNOS)
|
||||
#define EXYNOS_PCIE_VENDOR_ID 0x144d
|
||||
#if defined(CONFIG_MACH_UNIVERSAL7420) || defined(CONFIG_SOC_EXYNOS7420)
|
||||
#define EXYNOS_PCIE_DEVICE_ID 0xa575
|
||||
#define EXYNOS_PCIE_CH_NUM 1
|
||||
#elif defined(CONFIG_SOC_EXYNOS8890)
|
||||
#define EXYNOS_PCIE_DEVICE_ID 0xa544
|
||||
#define EXYNOS_PCIE_CH_NUM 0
|
||||
#elif defined(CONFIG_SOC_EXYNOS8895) || defined(CONFIG_SOC_EXYNOS9810) || \
|
||||
defined(CONFIG_SOC_EXYNOS9820) || defined(CONFIG_SOC_EXYNOS9830) || \
|
||||
defined(CONFIG_SOC_EXYNOS2100) || defined(CONFIG_SOC_EXYNOS1000) || \
|
||||
defined(CONFIG_SOC_GS101)
|
||||
#define EXYNOS_PCIE_DEVICE_ID 0xecec
|
||||
#define EXYNOS_PCIE_CH_NUM 0
|
||||
#else
|
||||
#error "Not supported platform"
|
||||
#endif /* CONFIG_SOC_EXYNOSXXXX & CONFIG_MACH_UNIVERSALXXXX */
|
||||
extern void exynos_pcie_pm_suspend(int ch_num);
|
||||
extern void exynos_pcie_pm_resume(int ch_num);
|
||||
#endif /* CONFIG_ARCH_EXYNOS */
|
||||
|
||||
#if defined(CONFIG_ARCH_MSM)
|
||||
#define MSM_PCIE_VENDOR_ID 0x17cb
|
||||
#if defined(CONFIG_ARCH_APQ8084)
|
||||
#define MSM_PCIE_DEVICE_ID 0x0101
|
||||
#elif defined(CONFIG_ARCH_MSM8994)
|
||||
#define MSM_PCIE_DEVICE_ID 0x0300
|
||||
#elif defined(CONFIG_ARCH_MSM8996)
|
||||
#define MSM_PCIE_DEVICE_ID 0x0104
|
||||
#elif defined(CONFIG_ARCH_MSM8998)
|
||||
#define MSM_PCIE_DEVICE_ID 0x0105
|
||||
#elif defined(CONFIG_ARCH_SDM845) || defined(CONFIG_ARCH_SM8150) || \
|
||||
defined(CONFIG_ARCH_KONA) || defined(CONFIG_ARCH_LAHAINA)
|
||||
#define MSM_PCIE_DEVICE_ID 0x0106
|
||||
#else
|
||||
#error "Not supported platform"
|
||||
#endif
|
||||
#endif /* CONFIG_ARCH_MSM */
|
||||
|
||||
#if defined(CONFIG_X86)
|
||||
#define X86_PCIE_VENDOR_ID 0x8086
|
||||
#define X86_PCIE_DEVICE_ID 0x9c1a
|
||||
#endif /* CONFIG_X86 */
|
||||
|
||||
#if defined(CONFIG_ARCH_TEGRA)
|
||||
#define TEGRA_PCIE_VENDOR_ID 0x14e4
|
||||
#define TEGRA_PCIE_DEVICE_ID 0x4347
|
||||
#endif /* CONFIG_ARCH_TEGRA */
|
||||
|
||||
#if defined(BOARD_HIKEY)
|
||||
#define HIKEY_PCIE_VENDOR_ID 0x19e5
|
||||
#define HIKEY_PCIE_DEVICE_ID 0x3660
|
||||
#endif /* BOARD_HIKEY */
|
||||
|
||||
#define DUMMY_PCIE_VENDOR_ID 0xffff
|
||||
#define DUMMY_PCIE_DEVICE_ID 0xffff
|
||||
|
||||
#if defined(CONFIG_ARCH_EXYNOS)
|
||||
#define PCIE_RC_VENDOR_ID EXYNOS_PCIE_VENDOR_ID
|
||||
#define PCIE_RC_DEVICE_ID EXYNOS_PCIE_DEVICE_ID
|
||||
#elif defined(CONFIG_ARCH_MSM)
|
||||
#define PCIE_RC_VENDOR_ID MSM_PCIE_VENDOR_ID
|
||||
#define PCIE_RC_DEVICE_ID MSM_PCIE_DEVICE_ID
|
||||
#elif defined(CONFIG_X86)
|
||||
#define PCIE_RC_VENDOR_ID X86_PCIE_VENDOR_ID
|
||||
#define PCIE_RC_DEVICE_ID X86_PCIE_DEVICE_ID
|
||||
#elif defined(CONFIG_ARCH_TEGRA)
|
||||
#define PCIE_RC_VENDOR_ID TEGRA_PCIE_VENDOR_ID
|
||||
#define PCIE_RC_DEVICE_ID TEGRA_PCIE_DEVICE_ID
|
||||
#elif defined(BOARD_HIKEY)
|
||||
#define PCIE_RC_VENDOR_ID HIKEY_PCIE_VENDOR_ID
|
||||
#define PCIE_RC_DEVICE_ID HIKEY_PCIE_DEVICE_ID
|
||||
#else
|
||||
/* Use dummy vendor and device IDs */
|
||||
#define PCIE_RC_VENDOR_ID DUMMY_PCIE_VENDOR_ID
|
||||
#define PCIE_RC_DEVICE_ID DUMMY_PCIE_DEVICE_ID
|
||||
#endif /* CONFIG_ARCH_EXYNOS */
|
||||
#endif /* linux || LINUX */
|
||||
|
||||
#define DHD_REGULAR_RING 0
|
||||
#define DHD_HP2P_RING 1
|
||||
|
||||
#ifdef DHD_SET_PCIE_DMA_MASK_FOR_GS101
|
||||
/* This is only for GS101 platform. Others is done on RC side */
|
||||
#define DHD_PCIE_DMA_MASK_FOR_GS101 36
|
||||
#endif /* DHD_SET_PCIE_DMA_MASK_FOR_GS101 */
|
||||
|
||||
#ifdef CONFIG_ARCH_TEGRA
|
||||
extern int tegra_pcie_pm_suspend(void);
|
||||
extern int tegra_pcie_pm_resume(void);
|
||||
|
|
@ -932,6 +836,8 @@ extern int dhdpcie_send_mb_data(dhd_bus_t *bus, uint32 h2d_mb_data);
|
|||
#ifdef DHD_WAKE_STATUS
|
||||
int bcmpcie_get_total_wake(struct dhd_bus *bus);
|
||||
int bcmpcie_set_get_wake(struct dhd_bus *bus, int flag);
|
||||
int bcmpcie_get_wake(struct dhd_bus *bus);
|
||||
int bcmpcie_set_get_wake_pkt_dump(struct dhd_bus *bus, int wake_pkt_dump);
|
||||
#endif /* DHD_WAKE_STATUS */
|
||||
#ifdef DHD_MMIO_TRACE
|
||||
extern void dhd_dump_bus_mmio_trace(dhd_bus_t *bus, struct bcmstrbuf *strbuf);
|
||||
|
|
@ -950,6 +856,9 @@ extern enum dhd_bus_ds_state dhdpcie_bus_get_pcie_inband_dw_state(dhd_bus_t *bus
|
|||
extern const char * dhd_convert_inb_state_names(enum dhd_bus_ds_state inbstate);
|
||||
extern const char * dhd_convert_dsval(uint32 val, bool d2h);
|
||||
extern int dhd_bus_inb_set_device_wake(struct dhd_bus *bus, bool val);
|
||||
#ifdef PCIE_INB_DSACK_EXT_WAIT
|
||||
extern void dhd_bus_ds_ack_debug_dump(struct dhd_bus *bus);
|
||||
#endif /* PCIE_INB_DSACK_EXT_WAIT */
|
||||
extern void dhd_bus_inb_ack_pending_ds_req(dhd_bus_t *bus);
|
||||
#endif /* PCIE_INB_DW */
|
||||
extern void dhdpcie_bus_enab_pcie_dw(dhd_bus_t *bus, uint8 dw_option);
|
||||
|
|
@ -962,27 +871,11 @@ static INLINE int dhdpcie_set_master_and_d0_pwrstate(struct dhd_bus *bus)
|
|||
{ return BCME_ERROR;}
|
||||
#endif /* defined(LINUX) || defined(linux) */
|
||||
|
||||
#ifdef DHD_EFI
|
||||
extern bool dhdpcie_is_arm_halted(struct dhd_bus *bus);
|
||||
extern int dhd_os_wifi_platform_set_power(uint32 value);
|
||||
extern void dhdpcie_dongle_pwr_toggle(dhd_bus_t *bus);
|
||||
void dhdpcie_dongle_flr_or_pwr_toggle(dhd_bus_t *bus);
|
||||
int dhd_control_signal(dhd_bus_t *bus, char *arg, int len, int set);
|
||||
extern int dhd_wifi_properties(struct dhd_bus *bus, char *arg, int len);
|
||||
extern int dhd_otp_dump(dhd_bus_t *bus, char *arg, int len);
|
||||
extern int dhdpcie_deinit_phase1(dhd_bus_t *bus);
|
||||
int dhdpcie_disable_intr_poll(dhd_bus_t *bus);
|
||||
int dhdpcie_enable_intr_poll(dhd_bus_t *bus);
|
||||
#ifdef BT_OVER_PCIE
|
||||
int dhd_btop_test(dhd_bus_t *bus, char *arg, int len);
|
||||
#endif /* BT_OVER_PCIE */
|
||||
#else
|
||||
static INLINE bool dhdpcie_is_arm_halted(struct dhd_bus *bus) {return TRUE;}
|
||||
static INLINE int dhd_os_wifi_platform_set_power(uint32 value) {return BCME_OK; }
|
||||
static INLINE void
|
||||
dhdpcie_dongle_flr_or_pwr_toggle(dhd_bus_t *bus)
|
||||
{ return; }
|
||||
#endif /* DHD_EFI */
|
||||
|
||||
int dhdpcie_config_check(dhd_bus_t *bus);
|
||||
int dhdpcie_config_restore(dhd_bus_t *bus, bool restore_pmcsr);
|
||||
|
|
@ -1022,18 +915,10 @@ extern int dhdpcie_get_fwpath_otp(dhd_bus_t *bus, char *fw_path, char *nv_path,
|
|||
extern int dhd_pcie_debug_info_dump(dhd_pub_t *dhd);
|
||||
extern void dhd_pcie_intr_count_dump(dhd_pub_t *dhd);
|
||||
extern void dhdpcie_bus_clear_intstatus(dhd_bus_t *bus);
|
||||
#ifdef DHD_HP2P
|
||||
extern uint16 dhd_bus_get_hp2p_ring_max_size(dhd_bus_t *bus, bool tx);
|
||||
#endif
|
||||
|
||||
#if defined(DHD_EFI)
|
||||
extern wifi_properties_t *dhd_get_props(dhd_bus_t *bus);
|
||||
#endif
|
||||
|
||||
#if defined(DHD_EFI) || defined(NDIS)
|
||||
#if defined(NDIS)
|
||||
extern int dhd_get_platform(dhd_pub_t* dhd, char *progname);
|
||||
extern bool dhdpcie_is_chip_supported(uint32 chipid, int *idx);
|
||||
extern bool dhdpcie_is_sflash_chip(uint32 chipid);
|
||||
#endif
|
||||
|
||||
extern int dhd_get_pcie_linkspeed(dhd_pub_t *dhd);
|
||||
|
|
@ -1045,4 +930,11 @@ extern void dhd_init_dongle_ds_lock(dhd_bus_t *bus);
|
|||
extern void dhd_deinit_dongle_ds_lock(dhd_bus_t *bus);
|
||||
#endif /* PCIE_INB_DW */
|
||||
|
||||
extern bool dhd_check_htput_chip(dhd_bus_t *bus);
|
||||
|
||||
#if defined(DEVICE_TX_STUCK_DETECT) && defined(ASSOC_CHECK_SR)
|
||||
void dhd_assoc_check_sr(dhd_pub_t *dhd, bool state);
|
||||
#endif /* DEVICE_TX_STUCK_DETECT && ASSOC_CHECK_SR */
|
||||
|
||||
void dhd_init_bar1_switch_lock(dhd_bus_t *bus);
|
||||
#endif /* dhd_pcie_h */
|
||||
|
|
|
|||
1106
drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_pcie_linux.c
Executable file → Normal file
1106
drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_pcie_linux.c
Executable file → Normal file
File diff suppressed because it is too large
Load Diff
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* DHD debugability packet logging support
|
||||
*
|
||||
* Copyright (C) 2020, Broadcom.
|
||||
* Copyright (C) 2022, Broadcom.
|
||||
*
|
||||
* Unless you and Broadcom execute a separate written software license
|
||||
* agreement governing use of this software, this software is licensed to you
|
||||
|
|
@ -32,6 +32,7 @@
|
|||
#include <dhd_dbg.h>
|
||||
#include <dhd_pktlog.h>
|
||||
#include <dhd_wlfc.h>
|
||||
#include <dhd_debug.h>
|
||||
|
||||
#ifdef DHD_COMPACT_PKT_LOG
|
||||
#include <bcmip.h>
|
||||
|
|
@ -41,6 +42,7 @@
|
|||
#include <bcmicmp.h>
|
||||
#include <bcmtlv.h>
|
||||
#include <802.11.h>
|
||||
#include <802.11u.h>
|
||||
#include <eap.h>
|
||||
#include <eapol.h>
|
||||
#include <bcmendian.h>
|
||||
|
|
@ -129,9 +131,37 @@ static int dhd_cpkt_log_init_tt(dhd_pub_t *dhdp);
|
|||
static void dhd_cpkt_log_deinit_tt(dhd_pub_t *dhdp);
|
||||
#endif /* DHD_COMPACT_PKT_LOG */
|
||||
|
||||
#ifdef DHD_PKT_LOGGING_DBGRING
|
||||
#define DHD_PKT_LOGGING_DBGRING_MAX_SIZE 400u
|
||||
const char dhd_eap_pattern[] = "12 0xffff 0x888e";
|
||||
const char dhd_arp_pattern[] = "12 0xffff 0x0806";
|
||||
const char dhd_icmp_pattern[] =
|
||||
"12 0xffffff0000000000000000ff 0x080045000000000000000001";
|
||||
const char dhd_icmpv6_pattern[] =
|
||||
"12 0xfffff00000000000ff 0x86dd6000000000003a";
|
||||
const char dhd_dhcp_pattern_01[] =
|
||||
"12 0xffffff0000000000000000ff00000000000000000000ffffffff"
|
||||
" 0x0800450000000000000000110000000000000000000000430044";
|
||||
const char dhd_dhcp_pattern_02[] =
|
||||
"12 0xffffff0000000000000000ff00000000000000000000ffffffff"
|
||||
" 0x0800450000000000000000110000000000000000000000440043";
|
||||
const char dhd_dns_pattern_01[] =
|
||||
"12 0xffffff0000000000000000ff000000000000000000000000ffff"
|
||||
" 0x0800450000000000000000110000000000000000000000000035";
|
||||
const char dhd_dns_pattern_02[] =
|
||||
"12 0xffffff0000000000000000ff00000000000000000000ffff0000"
|
||||
" 0x0800450000000000000000110000000000000000000000350000";
|
||||
const char dhd_dns_pattern_03[] =
|
||||
"12 0xffffff0000000000000000ff00000000000000000000ffffffff"
|
||||
" 0x0800450000000000000000110000000000000000000014e914e9";
|
||||
#endif /* DHD_PKT_LOGGING_DBGRING */
|
||||
|
||||
int
|
||||
dhd_os_attach_pktlog(dhd_pub_t *dhdp)
|
||||
{
|
||||
#ifdef DHD_PKT_LOGGING_DBGRING
|
||||
char filter_pattern[MAX_FILTER_PATTERN_LEN];
|
||||
#endif /* DHD_PKT_LOGGING_DBGRING */
|
||||
dhd_pktlog_t *pktlog;
|
||||
|
||||
if (!dhdp) {
|
||||
|
|
@ -139,7 +169,7 @@ dhd_os_attach_pktlog(dhd_pub_t *dhdp)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
pktlog = (dhd_pktlog_t *)MALLOCZ(dhdp->osh, sizeof(dhd_pktlog_t));
|
||||
pktlog = (dhd_pktlog_t *)VMALLOCZ(dhdp->osh, sizeof(dhd_pktlog_t));
|
||||
if (unlikely(!pktlog)) {
|
||||
DHD_ERROR(("%s(): could not allocate memory for - "
|
||||
"dhd_pktlog_t\n", __FUNCTION__));
|
||||
|
|
@ -150,6 +180,9 @@ dhd_os_attach_pktlog(dhd_pub_t *dhdp)
|
|||
pktlog->dhdp = dhdp;
|
||||
|
||||
OSL_ATOMIC_INIT(dhdp->osh, &pktlog->pktlog_status);
|
||||
#ifdef DHD_PKT_LOGGING_DBGRING
|
||||
OSL_ATOMIC_INIT(dhdp->osh, &pktlog->enable);
|
||||
#endif /* DHD_PKT_LOGGING_DBGRING */
|
||||
|
||||
/* pktlog ring */
|
||||
dhdp->pktlog->pktlog_ring = dhd_pktlog_ring_init(dhdp, MIN_PKTLOG_LEN);
|
||||
|
|
@ -158,6 +191,16 @@ dhd_os_attach_pktlog(dhd_pub_t *dhdp)
|
|||
dhd_cpkt_log_init_tt(dhdp);
|
||||
#endif
|
||||
|
||||
#ifdef DHD_PKT_LOGGING_DBGRING
|
||||
/* By default, EAP, ARP, ICMP, ICMPV6, DHCP packets are allowed. */
|
||||
DHD_PKTLOG_FILTER_ADD(dhd_eap_pattern, filter_pattern, dhdp);
|
||||
DHD_PKTLOG_FILTER_ADD(dhd_arp_pattern, filter_pattern, dhdp);
|
||||
DHD_PKTLOG_FILTER_ADD(dhd_icmp_pattern, filter_pattern, dhdp);
|
||||
DHD_PKTLOG_FILTER_ADD(dhd_icmpv6_pattern, filter_pattern, dhdp);
|
||||
DHD_PKTLOG_FILTER_ADD(dhd_dhcp_pattern_01, filter_pattern, dhdp);
|
||||
DHD_PKTLOG_FILTER_ADD(dhd_dhcp_pattern_02, filter_pattern, dhdp);
|
||||
#endif /* DHD_PKT_LOGGING_DBGRING */
|
||||
|
||||
DHD_ERROR(("%s(): dhd_os_attach_pktlog attach\n", __FUNCTION__));
|
||||
|
||||
return BCME_OK;
|
||||
|
|
@ -178,13 +221,80 @@ dhd_os_detach_pktlog(dhd_pub_t *dhdp)
|
|||
dhd_cpkt_log_deinit_tt(dhdp);
|
||||
#endif /* DHD_COMPACT_PKT_LOG */
|
||||
|
||||
DHD_ERROR(("%s(): dhd_os_attach_pktlog detach\n", __FUNCTION__));
|
||||
DHD_INFO(("%s(): dhd_os_attach_pktlog detach\n", __FUNCTION__));
|
||||
|
||||
MFREE(dhdp->osh, dhdp->pktlog, sizeof(dhd_pktlog_t));
|
||||
VMFREE(dhdp->osh, dhdp->pktlog, sizeof(dhd_pktlog_t));
|
||||
|
||||
return BCME_OK;
|
||||
}
|
||||
|
||||
#ifdef DHD_PKT_LOGGING_DBGRING
|
||||
int dhd_pktlog_is_enabled(dhd_pub_t *dhdp)
|
||||
{
|
||||
if (!dhdp || !dhdp->pktlog) {
|
||||
DHD_ERROR(("%s(): dhdp=%p pktlog=%p\n",
|
||||
__FUNCTION__, dhdp, (dhdp ? dhdp->pktlog : NULL)));
|
||||
return BCME_ERROR;
|
||||
}
|
||||
|
||||
if (!dhdp->pktlog->pktlog_ring) {
|
||||
DHD_ERROR(("%s(): pktlog_ring=%p\n",
|
||||
__FUNCTION__, dhdp->pktlog->pktlog_ring));
|
||||
return BCME_ERROR;
|
||||
}
|
||||
|
||||
return OSL_ATOMIC_READ(dhdp->osh, &dhdp->pktlog->enable);
|
||||
}
|
||||
|
||||
void dhd_pktlog_resume(dhd_pub_t *dhdp)
|
||||
{
|
||||
struct dhd_pktlog_ring *pktlog_ring;
|
||||
|
||||
if (!dhdp || !dhdp->pktlog) {
|
||||
DHD_ERROR(("%s(): dhdp=%p pktlog=%p\n",
|
||||
__FUNCTION__, dhdp, (dhdp ? dhdp->pktlog : NULL)));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!dhdp->pktlog->pktlog_ring) {
|
||||
DHD_ERROR(("%s(): pktlog_ring=%p\n",
|
||||
__FUNCTION__, dhdp->pktlog->pktlog_ring));
|
||||
return;
|
||||
}
|
||||
|
||||
pktlog_ring = dhdp->pktlog->pktlog_ring;
|
||||
if (!OSL_ATOMIC_READ(dhdp->osh, &dhdp->pktlog->enable)) {
|
||||
OSL_ATOMIC_SET(dhdp->osh, &dhdp->pktlog->enable, TRUE);
|
||||
DHD_INFO(("pktlog ring is resumed. pktcount(%d)\n",
|
||||
pktlog_ring->pktcount));
|
||||
}
|
||||
}
|
||||
|
||||
void dhd_pktlog_suspend(dhd_pub_t *dhdp)
|
||||
{
|
||||
struct dhd_pktlog_ring *pktlog_ring;
|
||||
|
||||
if (!dhdp || !dhdp->pktlog) {
|
||||
DHD_ERROR(("%s(): dhdp=%p pktlog=%p\n",
|
||||
__FUNCTION__, dhdp, (dhdp ? dhdp->pktlog : NULL)));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!dhdp->pktlog->pktlog_ring) {
|
||||
DHD_ERROR(("%s(): pktlog_ring=%p\n",
|
||||
__FUNCTION__, dhdp->pktlog->pktlog_ring));
|
||||
return;
|
||||
}
|
||||
|
||||
pktlog_ring = dhdp->pktlog->pktlog_ring;
|
||||
if (OSL_ATOMIC_READ(dhdp->osh, &dhdp->pktlog->enable)) {
|
||||
OSL_ATOMIC_SET(dhdp->osh, &dhdp->pktlog->enable, FALSE);
|
||||
DHD_INFO(("pktlog ring is suspended. pktcount(%d)\n",
|
||||
pktlog_ring->pktcount));
|
||||
}
|
||||
}
|
||||
#endif /* DHD_PKT_LOGGING_DBGRING */
|
||||
|
||||
dhd_pktlog_ring_t*
|
||||
dhd_pktlog_ring_init(dhd_pub_t *dhdp, int size)
|
||||
{
|
||||
|
|
@ -196,7 +306,7 @@ dhd_pktlog_ring_init(dhd_pub_t *dhdp, int size)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
ring = (dhd_pktlog_ring_t *)MALLOCZ(dhdp->osh, sizeof(dhd_pktlog_ring_t));
|
||||
ring = (dhd_pktlog_ring_t *)VMALLOCZ(dhdp->osh, sizeof(dhd_pktlog_ring_t));
|
||||
if (unlikely(!ring)) {
|
||||
DHD_ERROR(("%s(): could not allocate memory for - "
|
||||
"dhd_pktlog_ring_t\n", __FUNCTION__));
|
||||
|
|
@ -206,7 +316,7 @@ dhd_pktlog_ring_init(dhd_pub_t *dhdp, int size)
|
|||
dll_init(&ring->ring_info_head);
|
||||
dll_init(&ring->ring_info_free);
|
||||
|
||||
ring->ring_info_mem = (dhd_pktlog_ring_info_t *)MALLOCZ(dhdp->osh,
|
||||
ring->ring_info_mem = (dhd_pktlog_ring_info_t *)VMALLOCZ(dhdp->osh,
|
||||
sizeof(dhd_pktlog_ring_info_t) * size);
|
||||
if (unlikely(!ring->ring_info_mem)) {
|
||||
DHD_ERROR(("%s(): could not allocate memory for - "
|
||||
|
|
@ -225,13 +335,16 @@ dhd_pktlog_ring_init(dhd_pub_t *dhdp, int size)
|
|||
ring->pktcount = 0;
|
||||
ring->dhdp = dhdp;
|
||||
ring->pktlog_ring_lock = osl_spin_lock_init(dhdp->osh);
|
||||
#ifdef DHD_PKT_LOGGING_DBGRING
|
||||
OSL_ATOMIC_SET(dhdp->osh, &dhdp->pktlog->enable, TRUE);
|
||||
#endif /* DHD_PKT_LOGGING_DBGRING */
|
||||
|
||||
DHD_ERROR(("%s(): pktlog ring init success\n", __FUNCTION__));
|
||||
DHD_INFO(("%s(): pktlog ring init success\n", __FUNCTION__));
|
||||
|
||||
return ring;
|
||||
fail:
|
||||
if (ring) {
|
||||
MFREE(dhdp->osh, ring, sizeof(dhd_pktlog_ring_t));
|
||||
VMFREE(dhdp->osh, ring, sizeof(dhd_pktlog_ring_t));
|
||||
}
|
||||
|
||||
return NULL;
|
||||
|
|
@ -290,7 +403,7 @@ dhd_pktlog_ring_deinit(dhd_pub_t *dhdp, dhd_pktlog_ring_t *ring)
|
|||
}
|
||||
|
||||
if (ring->ring_info_mem) {
|
||||
MFREE(ring->dhdp->osh, ring->ring_info_mem,
|
||||
VMFREE(ring->dhdp->osh, ring->ring_info_mem,
|
||||
sizeof(dhd_pktlog_ring_info_t) * ring->pktlog_len);
|
||||
}
|
||||
|
||||
|
|
@ -298,13 +411,86 @@ dhd_pktlog_ring_deinit(dhd_pub_t *dhdp, dhd_pktlog_ring_t *ring)
|
|||
osl_spin_lock_deinit(ring->dhdp->osh, ring->pktlog_ring_lock);
|
||||
}
|
||||
|
||||
MFREE(dhdp->osh, ring, sizeof(dhd_pktlog_ring_t));
|
||||
VMFREE(dhdp->osh, ring, sizeof(dhd_pktlog_ring_t));
|
||||
|
||||
DHD_ERROR(("%s(): pktlog ring deinit\n", __FUNCTION__));
|
||||
DHD_INFO(("%s(): pktlog ring deinit\n", __FUNCTION__));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef DHD_PKT_LOGGING_DBGRING
|
||||
int
|
||||
dhd_pktlog_ring_reinit(dhd_pub_t *dhdp)
|
||||
{
|
||||
dhd_pktlog_ring_info_t *ring_info;
|
||||
dhd_pktlog_ring_t *pktlog_ring;
|
||||
dll_t *item, *next_p;
|
||||
int waitcounts = 0;
|
||||
dhd_dbg_ring_t *ring;
|
||||
|
||||
DHD_ERROR(("%s: ENTER\n", __FUNCTION__));
|
||||
|
||||
if (!dhdp) {
|
||||
DHD_ERROR(("%s(): dhdp is NULL\n", __FUNCTION__));
|
||||
return -EINVAL;
|
||||
}
|
||||
pktlog_ring = dhdp->pktlog->pktlog_ring;
|
||||
ring = &dhdp->dbg->dbg_rings[PACKET_LOG_RING_ID];
|
||||
|
||||
if (!ring) {
|
||||
DHD_ERROR(("%s(): ring is NULL\n", __FUNCTION__));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* stop pkt log */
|
||||
OSL_ATOMIC_SET(dhdp->osh, &pktlog_ring->start, FALSE);
|
||||
|
||||
/* waiting TX/RX/TXS context is done, max timeout 1 second */
|
||||
while ((waitcounts++ < DHD_PKTLOG_WAIT_MAXCOUNT)) {
|
||||
if (!OSL_ATOMIC_READ(dhdp->osh, &dhdp->pktlog->pktlog_status))
|
||||
break;
|
||||
OSL_SLEEP(1);
|
||||
}
|
||||
|
||||
if (waitcounts >= DHD_PKTLOG_WAIT_MAXCOUNT) {
|
||||
DHD_ERROR(("%s(): pktlog wait timeout pktlog_status : 0x%x \n",
|
||||
__FUNCTION__,
|
||||
OSL_ATOMIC_READ(dhdp->osh, &dhdp->pktlog->pktlog_status)));
|
||||
ASSERT(0);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* free ring_info->info.pkt */
|
||||
for (item = dll_head_p(&pktlog_ring->ring_info_head);
|
||||
!dll_end(&pktlog_ring->ring_info_head, item);
|
||||
item = next_p) {
|
||||
next_p = dll_next_p(item);
|
||||
|
||||
ring_info = (dhd_pktlog_ring_info_t *)item;
|
||||
|
||||
dll_delete((dll_t *)item);
|
||||
if (ring_info->info.pkt) {
|
||||
PKTFREE(pktlog_ring->dhdp->osh, ring_info->info.pkt, TRUE);
|
||||
DHD_PKT_LOG(("%s(): pkt free pos %p\n",
|
||||
__FUNCTION__, ring_info->info.pkt));
|
||||
}
|
||||
dll_append(&pktlog_ring->ring_info_free, (dll_t *)item);
|
||||
}
|
||||
|
||||
/* reset stats and pktcount */
|
||||
pktlog_ring->pktcount = 0;
|
||||
memset(&ring->stat, 0, sizeof(struct ring_statistics));
|
||||
/* start pkt log */
|
||||
OSL_ATOMIC_SET(dhdp->osh, &pktlog_ring->start, TRUE);
|
||||
#ifdef DHD_PKT_LOGGING_DBGRING
|
||||
OSL_ATOMIC_SET(dhdp->osh, &dhdp->pktlog->enable, TRUE);
|
||||
#endif /* DHD_PKT_LOGGING_DBGRING */
|
||||
DHD_ERROR(("%s: EXIT\n", __FUNCTION__));
|
||||
|
||||
return BCME_OK;
|
||||
}
|
||||
#endif /* DHD_PKT_LOGGING_DBGRING */
|
||||
|
||||
/*
|
||||
* dhd_pktlog_ring_add_pkts : add filtered packets into pktlog ring
|
||||
* pktid : incase of rx, pktid is not used (pass DHD_INVALID_PKID)
|
||||
|
|
@ -316,10 +502,16 @@ dhd_pktlog_ring_add_pkts(dhd_pub_t *dhdp, void *pkt, void *pktdata, uint32 pktid
|
|||
dhd_pktlog_ring_info_t *pkts;
|
||||
dhd_pktlog_ring_t *pktlog_ring;
|
||||
dhd_pktlog_filter_t *pktlog_filter;
|
||||
u64 ts_nsec;
|
||||
uint32 pktlog_case = 0;
|
||||
unsigned long rem_nsec;
|
||||
unsigned long flags = 0;
|
||||
#ifdef DHD_PKT_LOGGING_DBGRING
|
||||
struct timespec64 ts;
|
||||
dhd_dbg_ring_t *ring;
|
||||
ring = &dhdp->dbg->dbg_rings[PACKET_LOG_RING_ID];
|
||||
#else
|
||||
u64 ts_nsec;
|
||||
unsigned long rem_nsec;
|
||||
#endif /* DHD_PKT_LOGGING_DBGRING */
|
||||
|
||||
/*
|
||||
* dhdp, dhdp->pktlog, dhd->pktlog_ring, pktlog_ring->start
|
||||
|
|
@ -335,6 +527,16 @@ dhd_pktlog_ring_add_pkts(dhd_pub_t *dhdp, void *pkt, void *pktdata, uint32 pktid
|
|||
pktlog_case = PKTLOG_RXPKT_CASE;
|
||||
}
|
||||
|
||||
if (pktlog_filter && pktlog_filter->list_cnt == 0) {
|
||||
/* There is no packet log list */
|
||||
return BCME_OK;
|
||||
}
|
||||
|
||||
#ifdef DHD_PKT_LOGGING_DBGRING
|
||||
if (ring->log_level == RING_LOG_LEVEL_EXCESSIVE) {
|
||||
/* In excessive log level, pass through without pattern matching */
|
||||
} else
|
||||
#endif /* DHD_PKT_LOGGING_DBGRING */
|
||||
if ((direction != PKT_WAKERX) &&
|
||||
dhd_pktlog_filter_matched(pktlog_filter, pktdata, pktlog_case)
|
||||
== FALSE) {
|
||||
|
|
@ -361,17 +563,36 @@ dhd_pktlog_ring_add_pkts(dhd_pub_t *dhdp, void *pkt, void *pktdata, uint32 pktid
|
|||
}
|
||||
|
||||
/* Update packet information */
|
||||
#ifdef DHD_PKT_LOGGING_DBGRING
|
||||
ktime_get_real_ts64(&ts);
|
||||
|
||||
pkts->info.driver_ts_sec = (uint32)ts.tv_sec;
|
||||
pkts->info.driver_ts_usec = (uint32)(ts.tv_nsec/NSEC_PER_USEC);
|
||||
#else
|
||||
ts_nsec = local_clock();
|
||||
rem_nsec = do_div(ts_nsec, NSEC_PER_SEC);
|
||||
|
||||
pkts->info.pkt = PKTDUP(dhdp->osh, pkt);
|
||||
pkts->info.pkt_len = PKTLEN(dhdp->osh, pkt);
|
||||
pkts->info.driver_ts_sec = (uint32)ts_nsec;
|
||||
pkts->info.driver_ts_usec = (uint32)(rem_nsec/NSEC_PER_USEC);
|
||||
#endif /* DHD_PKT_LOGGING_DBGRING */
|
||||
|
||||
pkts->info.pkt = PKTDUP(dhdp->osh, pkt);
|
||||
/*
|
||||
* skb clone can be NULL, but pktlog feature assume it alway can be cloned
|
||||
* The dummy pkt info will be added in the list to fit pktcount & list items
|
||||
* and handled in the dhd_pktlog_dump_write() with ignoring info.pkt
|
||||
*/
|
||||
if (pkts->info.pkt == NULL) {
|
||||
DHD_ERROR(("%s : skb clone returns NULL \n", __FUNCTION__));
|
||||
}
|
||||
pkts->info.pkt_len = PKTLEN(dhdp->osh, pkt);
|
||||
pkts->info.firmware_ts = 0U;
|
||||
pkts->info.payload_type = FRAME_TYPE_ETHERNET_II;
|
||||
pkts->info.direction = direction;
|
||||
|
||||
pkts->info.tx_status_ts_sec = 0;
|
||||
pkts->info.tx_status_ts_usec = 0;
|
||||
|
||||
if (direction == PKT_TX) {
|
||||
pkts->info.pkt_hash = __dhd_dbg_pkt_hash((uintptr_t)pkt, pktid);
|
||||
pkts->tx_fate = TX_PKT_FATE_DRV_QUEUED;
|
||||
|
|
@ -391,6 +612,12 @@ dhd_pktlog_ring_add_pkts(dhd_pub_t *dhdp, void *pkt, void *pktdata, uint32 pktid
|
|||
dll_append(&pktlog_ring->ring_info_head, (dll_t *)pkts);
|
||||
pktlog_ring->pktcount++;
|
||||
DHD_PKT_LOG_UNLOCK(pktlog_ring->pktlog_ring_lock, flags);
|
||||
#ifdef DHD_PKT_LOGGING_DBGRING
|
||||
dhd_dbg_update_to_ring(dhdp, pktlog_ring->dbg_ring,
|
||||
dhd_pktlog_get_item_length(pkts));
|
||||
#endif /* DHD_PKT_LOGGING_DBGRING */
|
||||
|
||||
DHD_PKT_LOG(("%s(): pktcount=%d\n", __FUNCTION__, pktlog_ring->pktcount));
|
||||
return BCME_OK;
|
||||
}
|
||||
|
||||
|
|
@ -405,7 +632,8 @@ dhd_pktlog_ring_tx_status(dhd_pub_t *dhdp, void *pkt, void *pktdata, uint32 pkti
|
|||
dhd_pktlog_filter_t *pktlog_filter;
|
||||
dll_t *item_p, *next_p;
|
||||
unsigned long flags = 0;
|
||||
|
||||
u64 ts_nsec;
|
||||
unsigned long rem_nsec;
|
||||
#ifdef BDC
|
||||
struct bdc_header *h;
|
||||
BCM_REFERENCE(h);
|
||||
|
|
@ -426,6 +654,9 @@ dhd_pktlog_ring_tx_status(dhd_pub_t *dhdp, void *pkt, void *pktdata, uint32 pkti
|
|||
pkt_hash = __dhd_dbg_pkt_hash((uintptr_t)pkt, pktid);
|
||||
pkt_fate = __dhd_dbg_map_tx_status_to_pkt_fate(status);
|
||||
|
||||
ts_nsec = local_clock();
|
||||
rem_nsec = do_div(ts_nsec, NSEC_PER_SEC);
|
||||
|
||||
/* find the sent tx packet and adding pkt_fate info */
|
||||
DHD_PKT_LOG_LOCK(pktlog_ring->pktlog_ring_lock, flags);
|
||||
/* Inverse traverse from the last packets */
|
||||
|
|
@ -446,6 +677,8 @@ dhd_pktlog_ring_tx_status(dhd_pub_t *dhdp, void *pkt, void *pktdata, uint32 pkti
|
|||
PKTPULL(dhdp->osh, tx_pkt->info.pkt, BDC_HEADER_LEN);
|
||||
PKTPULL(dhdp->osh, tx_pkt->info.pkt, (h->dataOffset << DHD_WORD_TO_LEN_SHIFT));
|
||||
#endif /* BDC */
|
||||
tx_pkt->info.tx_status_ts_sec = (uint32)ts_nsec;
|
||||
tx_pkt->info.tx_status_ts_usec = (uint32)(rem_nsec/NSEC_PER_USEC);
|
||||
DHD_PKT_LOG(("%s(): Found pkt hash in prev pos\n", __FUNCTION__));
|
||||
break;
|
||||
}
|
||||
|
|
@ -491,7 +724,7 @@ dhd_pktlog_filter_init(int size)
|
|||
|
||||
filter->enable = PKTLOG_TXPKT_CASE | PKTLOG_TXSTATUS_CASE | PKTLOG_RXPKT_CASE;
|
||||
|
||||
DHD_ERROR(("%s(): pktlog filter init success\n", __FUNCTION__));
|
||||
DHD_INFO(("%s(): pktlog filter init success\n", __FUNCTION__));
|
||||
|
||||
return filter;
|
||||
fail:
|
||||
|
|
@ -517,7 +750,7 @@ dhd_pktlog_filter_deinit(dhd_pktlog_filter_t *filter)
|
|||
}
|
||||
kfree(filter);
|
||||
|
||||
DHD_ERROR(("%s(): pktlog filter deinit\n", __FUNCTION__));
|
||||
DHD_INFO(("%s(): pktlog filter deinit\n", __FUNCTION__));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -837,6 +1070,7 @@ dhd_pktlog_filter_matched(dhd_pktlog_filter_t *filter, char *data, uint32 pktlog
|
|||
/* Ethernet Type MAC Header 12 bytes + Frame payload 10 bytes */
|
||||
#define PKTLOG_MINIMIZE_REPORT_LEN 22
|
||||
|
||||
#ifndef DHD_PKT_LOGGING_DBGRING
|
||||
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 */
|
||||
|
|
@ -890,6 +1124,7 @@ dhd_pktlog_minimize_report(char *pkt, uint32 frame_len,
|
|||
}
|
||||
vfree(mem_buf);
|
||||
}
|
||||
#endif /* !DHD_PKT_LOGGING_DBGRING */
|
||||
|
||||
dhd_pktlog_ring_t*
|
||||
dhd_pktlog_ring_change_size(dhd_pktlog_ring_t *ringbuf, int size)
|
||||
|
|
@ -1018,27 +1253,39 @@ dhd_pktlog_get_item_length(dhd_pktlog_ring_info_t *report_ptr)
|
|||
} else {
|
||||
frame_len = (uint32)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);
|
||||
#ifdef DHD_PKT_LOGGING_DBGRING
|
||||
frame_len = (uint32)min(frame_len, DHD_PKT_LOGGING_DBGRING_MAX_SIZE);
|
||||
bytes_user_data = snprintf(buf, sizeof(buf), "%s:%s:%02d\n",
|
||||
DHD_PKTLOG_FATE_INFO_FORMAT,
|
||||
(report_ptr->tx_fate ? "Failure" : "Succeed"), report_ptr->tx_fate);
|
||||
#else
|
||||
bytes_user_data = snprintf(buf, sizeof(buf), "%s:%s:%02d:%s:%d.%d s\n",
|
||||
DHD_PKTLOG_FATE_INFO_FORMAT,
|
||||
(report_ptr->tx_fate ? "Failure" : "Succeed"), report_ptr->tx_fate,
|
||||
(report_ptr->info.direction == PKT_TX) ? "TX" : "RX",
|
||||
report_ptr->info.tx_status_ts_sec, report_ptr->info.tx_status_ts_usec);
|
||||
#endif /* DHD_PKT_LOGGING_DBGRING */
|
||||
write_frame_len = frame_len + bytes_user_data;
|
||||
|
||||
/* pcap pkt head has incl_len and orig_len */
|
||||
len += (uint32)sizeof(write_frame_len);
|
||||
len += (uint32)sizeof(write_frame_len);
|
||||
len += frame_len;
|
||||
len += bytes_user_data;
|
||||
len += write_frame_len;
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
uint32
|
||||
int
|
||||
dhd_pktlog_get_dump_length(dhd_pub_t *dhdp)
|
||||
{
|
||||
dhd_pktlog_ring_info_t *report_ptr;
|
||||
dhd_pktlog_ring_t *pktlog_ring;
|
||||
uint32 len;
|
||||
uint32 len = 0;
|
||||
dll_t *item_p, *next_p;
|
||||
#ifdef DHD_PKT_LOGGING_DBGRING
|
||||
dhd_dbg_ring_t *ring;
|
||||
ring = &dhdp->dbg->dbg_rings[PACKET_LOG_RING_ID];
|
||||
#endif /* DHD_PKT_LOGGING_DBGRING */
|
||||
|
||||
if (!dhdp || !dhdp->pktlog) {
|
||||
DHD_PKT_LOG(("%s(): dhdp=%p pktlog=%p\n",
|
||||
|
|
@ -1054,15 +1301,20 @@ dhd_pktlog_get_dump_length(dhd_pub_t *dhdp)
|
|||
|
||||
pktlog_ring = dhdp->pktlog->pktlog_ring;
|
||||
OSL_ATOMIC_SET(dhdp->osh, &pktlog_ring->start, FALSE);
|
||||
|
||||
#ifndef DHD_PKT_LOGGING_DBGRING
|
||||
len = sizeof(dhd_pktlog_pcap_hdr_t);
|
||||
|
||||
#endif /* !DHD_PKT_LOGGING_DBGRING */
|
||||
for (item_p = dll_head_p(&pktlog_ring->ring_info_head);
|
||||
!dll_end(&pktlog_ring->ring_info_head, item_p);
|
||||
item_p = next_p) {
|
||||
next_p = dll_next_p(item_p);
|
||||
report_ptr = (dhd_pktlog_ring_info_t *)item_p;
|
||||
len += dhd_pktlog_get_item_length(report_ptr);
|
||||
#ifdef DHD_PKT_LOGGING_DBGRING
|
||||
if (len >= ring->threshold) {
|
||||
break;
|
||||
}
|
||||
#endif /* DHD_PKT_LOGGING_DBGRING */
|
||||
}
|
||||
OSL_ATOMIC_SET(dhdp->osh, &pktlog_ring->start, TRUE);
|
||||
DHD_PKT_LOG(("calcuated pkt log dump len:%d\n", len));
|
||||
|
|
@ -1071,17 +1323,27 @@ dhd_pktlog_get_dump_length(dhd_pub_t *dhdp)
|
|||
}
|
||||
|
||||
int
|
||||
#ifdef DHD_PKT_LOGGING_DBGRING
|
||||
dhd_pktlog_dump_write(dhd_pub_t *dhdp, void *file, const void *user_buf,
|
||||
uint32 *written_bytes)
|
||||
#else
|
||||
dhd_pktlog_dump_write(dhd_pub_t *dhdp, void *file, const void *user_buf, uint32 size)
|
||||
#endif /* DHD_PKT_LOGGING_DBGRING */
|
||||
{
|
||||
dhd_pktlog_ring_info_t *report_ptr;
|
||||
dhd_pktlog_ring_t *pktlog_ring;
|
||||
char buf[DHD_PKTLOG_FATE_INFO_STR_LEN];
|
||||
#ifndef DHD_PKT_LOGGING_DBGRING
|
||||
dhd_pktlog_pcap_hdr_t pcap_h;
|
||||
loff_t pos = 0;
|
||||
#else
|
||||
uint32 size = 0;
|
||||
unsigned long flags = 0;
|
||||
#endif /* !DHD_PKT_LOGGING_DBGRING */
|
||||
uint32 write_frame_len;
|
||||
uint32 frame_len;
|
||||
ulong len;
|
||||
ulong len = 0;
|
||||
int bytes_user_data = 0;
|
||||
loff_t pos = 0;
|
||||
int ret = BCME_OK;
|
||||
dll_t *item_p, *next_p;
|
||||
|
||||
|
|
@ -1097,10 +1359,23 @@ dhd_pktlog_dump_write(dhd_pub_t *dhdp, void *file, const void *user_buf, uint32
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
#ifdef DHD_PKT_LOGGING_DBGRING
|
||||
if (user_buf) {
|
||||
size = *written_bytes;
|
||||
} else if (file) {
|
||||
/* With DHD_PKT_LOGGING_DBGRING, this path is not allowed. */
|
||||
return BCME_UNSUPPORTED;
|
||||
}
|
||||
#endif /* DHD_PKT_LOGGING_DBGRING */
|
||||
|
||||
if (file && !user_buf && (size == 0)) {
|
||||
DHD_ERROR(("Local file pktlog dump requested\n"));
|
||||
} else if (!file && user_buf && (size > 0)) {
|
||||
#ifdef DHD_PKT_LOGGING_DBGRING
|
||||
DHD_INFO(("HAL file pktlog dump %d bytes requested\n", size));
|
||||
#else
|
||||
DHD_ERROR(("HAL file pktlog dump %d bytes requested\n", size));
|
||||
#endif /* DHD_PKT_LOGGING_DBGRING */
|
||||
} else {
|
||||
DHD_ERROR(("Wrong type pktlog dump requested\n"));
|
||||
return -EINVAL;
|
||||
|
|
@ -1108,7 +1383,7 @@ dhd_pktlog_dump_write(dhd_pub_t *dhdp, void *file, const void *user_buf, uint32
|
|||
|
||||
pktlog_ring = dhdp->pktlog->pktlog_ring;
|
||||
OSL_ATOMIC_SET(dhdp->osh, &pktlog_ring->start, FALSE);
|
||||
|
||||
#ifndef DHD_PKT_LOGGING_DBGRING
|
||||
pcap_h.magic_number = PKTLOG_PCAP_MAGIC_NUM;
|
||||
pcap_h.version_major = PKTLOG_PCAP_MAJOR_VER;
|
||||
pcap_h.version_minor = PKTLOG_PCAP_MINOR_VER;
|
||||
|
|
@ -1119,20 +1394,90 @@ dhd_pktlog_dump_write(dhd_pub_t *dhdp, void *file, const void *user_buf, uint32
|
|||
|
||||
ret = dhd_export_debug_data((char *)&pcap_h, file, user_buf, sizeof(pcap_h), &pos);
|
||||
len = sizeof(pcap_h);
|
||||
|
||||
#endif /* !DHD_PKT_LOGGING_DBGRING */
|
||||
#ifdef DHD_PKT_LOGGING_DBGRING
|
||||
DHD_PKT_LOG_LOCK(dhd_os_get_pktlog_lock(dhdp), flags);
|
||||
#endif /* DHD_PKT_LOGGING_DBGRING */
|
||||
for (item_p = dll_head_p(&pktlog_ring->ring_info_head);
|
||||
!dll_end(&pktlog_ring->ring_info_head, item_p);
|
||||
item_p = next_p) {
|
||||
#ifdef DHD_PKT_LOGGING_DBGRING
|
||||
uint32 captured_frame_len;
|
||||
#endif /* DHD_PKT_LOGGING_DBGRING */
|
||||
|
||||
next_p = dll_next_p(item_p);
|
||||
report_ptr = (dhd_pktlog_ring_info_t *)item_p;
|
||||
|
||||
#ifdef DHD_PKT_LOGGING_DBGRING
|
||||
if (report_ptr->info.direction == PKT_TX &&
|
||||
report_ptr->tx_fate == TX_PKT_FATE_DRV_QUEUED) {
|
||||
/* Not updated txfate yet, postpone some time. */
|
||||
report_ptr->tx_fate |= TX_PKT_FATE_DRV_WAIT_UPDATE;
|
||||
continue;
|
||||
}
|
||||
#endif /* DHD_PKT_LOGGING_DBGRING */
|
||||
if ((file == NULL) &&
|
||||
(len + dhd_pktlog_get_item_length(report_ptr) > size)) {
|
||||
#ifdef DHD_PKT_LOGGING_DBGRING
|
||||
DHD_INFO(("overflowed pkt logs are dropped\n"));
|
||||
#else
|
||||
DHD_ERROR(("overflowed pkt logs are dropped\n"));
|
||||
#endif /* DHD_PKT_LOGGING_DBGRING */
|
||||
break;
|
||||
}
|
||||
|
||||
if (report_ptr->info.pkt == NULL) {
|
||||
DHD_ERROR(("%s : pkt isn't located skip it\n", __FUNCTION__));
|
||||
continue;
|
||||
}
|
||||
|
||||
#ifdef DHD_PKT_LOGGING_DBGRING
|
||||
ret = memcpy_s((void*)(user_buf + len), size - len,
|
||||
(char*)&report_ptr->info.driver_ts_sec,
|
||||
sizeof(report_ptr->info.driver_ts_sec));
|
||||
len += sizeof(report_ptr->info.driver_ts_sec);
|
||||
|
||||
ret = memcpy_s((void*)(user_buf + len), size - len,
|
||||
(char*)&report_ptr->info.driver_ts_usec,
|
||||
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 = (uint32)min(report_ptr->info.pkt_len,
|
||||
(size_t)MAX_FRAME_LEN_ETHERNET);
|
||||
} else {
|
||||
frame_len = (uint32)min(report_ptr->info.pkt_len,
|
||||
(size_t)MAX_FRAME_LEN_80211_MGMT);
|
||||
}
|
||||
|
||||
bytes_user_data = snprintf(buf, sizeof(buf), "%s:%s:%02d\n",
|
||||
DHD_PKTLOG_FATE_INFO_FORMAT,
|
||||
(report_ptr->tx_fate ? "Failure" : "Succeed"),
|
||||
(report_ptr->tx_fate & ~(TX_PKT_FATE_DRV_WAIT_UPDATE)));
|
||||
write_frame_len = frame_len + bytes_user_data;
|
||||
frame_len = (uint32)min(frame_len, DHD_PKT_LOGGING_DBGRING_MAX_SIZE);
|
||||
captured_frame_len = frame_len + bytes_user_data;
|
||||
|
||||
/* pcap pkt head has incl_len and orig_len */
|
||||
ret = memcpy_s((void*)(user_buf + len), size - len,
|
||||
(char*)&captured_frame_len, sizeof(captured_frame_len));
|
||||
len += sizeof(captured_frame_len);
|
||||
|
||||
ret = memcpy_s((void*)(user_buf + len), size - len,
|
||||
(char*)&write_frame_len, sizeof(write_frame_len));
|
||||
len += sizeof(write_frame_len);
|
||||
|
||||
ret = memcpy_s((void*)(user_buf + len), size - len, PKTDATA(pktlog_ring->dhdp->osh,
|
||||
report_ptr->info.pkt), frame_len);
|
||||
len += frame_len;
|
||||
|
||||
ret = memcpy_s((void*)(user_buf + len), size - len, buf, bytes_user_data);
|
||||
len += bytes_user_data;
|
||||
|
||||
dll_delete((dll_t *)report_ptr);
|
||||
PKTFREE(pktlog_ring->dhdp->osh, report_ptr->info.pkt, TRUE);
|
||||
pktlog_ring->pktcount--;
|
||||
dll_append(&pktlog_ring->ring_info_free, (dll_t *)report_ptr);
|
||||
#else
|
||||
ret = dhd_export_debug_data((char*)&report_ptr->info.driver_ts_sec, file,
|
||||
user_buf, sizeof(report_ptr->info.driver_ts_sec), &pos);
|
||||
len += sizeof(report_ptr->info.driver_ts_sec);
|
||||
|
|
@ -1150,8 +1495,13 @@ dhd_pktlog_dump_write(dhd_pub_t *dhdp, void *file, const void *user_buf, uint32
|
|||
(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);
|
||||
bytes_user_data = snprintf(buf, sizeof(buf), "%s:%s:%02d:%s:%d.%d s\n",
|
||||
DHD_PKTLOG_FATE_INFO_FORMAT,
|
||||
(report_ptr->tx_fate ? "Failure" : "Succeed"),
|
||||
report_ptr->tx_fate,
|
||||
(report_ptr->info.direction == PKT_TX) ? "TX" : "RX",
|
||||
report_ptr->info.tx_status_ts_sec,
|
||||
report_ptr->info.tx_status_ts_usec);
|
||||
write_frame_len = frame_len + bytes_user_data;
|
||||
|
||||
/* pcap pkt head has incl_len and orig_len */
|
||||
|
|
@ -1174,7 +1524,12 @@ dhd_pktlog_dump_write(dhd_pub_t *dhdp, void *file, const void *user_buf, uint32
|
|||
|
||||
ret = dhd_export_debug_data(buf, file, user_buf, bytes_user_data, &pos);
|
||||
len += bytes_user_data;
|
||||
#endif /* DHD_PKT_LOGGING_DBGRING */
|
||||
}
|
||||
#ifdef DHD_PKT_LOGGING_DBGRING
|
||||
DHD_PKT_LOG_UNLOCK(dhd_os_get_pktlog_lock(dhdp), flags);
|
||||
*written_bytes = len;
|
||||
#endif /* DHD_PKT_LOGGING_DBGRING */
|
||||
OSL_ATOMIC_SET(dhdp->osh, &pktlog_ring->start, TRUE);
|
||||
|
||||
return ret;
|
||||
|
|
@ -1183,7 +1538,11 @@ dhd_pktlog_dump_write(dhd_pub_t *dhdp, void *file, const void *user_buf, uint32
|
|||
int
|
||||
dhd_pktlog_dump_write_memory(dhd_pub_t *dhdp, const void *user_buf, uint32 size)
|
||||
{
|
||||
#ifdef DHD_PKT_LOGGING_DBGRING
|
||||
int ret = dhd_pktlog_dump_write(dhdp, NULL, user_buf, &size);
|
||||
#else
|
||||
int ret = dhd_pktlog_dump_write(dhdp, NULL, user_buf, size);
|
||||
#endif /* DHD_PKT_LOGGING_DBGRING */
|
||||
if (ret < 0) {
|
||||
DHD_ERROR(("dhd_pktlog_dump_write_memory error\n"));
|
||||
}
|
||||
|
|
@ -1195,17 +1554,21 @@ dhd_pktlog_dump_write_file(dhd_pub_t *dhdp)
|
|||
{
|
||||
struct file *w_pcap_fp = NULL;
|
||||
uint32 file_mode;
|
||||
#ifdef get_fs
|
||||
mm_segment_t old_fs;
|
||||
#endif /* get_fs */
|
||||
char pktlogdump_path[128];
|
||||
int ret = BCME_OK;
|
||||
|
||||
dhd_pktlog_get_filename(dhdp, pktlogdump_path, 128);
|
||||
#ifdef get_fs
|
||||
old_fs = get_fs();
|
||||
set_fs(KERNEL_DS);
|
||||
#endif /* get_fs */
|
||||
file_mode = O_CREAT | O_WRONLY;
|
||||
|
||||
w_pcap_fp = filp_open(pktlogdump_path, file_mode, 0664);
|
||||
if (IS_ERR(w_pcap_fp)) {
|
||||
w_pcap_fp = dhd_filp_open(pktlogdump_path, file_mode, 0664);
|
||||
if (IS_ERR(w_pcap_fp) || (w_pcap_fp == NULL)) {
|
||||
DHD_ERROR(("%s: Couldn't open file '%s' err %ld\n",
|
||||
__FUNCTION__, pktlogdump_path, PTR_ERR(w_pcap_fp)));
|
||||
ret = BCME_ERROR;
|
||||
|
|
@ -1219,18 +1582,18 @@ dhd_pktlog_dump_write_file(dhd_pub_t *dhdp)
|
|||
}
|
||||
|
||||
/* Sync file from filesystem to physical media */
|
||||
ret = vfs_fsync(w_pcap_fp, 0);
|
||||
ret = dhd_vfs_fsync(w_pcap_fp, 0);
|
||||
if (ret < 0) {
|
||||
DHD_ERROR(("%s(): sync pcap file error, err = %d\n", __FUNCTION__, ret));
|
||||
goto fail;
|
||||
}
|
||||
fail:
|
||||
if (!IS_ERR(w_pcap_fp)) {
|
||||
filp_close(w_pcap_fp, NULL);
|
||||
dhd_filp_close(w_pcap_fp, NULL);
|
||||
}
|
||||
|
||||
#ifdef get_fs
|
||||
set_fs(old_fs);
|
||||
|
||||
#endif /* get_fs */
|
||||
#ifdef DHD_DUMP_MNGR
|
||||
if (ret >= 0) {
|
||||
dhd_dump_file_manage_enqueue(dhdp, pktlogdump_path, DHD_PKTLOG_DUMP_TYPE);
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* DHD debugability packet logging header file
|
||||
*
|
||||
* Copyright (C) 2020, Broadcom.
|
||||
* Copyright (C) 2022, Broadcom.
|
||||
*
|
||||
* Unless you and Broadcom execute a separate written software license
|
||||
* agreement governing use of this software, this software is licensed to you
|
||||
|
|
@ -58,6 +58,8 @@ typedef struct dhd_dbg_pktlog_info {
|
|||
uint32 driver_ts_usec;
|
||||
uint32 firmware_ts;
|
||||
uint32 pkt_hash;
|
||||
uint32 tx_status_ts_sec;
|
||||
uint32 tx_status_ts_usec;
|
||||
bool direction;
|
||||
void *pkt;
|
||||
} dhd_dbg_pktlog_info_t;
|
||||
|
|
@ -84,6 +86,9 @@ typedef struct dhd_pktlog_ring
|
|||
spinlock_t *pktlog_ring_lock;
|
||||
dhd_pub_t *dhdp;
|
||||
dhd_pktlog_ring_info_t *ring_info_mem; /* ring_info mem pointer */
|
||||
#ifdef DHD_PKT_LOGGING_DBGRING
|
||||
void *dbg_ring;
|
||||
#endif /* DHD_PKT_LOGGING_DBGRING */
|
||||
} dhd_pktlog_ring_t;
|
||||
|
||||
typedef struct dhd_pktlog_filter_info
|
||||
|
|
@ -112,6 +117,9 @@ typedef struct dhd_pktlog
|
|||
#ifdef DHD_COMPACT_PKT_LOG
|
||||
struct rb_root cpkt_log_tt_rbt;
|
||||
#endif /* DHD_COMPACT_PKT_LOG */
|
||||
#ifdef DHD_PKT_LOGGING_DBGRING
|
||||
osl_atomic_t enable; /* logging suspend/resume */
|
||||
#endif /* DHD_PKT_LOGGING_DBGRING */
|
||||
} dhd_pktlog_t;
|
||||
|
||||
typedef struct dhd_pktlog_pcap_hdr
|
||||
|
|
@ -133,6 +141,12 @@ typedef struct dhd_pktlog_pcap_hdr
|
|||
|
||||
extern int dhd_os_attach_pktlog(dhd_pub_t *dhdp);
|
||||
extern int dhd_os_detach_pktlog(dhd_pub_t *dhdp);
|
||||
#ifdef DHD_PKT_LOGGING_DBGRING
|
||||
extern int dhd_pktlog_is_enabled(dhd_pub_t *dhdp);
|
||||
extern void dhd_pktlog_suspend(dhd_pub_t *dhdp);
|
||||
extern void dhd_pktlog_resume(dhd_pub_t *dhdp);
|
||||
extern int dhd_pktlog_ring_reinit(dhd_pub_t *dhdp);
|
||||
#endif /* DHD_PKT_LOGGING_DBGRING */
|
||||
extern dhd_pktlog_ring_t* dhd_pktlog_ring_init(dhd_pub_t *dhdp, int size);
|
||||
extern int dhd_pktlog_ring_deinit(dhd_pub_t *dhdp, dhd_pktlog_ring_t *ring);
|
||||
extern int dhd_pktlog_ring_set_nextpos(dhd_pktlog_ring_t *ringbuf);
|
||||
|
|
@ -298,7 +312,7 @@ extern int dhd_pktlog_dump_write_file(dhd_pub_t *dhdp);
|
|||
|
||||
extern void dhd_pktlog_get_filename(dhd_pub_t *dhdp, char *dump_path, int len);
|
||||
extern uint32 dhd_pktlog_get_item_length(dhd_pktlog_ring_info_t *report_ptr);
|
||||
extern uint32 dhd_pktlog_get_dump_length(dhd_pub_t *dhdp);
|
||||
extern int dhd_pktlog_get_dump_length(dhd_pub_t *dhdp);
|
||||
extern uint32 __dhd_dbg_pkt_hash(uintptr_t pkt, uint32 pktid);
|
||||
|
||||
#ifdef DHD_COMPACT_PKT_LOG
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* DHD Linux platform header file
|
||||
*
|
||||
* Copyright (C) 2020, Broadcom.
|
||||
* Copyright (C) 2022, Broadcom.
|
||||
*
|
||||
* Unless you and Broadcom execute a separate written software license
|
||||
* agreement governing use of this software, this software is licensed to you
|
||||
|
|
@ -26,6 +26,8 @@
|
|||
#ifndef __DHD_PLAT_H__
|
||||
#define __DHD_PLAT_H__
|
||||
|
||||
#if defined(__linux__)
|
||||
|
||||
#include <linuxver.h>
|
||||
|
||||
#if !defined(CONFIG_WIFI_CONTROL_FUNC)
|
||||
|
|
@ -38,7 +40,7 @@ struct wifi_platform_data {
|
|||
#ifdef DHD_COREDUMP
|
||||
int (*set_coredump)(const char *buf, int buf_len, const char *info);
|
||||
#endif /* DHD_COREDUMP */
|
||||
#ifdef BCMDHD_MDRIVER
|
||||
#if defined(BCMDHD_MDRIVER) && !defined(DHD_STATIC_IN_DRIVER)
|
||||
void *(*mem_prealloc)(uint bus_type, int index, int section, unsigned long size);
|
||||
#else
|
||||
void *(*mem_prealloc)(int section, unsigned long size);
|
||||
|
|
@ -53,6 +55,49 @@ struct wifi_platform_data {
|
|||
void *(*get_country_code)(char *ccode);
|
||||
#endif
|
||||
};
|
||||
#endif /* CONFIG_WIFI_CONTROL_FUNC */
|
||||
#endif
|
||||
|
||||
#include <linux/pci.h>
|
||||
|
||||
/*
|
||||
* Plat Layer defines the interfaces that the BSP specific file should override
|
||||
* The default implementation of the interfaces are present in dhd_linux_platdev.c
|
||||
* The data structure/handle to be passed by the DHD to BSP specific file is opaque
|
||||
* called plat_info. The data structure is to be maintained purely inside the
|
||||
* BSP specific file and hence its kept opaque.
|
||||
*
|
||||
* There are two types of interface functions
|
||||
* 1) Functions that need the interface structure plat_info to be passed down
|
||||
* from DHD.
|
||||
* 2) Functions that queries for certain information in BSP specific way and just
|
||||
* returns to DHD - These functions does not take the plat_info as argument.
|
||||
*
|
||||
* The declarations are grouped accordingly. While adding a new interface function
|
||||
* declaration based on the group it belongs to add it in the appropriate section
|
||||
*/
|
||||
|
||||
typedef void (*dhd_pcie_event_cb_t) (struct pci_dev *pdev);
|
||||
extern int dhd_plat_pcie_register_event(void *plat_info,
|
||||
struct pci_dev *pdev, dhd_pcie_event_cb_t pfn);
|
||||
extern void dhd_plat_pcie_deregister_event(void *plat_info);
|
||||
extern void dhd_plat_report_bh_sched(void *plat_info, int resched);
|
||||
extern int dhd_plat_pcie_suspend(void *plat_info);
|
||||
extern int dhd_plat_pcie_resume(void *plat_info);
|
||||
extern void dhd_plat_pcie_register_dump(void *plat_info);
|
||||
extern void dhd_plat_pin_dbg_show(void *plat_info);
|
||||
|
||||
extern uint32 dhd_plat_get_info_size(void);
|
||||
extern void dhd_plat_l1ss_ctrl(bool ctrl);
|
||||
|
||||
/* To be called when we intend to exit L1 while performing wreg, rreg operations */
|
||||
extern void dhd_plat_l1_exit_io(void);
|
||||
|
||||
/* To be called when we intend to exit L1 in non-io case */
|
||||
extern void dhd_plat_l1_exit(void);
|
||||
|
||||
extern uint32 dhd_plat_get_rc_vendor_id(void);
|
||||
extern uint32 dhd_plat_get_rc_device_id(void);
|
||||
|
||||
extern uint16 dhd_plat_align_rxbuf_size(uint16 rxbufpost_sz);
|
||||
#endif /* __linux__ */
|
||||
#endif /* __DHD_PLAT_H__ */
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
* Broadcom Dongle Host Driver (DHD)
|
||||
* Prefered Network Offload and Wi-Fi Location Service(WLS) code.
|
||||
*
|
||||
* Copyright (C) 2020, Broadcom.
|
||||
* Copyright (C) 2022, Broadcom.
|
||||
*
|
||||
* Unless you and Broadcom execute a separate written software license
|
||||
* agreement governing use of this software, this software is licensed to you
|
||||
|
|
@ -22,7 +22,7 @@
|
|||
* <<Broadcom-WL-IPTag/Dual:>>
|
||||
*/
|
||||
|
||||
#if defined (GSCAN_SUPPORT) && !defined(PNO_SUPPORT)
|
||||
#if defined(GSCAN_SUPPORT) && !defined(PNO_SUPPORT)
|
||||
#error "GSCAN needs PNO to be enabled!"
|
||||
#endif
|
||||
|
||||
|
|
@ -35,13 +35,11 @@
|
|||
|
||||
#include <bcmendian.h>
|
||||
|
||||
#ifdef OEM_ANDROID
|
||||
#include <linuxver.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/sort.h>
|
||||
#endif
|
||||
|
||||
#include <dngl_stats.h>
|
||||
#include <wlioctl.h>
|
||||
|
|
@ -74,15 +72,34 @@
|
|||
#define dtohchanspec(i) (i)
|
||||
#endif /* IL_BIGENDINA */
|
||||
|
||||
#ifdef OEM_ANDROID
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 7, 0))
|
||||
#define COMPLETION_WAIT_QUEUE_ACTIVE(wait_queue) swait_active(wait_queue)
|
||||
#else
|
||||
#define COMPLETION_WAIT_QUEUE_ACTIVE(wait_queue) waitqueue_active(wait_queue)
|
||||
#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(5, 7, 0) */
|
||||
|
||||
#ifdef CUSTOM_PREFIX
|
||||
#define PNO_PRINT_PREFIX "[%s]"CUSTOM_PREFIX, OSL_GET_RTCTIME()
|
||||
#define PNO_PRINT_SYSTEM_TIME pr_cont(PNO_PRINT_PREFIX)
|
||||
#define PNO_CONS_ONLY(args) \
|
||||
do { \
|
||||
PNO_PRINT_SYSTEM_TIME; \
|
||||
pr_cont args; \
|
||||
} while (0)
|
||||
#else
|
||||
#define PNO_PRINT_SYSTEM_TIME
|
||||
#define PNO_CONS_ONLY(args) do { printf args;} while (0)
|
||||
#endif /* CUSTOM_PREFIX */
|
||||
|
||||
#define NULL_CHECK(p, s, err) \
|
||||
do { \
|
||||
if (!(p)) { \
|
||||
printf("NULL POINTER (%s) : %s\n", __FUNCTION__, (s)); \
|
||||
err = BCME_ERROR; \
|
||||
return err; \
|
||||
} \
|
||||
} while (0)
|
||||
do { \
|
||||
if (!(p)) { \
|
||||
PNO_CONS_ONLY(("NULL POINTER (%s) : %s\n", __FUNCTION__, (s))); \
|
||||
err = BCME_ERROR; \
|
||||
return err; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define PNO_GET_PNOSTATE(dhd) ((dhd_pno_status_info_t *)dhd->pno_state)
|
||||
|
||||
#define PNO_BESTNET_LEN WLC_IOCTL_MEDLEN
|
||||
|
|
@ -103,8 +120,6 @@
|
|||
- (uint32)(timestamp2/1000)))
|
||||
#define TIME_DIFF_MS(timestamp1, timestamp2) (abs((uint32)(timestamp1) \
|
||||
- (uint32)(timestamp2)))
|
||||
#define TIMESPEC_TO_US(ts) (((uint64)(ts).tv_sec * USEC_PER_SEC) + \
|
||||
(ts).tv_nsec / NSEC_PER_USEC)
|
||||
|
||||
#define ENTRY_OVERHEAD strlen("bssid=\nssid=\nfreq=\nlevel=\nage=\ndist=\ndistSd=\n====")
|
||||
#define TIME_MIN_DIFF 5
|
||||
|
|
@ -210,7 +225,7 @@ dhd_is_legacy_pno_enabled(dhd_pub_t *dhd)
|
|||
static uint64
|
||||
convert_fw_rel_time_to_systime(struct osl_timespec *ts, uint32 fw_ts_ms)
|
||||
{
|
||||
return ((uint64)(TIMESPEC_TO_US(*ts)) - (uint64)(fw_ts_ms * 1000));
|
||||
return ((uint64)(TIMESPEC64_TO_US(*ts)) - (uint64)(fw_ts_ms * USEC_PER_MSEC));
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -382,6 +397,7 @@ _dhd_pno_suspend(dhd_pub_t *dhd)
|
|||
exit:
|
||||
return err;
|
||||
}
|
||||
|
||||
static int
|
||||
_dhd_pno_enable(dhd_pub_t *dhd, int enable)
|
||||
{
|
||||
|
|
@ -402,15 +418,6 @@ _dhd_pno_enable(dhd_pub_t *dhd, int enable)
|
|||
err = BCME_BADOPTION;
|
||||
goto exit;
|
||||
}
|
||||
if (enable) {
|
||||
if ((_pno_state->pno_mode & DHD_PNO_LEGACY_MODE) &&
|
||||
dhd_is_associated(dhd, 0, NULL)) {
|
||||
DHD_ERROR(("%s Legacy PNO mode cannot be enabled "
|
||||
"in assoc mode , ignore it\n", __FUNCTION__));
|
||||
err = BCME_BADOPTION;
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
/* Enable/Disable PNO */
|
||||
err = dhd_iovar(dhd, 0, "pfn", (char *)&enable, sizeof(enable), NULL, 0, TRUE);
|
||||
if (err < 0) {
|
||||
|
|
@ -432,28 +439,71 @@ static int
|
|||
_dhd_pno_set(dhd_pub_t *dhd, const dhd_pno_params_t *pno_params, dhd_pno_mode_t mode)
|
||||
{
|
||||
int err = BCME_OK;
|
||||
wl_pfn_param_t pfn_param;
|
||||
wl_pfn_param_v3_t pfn_param;
|
||||
dhd_pno_params_t *_params;
|
||||
dhd_pno_status_info_t *_pno_state;
|
||||
bool combined_scan = FALSE;
|
||||
uint16 size;
|
||||
bool use_v3 = FALSE;
|
||||
DHD_PNO(("%s enter\n", __FUNCTION__));
|
||||
|
||||
NULL_CHECK(dhd, "dhd is NULL", err);
|
||||
NULL_CHECK(dhd->pno_state, "pno_state is NULL", err);
|
||||
_pno_state = PNO_GET_PNOSTATE(dhd);
|
||||
|
||||
memset(&pfn_param, 0, sizeof(pfn_param));
|
||||
/* Query pfn version */
|
||||
bzero(&pfn_param, sizeof(pfn_param));
|
||||
err = dhd_iovar(dhd, 0, "pfn_set", (char *)&pfn_param, sizeof(pfn_param),
|
||||
(char *)&pfn_param, sizeof(pfn_param), FALSE);
|
||||
if (err < 0) {
|
||||
if (err == BCME_UNSUPPORTED) {
|
||||
DHD_PNO(("%s : PFN versioning not supported. Use v2\n",
|
||||
__FUNCTION__));
|
||||
use_v3 = FALSE;
|
||||
} else {
|
||||
DHD_ERROR(("%s : failed to query pfn_set %d\n", __FUNCTION__, err));
|
||||
goto exit;
|
||||
}
|
||||
} else {
|
||||
if (pfn_param.version == PFN_VERSION_V3) {
|
||||
DHD_ERROR(("%s : using pfn_param v3\n", __FUNCTION__));
|
||||
use_v3 = TRUE;
|
||||
} else if (pfn_param.version == PFN_VERSION_V2) {
|
||||
DHD_ERROR(("%s : using pfn_param v2\n", __FUNCTION__));
|
||||
use_v3 = FALSE;
|
||||
} else {
|
||||
DHD_ERROR(("unsupported pfn ver:%d\n", pfn_param.version));
|
||||
err = BCME_UNSUPPORTED;
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
|
||||
/* set pfn parameters */
|
||||
pfn_param.version = htod32(PFN_VERSION);
|
||||
bzero(&pfn_param, sizeof(pfn_param));
|
||||
if (use_v3) {
|
||||
pfn_param.version = PFN_VERSION_V3;
|
||||
pfn_param.version = htod32(pfn_param.version);
|
||||
size = sizeof(wl_pfn_param_v3_t);
|
||||
pfn_param.length = htod32(size);
|
||||
} else {
|
||||
wl_pfn_param_v2_t *pfn_param_v2 = (wl_pfn_param_v2_t *)&pfn_param;
|
||||
pfn_param_v2->version = PFN_VERSION_V2;
|
||||
pfn_param_v2->version = htod32(pfn_param_v2->version);
|
||||
size = sizeof(wl_pfn_param_v2_t);
|
||||
}
|
||||
|
||||
pfn_param.flags = ((PFN_LIST_ORDER << SORT_CRITERIA_BIT) |
|
||||
(ENABLE << IMMEDIATE_SCAN_BIT) | (ENABLE << REPORT_SEPERATELY_BIT));
|
||||
#ifdef WL_SCHED_SCAN
|
||||
/* bit to select the pfn partial scan result event logic */
|
||||
pfn_param.flags |= htod16(ENABLE << PFN_FULL_SCAN_RESULT_BIT);
|
||||
#endif /* WL_SCHED_SCAN */
|
||||
if (mode == DHD_PNO_LEGACY_MODE) {
|
||||
pfn_param.repeat = (uchar) (pno_params->params_legacy.pno_repeat);
|
||||
/* check and set extra pno params */
|
||||
if ((pno_params->params_legacy.pno_repeat != 0) ||
|
||||
if ((pno_params->params_legacy.pno_repeat != 0) &&
|
||||
(pno_params->params_legacy.pno_freq_expo_max != 0)) {
|
||||
pfn_param.flags |= htod16(ENABLE << ENABLE_ADAPTSCAN_BIT);
|
||||
pfn_param.repeat = (uchar) (pno_params->params_legacy.pno_repeat);
|
||||
pfn_param.exp = (uchar) (pno_params->params_legacy.pno_freq_expo_max);
|
||||
}
|
||||
/* set up pno scan fr */
|
||||
|
|
@ -590,7 +640,7 @@ _dhd_pno_set(dhd_pub_t *dhd, const dhd_pno_params_t *pno_params, dhd_pno_mode_t
|
|||
goto exit;
|
||||
}
|
||||
}
|
||||
#if (!defined(WL_USE_RANDOMIZED_SCAN))
|
||||
#if !defined(WL_USE_RANDOMIZED_SCAN)
|
||||
err = dhd_set_rand_mac_oui(dhd);
|
||||
/* Ignore if chip doesnt support the feature */
|
||||
if (err < 0 && err != BCME_UNSUPPORTED) {
|
||||
|
|
@ -622,7 +672,7 @@ _dhd_pno_set(dhd_pub_t *dhd, const dhd_pno_params_t *pno_params, dhd_pno_mode_t
|
|||
DHD_PNO((" returned mscan : %d, set bestn : %d mscan %d\n", _tmp, pfn_param.bestn,
|
||||
pfn_param.mscan));
|
||||
}
|
||||
err = dhd_iovar(dhd, 0, "pfn_set", (char *)&pfn_param, sizeof(pfn_param), NULL, 0, TRUE);
|
||||
err = dhd_iovar(dhd, 0, "pfn_set", (char *)&pfn_param, size, NULL, 0, TRUE);
|
||||
if (err < 0) {
|
||||
DHD_ERROR(("%s : failed to execute pfn_set %d\n", __FUNCTION__, err));
|
||||
goto exit;
|
||||
|
|
@ -970,6 +1020,15 @@ _dhd_pno_cfg(dhd_pub_t *dhd, uint16 *channel_list, int nchan)
|
|||
int err = BCME_OK;
|
||||
int i = 0;
|
||||
wl_pfn_cfg_t pfncfg_param;
|
||||
bool use_chanspec = FALSE;
|
||||
|
||||
#if defined(WL_6G_BAND) || defined(CFG80211_6G_SUPPORT)
|
||||
/* When enable 6G, force to use chanspec list */
|
||||
if (FW_SUPPORTED((dhd), 6g)) {
|
||||
use_chanspec = TRUE;
|
||||
}
|
||||
#endif /* WL_6G_BAND || CFG80211_6G_SUPPORT */
|
||||
|
||||
NULL_CHECK(dhd, "dhd is NULL", err);
|
||||
if (nchan) {
|
||||
if (nchan > WL_NUMCHANNELS) {
|
||||
|
|
@ -980,8 +1039,8 @@ _dhd_pno_cfg(dhd_pub_t *dhd, uint16 *channel_list, int nchan)
|
|||
pfncfg_param.channel_num = htod32(0);
|
||||
|
||||
for (i = 0; i < nchan; i++) {
|
||||
if (dhd->wlc_ver_major >= DHD_PNO_CHSPEC_SUPPORT_VER) {
|
||||
pfncfg_param.channel_list[i] = CH20MHZ_CHSPEC(channel_list[i]);
|
||||
if ((dhd->wlc_ver_major >= DHD_PNO_CHSPEC_SUPPORT_VER) || use_chanspec) {
|
||||
pfncfg_param.channel_list[i] = wf_chspec_ctlchspec(channel_list[i]);
|
||||
} else {
|
||||
pfncfg_param.channel_list[i] = channel_list[i];
|
||||
}
|
||||
|
|
@ -1564,13 +1623,13 @@ dhd_pno_set_for_batch(dhd_pub_t *dhd, struct dhd_pno_batch_params *batch_params)
|
|||
sizeof(_params->params_batch.chan_list[0]), _dhd_pno_cmpfunc, NULL);
|
||||
}
|
||||
#ifdef PNO_DEBUG
|
||||
{
|
||||
{
|
||||
DHD_PNO(("Channel list : "));
|
||||
for (i = 0; i < _params->params_batch.nchan; i++) {
|
||||
DHD_PNO(("%d ", _params->params_batch.chan_list[i]));
|
||||
}
|
||||
DHD_PNO(("\n"));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (_params->params_batch.nchan) {
|
||||
/* copy the channel list into local array */
|
||||
|
|
@ -2111,7 +2170,7 @@ dhd_pno_set_for_gscan(dhd_pub_t *dhd, struct dhd_pno_gscan_params *gscan_params)
|
|||
goto exit;
|
||||
}
|
||||
|
||||
pfn_gscan_cfg_t->version = WL_GSCAN_CFG_VERSION;
|
||||
pfn_gscan_cfg_t->version = WL_GSCAN_CFG_VERSION_1;
|
||||
if (gscan_params->mscan)
|
||||
pfn_gscan_cfg_t->buffer_threshold = gscan_params->buffer_threshold;
|
||||
else
|
||||
|
|
@ -2480,7 +2539,7 @@ dhd_pno_enable_full_scan_result(dhd_pub_t *dhd, bool real_time_flag)
|
|||
if (old_flag != gscan_params->send_all_results_flag) {
|
||||
wl_pfn_gscan_cfg_t gscan_cfg;
|
||||
|
||||
gscan_cfg.version = WL_GSCAN_CFG_VERSION;
|
||||
gscan_cfg.version = WL_GSCAN_CFG_VERSION_1;
|
||||
gscan_cfg.flags = (gscan_params->send_all_results_flag &
|
||||
GSCAN_SEND_ALL_RESULTS_MASK);
|
||||
gscan_cfg.flags |= GSCAN_CFG_FLAGS_ONLY_MASK;
|
||||
|
|
@ -2904,7 +2963,7 @@ exit:
|
|||
}
|
||||
#endif /* GSCAN_SUPPORT */
|
||||
|
||||
#if defined (GSCAN_SUPPORT) || defined(DHD_GET_VALID_CHANNELS)
|
||||
#if defined(GSCAN_SUPPORT) || defined(DHD_GET_VALID_CHANNELS)
|
||||
static void *
|
||||
dhd_get_gscan_batch_results(dhd_pub_t *dhd, uint32 *len)
|
||||
{
|
||||
|
|
@ -3098,8 +3157,6 @@ _dhd_pno_get_for_batch(dhd_pub_t *dhd, char *buf, int bufsize, int reason)
|
|||
STATIC_ASSERT(sizeof(wl_pfn_net_info_v1_t) == sizeof(wl_pfn_net_info_v2_t));
|
||||
STATIC_ASSERT(sizeof(wl_pfn_lnet_info_v1_t) == sizeof(wl_pfn_lnet_info_v2_t));
|
||||
STATIC_ASSERT(sizeof(wl_pfn_subnet_info_v1_t) == sizeof(wl_pfn_subnet_info_v2_t));
|
||||
ASSERT(OFFSETOF(wl_pfn_subnet_info_v1_t, SSID) ==
|
||||
OFFSETOF(wl_pfn_subnet_info_v2_t, u.SSID));
|
||||
|
||||
DHD_PNO(("%s enter\n", __FUNCTION__));
|
||||
_pno_state = PNO_GET_PNOSTATE(dhd);
|
||||
|
|
@ -3466,15 +3523,8 @@ exit:
|
|||
}
|
||||
mutex_unlock(&_pno_state->pno_mutex);
|
||||
exit_no_unlock:
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 7, 0))
|
||||
if (waitqueue_active(&_pno_state->get_batch_done)) {
|
||||
_pno_state->batch_recvd = TRUE;
|
||||
wake_up(&_pno_state->get_batch_done);
|
||||
}
|
||||
#else
|
||||
if (waitqueue_active(&_pno_state->get_batch_done.wait))
|
||||
if (COMPLETION_WAIT_QUEUE_ACTIVE(&_pno_state->get_batch_done.wait))
|
||||
complete(&_pno_state->get_batch_done);
|
||||
#endif
|
||||
return err;
|
||||
}
|
||||
|
||||
|
|
@ -3554,15 +3604,8 @@ dhd_pno_get_for_batch(dhd_pub_t *dhd, char *buf, int bufsize, int reason)
|
|||
params_batch->get_batch.bufsize = bufsize;
|
||||
params_batch->get_batch.reason = reason;
|
||||
params_batch->get_batch.bytes_written = 0;
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 7, 0))
|
||||
_pno_state->batch_recvd = FALSE;
|
||||
#endif
|
||||
schedule_work(&_pno_state->work);
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 7, 0))
|
||||
wait_event(_pno_state->get_batch_done, _pno_state->batch_recvd);
|
||||
#else
|
||||
wait_for_completion(&_pno_state->get_batch_done);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef GSCAN_SUPPORT
|
||||
|
|
@ -3749,14 +3792,14 @@ dhd_pno_set_for_hotlist(dhd_pub_t *dhd, wl_pfn_bssid_t *p_pfn_bssid,
|
|||
sizeof(_params->params_hotlist.chan_list[0]), _dhd_pno_cmpfunc, NULL);
|
||||
}
|
||||
#ifdef PNO_DEBUG
|
||||
{
|
||||
{
|
||||
int i;
|
||||
DHD_PNO(("Channel list : "));
|
||||
for (i = 0; i < _params->params_batch.nchan; i++) {
|
||||
DHD_PNO(("%d ", _params->params_batch.chan_list[i]));
|
||||
}
|
||||
DHD_PNO(("\n"));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (_params->params_hotlist.nchan) {
|
||||
/* copy the channel list into local array */
|
||||
|
|
@ -3975,8 +4018,8 @@ 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, uint32 len, int *size)
|
||||
{
|
||||
wl_bss_info_t *bi = NULL;
|
||||
wl_gscan_result_t *gscan_result;
|
||||
wl_bss_info_v109_t *bi = NULL;
|
||||
wl_gscan_result_v2_t *gscan_result;
|
||||
wifi_gscan_full_result_t *result = NULL;
|
||||
u32 bi_length = 0;
|
||||
uint8 channel;
|
||||
|
|
@ -3987,7 +4030,7 @@ dhd_process_full_gscan_result(dhd_pub_t *dhd, const void *data, uint32 len, int
|
|||
|
||||
*size = 0;
|
||||
GCC_DIAGNOSTIC_PUSH_SUPPRESS_CAST();
|
||||
gscan_result = (wl_gscan_result_t *)data;
|
||||
gscan_result = (wl_gscan_result_v2_t *)data;
|
||||
GCC_DIAGNOSTIC_POP();
|
||||
if (!gscan_result) {
|
||||
DHD_ERROR(("Invalid gscan result (NULL pointer)\n"));
|
||||
|
|
@ -4006,7 +4049,8 @@ dhd_process_full_gscan_result(dhd_pub_t *dhd, const void *data, uint32 len, int
|
|||
bi = &gscan_result->bss_info[0].info;
|
||||
bi_length = dtoh32(bi->length);
|
||||
if (bi_length != (dtoh32(gscan_result->buflen) -
|
||||
WL_GSCAN_RESULTS_FIXED_SIZE - WL_GSCAN_INFO_FIXED_FIELD_SIZE)) {
|
||||
OFFSETOF(wl_gscan_result_v2_t, bss_info) -
|
||||
OFFSETOF(wl_gscan_bss_info_v2_t, info))) {
|
||||
DHD_ERROR(("Invalid bss_info length %d: ignoring\n", bi_length));
|
||||
goto exit;
|
||||
}
|
||||
|
|
@ -4039,7 +4083,7 @@ dhd_process_full_gscan_result(dhd_pub_t *dhd, const void *data, uint32 len, int
|
|||
result->fixed.rtt = 0;
|
||||
result->fixed.rtt_sd = 0;
|
||||
osl_get_monotonic_boottime(&ts);
|
||||
result->fixed.ts = (uint64) TIMESPEC_TO_US(ts);
|
||||
result->fixed.ts = (uint64) TIMESPEC64_TO_US(ts);
|
||||
result->fixed.beacon_period = dtoh16(bi->beacon_period);
|
||||
result->fixed.capability = dtoh16(bi->capability);
|
||||
result->ie_length = bi_ie_length;
|
||||
|
|
@ -4508,12 +4552,7 @@ dhd_pno_event_handler(dhd_pub_t *dhd, wl_event_msg_t *event, void *event_data)
|
|||
{
|
||||
struct dhd_pno_batch_params *params_batch;
|
||||
params_batch = &_pno_state->pno_params_arr[INDEX_OF_BATCH_PARAMS].params_batch;
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 7, 0))
|
||||
if (!waitqueue_active(&_pno_state->get_batch_done))
|
||||
#else
|
||||
if (!waitqueue_active(&_pno_state->get_batch_done.wait))
|
||||
#endif
|
||||
{
|
||||
if (!COMPLETION_WAIT_QUEUE_ACTIVE(&_pno_state->get_batch_done.wait)) {
|
||||
DHD_PNO(("%s : WLC_E_PFN_BEST_BATCHING\n", __FUNCTION__));
|
||||
params_batch->get_batch.buf = NULL;
|
||||
params_batch->get_batch.bufsize = 0;
|
||||
|
|
@ -4553,11 +4592,7 @@ int dhd_pno_init(dhd_pub_t *dhd)
|
|||
_pno_state->dhd = dhd;
|
||||
mutex_init(&_pno_state->pno_mutex);
|
||||
INIT_WORK(&_pno_state->work, _dhd_pno_get_batch_handler);
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 7, 0))
|
||||
init_waitqueue_head(&_pno_state->get_batch_done);
|
||||
#else
|
||||
init_completion(&_pno_state->get_batch_done);
|
||||
#endif
|
||||
#ifdef GSCAN_SUPPORT
|
||||
init_waitqueue_head(&_pno_state->batch_get_wait);
|
||||
#endif /* GSCAN_SUPPORT */
|
||||
|
|
@ -4617,7 +4652,6 @@ int dhd_pno_deinit(dhd_pub_t *dhd)
|
|||
dhd->pno_state = NULL;
|
||||
return err;
|
||||
}
|
||||
#endif /* OEM_ANDROID */
|
||||
|
||||
#ifndef OEM_ANDROID
|
||||
#if defined(NDIS)
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue