mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-07 11:26:02 +09:00
net: wifi: rockchip_wlan: add wifi6 support for bcmdhd chipset
1. support wifi6 2. support sta/ap coex for Android P 3. support sta/ap coex for Linux Connman(Connection Manager) notice: As the new drivers are unstable, the vendor suggests to maintain two sets of drivers, and delete them after the new drivers are stable. Signed-off-by: Yao Xiao <xiaoyao@rock-chips.com> Change-Id: I6c98e6e031aee1d619a7f1f4a357b09975237d80
This commit is contained in:
@@ -28,15 +28,24 @@ config WIFI_GENERATE_RANDOM_MAC_ADDR
|
||||
help
|
||||
Wifi generate random mac address and save to vendor storage for cob chip
|
||||
|
||||
menuconfig BCMDHD
|
||||
bool "Broadcom Wireless Device Driver Support"
|
||||
default y
|
||||
|
||||
if BCMDHD
|
||||
source "drivers/net/wireless/rockchip_wlan/rkwifi/Kconfig"
|
||||
source "drivers/net/wireless/rockchip_wlan/cywdhd/Kconfig"
|
||||
endif
|
||||
|
||||
menuconfig RTL_WIRELESS_SOLUTION
|
||||
bool "Realtek Wireless Device Driver Support"
|
||||
default y
|
||||
bool "Realtek Wireless Device Driver Support"
|
||||
default n
|
||||
|
||||
if RTL_WIRELESS_SOLUTION
|
||||
source "drivers/net/wireless/rockchip_wlan/rtl8723cs/Kconfig"
|
||||
source "drivers/net/wireless/rockchip_wlan/rtl8822bs/Kconfig"
|
||||
endif
|
||||
|
||||
source "drivers/net/wireless/rockchip_wlan/mvl88w8977/Kconfig"
|
||||
source "drivers/net/wireless/rockchip_wlan/cywdhd/Kconfig"
|
||||
|
||||
endif # WL_ROCKCHIP
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
obj-$(CONFIG_AP6XXX) += rkwifi/
|
||||
obj-$(CONFIG_BCMDHD) += rkwifi/
|
||||
obj-$(CONFIG_RTL8723CS) += rtl8723cs/
|
||||
obj-$(CONFIG_RTL8822BS) += rtl8822bs/
|
||||
obj-$(CONFIG_MVL88W8977) += mvl88w8977/
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
config CYW_BCMDHD
|
||||
tristate "Cypress wireless sdio cards support"
|
||||
depends on (!AP6XXX)
|
||||
select WIRELESS_EXT
|
||||
select WEXT_PRIV
|
||||
depends on (!BCMDHD)
|
||||
#select CFG80211
|
||||
#select MAC80211
|
||||
select CFG80211_WEXT
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
choice
|
||||
prompt "Select driver version for ap6xxx chips"
|
||||
|
||||
config AP6XXX
|
||||
tristate "ap6xxx wireless sdio cards support"
|
||||
tristate "stable version (wifi5)"
|
||||
#depends on MMC && WLAN_80211
|
||||
select CFG80211
|
||||
select MAC80211
|
||||
select CFG80211
|
||||
select MAC80211
|
||||
---help---
|
||||
This module adds support for wireless adapters based on
|
||||
Broadcom ap6xxx chipset.
|
||||
@@ -13,3 +16,19 @@ config AP6XXX
|
||||
If you choose to build a module, it'll be called dhd. Say M if
|
||||
unsure.
|
||||
|
||||
config AP6XXX_WIFI6
|
||||
tristate "support wifi6(80211ax)"
|
||||
#depends on MMC && WLAN_80211
|
||||
select CFG80211
|
||||
select MAC80211
|
||||
---help---
|
||||
This driver supports wifi6 for ap6xxx chipset.
|
||||
|
||||
This driver uses the kernel's wireless extensions subsystem.
|
||||
|
||||
If you choose to build a module, it'll be called dhd. Say M if
|
||||
unsure.
|
||||
if AP6XXX_WIFI6
|
||||
source "drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd_wifi6/Kconfig"
|
||||
endif
|
||||
endchoice
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
# (gwl)
|
||||
|
||||
obj-$(CONFIG_AP6XXX) += bcmdhd/
|
||||
obj-$(CONFIG_AP6XXX_WIFI6) += bcmdhd_wifi6/
|
||||
|
||||
.PHONY: clean
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ CONFIG_BCMDHD_SDIO := y
|
||||
#CONFIG_BCMDHD_PCIE := y
|
||||
#CONFIG_BCMDHD_USB := y
|
||||
|
||||
CONFIG_BCMDHD_OOB := y
|
||||
CONFIG_BCMDHD_OOB := n
|
||||
#CONFIG_BCMDHD_CUSB := y
|
||||
CONFIG_BCMDHD_PROPTXSTATUS := y
|
||||
CONFIG_BCMDHD_AG := y
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
config BCMDHD_FW_PATH
|
||||
depends on BCMDHD
|
||||
string "Firmware path"
|
||||
default "/vendor/etc/firmware/fw_bcmdhd.bin"
|
||||
---help---
|
||||
Path to the firmware file.
|
||||
|
||||
config BCMDHD_NVRAM_PATH
|
||||
depends on BCMDHD
|
||||
string "NVRAM path"
|
||||
default "/vendor/etc/firmware/nvram.txt"
|
||||
---help---
|
||||
Path to the calibration file.
|
||||
|
||||
config BCMDHD_WEXT
|
||||
bool "Enable WEXT support"
|
||||
depends on BCMDHD && CFG80211 = n
|
||||
select WIRELESS_EXT
|
||||
select WEXT_PRIV
|
||||
help
|
||||
Enables WEXT support
|
||||
|
||||
config BCMDHD_STATIC_IF
|
||||
bool "Enable wlan1 support"
|
||||
|
||||
choice
|
||||
prompt "Enable Chip Interface"
|
||||
depends on BCMDHD
|
||||
---help---
|
||||
Enable Chip Interface.
|
||||
config BCMDHD_SDIO
|
||||
bool "SDIO bus interface support"
|
||||
depends on BCMDHD && MMC
|
||||
config BCMDHD_PCIE
|
||||
bool "PCIe bus interface support"
|
||||
depends on BCMDHD && PCI
|
||||
config BCMDHD_USB
|
||||
bool "USB bus interface support"
|
||||
depends on BCMDHD && USB
|
||||
endchoice
|
||||
|
||||
choice
|
||||
depends on BCMDHD && BCMDHD_SDIO
|
||||
prompt "Interrupt type"
|
||||
default BCMDHD_OOB
|
||||
---help---
|
||||
Interrupt type
|
||||
config BCMDHD_OOB
|
||||
depends on BCMDHD && BCMDHD_SDIO
|
||||
bool "Out-of-Band Interrupt"
|
||||
---help---
|
||||
Interrupt from WL_HOST_WAKE.
|
||||
config BCMDHD_SDIO_IRQ
|
||||
depends on BCMDHD && BCMDHD_SDIO
|
||||
bool "In-Band Interrupt"
|
||||
---help---
|
||||
Interrupt from SDIO DAT[1]
|
||||
endchoice
|
||||
210
drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd_wifi6/Makefile
Normal file
210
drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd_wifi6/Makefile
Normal file
@@ -0,0 +1,210 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
# bcmdhd
|
||||
|
||||
MODULE_NAME := bcmdhd_wifi6
|
||||
CONFIG_BCMDHD_SDIO := y
|
||||
#CONFIG_BCMDHD_PCIE := y
|
||||
#CONFIG_BCMDHD_USB := y
|
||||
|
||||
CONFIG_BCMDHD_OOB := y
|
||||
#CONFIG_BCMDHD_CUSB := y
|
||||
CONFIG_BCMDHD_PROPTXSTATUS := y
|
||||
CONFIG_BCMDHD_AG := y
|
||||
#CONFIG_DHD_USE_STATIC_BUF := y
|
||||
CONFIG_VTS_SUPPORT := y
|
||||
#CONFIG_BCMDHD_DEBUG := y
|
||||
|
||||
CONFIG_MACH_PLATFORM := y
|
||||
#CONFIG_BCMDHD_DTS := y
|
||||
|
||||
DHDCFLAGS = -Wall -Wstrict-prototypes -Dlinux -DBCMDRIVER \
|
||||
-DBCMDONGLEHOST -DBCMDMA32 -DBCMFILEIMAGE \
|
||||
-DDHDTHREAD -DDHD_DEBUG -DSHOW_EVENTS -DBCMDBG -DGET_OTP_MAC_ENABLE \
|
||||
-DWIFI_ACT_FRAME -DARP_OFFLOAD_SUPPORT -DSUPPORT_PM2_ONLY \
|
||||
-DKEEP_ALIVE -DPKT_FILTER_SUPPORT -DDHDTCPACK_SUPPRESS \
|
||||
-DDHD_DONOT_FORWARD_BCMEVENT_AS_NETWORK_PKT \
|
||||
-DMULTIPLE_SUPPLICANT -DTSQ_MULTIPLIER -DMFP -DDHD_8021X_DUMP \
|
||||
-DPOWERUP_MAX_RETRY=0 -DIFACE_HANG_FORCE_DEV_CLOSE -DWAIT_DEQUEUE \
|
||||
-DWL_EXT_IAPSTA -DWL_ESCAN \
|
||||
-DENABLE_INSMOD_NO_FW_LOAD \
|
||||
-Idrivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd_wifi6 \
|
||||
-Idrivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd_wifi6/include
|
||||
|
||||
DHDOFILES = aiutils.o siutils.o sbutils.o bcmutils.o bcmwifi_channels.o \
|
||||
dhd_linux.o dhd_linux_platdev.o dhd_linux_sched.o dhd_pno.o \
|
||||
dhd_common.o dhd_ip.o dhd_linux_wq.o dhd_custom_gpio.o \
|
||||
bcmevent.o hndpmu.o linux_osl.o wldev_common.o wl_android.o \
|
||||
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_config.o wl_event.o wl_android_ext.o wl_escan.o
|
||||
|
||||
ifeq ($(BCMDHD_STATIC_IF),y)
|
||||
DHDCFLAGS += -DWL_STATIC_IF
|
||||
endif
|
||||
|
||||
ifneq ($(CONFIG_WIRELESS_EXT),)
|
||||
DHDOFILES += wl_iw.o
|
||||
DHDCFLAGS += -DSOFTAP -DWL_WIRELESS_EXT -DUSE_IW
|
||||
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
|
||||
DHDCFLAGS += -DWL_CFG80211 -DWLP2P -DWL_CFG80211_STA_EVENT
|
||||
# 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 += -DDHD_USE_SCAN_WAKELOCK
|
||||
# DHDCFLAGS += -DWL_STATIC_IF
|
||||
# DHDCFLAGS += -DWL_SAE
|
||||
endif
|
||||
|
||||
#BCMDHD_SDIO
|
||||
ifneq ($(CONFIG_BCMDHD_SDIO),)
|
||||
DHDCFLAGS += -DBCMSDIO -DMMC_SDIO_ABORT -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 \
|
||||
-DBCMSDIO_RXLIM_POST -DCONSOLE_DPC
|
||||
ifeq ($(CONFIG_BCMDHD_OOB),y)
|
||||
DHDCFLAGS += -DOOB_INTR_ONLY -DCUSTOMER_OOB -DHW_OOB
|
||||
ifeq ($(CONFIG_BCMDHD_DISABLE_WOWLAN),y)
|
||||
DHDCFLAGS += -DDISABLE_WOWLAN
|
||||
endif
|
||||
else
|
||||
DHDCFLAGS += -DSDIO_ISR_THREAD
|
||||
endif
|
||||
DHDOFILES += bcmsdh.o bcmsdh_linux.o bcmsdh_sdmmc.o bcmsdh_sdmmc_linux.o \
|
||||
dhd_sdio.o dhd_cdc.o dhd_wlfc.o
|
||||
endif
|
||||
|
||||
#BCMDHD_PCIE
|
||||
ifneq ($(CONFIG_BCMDHD_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
|
||||
ifeq ($(CONFIG_BCMDHD_OOB),y)
|
||||
DHDCFLAGS += -DCUSTOMER_OOB -DBCMPCIE_OOB_HOST_WAKE
|
||||
endif
|
||||
ifneq ($(CONFIG_PCI_MSI),)
|
||||
DHDCFLAGS += -DDHD_MSI_SUPPORT
|
||||
endif
|
||||
DHDOFILES += dhd_pcie.o dhd_pcie_linux.o pcie_core.o dhd_flowring.o \
|
||||
dhd_msgbuf.o dhd_linux_lb.o
|
||||
endif
|
||||
|
||||
#BCMDHD_USB
|
||||
ifneq ($(CONFIG_BCMDHD_USB),)
|
||||
DHDCFLAGS += -DUSBOS_TX_THREAD -DBCMDBUS -DBCMTRXV2 -DDBUS_USB_LOOPBACK \
|
||||
-DBDC
|
||||
DHDCFLAGS += -DBCM_REQUEST_FW -DEXTERNAL_FW_PATH
|
||||
#DHDCFLAGS :=$(filter-out -DENABLE_INSMOD_NO_FW_LOAD,$(DHDCFLAGS))
|
||||
ifneq ($(CONFIG_BCMDHD_CUSB),)
|
||||
DHDCFLAGS += -DBCMUSBDEV_COMPOSITE
|
||||
DHDCFLAGS :=$(filter-out -DENABLE_INSMOD_NO_FW_LOAD,$(DHDCFLAGS))
|
||||
endif
|
||||
DHDOFILES += dbus.o dbus_usb.o dbus_usb_linux.o dhd_cdc.o dhd_wlfc.o
|
||||
endif
|
||||
|
||||
#PROPTXSTATUS
|
||||
ifeq ($(CONFIG_BCMDHD_PROPTXSTATUS),y)
|
||||
ifneq ($(CONFIG_BCMDHD_USB),)
|
||||
DHDCFLAGS += -DPROP_TXSTATUS
|
||||
endif
|
||||
ifneq ($(CONFIG_BCMDHD_SDIO),)
|
||||
DHDCFLAGS += -DPROP_TXSTATUS
|
||||
endif
|
||||
ifneq ($(CONFIG_CFG80211),)
|
||||
DHDCFLAGS += -DPROP_TXSTATUS_VSDB
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_64BIT),y)
|
||||
DHDCFLAGS := $(filter-out -DBCMDMA32,$(DHDCFLAGS))
|
||||
DHDCFLAGS += -DBCMDMA64OSL
|
||||
endif
|
||||
|
||||
#VTS_SUPPORT
|
||||
ifeq ($(CONFIG_VTS_SUPPORT),y)
|
||||
ifneq ($(CONFIG_CFG80211),)
|
||||
DHDCFLAGS += -DGSCAN_SUPPORT -DRTT_SUPPORT -DLINKSTAT_SUPPORT \
|
||||
-DCUSTOM_COUNTRY_CODE -DDHD_GET_VALID_CHANNELS \
|
||||
-DDEBUGABILITY -DDBG_PKT_MON -DDHD_LOG_DUMP -DDHD_FW_COREDUMP \
|
||||
-DAPF -DNDO_CONFIG_SUPPORT -DRSSI_MONITOR_SUPPORT -DDHD_WAKE_STATUS
|
||||
DHDOFILES += dhd_rtt.o bcm_app_utils.o
|
||||
endif
|
||||
endif
|
||||
|
||||
# For Debug
|
||||
ifneq ($(CONFIG_BCMDHD_DEBUG),)
|
||||
DHDCFLAGS += -DDEBUGFS_CFG80211
|
||||
DHDCFLAGS += -DSHOW_LOGTRACE -DDHD_LOG_DUMP -DDHD_FW_COREDUMP \
|
||||
-DBCMASSERT_LOG -DSI_ERROR_ENFORCE
|
||||
ifneq ($(CONFIG_BCMDHD_PCIE),)
|
||||
DHDCFLAGS += -DEWP_EDL
|
||||
DHDCFLAGS += -DDNGL_EVENT_SUPPORT
|
||||
DHDCFLAGS += -DDHD_SSSR_DUMP
|
||||
endif
|
||||
endif
|
||||
|
||||
# MESH support for kernel 3.10 later
|
||||
ifeq ($(CONFIG_WL_MESH),y)
|
||||
DHDCFLAGS += -DWLMESH
|
||||
ifneq ($(CONFIG_CFG80211),)
|
||||
DHDCFLAGS += -DWLMESH_CFG80211
|
||||
endif
|
||||
ifneq ($(CONFIG_BCMDHD_PCIE),)
|
||||
DHDCFLAGS += -DBCM_HOST_BUF -DDMA_HOST_BUFFER_LEN=0x80000
|
||||
endif
|
||||
DHDCFLAGS += -DDHD_UPDATE_INTF_MAC
|
||||
DHDCFLAGS :=$(filter-out -DDHD_FW_COREDUMP,$(DHDCFLAGS))
|
||||
DHDCFLAGS :=$(filter-out -DWL_STATIC_IF,$(DHDCFLAGS))
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_WL_EASYMESH),y)
|
||||
DHDCFLAGS :=$(filter-out -DDHD_FW_COREDUMP,$(DHDCFLAGS))
|
||||
DHDCFLAGS :=$(filter-out -DDHD_LOG_DUMP,$(DHDCFLAGS))
|
||||
DHDCFLAGS += -DWLEASYMESH -DWL_STATIC_IF -DWLDWDS -DFOURADDR_AUTO_BRG
|
||||
endif
|
||||
|
||||
#obj-$(CONFIG_RKWIFI) += $(MODULE_NAME).o
|
||||
obj-$(CONFIG_AP6XXX_WIFI6) += $(MODULE_NAME).o
|
||||
$(MODULE_NAME)-objs += $(DHDOFILES)
|
||||
|
||||
ifeq ($(CONFIG_MACH_PLATFORM),y)
|
||||
DHDOFILES += dhd_gpio.o
|
||||
ifeq ($(CONFIG_BCMDHD_DTS),y)
|
||||
DHDCFLAGS += -DCONFIG_DTS
|
||||
else
|
||||
DHDCFLAGS += -DCUSTOMER_HW -DDHD_OF_SUPPORT
|
||||
endif
|
||||
# DHDCFLAGS += -DBCMWAPI_WPI -DBCMWAPI_WAI
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_BCMDHD_AG),y)
|
||||
DHDCFLAGS += -DBAND_AG
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_DHD_USE_STATIC_BUF),y)
|
||||
obj-m += dhd_static_buf.o
|
||||
DHDCFLAGS += -DSTATIC_WL_PRIV_STRUCT -DENHANCED_STATIC_BUF
|
||||
DHDCFLAGS += -DCONFIG_DHD_USE_STATIC_BUF
|
||||
DHDCFLAGS += -DDHD_USE_STATIC_MEMDUMP
|
||||
endif
|
||||
|
||||
EXTRA_CFLAGS = $(DHDCFLAGS)
|
||||
ifeq ($(CONFIG_BCMDHD),m)
|
||||
EXTRA_LDFLAGS += --strip-debug
|
||||
endif
|
||||
|
||||
EXTRA_CFLAGS += -Wno-parentheses-equality
|
||||
EXTRA_CFLAGS += -Wno-unused-const-variable
|
||||
EXTRA_CFLAGS += -Wno-non-literal-null-conversion
|
||||
2099
drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd_wifi6/aiutils.c
Normal file
2099
drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd_wifi6/aiutils.c
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,243 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Bloom filter support
|
||||
*
|
||||
* Copyright (C) 1999-2019, 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.
|
||||
*
|
||||
* 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: bcmbloom.c 788740 2018-11-13 21:45:01Z $
|
||||
*/
|
||||
|
||||
#include <typedefs.h>
|
||||
#include <bcmdefs.h>
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#ifdef BCMDRIVER
|
||||
#include <osl.h>
|
||||
#include <bcmutils.h>
|
||||
#else /* !BCMDRIVER */
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#ifndef ASSERT
|
||||
#define ASSERT(exp)
|
||||
#endif // endif
|
||||
#endif /* !BCMDRIVER */
|
||||
#include <bcmutils.h>
|
||||
|
||||
#include <bcmbloom.h>
|
||||
|
||||
#define BLOOM_BIT_LEN(_x) ((_x) << 3)
|
||||
|
||||
struct bcm_bloom_filter {
|
||||
void *cb_ctx;
|
||||
uint max_hash;
|
||||
bcm_bloom_hash_t *hash; /* array of hash functions */
|
||||
uint filter_size; /* in bytes */
|
||||
uint8 *filter; /* can be NULL for validate only */
|
||||
};
|
||||
|
||||
/* public interface */
|
||||
int
|
||||
bcm_bloom_create(bcm_bloom_alloc_t alloc_cb,
|
||||
bcm_bloom_free_t free_cb, void *cb_ctx, uint max_hash,
|
||||
uint filter_size, bcm_bloom_filter_t **bloom)
|
||||
{
|
||||
int err = BCME_OK;
|
||||
bcm_bloom_filter_t *bp = NULL;
|
||||
|
||||
if (!bloom || !alloc_cb || (max_hash == 0)) {
|
||||
err = BCME_BADARG;
|
||||
goto done;
|
||||
}
|
||||
|
||||
bp = (*alloc_cb)(cb_ctx, sizeof(*bp));
|
||||
if (!bp) {
|
||||
err = BCME_NOMEM;
|
||||
goto done;
|
||||
}
|
||||
|
||||
memset(bp, 0, sizeof(*bp));
|
||||
bp->cb_ctx = cb_ctx;
|
||||
bp->max_hash = max_hash;
|
||||
bp->hash = (*alloc_cb)(cb_ctx, sizeof(*bp->hash) * max_hash);
|
||||
memset(bp->hash, 0, sizeof(*bp->hash) * max_hash);
|
||||
|
||||
if (!bp->hash) {
|
||||
err = BCME_NOMEM;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (filter_size > 0) {
|
||||
bp->filter = (*alloc_cb)(cb_ctx, filter_size);
|
||||
if (!bp->filter) {
|
||||
err = BCME_NOMEM;
|
||||
goto done;
|
||||
}
|
||||
bp->filter_size = filter_size;
|
||||
memset(bp->filter, 0, filter_size);
|
||||
}
|
||||
|
||||
*bloom = bp;
|
||||
|
||||
done:
|
||||
if (err != BCME_OK)
|
||||
bcm_bloom_destroy(&bp, free_cb);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
int
|
||||
bcm_bloom_destroy(bcm_bloom_filter_t **bloom, bcm_bloom_free_t free_cb)
|
||||
{
|
||||
int err = BCME_OK;
|
||||
bcm_bloom_filter_t *bp;
|
||||
|
||||
if (!bloom || !*bloom || !free_cb)
|
||||
goto done;
|
||||
|
||||
bp = *bloom;
|
||||
*bloom = NULL;
|
||||
|
||||
if (bp->filter)
|
||||
(*free_cb)(bp->cb_ctx, bp->filter, bp->filter_size);
|
||||
if (bp->hash)
|
||||
(*free_cb)(bp->cb_ctx, bp->hash,
|
||||
sizeof(*bp->hash) * bp->max_hash);
|
||||
(*free_cb)(bp->cb_ctx, bp, sizeof(*bp));
|
||||
|
||||
done:
|
||||
return err;
|
||||
}
|
||||
|
||||
int
|
||||
bcm_bloom_add_hash(bcm_bloom_filter_t *bp, bcm_bloom_hash_t hash, uint *idx)
|
||||
{
|
||||
uint i;
|
||||
|
||||
if (!bp || !hash || !idx)
|
||||
return BCME_BADARG;
|
||||
|
||||
for (i = 0; i < bp->max_hash; ++i) {
|
||||
if (bp->hash[i] == NULL)
|
||||
break;
|
||||
}
|
||||
|
||||
if (i >= bp->max_hash)
|
||||
return BCME_NORESOURCE;
|
||||
|
||||
bp->hash[i] = hash;
|
||||
*idx = i;
|
||||
return BCME_OK;
|
||||
}
|
||||
|
||||
int
|
||||
bcm_bloom_remove_hash(bcm_bloom_filter_t *bp, uint idx)
|
||||
{
|
||||
if (!bp)
|
||||
return BCME_BADARG;
|
||||
|
||||
if (idx >= bp->max_hash)
|
||||
return BCME_NOTFOUND;
|
||||
|
||||
bp->hash[idx] = NULL;
|
||||
return BCME_OK;
|
||||
}
|
||||
|
||||
bool
|
||||
bcm_bloom_is_member(bcm_bloom_filter_t *bp,
|
||||
const uint8 *tag, uint tag_len, const uint8 *buf, uint buf_len)
|
||||
{
|
||||
uint i;
|
||||
int err = BCME_OK;
|
||||
|
||||
if (!tag || (tag_len == 0)) /* empty tag is always a member */
|
||||
goto done;
|
||||
|
||||
/* use internal buffer if none was specified */
|
||||
if (!buf || (buf_len == 0)) {
|
||||
if (!bp->filter) /* every one is a member of empty filter */
|
||||
goto done;
|
||||
|
||||
buf = bp->filter;
|
||||
buf_len = bp->filter_size;
|
||||
}
|
||||
|
||||
for (i = 0; i < bp->max_hash; ++i) {
|
||||
uint pos;
|
||||
if (!bp->hash[i])
|
||||
continue;
|
||||
pos = (*bp->hash[i])(bp->cb_ctx, i, tag, tag_len);
|
||||
|
||||
/* all bits must be set for a match */
|
||||
CLANG_DIAGNOSTIC_PUSH_SUPPRESS_CAST()
|
||||
if (isclr(buf, pos % BLOOM_BIT_LEN(buf_len))) {
|
||||
CLANG_DIAGNOSTIC_POP()
|
||||
err = BCME_NOTFOUND;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
done:
|
||||
return err;
|
||||
}
|
||||
|
||||
int
|
||||
bcm_bloom_add_member(bcm_bloom_filter_t *bp, const uint8 *tag, uint tag_len)
|
||||
{
|
||||
uint i;
|
||||
|
||||
if (!bp || !tag || (tag_len == 0))
|
||||
return BCME_BADARG;
|
||||
|
||||
if (!bp->filter) /* validate only */
|
||||
return BCME_UNSUPPORTED;
|
||||
|
||||
for (i = 0; i < bp->max_hash; ++i) {
|
||||
uint pos;
|
||||
if (!bp->hash[i])
|
||||
continue;
|
||||
pos = (*bp->hash[i])(bp->cb_ctx, i, tag, tag_len);
|
||||
setbit(bp->filter, pos % BLOOM_BIT_LEN(bp->filter_size));
|
||||
}
|
||||
|
||||
return BCME_OK;
|
||||
}
|
||||
|
||||
int bcm_bloom_get_filter_data(bcm_bloom_filter_t *bp,
|
||||
uint buf_size, uint8 *buf, uint *buf_len)
|
||||
{
|
||||
if (!bp)
|
||||
return BCME_BADARG;
|
||||
|
||||
if (buf_len)
|
||||
*buf_len = bp->filter_size;
|
||||
|
||||
if (buf_size < bp->filter_size)
|
||||
return BCME_BUFTOOSHORT;
|
||||
|
||||
if (bp->filter && bp->filter_size)
|
||||
memcpy(buf, bp->filter, bp->filter_size);
|
||||
|
||||
return BCME_OK;
|
||||
}
|
||||
@@ -0,0 +1,396 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* bcmevent read-only data shared by kernel or app layers
|
||||
*
|
||||
* Copyright (C) 1999-2019, 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.
|
||||
*
|
||||
* 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: bcmevent.c 807989 2019-03-05 07:57:42Z $
|
||||
*/
|
||||
|
||||
#include <typedefs.h>
|
||||
#include <bcmutils.h>
|
||||
#include <bcmendian.h>
|
||||
#include <ethernet.h>
|
||||
#include <bcmeth.h>
|
||||
#include <bcmevent.h>
|
||||
#include <802.11.h>
|
||||
|
||||
/* Table of event name strings for UIs and debugging dumps */
|
||||
typedef struct {
|
||||
uint event;
|
||||
const char *name;
|
||||
} bcmevent_name_str_t;
|
||||
|
||||
/* Use the actual name for event tracing */
|
||||
#define BCMEVENT_NAME(_event) {(_event), #_event}
|
||||
|
||||
static const bcmevent_name_str_t bcmevent_names[] = {
|
||||
BCMEVENT_NAME(WLC_E_SET_SSID),
|
||||
BCMEVENT_NAME(WLC_E_JOIN),
|
||||
BCMEVENT_NAME(WLC_E_START),
|
||||
BCMEVENT_NAME(WLC_E_AUTH),
|
||||
BCMEVENT_NAME(WLC_E_AUTH_IND),
|
||||
BCMEVENT_NAME(WLC_E_DEAUTH),
|
||||
BCMEVENT_NAME(WLC_E_DEAUTH_IND),
|
||||
BCMEVENT_NAME(WLC_E_ASSOC),
|
||||
BCMEVENT_NAME(WLC_E_ASSOC_IND),
|
||||
BCMEVENT_NAME(WLC_E_REASSOC),
|
||||
BCMEVENT_NAME(WLC_E_REASSOC_IND),
|
||||
BCMEVENT_NAME(WLC_E_DISASSOC),
|
||||
BCMEVENT_NAME(WLC_E_DISASSOC_IND),
|
||||
BCMEVENT_NAME(WLC_E_QUIET_START),
|
||||
BCMEVENT_NAME(WLC_E_QUIET_END),
|
||||
BCMEVENT_NAME(WLC_E_BEACON_RX),
|
||||
BCMEVENT_NAME(WLC_E_LINK),
|
||||
BCMEVENT_NAME(WLC_E_MIC_ERROR),
|
||||
BCMEVENT_NAME(WLC_E_NDIS_LINK),
|
||||
BCMEVENT_NAME(WLC_E_ROAM),
|
||||
BCMEVENT_NAME(WLC_E_TXFAIL),
|
||||
BCMEVENT_NAME(WLC_E_PMKID_CACHE),
|
||||
BCMEVENT_NAME(WLC_E_RETROGRADE_TSF),
|
||||
BCMEVENT_NAME(WLC_E_PRUNE),
|
||||
BCMEVENT_NAME(WLC_E_AUTOAUTH),
|
||||
BCMEVENT_NAME(WLC_E_EAPOL_MSG),
|
||||
BCMEVENT_NAME(WLC_E_SCAN_COMPLETE),
|
||||
BCMEVENT_NAME(WLC_E_ADDTS_IND),
|
||||
BCMEVENT_NAME(WLC_E_DELTS_IND),
|
||||
BCMEVENT_NAME(WLC_E_BCNSENT_IND),
|
||||
BCMEVENT_NAME(WLC_E_BCNRX_MSG),
|
||||
BCMEVENT_NAME(WLC_E_BCNLOST_MSG),
|
||||
BCMEVENT_NAME(WLC_E_ROAM_PREP),
|
||||
BCMEVENT_NAME(WLC_E_PFN_NET_FOUND),
|
||||
BCMEVENT_NAME(WLC_E_PFN_SCAN_ALLGONE),
|
||||
BCMEVENT_NAME(WLC_E_PFN_NET_LOST),
|
||||
BCMEVENT_NAME(WLC_E_JOIN_START),
|
||||
BCMEVENT_NAME(WLC_E_ROAM_START),
|
||||
BCMEVENT_NAME(WLC_E_ASSOC_START),
|
||||
#if defined(IBSS_PEER_DISCOVERY_EVENT)
|
||||
BCMEVENT_NAME(WLC_E_IBSS_ASSOC),
|
||||
#endif /* defined(IBSS_PEER_DISCOVERY_EVENT) */
|
||||
BCMEVENT_NAME(WLC_E_RADIO),
|
||||
BCMEVENT_NAME(WLC_E_PSM_WATCHDOG),
|
||||
BCMEVENT_NAME(WLC_E_PROBREQ_MSG),
|
||||
BCMEVENT_NAME(WLC_E_SCAN_CONFIRM_IND),
|
||||
BCMEVENT_NAME(WLC_E_PSK_SUP),
|
||||
BCMEVENT_NAME(WLC_E_COUNTRY_CODE_CHANGED),
|
||||
BCMEVENT_NAME(WLC_E_EXCEEDED_MEDIUM_TIME),
|
||||
BCMEVENT_NAME(WLC_E_ICV_ERROR),
|
||||
BCMEVENT_NAME(WLC_E_UNICAST_DECODE_ERROR),
|
||||
BCMEVENT_NAME(WLC_E_MULTICAST_DECODE_ERROR),
|
||||
BCMEVENT_NAME(WLC_E_TRACE),
|
||||
BCMEVENT_NAME(WLC_E_IF),
|
||||
#ifdef WLP2P
|
||||
BCMEVENT_NAME(WLC_E_P2P_DISC_LISTEN_COMPLETE),
|
||||
#endif // endif
|
||||
BCMEVENT_NAME(WLC_E_RSSI),
|
||||
BCMEVENT_NAME(WLC_E_PFN_SCAN_COMPLETE),
|
||||
BCMEVENT_NAME(WLC_E_ACTION_FRAME),
|
||||
BCMEVENT_NAME(WLC_E_ACTION_FRAME_RX),
|
||||
BCMEVENT_NAME(WLC_E_ACTION_FRAME_COMPLETE),
|
||||
#ifdef BCMWAPI_WAI
|
||||
BCMEVENT_NAME(WLC_E_WAI_STA_EVENT),
|
||||
BCMEVENT_NAME(WLC_E_WAI_MSG),
|
||||
#endif /* BCMWAPI_WAI */
|
||||
BCMEVENT_NAME(WLC_E_ESCAN_RESULT),
|
||||
BCMEVENT_NAME(WLC_E_ACTION_FRAME_OFF_CHAN_COMPLETE),
|
||||
#ifdef WLP2P
|
||||
BCMEVENT_NAME(WLC_E_PROBRESP_MSG),
|
||||
BCMEVENT_NAME(WLC_E_P2P_PROBREQ_MSG),
|
||||
#endif // endif
|
||||
#ifdef PROP_TXSTATUS
|
||||
BCMEVENT_NAME(WLC_E_FIFO_CREDIT_MAP),
|
||||
#endif // endif
|
||||
BCMEVENT_NAME(WLC_E_WAKE_EVENT),
|
||||
BCMEVENT_NAME(WLC_E_DCS_REQUEST),
|
||||
BCMEVENT_NAME(WLC_E_RM_COMPLETE),
|
||||
BCMEVENT_NAME(WLC_E_OVERLAY_REQ),
|
||||
BCMEVENT_NAME(WLC_E_CSA_COMPLETE_IND),
|
||||
BCMEVENT_NAME(WLC_E_EXCESS_PM_WAKE_EVENT),
|
||||
BCMEVENT_NAME(WLC_E_PFN_SCAN_NONE),
|
||||
BCMEVENT_NAME(WLC_E_PFN_SCAN_ALLGONE),
|
||||
#ifdef SOFTAP
|
||||
BCMEVENT_NAME(WLC_E_GTK_PLUMBED),
|
||||
#endif // endif
|
||||
BCMEVENT_NAME(WLC_E_ASSOC_REQ_IE),
|
||||
BCMEVENT_NAME(WLC_E_ASSOC_RESP_IE),
|
||||
BCMEVENT_NAME(WLC_E_BEACON_FRAME_RX),
|
||||
#ifdef WLTDLS
|
||||
BCMEVENT_NAME(WLC_E_TDLS_PEER_EVENT),
|
||||
#endif /* WLTDLS */
|
||||
BCMEVENT_NAME(WLC_E_NATIVE),
|
||||
#ifdef WLPKTDLYSTAT
|
||||
BCMEVENT_NAME(WLC_E_PKTDELAY_IND),
|
||||
#endif /* WLPKTDLYSTAT */
|
||||
BCMEVENT_NAME(WLC_E_SERVICE_FOUND),
|
||||
BCMEVENT_NAME(WLC_E_GAS_FRAGMENT_RX),
|
||||
BCMEVENT_NAME(WLC_E_GAS_COMPLETE),
|
||||
BCMEVENT_NAME(WLC_E_P2PO_ADD_DEVICE),
|
||||
BCMEVENT_NAME(WLC_E_P2PO_DEL_DEVICE),
|
||||
#ifdef WLWNM
|
||||
BCMEVENT_NAME(WLC_E_WNM_STA_SLEEP),
|
||||
#endif /* WLWNM */
|
||||
#if defined(WL_PROXDETECT) || defined(RTT_SUPPORT)
|
||||
BCMEVENT_NAME(WLC_E_PROXD),
|
||||
#endif // endif
|
||||
BCMEVENT_NAME(WLC_E_CCA_CHAN_QUAL),
|
||||
BCMEVENT_NAME(WLC_E_BSSID),
|
||||
#ifdef PROP_TXSTATUS
|
||||
BCMEVENT_NAME(WLC_E_BCMC_CREDIT_SUPPORT),
|
||||
#endif // endif
|
||||
BCMEVENT_NAME(WLC_E_PSTA_PRIMARY_INTF_IND),
|
||||
BCMEVENT_NAME(WLC_E_TXFAIL_THRESH),
|
||||
#ifdef GSCAN_SUPPORT
|
||||
BCMEVENT_NAME(WLC_E_PFN_GSCAN_FULL_RESULT),
|
||||
BCMEVENT_NAME(WLC_E_PFN_SSID_EXT),
|
||||
#endif /* GSCAN_SUPPORT */
|
||||
#ifdef WLBSSLOAD_REPORT
|
||||
BCMEVENT_NAME(WLC_E_BSS_LOAD),
|
||||
#endif // endif
|
||||
#if defined(BT_WIFI_HANDOVER) || defined(WL_TBOW)
|
||||
BCMEVENT_NAME(WLC_E_BT_WIFI_HANDOVER_REQ),
|
||||
#endif // endif
|
||||
#ifdef WLFBT
|
||||
BCMEVENT_NAME(WLC_E_FBT),
|
||||
#endif /* WLFBT */
|
||||
BCMEVENT_NAME(WLC_E_AUTHORIZED),
|
||||
BCMEVENT_NAME(WLC_E_PROBREQ_MSG_RX),
|
||||
BCMEVENT_NAME(WLC_E_CSA_START_IND),
|
||||
BCMEVENT_NAME(WLC_E_CSA_DONE_IND),
|
||||
BCMEVENT_NAME(WLC_E_CSA_FAILURE_IND),
|
||||
BCMEVENT_NAME(WLC_E_RMC_EVENT),
|
||||
BCMEVENT_NAME(WLC_E_DPSTA_INTF_IND),
|
||||
BCMEVENT_NAME(WLC_E_ALLOW_CREDIT_BORROW),
|
||||
BCMEVENT_NAME(WLC_E_MSCH),
|
||||
BCMEVENT_NAME(WLC_E_ULP),
|
||||
BCMEVENT_NAME(WLC_E_NAN),
|
||||
BCMEVENT_NAME(WLC_E_PKT_FILTER),
|
||||
BCMEVENT_NAME(WLC_E_DMA_TXFLUSH_COMPLETE),
|
||||
BCMEVENT_NAME(WLC_E_PSK_AUTH),
|
||||
BCMEVENT_NAME(WLC_E_SDB_TRANSITION),
|
||||
BCMEVENT_NAME(WLC_E_PFN_SCAN_BACKOFF),
|
||||
BCMEVENT_NAME(WLC_E_PFN_BSSID_SCAN_BACKOFF),
|
||||
BCMEVENT_NAME(WLC_E_AGGR_EVENT),
|
||||
BCMEVENT_NAME(WLC_E_TVPM_MITIGATION),
|
||||
#ifdef WL_NAN
|
||||
BCMEVENT_NAME(WLC_E_NAN_CRITICAL),
|
||||
BCMEVENT_NAME(WLC_E_NAN_NON_CRITICAL),
|
||||
BCMEVENT_NAME(WLC_E_NAN),
|
||||
#endif /* WL_NAN */
|
||||
BCMEVENT_NAME(WLC_E_RPSNOA),
|
||||
BCMEVENT_NAME(WLC_E_PHY_CAL),
|
||||
BCMEVENT_NAME(WLC_E_WA_LQM),
|
||||
};
|
||||
|
||||
const char *bcmevent_get_name(uint event_type)
|
||||
{
|
||||
/* note: first coded this as a static const but some
|
||||
* ROMs already have something called event_name so
|
||||
* changed it so we don't have a variable for the
|
||||
* 'unknown string
|
||||
*/
|
||||
const char *event_name = NULL;
|
||||
|
||||
uint idx;
|
||||
for (idx = 0; idx < (uint)ARRAYSIZE(bcmevent_names); idx++) {
|
||||
|
||||
if (bcmevent_names[idx].event == event_type) {
|
||||
event_name = bcmevent_names[idx].name;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* if we find an event name in the array, return it.
|
||||
* otherwise return unknown string.
|
||||
*/
|
||||
return ((event_name) ? event_name : "Unknown Event");
|
||||
}
|
||||
|
||||
void
|
||||
wl_event_to_host_order(wl_event_msg_t * evt)
|
||||
{
|
||||
/* Event struct members passed from dongle to host are stored in network
|
||||
* byte order. Convert all members to host-order.
|
||||
*/
|
||||
evt->event_type = ntoh32(evt->event_type);
|
||||
evt->flags = ntoh16(evt->flags);
|
||||
evt->status = ntoh32(evt->status);
|
||||
evt->reason = ntoh32(evt->reason);
|
||||
evt->auth_type = ntoh32(evt->auth_type);
|
||||
evt->datalen = ntoh32(evt->datalen);
|
||||
evt->version = ntoh16(evt->version);
|
||||
}
|
||||
|
||||
void
|
||||
wl_event_to_network_order(wl_event_msg_t * evt)
|
||||
{
|
||||
/* Event struct members passed from dongle to host are stored in network
|
||||
* byte order. Convert all members to host-order.
|
||||
*/
|
||||
evt->event_type = hton32(evt->event_type);
|
||||
evt->flags = hton16(evt->flags);
|
||||
evt->status = hton32(evt->status);
|
||||
evt->reason = hton32(evt->reason);
|
||||
evt->auth_type = hton32(evt->auth_type);
|
||||
evt->datalen = hton32(evt->datalen);
|
||||
evt->version = hton16(evt->version);
|
||||
}
|
||||
|
||||
/*
|
||||
* Validate if the event is proper and if valid copy event header to event.
|
||||
* If proper event pointer is passed, to just validate, pass NULL to event.
|
||||
*
|
||||
* Return values are
|
||||
* BCME_OK - It is a BRCM event or BRCM dongle event
|
||||
* BCME_NOTFOUND - Not BRCM, not an event, may be okay
|
||||
* BCME_BADLEN - Bad length, should not process, just drop
|
||||
*/
|
||||
int
|
||||
is_wlc_event_frame(void *pktdata, uint pktlen, uint16 exp_usr_subtype,
|
||||
bcm_event_msg_u_t *out_event)
|
||||
{
|
||||
uint16 evlen = 0; /* length in bcmeth_hdr */
|
||||
uint16 subtype;
|
||||
uint16 usr_subtype;
|
||||
bcm_event_t *bcm_event;
|
||||
uint8 *pktend;
|
||||
uint8 *evend;
|
||||
int err = BCME_OK;
|
||||
uint32 data_len = 0; /* data length in bcm_event */
|
||||
|
||||
pktend = (uint8 *)pktdata + pktlen;
|
||||
bcm_event = (bcm_event_t *)pktdata;
|
||||
|
||||
/* only care about 16-bit subtype / length versions */
|
||||
if ((uint8 *)&bcm_event->bcm_hdr < pktend) {
|
||||
uint8 short_subtype = *(uint8 *)&bcm_event->bcm_hdr;
|
||||
if (!(short_subtype & 0x80)) {
|
||||
err = BCME_NOTFOUND;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
/* must have both ether_header and bcmeth_hdr */
|
||||
if (pktlen < OFFSETOF(bcm_event_t, event)) {
|
||||
err = BCME_BADLEN;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* check length in bcmeth_hdr */
|
||||
|
||||
/* temporary - header length not always set properly. When the below
|
||||
* !BCMDONGLEHOST is in all branches that use trunk DHD, the code
|
||||
* under BCMDONGLEHOST can be removed.
|
||||
*/
|
||||
evlen = (uint16)(pktend - (uint8 *)&bcm_event->bcm_hdr.version);
|
||||
evend = (uint8 *)&bcm_event->bcm_hdr.version + evlen;
|
||||
if (evend != pktend) {
|
||||
err = BCME_BADLEN;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* match on subtype, oui and usr subtype for BRCM events */
|
||||
subtype = ntoh16_ua((void *)&bcm_event->bcm_hdr.subtype);
|
||||
if (subtype != BCMILCP_SUBTYPE_VENDOR_LONG) {
|
||||
err = BCME_NOTFOUND;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (bcmp(BRCM_OUI, &bcm_event->bcm_hdr.oui[0], DOT11_OUI_LEN)) {
|
||||
err = BCME_NOTFOUND;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* if it is a bcm_event or bcm_dngl_event_t, validate it */
|
||||
usr_subtype = ntoh16_ua((void *)&bcm_event->bcm_hdr.usr_subtype);
|
||||
switch (usr_subtype) {
|
||||
case BCMILCP_BCM_SUBTYPE_EVENT:
|
||||
/* check that header length and pkt length are sufficient */
|
||||
if ((pktlen < sizeof(bcm_event_t)) ||
|
||||
(evend < ((uint8 *)bcm_event + sizeof(bcm_event_t)))) {
|
||||
err = BCME_BADLEN;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* ensure data length in event is not beyond the packet. */
|
||||
data_len = ntoh32_ua((void *)&bcm_event->event.datalen);
|
||||
if ((sizeof(bcm_event_t) + data_len +
|
||||
BCMILCP_BCM_SUBTYPE_EVENT_DATA_PAD) != pktlen) {
|
||||
err = BCME_BADLEN;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (exp_usr_subtype && (exp_usr_subtype != usr_subtype)) {
|
||||
err = BCME_NOTFOUND;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (out_event) {
|
||||
/* ensure BRCM event pkt aligned */
|
||||
memcpy(&out_event->event, &bcm_event->event, sizeof(wl_event_msg_t));
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case BCMILCP_BCM_SUBTYPE_DNGLEVENT:
|
||||
#if defined(DNGL_EVENT_SUPPORT)
|
||||
if ((pktlen < sizeof(bcm_dngl_event_t)) ||
|
||||
(evend < ((uint8 *)bcm_event + sizeof(bcm_dngl_event_t)))) {
|
||||
err = BCME_BADLEN;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* ensure data length in event is not beyond the packet. */
|
||||
data_len = ntoh16_ua((void *)&((bcm_dngl_event_t *)pktdata)->dngl_event.datalen);
|
||||
if ((sizeof(bcm_dngl_event_t) + data_len +
|
||||
BCMILCP_BCM_SUBTYPE_EVENT_DATA_PAD) != pktlen) {
|
||||
err = BCME_BADLEN;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (exp_usr_subtype && (exp_usr_subtype != usr_subtype)) {
|
||||
err = BCME_NOTFOUND;
|
||||
goto done;
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
break;
|
||||
#else
|
||||
err = BCME_UNSUPPORTED;
|
||||
break;
|
||||
#endif // endif
|
||||
|
||||
default:
|
||||
err = BCME_NOTFOUND;
|
||||
goto done;
|
||||
}
|
||||
|
||||
BCM_REFERENCE(data_len);
|
||||
done:
|
||||
return err;
|
||||
}
|
||||
884
drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd_wifi6/bcmsdh.c
Normal file
884
drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd_wifi6/bcmsdh.c
Normal file
@@ -0,0 +1,884 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* BCMSDH interface glue
|
||||
* implement bcmsdh API for SDIOH driver
|
||||
*
|
||||
* Copyright (C) 1999-2019, 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.
|
||||
*
|
||||
* 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: bcmsdh.c 727623 2017-10-21 01:00:32Z $
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file bcmsdh.c
|
||||
*/
|
||||
|
||||
/* ****************** BCMSDH Interface Functions *************************** */
|
||||
|
||||
#include <typedefs.h>
|
||||
#include <bcmdevs.h>
|
||||
#include <bcmendian.h>
|
||||
#include <bcmutils.h>
|
||||
#include <hndsoc.h>
|
||||
#include <siutils.h>
|
||||
#include <osl.h>
|
||||
|
||||
#include <bcmsdh.h> /* BRCM API for SDIO clients (such as wl, dhd) */
|
||||
#include <bcmsdbus.h> /* common SDIO/controller interface */
|
||||
#include <sbsdio.h> /* SDIO device core hardware definitions. */
|
||||
#include <sdio.h> /* SDIO Device and Protocol Specs */
|
||||
|
||||
#if defined(BT_OVER_SDIO)
|
||||
#include <dhd_bt_interface.h>
|
||||
#endif /* defined (BT_OVER_SDIO) */
|
||||
|
||||
#define SDIOH_API_ACCESS_RETRY_LIMIT 2
|
||||
const uint bcmsdh_msglevel = BCMSDH_ERROR_VAL;
|
||||
|
||||
/* local copy of bcm sd handler */
|
||||
bcmsdh_info_t * l_bcmsdh = NULL;
|
||||
|
||||
#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;
|
||||
static dhd_hang_state_t g_dhd_hang_state = NO_HANG_STATE;
|
||||
#endif /* defined (BT_OVER_SDIO) */
|
||||
|
||||
#if defined(OOB_INTR_ONLY) && defined(HW_OOB) || defined(FORCE_WOWLAN)
|
||||
extern int
|
||||
sdioh_enable_hw_oob_intr(void *sdioh, bool enable);
|
||||
|
||||
void
|
||||
bcmsdh_enable_hw_oob_intr(bcmsdh_info_t *sdh, bool enable)
|
||||
{
|
||||
sdioh_enable_hw_oob_intr(sdh->sdioh, enable);
|
||||
}
|
||||
#endif // endif
|
||||
|
||||
#if defined(BT_OVER_SDIO)
|
||||
void bcmsdh_btsdio_process_hang_state(dhd_hang_state_t new_state)
|
||||
{
|
||||
bool state_change = false;
|
||||
|
||||
BCMSDH_ERROR(("%s: DHD hang state changed - [%d] -> [%d]\n",
|
||||
__FUNCTION__, g_dhd_hang_state, new_state));
|
||||
|
||||
if (g_dhd_hang_state == new_state)
|
||||
return;
|
||||
|
||||
switch (g_dhd_hang_state) {
|
||||
case NO_HANG_STATE:
|
||||
if (HANG_START_STATE == new_state)
|
||||
state_change = true;
|
||||
break;
|
||||
|
||||
case HANG_START_STATE:
|
||||
if (HANG_RECOVERY_STATE == new_state ||
|
||||
NO_HANG_STATE == new_state)
|
||||
state_change = true;
|
||||
|
||||
break;
|
||||
|
||||
case HANG_RECOVERY_STATE:
|
||||
if (NO_HANG_STATE == new_state)
|
||||
state_change = true;
|
||||
break;
|
||||
|
||||
default:
|
||||
BCMSDH_ERROR(("%s: Unhandled Hang state\n", __FUNCTION__));
|
||||
break;
|
||||
}
|
||||
|
||||
if (!state_change) {
|
||||
BCMSDH_ERROR(("%s: Hang state cannot be changed\n", __FUNCTION__));
|
||||
return;
|
||||
}
|
||||
|
||||
g_dhd_hang_state = new_state;
|
||||
}
|
||||
|
||||
void bcmsdh_btsdio_process_f3_intr(void)
|
||||
{
|
||||
if (processf3intr && (g_dhd_hang_state == NO_HANG_STATE))
|
||||
processf3intr(func_f3);
|
||||
}
|
||||
|
||||
void bcmsdh_btsdio_process_dhd_hang_notification(bool wifi_recovery_completed)
|
||||
{
|
||||
bcmsdh_btsdio_process_hang_state(HANG_START_STATE);
|
||||
|
||||
if (process_dhd_hang_notification)
|
||||
process_dhd_hang_notification(func_f3, wifi_recovery_completed);
|
||||
|
||||
/* WiFi was off, so HANG_RECOVERY_STATE is not needed */
|
||||
if (wifi_recovery_completed)
|
||||
bcmsdh_btsdio_process_hang_state(NO_HANG_STATE);
|
||||
else {
|
||||
bcmsdh_btsdio_process_hang_state(HANG_RECOVERY_STATE);
|
||||
}
|
||||
}
|
||||
|
||||
void bcmsdh_btsdio_interface_init(struct sdio_func *func,
|
||||
f3intr_handler f3intr_fun, dhd_hang_notification hang_notification)
|
||||
{
|
||||
bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)l_bcmsdh;
|
||||
BCMSDH_INFO(("%s: func %p \n", __FUNCTION__, func));
|
||||
func_f3 = func;
|
||||
processf3intr = f3intr_fun;
|
||||
sdioh_sdmmc_card_enable_func_f3(bcmsdh->sdioh, func);
|
||||
process_dhd_hang_notification = hang_notification;
|
||||
|
||||
} EXPORT_SYMBOL(bcmsdh_btsdio_interface_init);
|
||||
#endif /* defined (BT_OVER_SDIO) */
|
||||
|
||||
/* Attach BCMSDH layer to SDIO Host Controller Driver
|
||||
*
|
||||
* @param osh OSL Handle.
|
||||
* @param cfghdl Configuration Handle.
|
||||
* @param regsva Virtual address of controller registers.
|
||||
* @param irq Interrupt number of SDIO controller.
|
||||
*
|
||||
* @return bcmsdh_info_t Handle to BCMSDH context.
|
||||
*/
|
||||
bcmsdh_info_t *
|
||||
bcmsdh_attach(osl_t *osh, void *sdioh, ulong *regsva)
|
||||
{
|
||||
bcmsdh_info_t *bcmsdh;
|
||||
|
||||
if ((bcmsdh = (bcmsdh_info_t *)MALLOC(osh, sizeof(bcmsdh_info_t))) == NULL) {
|
||||
BCMSDH_ERROR(("bcmsdh_attach: out of memory, malloced %d bytes\n", MALLOCED(osh)));
|
||||
return NULL;
|
||||
}
|
||||
bzero((char *)bcmsdh, sizeof(bcmsdh_info_t));
|
||||
bcmsdh->sdioh = sdioh;
|
||||
bcmsdh->osh = osh;
|
||||
bcmsdh->init_success = TRUE;
|
||||
*regsva = si_enum_base(0);
|
||||
|
||||
bcmsdh_force_sbwad_calc(bcmsdh, FALSE);
|
||||
|
||||
/* Report the BAR, to fix if needed */
|
||||
bcmsdh->sbwad = si_enum_base(0);
|
||||
|
||||
/* save the handler locally */
|
||||
l_bcmsdh = bcmsdh;
|
||||
|
||||
return bcmsdh;
|
||||
}
|
||||
|
||||
int
|
||||
bcmsdh_detach(osl_t *osh, void *sdh)
|
||||
{
|
||||
bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh;
|
||||
|
||||
if (bcmsdh != NULL) {
|
||||
MFREE(osh, bcmsdh, sizeof(bcmsdh_info_t));
|
||||
}
|
||||
|
||||
l_bcmsdh = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
bcmsdh_iovar_op(void *sdh, const char *name,
|
||||
void *params, uint plen, void *arg, uint len, bool set)
|
||||
{
|
||||
bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh;
|
||||
return sdioh_iovar_op(bcmsdh->sdioh, name, params, plen, arg, len, set);
|
||||
}
|
||||
|
||||
bool
|
||||
bcmsdh_intr_query(void *sdh)
|
||||
{
|
||||
bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh;
|
||||
SDIOH_API_RC status;
|
||||
bool on;
|
||||
|
||||
ASSERT(bcmsdh);
|
||||
status = sdioh_interrupt_query(bcmsdh->sdioh, &on);
|
||||
if (SDIOH_API_SUCCESS(status))
|
||||
return FALSE;
|
||||
else
|
||||
return on;
|
||||
}
|
||||
|
||||
int
|
||||
bcmsdh_intr_enable(void *sdh)
|
||||
{
|
||||
bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh;
|
||||
SDIOH_API_RC status;
|
||||
#ifdef BCMSPI_ANDROID
|
||||
uint32 data;
|
||||
#endif /* BCMSPI_ANDROID */
|
||||
ASSERT(bcmsdh);
|
||||
|
||||
status = sdioh_interrupt_set(bcmsdh->sdioh, TRUE);
|
||||
#ifdef BCMSPI_ANDROID
|
||||
data = bcmsdh_cfg_read_word(sdh, 0, 4, NULL);
|
||||
data |= 0xE0E70000;
|
||||
bcmsdh_cfg_write_word(sdh, 0, 4, data, NULL);
|
||||
#endif /* BCMSPI_ANDROID */
|
||||
return (SDIOH_API_SUCCESS(status) ? 0 : BCME_ERROR);
|
||||
}
|
||||
|
||||
int
|
||||
bcmsdh_intr_disable(void *sdh)
|
||||
{
|
||||
bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh;
|
||||
SDIOH_API_RC status;
|
||||
#ifdef BCMSPI_ANDROID
|
||||
uint32 data;
|
||||
#endif /* BCMSPI_ANDROID */
|
||||
ASSERT(bcmsdh);
|
||||
|
||||
status = sdioh_interrupt_set(bcmsdh->sdioh, FALSE);
|
||||
#ifdef BCMSPI_ANDROID
|
||||
data = bcmsdh_cfg_read_word(sdh, 0, 4, NULL);
|
||||
data &= ~0xE0E70000;
|
||||
bcmsdh_cfg_write_word(sdh, 0, 4, data, NULL);
|
||||
#endif /* BCMSPI_ANDROID */
|
||||
return (SDIOH_API_SUCCESS(status) ? 0 : BCME_ERROR);
|
||||
}
|
||||
|
||||
int
|
||||
bcmsdh_intr_reg(void *sdh, bcmsdh_cb_fn_t fn, void *argh)
|
||||
{
|
||||
bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh;
|
||||
SDIOH_API_RC status;
|
||||
|
||||
if (!bcmsdh)
|
||||
bcmsdh = l_bcmsdh;
|
||||
|
||||
ASSERT(bcmsdh);
|
||||
|
||||
status = sdioh_interrupt_register(bcmsdh->sdioh, fn, argh);
|
||||
return (SDIOH_API_SUCCESS(status) ? 0 : BCME_ERROR);
|
||||
}
|
||||
|
||||
int
|
||||
bcmsdh_intr_dereg(void *sdh)
|
||||
{
|
||||
bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh;
|
||||
SDIOH_API_RC status;
|
||||
|
||||
if (!bcmsdh)
|
||||
bcmsdh = l_bcmsdh;
|
||||
|
||||
ASSERT(bcmsdh);
|
||||
|
||||
status = sdioh_interrupt_deregister(bcmsdh->sdioh);
|
||||
return (SDIOH_API_SUCCESS(status) ? 0 : BCME_ERROR);
|
||||
}
|
||||
|
||||
#if defined(DHD_DEBUG)
|
||||
bool
|
||||
bcmsdh_intr_pending(void *sdh)
|
||||
{
|
||||
bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh;
|
||||
|
||||
ASSERT(sdh);
|
||||
return sdioh_interrupt_pending(bcmsdh->sdioh);
|
||||
}
|
||||
#endif // endif
|
||||
|
||||
int
|
||||
bcmsdh_devremove_reg(void *sdh, bcmsdh_cb_fn_t fn, void *argh)
|
||||
{
|
||||
ASSERT(sdh);
|
||||
|
||||
/* don't support yet */
|
||||
return BCME_UNSUPPORTED;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read from SDIO Configuration Space
|
||||
* @param sdh SDIO Host context.
|
||||
* @param func_num Function number to read from.
|
||||
* @param addr Address to read from.
|
||||
* @param err Error return.
|
||||
* @return value read from SDIO configuration space.
|
||||
*/
|
||||
uint8
|
||||
bcmsdh_cfg_read(void *sdh, uint fnc_num, uint32 addr, int *err)
|
||||
{
|
||||
bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh;
|
||||
SDIOH_API_RC status;
|
||||
#ifdef SDIOH_API_ACCESS_RETRY_LIMIT
|
||||
int32 retry = 0;
|
||||
#endif // endif
|
||||
uint8 data = 0;
|
||||
|
||||
if (!bcmsdh)
|
||||
bcmsdh = l_bcmsdh;
|
||||
|
||||
ASSERT(bcmsdh->init_success);
|
||||
|
||||
#ifdef SDIOH_API_ACCESS_RETRY_LIMIT
|
||||
do {
|
||||
if (retry) /* wait for 1 ms till bus get settled down */
|
||||
OSL_DELAY(1000);
|
||||
#endif // endif
|
||||
status = sdioh_cfg_read(bcmsdh->sdioh, fnc_num, addr, (uint8 *)&data);
|
||||
#ifdef SDIOH_API_ACCESS_RETRY_LIMIT
|
||||
} while (!SDIOH_API_SUCCESS(status) && (retry++ < SDIOH_API_ACCESS_RETRY_LIMIT));
|
||||
#endif // endif
|
||||
if (err)
|
||||
*err = (SDIOH_API_SUCCESS(status) ? 0 : BCME_SDIO_ERROR);
|
||||
|
||||
BCMSDH_INFO(("%s:fun = %d, addr = 0x%x, uint8data = 0x%x\n", __FUNCTION__,
|
||||
fnc_num, addr, data));
|
||||
|
||||
return data;
|
||||
} EXPORT_SYMBOL(bcmsdh_cfg_read);
|
||||
|
||||
void
|
||||
bcmsdh_cfg_write(void *sdh, uint fnc_num, uint32 addr, uint8 data, int *err)
|
||||
{
|
||||
bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh;
|
||||
SDIOH_API_RC status;
|
||||
#ifdef SDIOH_API_ACCESS_RETRY_LIMIT
|
||||
int32 retry = 0;
|
||||
#endif // endif
|
||||
|
||||
if (!bcmsdh)
|
||||
bcmsdh = l_bcmsdh;
|
||||
|
||||
ASSERT(bcmsdh->init_success);
|
||||
|
||||
#ifdef SDIOH_API_ACCESS_RETRY_LIMIT
|
||||
do {
|
||||
if (retry) /* wait for 1 ms till bus get settled down */
|
||||
OSL_DELAY(1000);
|
||||
#endif // endif
|
||||
status = sdioh_cfg_write(bcmsdh->sdioh, fnc_num, addr, (uint8 *)&data);
|
||||
#ifdef SDIOH_API_ACCESS_RETRY_LIMIT
|
||||
} while (!SDIOH_API_SUCCESS(status) && (retry++ < SDIOH_API_ACCESS_RETRY_LIMIT));
|
||||
#endif // endif
|
||||
if (err)
|
||||
*err = SDIOH_API_SUCCESS(status) ? 0 : BCME_SDIO_ERROR;
|
||||
|
||||
BCMSDH_INFO(("%s:fun = %d, addr = 0x%x, uint8data = 0x%x\n", __FUNCTION__,
|
||||
fnc_num, addr, data));
|
||||
} EXPORT_SYMBOL(bcmsdh_cfg_write);
|
||||
|
||||
uint32
|
||||
bcmsdh_cfg_read_word(void *sdh, uint fnc_num, uint32 addr, int *err)
|
||||
{
|
||||
bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh;
|
||||
SDIOH_API_RC status;
|
||||
uint32 data = 0;
|
||||
|
||||
if (!bcmsdh)
|
||||
bcmsdh = l_bcmsdh;
|
||||
|
||||
ASSERT(bcmsdh->init_success);
|
||||
|
||||
status = sdioh_request_word(bcmsdh->sdioh, SDIOH_CMD_TYPE_NORMAL, SDIOH_READ, fnc_num,
|
||||
addr, &data, 4);
|
||||
|
||||
if (err)
|
||||
*err = (SDIOH_API_SUCCESS(status) ? 0 : BCME_SDIO_ERROR);
|
||||
|
||||
BCMSDH_INFO(("%s:fun = %d, addr = 0x%x, uint32data = 0x%x\n", __FUNCTION__,
|
||||
fnc_num, addr, data));
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
void
|
||||
bcmsdh_cfg_write_word(void *sdh, uint fnc_num, uint32 addr, uint32 data, int *err)
|
||||
{
|
||||
bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh;
|
||||
SDIOH_API_RC status;
|
||||
|
||||
if (!bcmsdh)
|
||||
bcmsdh = l_bcmsdh;
|
||||
|
||||
ASSERT(bcmsdh->init_success);
|
||||
|
||||
status = sdioh_request_word(bcmsdh->sdioh, SDIOH_CMD_TYPE_NORMAL, SDIOH_WRITE, fnc_num,
|
||||
addr, &data, 4);
|
||||
|
||||
if (err)
|
||||
*err = (SDIOH_API_SUCCESS(status) ? 0 : BCME_SDIO_ERROR);
|
||||
|
||||
BCMSDH_INFO(("%s:fun = %d, addr = 0x%x, uint32data = 0x%x\n", __FUNCTION__, fnc_num,
|
||||
addr, data));
|
||||
}
|
||||
|
||||
int
|
||||
bcmsdh_cis_read(void *sdh, uint func, uint8 *cis, uint length)
|
||||
{
|
||||
bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh;
|
||||
SDIOH_API_RC status;
|
||||
|
||||
uint8 *tmp_buf, *tmp_ptr;
|
||||
uint8 *ptr;
|
||||
bool ascii = func & ~0xf;
|
||||
func &= 0x7;
|
||||
|
||||
if (!bcmsdh)
|
||||
bcmsdh = l_bcmsdh;
|
||||
|
||||
ASSERT(bcmsdh->init_success);
|
||||
ASSERT(cis);
|
||||
ASSERT(length <= SBSDIO_CIS_SIZE_LIMIT);
|
||||
|
||||
status = sdioh_cis_read(bcmsdh->sdioh, func, cis, length);
|
||||
|
||||
if (ascii) {
|
||||
/* Move binary bits to tmp and format them into the provided buffer. */
|
||||
if ((tmp_buf = (uint8 *)MALLOC(bcmsdh->osh, length)) == NULL) {
|
||||
BCMSDH_ERROR(("%s: out of memory\n", __FUNCTION__));
|
||||
return BCME_NOMEM;
|
||||
}
|
||||
bcopy(cis, tmp_buf, length);
|
||||
for (tmp_ptr = tmp_buf, ptr = cis; ptr < (cis + length - 4); tmp_ptr++) {
|
||||
ptr += snprintf((char*)ptr, (cis + length - ptr - 4),
|
||||
"%.2x ", *tmp_ptr & 0xff);
|
||||
if ((((tmp_ptr - tmp_buf) + 1) & 0xf) == 0)
|
||||
ptr += snprintf((char *)ptr, (cis + length - ptr -4), "\n");
|
||||
}
|
||||
MFREE(bcmsdh->osh, tmp_buf, length);
|
||||
}
|
||||
|
||||
return (SDIOH_API_SUCCESS(status) ? 0 : BCME_ERROR);
|
||||
}
|
||||
|
||||
int
|
||||
bcmsdh_cisaddr_read(void *sdh, uint func, uint8 *cisd, uint32 offset)
|
||||
{
|
||||
bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh;
|
||||
SDIOH_API_RC status;
|
||||
|
||||
func &= 0x7;
|
||||
|
||||
if (!bcmsdh)
|
||||
bcmsdh = l_bcmsdh;
|
||||
|
||||
ASSERT(bcmsdh->init_success);
|
||||
ASSERT(cisd);
|
||||
|
||||
status = sdioh_cisaddr_read(bcmsdh->sdioh, func, cisd, offset);
|
||||
|
||||
return (SDIOH_API_SUCCESS(status) ? 0 : BCME_ERROR);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
bcmsdhsdio_set_sbaddr_window(void *sdh, uint32 address, bool force_set)
|
||||
{
|
||||
int err = 0;
|
||||
uint bar0 = address & ~SBSDIO_SB_OFT_ADDR_MASK;
|
||||
bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh;
|
||||
|
||||
if (bar0 != bcmsdh->sbwad || force_set) {
|
||||
bcmsdh_cfg_write(bcmsdh, SDIO_FUNC_1, SBSDIO_FUNC1_SBADDRLOW,
|
||||
(address >> 8) & SBSDIO_SBADDRLOW_MASK, &err);
|
||||
if (!err)
|
||||
bcmsdh_cfg_write(bcmsdh, SDIO_FUNC_1, SBSDIO_FUNC1_SBADDRMID,
|
||||
(address >> 16) & SBSDIO_SBADDRMID_MASK, &err);
|
||||
if (!err)
|
||||
bcmsdh_cfg_write(bcmsdh, SDIO_FUNC_1, SBSDIO_FUNC1_SBADDRHIGH,
|
||||
(address >> 24) & SBSDIO_SBADDRHIGH_MASK, &err);
|
||||
|
||||
if (!err)
|
||||
bcmsdh->sbwad = bar0;
|
||||
else
|
||||
/* invalidate cached window var */
|
||||
bcmsdh->sbwad = 0;
|
||||
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
uint32
|
||||
bcmsdh_reg_read(void *sdh, uintptr addr, uint size)
|
||||
{
|
||||
bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh;
|
||||
SDIOH_API_RC status;
|
||||
uint32 word = 0;
|
||||
|
||||
BCMSDH_INFO(("%s:fun = 1, addr = 0x%x\n", __FUNCTION__, (unsigned int)addr));
|
||||
|
||||
if (!bcmsdh)
|
||||
bcmsdh = l_bcmsdh;
|
||||
|
||||
ASSERT(bcmsdh->init_success);
|
||||
|
||||
if (bcmsdhsdio_set_sbaddr_window(bcmsdh, addr, bcmsdh->force_sbwad_calc)) {
|
||||
bcmsdh->regfail = TRUE; // terence 20130621: prevent dhd_dpc in dead lock
|
||||
return 0xFFFFFFFF;
|
||||
}
|
||||
|
||||
addr &= SBSDIO_SB_OFT_ADDR_MASK;
|
||||
if (size == 4)
|
||||
addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
|
||||
|
||||
status = sdioh_request_word(bcmsdh->sdioh, SDIOH_CMD_TYPE_NORMAL,
|
||||
SDIOH_READ, SDIO_FUNC_1, addr, &word, size);
|
||||
|
||||
bcmsdh->regfail = !(SDIOH_API_SUCCESS(status));
|
||||
|
||||
BCMSDH_INFO(("uint32data = 0x%x\n", word));
|
||||
|
||||
/* if ok, return appropriately masked word */
|
||||
if (SDIOH_API_SUCCESS(status)) {
|
||||
switch (size) {
|
||||
case sizeof(uint8):
|
||||
return (word & 0xff);
|
||||
case sizeof(uint16):
|
||||
return (word & 0xffff);
|
||||
case sizeof(uint32):
|
||||
return word;
|
||||
default:
|
||||
bcmsdh->regfail = TRUE;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/* otherwise, bad sdio access or invalid size */
|
||||
BCMSDH_ERROR(("%s: error reading addr 0x%x size %d\n",
|
||||
__FUNCTION__, (unsigned int)addr, size));
|
||||
return 0xFFFFFFFF;
|
||||
}
|
||||
|
||||
uint32
|
||||
bcmsdh_reg_write(void *sdh, uintptr addr, uint size, uint32 data)
|
||||
{
|
||||
bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh;
|
||||
SDIOH_API_RC status;
|
||||
int err = 0;
|
||||
|
||||
BCMSDH_INFO(("%s:fun = 1, addr = 0x%x, uint%ddata = 0x%x\n",
|
||||
__FUNCTION__, (unsigned int)addr, size*8, data));
|
||||
|
||||
if (!bcmsdh)
|
||||
bcmsdh = l_bcmsdh;
|
||||
|
||||
ASSERT(bcmsdh->init_success);
|
||||
|
||||
if ((err = bcmsdhsdio_set_sbaddr_window(bcmsdh, addr, bcmsdh->force_sbwad_calc))) {
|
||||
bcmsdh->regfail = TRUE; // terence 20130621:
|
||||
return err;
|
||||
}
|
||||
|
||||
addr &= SBSDIO_SB_OFT_ADDR_MASK;
|
||||
if (size == 4)
|
||||
addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
|
||||
status = sdioh_request_word(bcmsdh->sdioh, SDIOH_CMD_TYPE_NORMAL, SDIOH_WRITE, SDIO_FUNC_1,
|
||||
addr, &data, size);
|
||||
bcmsdh->regfail = !(SDIOH_API_SUCCESS(status));
|
||||
|
||||
if (SDIOH_API_SUCCESS(status))
|
||||
return 0;
|
||||
|
||||
BCMSDH_ERROR(("%s: error writing 0x%08x to addr 0x%04x size %d\n",
|
||||
__FUNCTION__, data, (unsigned int)addr, size));
|
||||
return 0xFFFFFFFF;
|
||||
}
|
||||
|
||||
bool
|
||||
bcmsdh_regfail(void *sdh)
|
||||
{
|
||||
return ((bcmsdh_info_t *)sdh)->regfail;
|
||||
}
|
||||
|
||||
int
|
||||
bcmsdh_recv_buf(void *sdh, uint32 addr, uint fn, uint flags,
|
||||
uint8 *buf, uint nbytes, void *pkt,
|
||||
bcmsdh_cmplt_fn_t complete_fn, void *handle)
|
||||
{
|
||||
bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh;
|
||||
SDIOH_API_RC status;
|
||||
uint incr_fix;
|
||||
uint width;
|
||||
int err = 0;
|
||||
|
||||
ASSERT(bcmsdh);
|
||||
ASSERT(bcmsdh->init_success);
|
||||
|
||||
BCMSDH_INFO(("%s:fun = %d, addr = 0x%x, size = %d\n",
|
||||
__FUNCTION__, fn, addr, nbytes));
|
||||
|
||||
/* Async not implemented yet */
|
||||
ASSERT(!(flags & SDIO_REQ_ASYNC));
|
||||
if (flags & SDIO_REQ_ASYNC)
|
||||
return BCME_UNSUPPORTED;
|
||||
|
||||
if ((err = bcmsdhsdio_set_sbaddr_window(bcmsdh, addr, FALSE)))
|
||||
return err;
|
||||
|
||||
addr &= SBSDIO_SB_OFT_ADDR_MASK;
|
||||
|
||||
incr_fix = (flags & SDIO_REQ_FIXED) ? SDIOH_DATA_FIX : SDIOH_DATA_INC;
|
||||
width = (flags & SDIO_REQ_4BYTE) ? 4 : 2;
|
||||
if (width == 4)
|
||||
addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
|
||||
|
||||
status = sdioh_request_buffer(bcmsdh->sdioh, SDIOH_DATA_PIO, incr_fix,
|
||||
SDIOH_READ, fn, addr, width, nbytes, buf, pkt);
|
||||
|
||||
return (SDIOH_API_SUCCESS(status) ? 0 : BCME_SDIO_ERROR);
|
||||
}
|
||||
|
||||
int
|
||||
bcmsdh_send_buf(void *sdh, uint32 addr, uint fn, uint flags,
|
||||
uint8 *buf, uint nbytes, void *pkt,
|
||||
bcmsdh_cmplt_fn_t complete_fn, void *handle)
|
||||
{
|
||||
bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh;
|
||||
SDIOH_API_RC status;
|
||||
uint incr_fix;
|
||||
uint width;
|
||||
int err = 0;
|
||||
|
||||
ASSERT(bcmsdh);
|
||||
ASSERT(bcmsdh->init_success);
|
||||
|
||||
BCMSDH_INFO(("%s:fun = %d, addr = 0x%x, size = %d\n",
|
||||
__FUNCTION__, fn, addr, nbytes));
|
||||
|
||||
/* Async not implemented yet */
|
||||
ASSERT(!(flags & SDIO_REQ_ASYNC));
|
||||
if (flags & SDIO_REQ_ASYNC)
|
||||
return BCME_UNSUPPORTED;
|
||||
|
||||
if ((err = bcmsdhsdio_set_sbaddr_window(bcmsdh, addr, FALSE)))
|
||||
return err;
|
||||
|
||||
addr &= SBSDIO_SB_OFT_ADDR_MASK;
|
||||
|
||||
incr_fix = (flags & SDIO_REQ_FIXED) ? SDIOH_DATA_FIX : SDIOH_DATA_INC;
|
||||
width = (flags & SDIO_REQ_4BYTE) ? 4 : 2;
|
||||
if (width == 4)
|
||||
addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
|
||||
|
||||
status = sdioh_request_buffer(bcmsdh->sdioh, SDIOH_DATA_PIO, incr_fix,
|
||||
SDIOH_WRITE, fn, addr, width, nbytes, buf, pkt);
|
||||
|
||||
return (SDIOH_API_SUCCESS(status) ? 0 : BCME_ERROR);
|
||||
}
|
||||
|
||||
int
|
||||
bcmsdh_rwdata(void *sdh, uint rw, uint32 addr, uint8 *buf, uint nbytes)
|
||||
{
|
||||
bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh;
|
||||
SDIOH_API_RC status;
|
||||
|
||||
ASSERT(bcmsdh);
|
||||
ASSERT(bcmsdh->init_success);
|
||||
ASSERT((addr & SBSDIO_SBWINDOW_MASK) == 0);
|
||||
|
||||
addr &= SBSDIO_SB_OFT_ADDR_MASK;
|
||||
addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
|
||||
|
||||
status = sdioh_request_buffer(bcmsdh->sdioh, SDIOH_DATA_PIO, SDIOH_DATA_INC,
|
||||
(rw ? SDIOH_WRITE : SDIOH_READ), SDIO_FUNC_1,
|
||||
addr, 4, nbytes, buf, NULL);
|
||||
|
||||
return (SDIOH_API_SUCCESS(status) ? 0 : BCME_ERROR);
|
||||
}
|
||||
|
||||
int
|
||||
bcmsdh_abort(void *sdh, uint fn)
|
||||
{
|
||||
bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh;
|
||||
|
||||
return sdioh_abort(bcmsdh->sdioh, fn);
|
||||
}
|
||||
|
||||
int
|
||||
bcmsdh_start(void *sdh, int stage)
|
||||
{
|
||||
bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh;
|
||||
|
||||
return sdioh_start(bcmsdh->sdioh, stage);
|
||||
}
|
||||
|
||||
int
|
||||
bcmsdh_stop(void *sdh)
|
||||
{
|
||||
bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh;
|
||||
|
||||
return sdioh_stop(bcmsdh->sdioh);
|
||||
}
|
||||
|
||||
int
|
||||
bcmsdh_waitlockfree(void *sdh)
|
||||
{
|
||||
bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh;
|
||||
|
||||
return sdioh_waitlockfree(bcmsdh->sdioh);
|
||||
}
|
||||
|
||||
int
|
||||
bcmsdh_query_device(void *sdh)
|
||||
{
|
||||
bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh;
|
||||
bcmsdh->vendevid = (VENDOR_BROADCOM << 16) | 0;
|
||||
return (bcmsdh->vendevid);
|
||||
}
|
||||
|
||||
uint
|
||||
bcmsdh_query_iofnum(void *sdh)
|
||||
{
|
||||
bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh;
|
||||
|
||||
if (!bcmsdh)
|
||||
bcmsdh = l_bcmsdh;
|
||||
|
||||
return (sdioh_query_iofnum(bcmsdh->sdioh));
|
||||
}
|
||||
|
||||
int
|
||||
bcmsdh_reset(bcmsdh_info_t *sdh)
|
||||
{
|
||||
bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh;
|
||||
|
||||
return sdioh_sdio_reset(bcmsdh->sdioh);
|
||||
}
|
||||
|
||||
void *bcmsdh_get_sdioh(bcmsdh_info_t *sdh)
|
||||
{
|
||||
ASSERT(sdh);
|
||||
return sdh->sdioh;
|
||||
}
|
||||
|
||||
/* Function to pass device-status bits to DHD. */
|
||||
uint32
|
||||
bcmsdh_get_dstatus(void *sdh)
|
||||
{
|
||||
#ifdef BCMSPI
|
||||
bcmsdh_info_t *p = (bcmsdh_info_t *)sdh;
|
||||
sdioh_info_t *sd = (sdioh_info_t *)(p->sdioh);
|
||||
return sdioh_get_dstatus(sd);
|
||||
#else
|
||||
return 0;
|
||||
#endif /* BCMSPI */
|
||||
}
|
||||
uint32
|
||||
bcmsdh_cur_sbwad(void *sdh)
|
||||
{
|
||||
bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh;
|
||||
|
||||
if (!bcmsdh)
|
||||
bcmsdh = l_bcmsdh;
|
||||
|
||||
return (bcmsdh->sbwad);
|
||||
}
|
||||
|
||||
/* example usage: if force is TRUE, forces the bcmsdhsdio_set_sbaddr_window to
|
||||
* calculate sbwad always instead of caching.
|
||||
*/
|
||||
void
|
||||
bcmsdh_force_sbwad_calc(void *sdh, bool force)
|
||||
{
|
||||
bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh;
|
||||
|
||||
if (!bcmsdh)
|
||||
bcmsdh = l_bcmsdh;
|
||||
bcmsdh->force_sbwad_calc = force;
|
||||
}
|
||||
|
||||
void
|
||||
bcmsdh_chipinfo(void *sdh, uint32 chip, uint32 chiprev)
|
||||
{
|
||||
#ifdef BCMSPI
|
||||
bcmsdh_info_t *p = (bcmsdh_info_t *)sdh;
|
||||
sdioh_info_t *sd = (sdioh_info_t *)(p->sdioh);
|
||||
sdioh_chipinfo(sd, chip, chiprev);
|
||||
#else
|
||||
return;
|
||||
#endif /* BCMSPI */
|
||||
}
|
||||
|
||||
#ifdef BCMSPI
|
||||
void
|
||||
bcmsdh_dwordmode(void *sdh, bool set)
|
||||
{
|
||||
bcmsdh_info_t *p = (bcmsdh_info_t *)sdh;
|
||||
sdioh_info_t *sd = (sdioh_info_t *)(p->sdioh);
|
||||
sdioh_dwordmode(sd, set);
|
||||
return;
|
||||
}
|
||||
#endif /* BCMSPI */
|
||||
|
||||
int
|
||||
bcmsdh_sleep(void *sdh, bool enab)
|
||||
{
|
||||
#ifdef SDIOH_SLEEP_ENABLED
|
||||
bcmsdh_info_t *p = (bcmsdh_info_t *)sdh;
|
||||
sdioh_info_t *sd = (sdioh_info_t *)(p->sdioh);
|
||||
|
||||
return sdioh_sleep(sd, enab);
|
||||
#else
|
||||
return BCME_UNSUPPORTED;
|
||||
#endif // endif
|
||||
}
|
||||
|
||||
int
|
||||
bcmsdh_gpio_init(void *sdh)
|
||||
{
|
||||
bcmsdh_info_t *p = (bcmsdh_info_t *)sdh;
|
||||
sdioh_info_t *sd = (sdioh_info_t *)(p->sdioh);
|
||||
|
||||
return sdioh_gpio_init(sd);
|
||||
}
|
||||
|
||||
bool
|
||||
bcmsdh_gpioin(void *sdh, uint32 gpio)
|
||||
{
|
||||
bcmsdh_info_t *p = (bcmsdh_info_t *)sdh;
|
||||
sdioh_info_t *sd = (sdioh_info_t *)(p->sdioh);
|
||||
|
||||
return sdioh_gpioin(sd, gpio);
|
||||
}
|
||||
|
||||
int
|
||||
bcmsdh_gpioouten(void *sdh, uint32 gpio)
|
||||
{
|
||||
bcmsdh_info_t *p = (bcmsdh_info_t *)sdh;
|
||||
sdioh_info_t *sd = (sdioh_info_t *)(p->sdioh);
|
||||
|
||||
return sdioh_gpioouten(sd, gpio);
|
||||
}
|
||||
|
||||
int
|
||||
bcmsdh_gpioout(void *sdh, uint32 gpio, bool enab)
|
||||
{
|
||||
bcmsdh_info_t *p = (bcmsdh_info_t *)sdh;
|
||||
sdioh_info_t *sd = (sdioh_info_t *)(p->sdioh);
|
||||
|
||||
return sdioh_gpioout(sd, gpio, enab);
|
||||
}
|
||||
|
||||
uint
|
||||
bcmsdh_set_mode(void *sdh, uint mode)
|
||||
{
|
||||
bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh;
|
||||
return (sdioh_set_mode(bcmsdh->sdioh, mode));
|
||||
}
|
||||
@@ -0,0 +1,524 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* SDIO access interface for drivers - linux specific (pci only)
|
||||
*
|
||||
* Copyright (C) 1999-2019, 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.
|
||||
*
|
||||
* 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: bcmsdh_linux.c 689948 2017-03-14 05:21:03Z $
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file bcmsdh_linux.c
|
||||
*/
|
||||
|
||||
#define __UNDEF_NO_VERSION__
|
||||
|
||||
#include <typedefs.h>
|
||||
#include <linuxver.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/completion.h>
|
||||
|
||||
#include <osl.h>
|
||||
#include <pcicfg.h>
|
||||
#include <bcmdefs.h>
|
||||
#include <bcmdevs.h>
|
||||
#include <linux/irq.h>
|
||||
extern void dhdsdio_isr(void * args);
|
||||
#include <bcmutils.h>
|
||||
#include <dngl_stats.h>
|
||||
#include <dhd.h>
|
||||
#include <dhd_linux.h>
|
||||
|
||||
/* driver info, initialized when bcmsdh_register is called */
|
||||
static bcmsdh_driver_t drvinfo = {NULL, NULL, NULL, NULL};
|
||||
|
||||
typedef enum {
|
||||
DHD_INTR_INVALID = 0,
|
||||
DHD_INTR_INBAND,
|
||||
DHD_INTR_HWOOB,
|
||||
DHD_INTR_SWOOB
|
||||
} DHD_HOST_INTR_TYPE;
|
||||
|
||||
/* the BCMSDH module comprises the generic part (bcmsdh.c) and OS specific layer (e.g.
|
||||
* bcmsdh_linux.c). Put all OS specific variables (e.g. irq number and flags) here rather
|
||||
* than in the common structure bcmsdh_info. bcmsdh_info only keeps a handle (os_ctx) to this
|
||||
* structure.
|
||||
*/
|
||||
typedef struct bcmsdh_os_info {
|
||||
DHD_HOST_INTR_TYPE intr_type;
|
||||
int oob_irq_num; /* valid when hardware or software oob in use */
|
||||
unsigned long oob_irq_flags; /* valid when hardware or software oob in use */
|
||||
bool oob_irq_registered;
|
||||
bool oob_irq_enabled;
|
||||
bool oob_irq_wake_enabled;
|
||||
spinlock_t oob_irq_spinlock;
|
||||
bcmsdh_cb_fn_t oob_irq_handler;
|
||||
void *oob_irq_handler_context;
|
||||
void *context; /* context returned from upper layer */
|
||||
void *sdioh; /* handle to lower layer (sdioh) */
|
||||
void *dev; /* handle to the underlying device */
|
||||
bool dev_wake_enabled;
|
||||
} bcmsdh_os_info_t;
|
||||
|
||||
/* debugging macros */
|
||||
#define SDLX_ERR(x) printf x
|
||||
#define SDLX_MSG(x) printf x
|
||||
|
||||
/**
|
||||
* Checks to see if vendor and device IDs match a supported SDIO Host Controller.
|
||||
*/
|
||||
bool
|
||||
bcmsdh_chipmatch(uint16 vendor, uint16 device)
|
||||
{
|
||||
/* Add other vendors and devices as required */
|
||||
|
||||
#ifdef BCMSDIOH_STD
|
||||
/* Check for Arasan host controller */
|
||||
if (vendor == VENDOR_SI_IMAGE) {
|
||||
return (TRUE);
|
||||
}
|
||||
/* Check for BRCM 27XX Standard host controller */
|
||||
if (device == BCM27XX_SDIOH_ID && vendor == VENDOR_BROADCOM) {
|
||||
return (TRUE);
|
||||
}
|
||||
/* Check for BRCM Standard host controller */
|
||||
if (device == SDIOH_FPGA_ID && vendor == VENDOR_BROADCOM) {
|
||||
return (TRUE);
|
||||
}
|
||||
/* Check for TI PCIxx21 Standard host controller */
|
||||
if (device == PCIXX21_SDIOH_ID && vendor == VENDOR_TI) {
|
||||
return (TRUE);
|
||||
}
|
||||
if (device == PCIXX21_SDIOH0_ID && vendor == VENDOR_TI) {
|
||||
return (TRUE);
|
||||
}
|
||||
/* Ricoh R5C822 Standard SDIO Host */
|
||||
if (device == R5C822_SDIOH_ID && vendor == VENDOR_RICOH) {
|
||||
return (TRUE);
|
||||
}
|
||||
/* JMicron Standard SDIO Host */
|
||||
if (device == JMICRON_SDIOH_ID && vendor == VENDOR_JMICRON) {
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
#endif /* BCMSDIOH_STD */
|
||||
#ifdef BCMSDIOH_SPI
|
||||
/* This is the PciSpiHost. */
|
||||
if (device == SPIH_FPGA_ID && vendor == VENDOR_BROADCOM) {
|
||||
printf("Found PCI SPI Host Controller\n");
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
#endif /* BCMSDIOH_SPI */
|
||||
|
||||
return (FALSE);
|
||||
}
|
||||
|
||||
void* bcmsdh_probe(osl_t *osh, void *dev, void *sdioh, void *adapter_info, uint bus_type,
|
||||
uint bus_num, uint slot_num)
|
||||
{
|
||||
ulong regs;
|
||||
bcmsdh_info_t *bcmsdh;
|
||||
uint32 vendevid;
|
||||
bcmsdh_os_info_t *bcmsdh_osinfo = NULL;
|
||||
|
||||
bcmsdh = bcmsdh_attach(osh, sdioh, ®s);
|
||||
if (bcmsdh == NULL) {
|
||||
SDLX_ERR(("%s: bcmsdh_attach failed\n", __FUNCTION__));
|
||||
goto err;
|
||||
}
|
||||
bcmsdh_osinfo = MALLOC(osh, sizeof(bcmsdh_os_info_t));
|
||||
if (bcmsdh_osinfo == NULL) {
|
||||
SDLX_ERR(("%s: failed to allocate bcmsdh_os_info_t\n", __FUNCTION__));
|
||||
goto err;
|
||||
}
|
||||
bzero((char *)bcmsdh_osinfo, sizeof(bcmsdh_os_info_t));
|
||||
bcmsdh->os_cxt = bcmsdh_osinfo;
|
||||
bcmsdh_osinfo->sdioh = sdioh;
|
||||
bcmsdh_osinfo->dev = dev;
|
||||
osl_set_bus_handle(osh, bcmsdh);
|
||||
|
||||
#if !defined(CONFIG_HAS_WAKELOCK) && (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 36))
|
||||
if (dev && device_init_wakeup(dev, true) == 0)
|
||||
bcmsdh_osinfo->dev_wake_enabled = TRUE;
|
||||
#endif /* !defined(CONFIG_HAS_WAKELOCK) && (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 36)) */
|
||||
|
||||
#if defined(OOB_INTR_ONLY)
|
||||
spin_lock_init(&bcmsdh_osinfo->oob_irq_spinlock);
|
||||
/* Get customer specific OOB IRQ parametres: IRQ number as IRQ type */
|
||||
bcmsdh_osinfo->oob_irq_num = wifi_platform_get_irq_number(adapter_info,
|
||||
&bcmsdh_osinfo->oob_irq_flags);
|
||||
if (bcmsdh_osinfo->oob_irq_num < 0) {
|
||||
SDLX_ERR(("%s: Host OOB irq is not defined\n", __FUNCTION__));
|
||||
goto err;
|
||||
}
|
||||
#endif /* defined(BCMLXSDMMC) */
|
||||
|
||||
/* Read the vendor/device ID from the CIS */
|
||||
vendevid = bcmsdh_query_device(bcmsdh);
|
||||
/* try to attach to the target device */
|
||||
bcmsdh_osinfo->context = drvinfo.probe((vendevid >> 16), (vendevid & 0xFFFF), bus_num,
|
||||
slot_num, 0, bus_type, (void *)regs, osh, bcmsdh);
|
||||
if (bcmsdh_osinfo->context == NULL) {
|
||||
SDLX_ERR(("%s: device attach failed\n", __FUNCTION__));
|
||||
goto err;
|
||||
}
|
||||
|
||||
return bcmsdh;
|
||||
|
||||
/* error handling */
|
||||
err:
|
||||
if (bcmsdh != NULL)
|
||||
bcmsdh_detach(osh, bcmsdh);
|
||||
if (bcmsdh_osinfo != NULL)
|
||||
MFREE(osh, bcmsdh_osinfo, sizeof(bcmsdh_os_info_t));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int bcmsdh_remove(bcmsdh_info_t *bcmsdh)
|
||||
{
|
||||
bcmsdh_os_info_t *bcmsdh_osinfo = bcmsdh->os_cxt;
|
||||
|
||||
#if !defined(CONFIG_HAS_WAKELOCK) && (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 36))
|
||||
if (bcmsdh_osinfo->dev)
|
||||
device_init_wakeup(bcmsdh_osinfo->dev, false);
|
||||
bcmsdh_osinfo->dev_wake_enabled = FALSE;
|
||||
#endif /* !defined(CONFIG_HAS_WAKELOCK) && (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 36)) */
|
||||
|
||||
drvinfo.remove(bcmsdh_osinfo->context);
|
||||
MFREE(bcmsdh->osh, bcmsdh->os_cxt, sizeof(bcmsdh_os_info_t));
|
||||
bcmsdh_detach(bcmsdh->osh, bcmsdh);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef DHD_WAKE_STATUS
|
||||
int bcmsdh_get_total_wake(bcmsdh_info_t *bcmsdh)
|
||||
{
|
||||
return bcmsdh->total_wake_count;
|
||||
}
|
||||
|
||||
int bcmsdh_set_get_wake(bcmsdh_info_t *bcmsdh, int flag)
|
||||
{
|
||||
#if defined(OOB_INTR_ONLY)
|
||||
bcmsdh_os_info_t *bcmsdh_osinfo = bcmsdh->os_cxt;
|
||||
unsigned long flags;
|
||||
#endif
|
||||
int ret = 0;
|
||||
|
||||
#if defined(OOB_INTR_ONLY)
|
||||
spin_lock_irqsave(&bcmsdh_osinfo->oob_irq_spinlock, flags);
|
||||
|
||||
ret = bcmsdh->pkt_wake;
|
||||
bcmsdh->total_wake_count += flag;
|
||||
bcmsdh->pkt_wake = flag;
|
||||
|
||||
spin_unlock_irqrestore(&bcmsdh_osinfo->oob_irq_spinlock, flags);
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
#endif /* DHD_WAKE_STATUS */
|
||||
|
||||
int bcmsdh_suspend(bcmsdh_info_t *bcmsdh)
|
||||
{
|
||||
bcmsdh_os_info_t *bcmsdh_osinfo = bcmsdh->os_cxt;
|
||||
|
||||
if (drvinfo.suspend && drvinfo.suspend(bcmsdh_osinfo->context))
|
||||
return -EBUSY;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int bcmsdh_resume(bcmsdh_info_t *bcmsdh)
|
||||
{
|
||||
bcmsdh_os_info_t *bcmsdh_osinfo = bcmsdh->os_cxt;
|
||||
|
||||
if (drvinfo.resume)
|
||||
return drvinfo.resume(bcmsdh_osinfo->context);
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern int bcmsdh_register_client_driver(void);
|
||||
extern void bcmsdh_unregister_client_driver(void);
|
||||
extern int sdio_func_reg_notify(void* semaphore);
|
||||
extern void sdio_func_unreg_notify(void);
|
||||
|
||||
#if defined(BCMLXSDMMC)
|
||||
int bcmsdh_reg_sdio_notify(void* semaphore)
|
||||
{
|
||||
return sdio_func_reg_notify(semaphore);
|
||||
}
|
||||
|
||||
void bcmsdh_unreg_sdio_notify(void)
|
||||
{
|
||||
sdio_func_unreg_notify();
|
||||
}
|
||||
#endif /* defined(BCMLXSDMMC) */
|
||||
|
||||
int
|
||||
bcmsdh_register(bcmsdh_driver_t *driver)
|
||||
{
|
||||
int error = 0;
|
||||
|
||||
drvinfo = *driver;
|
||||
SDLX_MSG(("%s: register client driver\n", __FUNCTION__));
|
||||
error = bcmsdh_register_client_driver();
|
||||
if (error)
|
||||
SDLX_ERR(("%s: failed %d\n", __FUNCTION__, error));
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
void
|
||||
bcmsdh_unregister(void)
|
||||
{
|
||||
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0))
|
||||
if (bcmsdh_pci_driver.node.next == NULL)
|
||||
return;
|
||||
#endif // endif
|
||||
|
||||
bcmsdh_unregister_client_driver();
|
||||
}
|
||||
|
||||
void bcmsdh_dev_pm_stay_awake(bcmsdh_info_t *bcmsdh)
|
||||
{
|
||||
#if !defined(CONFIG_HAS_WAKELOCK) && (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 36))
|
||||
bcmsdh_os_info_t *bcmsdh_osinfo = bcmsdh->os_cxt;
|
||||
pm_stay_awake(bcmsdh_osinfo->dev);
|
||||
#endif /* !defined(CONFIG_HAS_WAKELOCK) && (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 36)) */
|
||||
}
|
||||
|
||||
void bcmsdh_dev_relax(bcmsdh_info_t *bcmsdh)
|
||||
{
|
||||
#if !defined(CONFIG_HAS_WAKELOCK) && (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 36))
|
||||
bcmsdh_os_info_t *bcmsdh_osinfo = bcmsdh->os_cxt;
|
||||
pm_relax(bcmsdh_osinfo->dev);
|
||||
#endif /* !defined(CONFIG_HAS_WAKELOCK) && (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 36)) */
|
||||
}
|
||||
|
||||
bool bcmsdh_dev_pm_enabled(bcmsdh_info_t *bcmsdh)
|
||||
{
|
||||
bcmsdh_os_info_t *bcmsdh_osinfo = bcmsdh->os_cxt;
|
||||
|
||||
return bcmsdh_osinfo->dev_wake_enabled;
|
||||
}
|
||||
|
||||
#if defined(OOB_INTR_ONLY) || defined(BCMSPI_ANDROID)
|
||||
void bcmsdh_oob_intr_set(bcmsdh_info_t *bcmsdh, bool enable)
|
||||
{
|
||||
unsigned long flags;
|
||||
bcmsdh_os_info_t *bcmsdh_osinfo;
|
||||
|
||||
if (!bcmsdh)
|
||||
return;
|
||||
|
||||
bcmsdh_osinfo = bcmsdh->os_cxt;
|
||||
spin_lock_irqsave(&bcmsdh_osinfo->oob_irq_spinlock, flags);
|
||||
if (bcmsdh_osinfo->oob_irq_enabled != enable) {
|
||||
if (enable)
|
||||
enable_irq(bcmsdh_osinfo->oob_irq_num);
|
||||
else
|
||||
disable_irq_nosync(bcmsdh_osinfo->oob_irq_num);
|
||||
bcmsdh_osinfo->oob_irq_enabled = enable;
|
||||
}
|
||||
spin_unlock_irqrestore(&bcmsdh_osinfo->oob_irq_spinlock, flags);
|
||||
}
|
||||
|
||||
static irqreturn_t wlan_oob_irq(int irq, void *dev_id)
|
||||
{
|
||||
bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)dev_id;
|
||||
bcmsdh_os_info_t *bcmsdh_osinfo = bcmsdh->os_cxt;
|
||||
|
||||
#ifndef BCMSPI_ANDROID
|
||||
bcmsdh_oob_intr_set(bcmsdh, FALSE);
|
||||
#endif /* !BCMSPI_ANDROID */
|
||||
bcmsdh_osinfo->oob_irq_handler(bcmsdh_osinfo->oob_irq_handler_context);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
int bcmsdh_oob_intr_register(bcmsdh_info_t *bcmsdh, bcmsdh_cb_fn_t oob_irq_handler,
|
||||
void* oob_irq_handler_context)
|
||||
{
|
||||
int err = 0;
|
||||
bcmsdh_os_info_t *bcmsdh_osinfo = bcmsdh->os_cxt;
|
||||
|
||||
if (bcmsdh_osinfo->oob_irq_registered) {
|
||||
SDLX_ERR(("%s: irq is already registered\n", __FUNCTION__));
|
||||
return -EBUSY;
|
||||
}
|
||||
#ifdef HW_OOB
|
||||
SDLX_MSG(("%s: HW_OOB irq=%d flags=0x%X\n", __FUNCTION__,
|
||||
(int)bcmsdh_osinfo->oob_irq_num, (int)bcmsdh_osinfo->oob_irq_flags));
|
||||
#else
|
||||
SDLX_MSG(("%s: SW_OOB irq=%d flags=0x%X\n", __FUNCTION__,
|
||||
(int)bcmsdh_osinfo->oob_irq_num, (int)bcmsdh_osinfo->oob_irq_flags));
|
||||
#endif
|
||||
bcmsdh_osinfo->oob_irq_handler = oob_irq_handler;
|
||||
bcmsdh_osinfo->oob_irq_handler_context = oob_irq_handler_context;
|
||||
bcmsdh_osinfo->oob_irq_enabled = TRUE;
|
||||
bcmsdh_osinfo->oob_irq_registered = TRUE;
|
||||
err = request_irq(bcmsdh_osinfo->oob_irq_num, wlan_oob_irq,
|
||||
bcmsdh_osinfo->oob_irq_flags, "bcmsdh_sdmmc", bcmsdh);
|
||||
if (err) {
|
||||
SDLX_ERR(("%s: request_irq failed with %d\n", __FUNCTION__, err));
|
||||
bcmsdh_osinfo->oob_irq_enabled = FALSE;
|
||||
bcmsdh_osinfo->oob_irq_registered = FALSE;
|
||||
return err;
|
||||
}
|
||||
|
||||
#if defined(DISABLE_WOWLAN)
|
||||
SDLX_MSG(("%s: disable_irq_wake\n", __FUNCTION__));
|
||||
bcmsdh_osinfo->oob_irq_wake_enabled = FALSE;
|
||||
#else
|
||||
#if defined(CONFIG_ARCH_RHEA) || defined(CONFIG_ARCH_CAPRI)
|
||||
if (device_may_wakeup(bcmsdh_osinfo->dev)) {
|
||||
#endif /* CONFIG_ARCH_RHEA || CONFIG_ARCH_CAPRI */
|
||||
err = enable_irq_wake(bcmsdh_osinfo->oob_irq_num);
|
||||
if (err)
|
||||
SDLX_ERR(("%s: enable_irq_wake failed with %d\n", __FUNCTION__, err));
|
||||
else
|
||||
bcmsdh_osinfo->oob_irq_wake_enabled = TRUE;
|
||||
#if defined(CONFIG_ARCH_RHEA) || defined(CONFIG_ARCH_CAPRI)
|
||||
}
|
||||
#endif /* CONFIG_ARCH_RHEA || CONFIG_ARCH_CAPRI */
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void bcmsdh_oob_intr_unregister(bcmsdh_info_t *bcmsdh)
|
||||
{
|
||||
int err = 0;
|
||||
bcmsdh_os_info_t *bcmsdh_osinfo = bcmsdh->os_cxt;
|
||||
|
||||
SDLX_MSG(("%s: Enter\n", __FUNCTION__));
|
||||
if (!bcmsdh_osinfo->oob_irq_registered) {
|
||||
SDLX_MSG(("%s: irq is not registered\n", __FUNCTION__));
|
||||
return;
|
||||
}
|
||||
if (bcmsdh_osinfo->oob_irq_wake_enabled) {
|
||||
#if defined(CONFIG_ARCH_RHEA) || defined(CONFIG_ARCH_CAPRI)
|
||||
if (device_may_wakeup(bcmsdh_osinfo->dev)) {
|
||||
#endif /* CONFIG_ARCH_RHEA || CONFIG_ARCH_CAPRI */
|
||||
err = disable_irq_wake(bcmsdh_osinfo->oob_irq_num);
|
||||
if (!err)
|
||||
bcmsdh_osinfo->oob_irq_wake_enabled = FALSE;
|
||||
#if defined(CONFIG_ARCH_RHEA) || defined(CONFIG_ARCH_CAPRI)
|
||||
}
|
||||
#endif /* CONFIG_ARCH_RHEA || CONFIG_ARCH_CAPRI */
|
||||
}
|
||||
if (bcmsdh_osinfo->oob_irq_enabled) {
|
||||
disable_irq(bcmsdh_osinfo->oob_irq_num);
|
||||
bcmsdh_osinfo->oob_irq_enabled = FALSE;
|
||||
}
|
||||
free_irq(bcmsdh_osinfo->oob_irq_num, bcmsdh);
|
||||
bcmsdh_osinfo->oob_irq_registered = FALSE;
|
||||
}
|
||||
#endif /* defined(OOB_INTR_ONLY) || defined(BCMSPI_ANDROID) */
|
||||
|
||||
/* Module parameters specific to each host-controller driver */
|
||||
|
||||
extern uint sd_msglevel; /* Debug message level */
|
||||
module_param(sd_msglevel, uint, 0);
|
||||
|
||||
extern uint sd_power; /* 0 = SD Power OFF, 1 = SD Power ON. */
|
||||
module_param(sd_power, uint, 0);
|
||||
|
||||
extern uint sd_clock; /* SD Clock Control, 0 = SD Clock OFF, 1 = SD Clock ON */
|
||||
module_param(sd_clock, uint, 0);
|
||||
|
||||
extern uint sd_divisor; /* Divisor (-1 means external clock) */
|
||||
module_param(sd_divisor, uint, 0);
|
||||
|
||||
extern uint sd_sdmode; /* Default is SD4, 0=SPI, 1=SD1, 2=SD4 */
|
||||
module_param(sd_sdmode, uint, 0);
|
||||
|
||||
extern uint sd_hiok; /* Ok to use hi-speed mode */
|
||||
module_param(sd_hiok, uint, 0);
|
||||
|
||||
extern uint sd_f2_blocksize;
|
||||
module_param(sd_f2_blocksize, int, 0);
|
||||
|
||||
extern uint sd_f1_blocksize;
|
||||
module_param(sd_f1_blocksize, int, 0);
|
||||
|
||||
#ifdef BCMSDIOH_STD
|
||||
extern int sd_uhsimode;
|
||||
module_param(sd_uhsimode, int, 0);
|
||||
extern uint sd_tuning_period;
|
||||
module_param(sd_tuning_period, uint, 0);
|
||||
extern int sd_delay_value;
|
||||
module_param(sd_delay_value, uint, 0);
|
||||
|
||||
/* SDIO Drive Strength for UHSI mode specific to SDIO3.0 */
|
||||
extern char dhd_sdiod_uhsi_ds_override[2];
|
||||
module_param_string(dhd_sdiod_uhsi_ds_override, dhd_sdiod_uhsi_ds_override, 2, 0);
|
||||
|
||||
#endif // endif
|
||||
|
||||
#ifdef BCMSDH_MODULE
|
||||
EXPORT_SYMBOL(bcmsdh_attach);
|
||||
EXPORT_SYMBOL(bcmsdh_detach);
|
||||
EXPORT_SYMBOL(bcmsdh_intr_query);
|
||||
EXPORT_SYMBOL(bcmsdh_intr_enable);
|
||||
EXPORT_SYMBOL(bcmsdh_intr_disable);
|
||||
EXPORT_SYMBOL(bcmsdh_intr_reg);
|
||||
EXPORT_SYMBOL(bcmsdh_intr_dereg);
|
||||
|
||||
#if defined(DHD_DEBUG)
|
||||
EXPORT_SYMBOL(bcmsdh_intr_pending);
|
||||
#endif // endif
|
||||
|
||||
#if defined(BT_OVER_SDIO)
|
||||
EXPORT_SYMBOL(bcmsdh_btsdio_interface_init);
|
||||
#endif /* defined (BT_OVER_SDIO) */
|
||||
|
||||
EXPORT_SYMBOL(bcmsdh_devremove_reg);
|
||||
EXPORT_SYMBOL(bcmsdh_cfg_read);
|
||||
EXPORT_SYMBOL(bcmsdh_cfg_write);
|
||||
EXPORT_SYMBOL(bcmsdh_cis_read);
|
||||
EXPORT_SYMBOL(bcmsdh_reg_read);
|
||||
EXPORT_SYMBOL(bcmsdh_reg_write);
|
||||
EXPORT_SYMBOL(bcmsdh_regfail);
|
||||
EXPORT_SYMBOL(bcmsdh_send_buf);
|
||||
EXPORT_SYMBOL(bcmsdh_recv_buf);
|
||||
|
||||
EXPORT_SYMBOL(bcmsdh_rwdata);
|
||||
EXPORT_SYMBOL(bcmsdh_abort);
|
||||
EXPORT_SYMBOL(bcmsdh_query_device);
|
||||
EXPORT_SYMBOL(bcmsdh_query_iofnum);
|
||||
EXPORT_SYMBOL(bcmsdh_iovar_op);
|
||||
EXPORT_SYMBOL(bcmsdh_register);
|
||||
EXPORT_SYMBOL(bcmsdh_unregister);
|
||||
EXPORT_SYMBOL(bcmsdh_chipmatch);
|
||||
EXPORT_SYMBOL(bcmsdh_reset);
|
||||
EXPORT_SYMBOL(bcmsdh_waitlockfree);
|
||||
|
||||
EXPORT_SYMBOL(bcmsdh_get_dstatus);
|
||||
EXPORT_SYMBOL(bcmsdh_cfg_read_word);
|
||||
EXPORT_SYMBOL(bcmsdh_cfg_write_word);
|
||||
EXPORT_SYMBOL(bcmsdh_cur_sbwad);
|
||||
EXPORT_SYMBOL(bcmsdh_chipinfo);
|
||||
|
||||
#endif /* BCMSDH_MODULE */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,383 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* BCMSDH Function Driver for the native SDIO/MMC driver in the Linux Kernel
|
||||
*
|
||||
* Copyright (C) 1999-2019, 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.
|
||||
*
|
||||
* 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/Proprietary,Open:>>
|
||||
*
|
||||
* $Id: bcmsdh_sdmmc_linux.c 825481 2019-06-14 10:06:03Z $
|
||||
*/
|
||||
|
||||
#include <typedefs.h>
|
||||
#include <bcmutils.h>
|
||||
#include <sdio.h> /* SDIO Device and Protocol Specs */
|
||||
#include <bcmsdbus.h> /* bcmsdh to/from specific controller APIs */
|
||||
#include <sdiovar.h> /* to get msglevel bit values */
|
||||
|
||||
#include <linux/sched.h> /* request_irq() */
|
||||
|
||||
#include <linux/mmc/core.h>
|
||||
#include <linux/mmc/card.h>
|
||||
#include <linux/mmc/host.h>
|
||||
#include <linux/mmc/sdio_func.h>
|
||||
#include <linux/mmc/sdio_ids.h>
|
||||
#include <dhd_linux.h>
|
||||
#include <bcmsdh_sdmmc.h>
|
||||
#include <dhd_dbg.h>
|
||||
#include <bcmdevs.h>
|
||||
|
||||
#if !defined(SDIO_VENDOR_ID_BROADCOM)
|
||||
#define SDIO_VENDOR_ID_BROADCOM 0x02d0
|
||||
#endif /* !defined(SDIO_VENDOR_ID_BROADCOM) */
|
||||
|
||||
#define SDIO_DEVICE_ID_BROADCOM_DEFAULT 0x0000
|
||||
|
||||
extern void wl_cfg80211_set_parent_dev(void *dev);
|
||||
extern void sdioh_sdmmc_devintr_off(sdioh_info_t *sd);
|
||||
extern void sdioh_sdmmc_devintr_on(sdioh_info_t *sd);
|
||||
extern void* bcmsdh_probe(osl_t *osh, void *dev, void *sdioh, void *adapter_info, uint bus_type,
|
||||
uint bus_num, uint slot_num);
|
||||
extern int bcmsdh_remove(bcmsdh_info_t *bcmsdh);
|
||||
|
||||
int sdio_function_init(void);
|
||||
void sdio_function_cleanup(void);
|
||||
|
||||
#define DESCRIPTION "bcmsdh_sdmmc Driver"
|
||||
#define AUTHOR "Broadcom Corporation"
|
||||
|
||||
/* module param defaults */
|
||||
static int clockoverride = 0;
|
||||
|
||||
module_param(clockoverride, int, 0644);
|
||||
MODULE_PARM_DESC(clockoverride, "SDIO card clock override");
|
||||
|
||||
#ifdef GLOBAL_SDMMC_INSTANCE
|
||||
PBCMSDH_SDMMC_INSTANCE gInstance;
|
||||
#endif
|
||||
|
||||
/* Maximum number of bcmsdh_sdmmc devices supported by driver */
|
||||
#define BCMSDH_SDMMC_MAX_DEVICES 1
|
||||
|
||||
extern volatile bool dhd_mmc_suspend;
|
||||
|
||||
static int sdioh_probe(struct sdio_func *func)
|
||||
{
|
||||
int host_idx = func->card->host->index;
|
||||
uint32 rca = func->card->rca;
|
||||
wifi_adapter_info_t *adapter;
|
||||
osl_t *osh = NULL;
|
||||
sdioh_info_t *sdioh = NULL;
|
||||
|
||||
sd_err(("bus num (host idx)=%d, slot num (rca)=%d\n", host_idx, rca));
|
||||
adapter = dhd_wifi_platform_get_adapter(SDIO_BUS, host_idx, rca);
|
||||
if (adapter != NULL) {
|
||||
sd_err(("found adapter info '%s'\n", adapter->name));
|
||||
#ifdef BUS_POWER_RESTORE
|
||||
adapter->sdio_func = func;
|
||||
#endif
|
||||
} else
|
||||
sd_err(("can't find adapter info for this chip\n"));
|
||||
|
||||
#ifdef WL_CFG80211
|
||||
wl_cfg80211_set_parent_dev(&func->dev);
|
||||
#endif // endif
|
||||
|
||||
/* allocate SDIO Host Controller state info */
|
||||
osh = osl_attach(&func->dev, SDIO_BUS, TRUE);
|
||||
if (osh == NULL) {
|
||||
sd_err(("%s: osl_attach failed\n", __FUNCTION__));
|
||||
goto fail;
|
||||
}
|
||||
osl_static_mem_init(osh, adapter);
|
||||
sdioh = sdioh_attach(osh, func);
|
||||
if (sdioh == NULL) {
|
||||
sd_err(("%s: sdioh_attach failed\n", __FUNCTION__));
|
||||
goto fail;
|
||||
}
|
||||
sdioh->bcmsdh = bcmsdh_probe(osh, &func->dev, sdioh, adapter, SDIO_BUS, host_idx, rca);
|
||||
if (sdioh->bcmsdh == NULL) {
|
||||
sd_err(("%s: bcmsdh_probe failed\n", __FUNCTION__));
|
||||
goto fail;
|
||||
}
|
||||
|
||||
sdio_set_drvdata(func, sdioh);
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
if (sdioh != NULL)
|
||||
sdioh_detach(osh, sdioh);
|
||||
if (osh != NULL)
|
||||
osl_detach(osh);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
static void sdioh_remove(struct sdio_func *func)
|
||||
{
|
||||
sdioh_info_t *sdioh;
|
||||
osl_t *osh;
|
||||
|
||||
sdioh = sdio_get_drvdata(func);
|
||||
if (sdioh == NULL) {
|
||||
sd_err(("%s: error, no sdioh handler found\n", __FUNCTION__));
|
||||
return;
|
||||
}
|
||||
sd_err(("%s: Enter\n", __FUNCTION__));
|
||||
|
||||
osh = sdioh->osh;
|
||||
bcmsdh_remove(sdioh->bcmsdh);
|
||||
sdioh_detach(osh, sdioh);
|
||||
osl_detach(osh);
|
||||
}
|
||||
|
||||
static int bcmsdh_sdmmc_probe(struct sdio_func *func,
|
||||
const struct sdio_device_id *id)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (func == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
sd_err(("%s: Enter num=%d\n", __FUNCTION__, func->num));
|
||||
sd_info(("sdio_bcmsdh: func->class=%x\n", func->class));
|
||||
sd_info(("sdio_vendor: 0x%04x\n", func->vendor));
|
||||
sd_info(("sdio_device: 0x%04x\n", func->device));
|
||||
sd_info(("Function#: 0x%04x\n", func->num));
|
||||
|
||||
#ifdef GLOBAL_SDMMC_INSTANCE
|
||||
gInstance->func[func->num] = func;
|
||||
#endif
|
||||
|
||||
/* 4318 doesn't have function 2 */
|
||||
if ((func->num == 2) || (func->num == 1 && func->device == 0x4))
|
||||
ret = sdioh_probe(func);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void bcmsdh_sdmmc_remove(struct sdio_func *func)
|
||||
{
|
||||
if (func == NULL) {
|
||||
sd_err(("%s is called with NULL SDIO function pointer\n", __FUNCTION__));
|
||||
return;
|
||||
}
|
||||
|
||||
sd_trace(("bcmsdh_sdmmc: %s Enter\n", __FUNCTION__));
|
||||
sd_info(("sdio_bcmsdh: func->class=%x\n", func->class));
|
||||
sd_info(("sdio_vendor: 0x%04x\n", func->vendor));
|
||||
sd_info(("sdio_device: 0x%04x\n", func->device));
|
||||
sd_info(("Function#: 0x%04x\n", func->num));
|
||||
|
||||
if ((func->num == 2) || (func->num == 1 && func->device == 0x4))
|
||||
sdioh_remove(func);
|
||||
}
|
||||
|
||||
/* devices we support, null terminated */
|
||||
static const struct sdio_device_id bcmsdh_sdmmc_ids[] = {
|
||||
{ SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_DEFAULT) },
|
||||
{ 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, BCM43012_CHIP_ID) },
|
||||
{ SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, BCM43014_CHIP_ID) },
|
||||
{ SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, BCM43014_D11N_ID) },
|
||||
{ SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, BCM43014_D11N2G_ID) },
|
||||
{ SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, BCM43014_D11N5G_ID) },
|
||||
/* { SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_ANY_ID) }, */
|
||||
{ SDIO_DEVICE_CLASS(SDIO_CLASS_NONE) },
|
||||
/* end: all zeroes */
|
||||
{ 0, 0, 0, 0},
|
||||
};
|
||||
|
||||
MODULE_DEVICE_TABLE(sdio, bcmsdh_sdmmc_ids);
|
||||
|
||||
#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 39)) && defined(CONFIG_PM)
|
||||
static int bcmsdh_sdmmc_suspend(struct device *pdev)
|
||||
{
|
||||
int err;
|
||||
sdioh_info_t *sdioh;
|
||||
struct sdio_func *func = dev_to_sdio_func(pdev);
|
||||
mmc_pm_flag_t sdio_flags;
|
||||
|
||||
printf("%s Enter func->num=%d\n", __FUNCTION__, func->num);
|
||||
if (func->num != 2)
|
||||
return 0;
|
||||
|
||||
dhd_mmc_suspend = TRUE;
|
||||
sdioh = sdio_get_drvdata(func);
|
||||
err = bcmsdh_suspend(sdioh->bcmsdh);
|
||||
if (err) {
|
||||
printf("%s bcmsdh_suspend err=%d\n", __FUNCTION__, err);
|
||||
dhd_mmc_suspend = FALSE;
|
||||
return err;
|
||||
}
|
||||
|
||||
sdio_flags = sdio_get_host_pm_caps(func);
|
||||
if (!(sdio_flags & MMC_PM_KEEP_POWER)) {
|
||||
sd_err(("%s: can't keep power while host is suspended\n", __FUNCTION__));
|
||||
dhd_mmc_suspend = FALSE;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* keep power while host suspended */
|
||||
err = sdio_set_host_pm_flags(func, MMC_PM_KEEP_POWER);
|
||||
if (err) {
|
||||
sd_err(("%s: error while trying to keep power\n", __FUNCTION__));
|
||||
dhd_mmc_suspend = FALSE;
|
||||
return err;
|
||||
}
|
||||
smp_mb();
|
||||
|
||||
printf("%s Exit\n", __FUNCTION__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int bcmsdh_sdmmc_resume(struct device *pdev)
|
||||
{
|
||||
sdioh_info_t *sdioh;
|
||||
struct sdio_func *func = dev_to_sdio_func(pdev);
|
||||
|
||||
printf("%s Enter func->num=%d\n", __FUNCTION__, func->num);
|
||||
if (func->num != 2)
|
||||
return 0;
|
||||
|
||||
dhd_mmc_suspend = FALSE;
|
||||
sdioh = sdio_get_drvdata(func);
|
||||
bcmsdh_resume(sdioh->bcmsdh);
|
||||
|
||||
smp_mb();
|
||||
printf("%s Exit\n", __FUNCTION__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct dev_pm_ops bcmsdh_sdmmc_pm_ops = {
|
||||
.suspend = bcmsdh_sdmmc_suspend,
|
||||
.resume = bcmsdh_sdmmc_resume,
|
||||
};
|
||||
#endif /* (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 39)) && defined(CONFIG_PM) */
|
||||
|
||||
#if defined(BCMLXSDMMC)
|
||||
static struct semaphore *notify_semaphore = NULL;
|
||||
|
||||
static int dummy_probe(struct sdio_func *func,
|
||||
const struct sdio_device_id *id)
|
||||
{
|
||||
if (func && (func->num != 2)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (notify_semaphore)
|
||||
up(notify_semaphore);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void dummy_remove(struct sdio_func *func)
|
||||
{
|
||||
}
|
||||
|
||||
static struct sdio_driver dummy_sdmmc_driver = {
|
||||
.probe = dummy_probe,
|
||||
.remove = dummy_remove,
|
||||
.name = "dummy_sdmmc",
|
||||
.id_table = bcmsdh_sdmmc_ids,
|
||||
};
|
||||
|
||||
int sdio_func_reg_notify(void* semaphore)
|
||||
{
|
||||
notify_semaphore = semaphore;
|
||||
return sdio_register_driver(&dummy_sdmmc_driver);
|
||||
}
|
||||
|
||||
void sdio_func_unreg_notify(void)
|
||||
{
|
||||
OSL_SLEEP(15);
|
||||
sdio_unregister_driver(&dummy_sdmmc_driver);
|
||||
}
|
||||
|
||||
#endif /* defined(BCMLXSDMMC) */
|
||||
|
||||
static struct sdio_driver bcmsdh_sdmmc_driver = {
|
||||
.probe = bcmsdh_sdmmc_probe,
|
||||
.remove = bcmsdh_sdmmc_remove,
|
||||
.name = "bcmsdh_sdmmc",
|
||||
.id_table = bcmsdh_sdmmc_ids,
|
||||
#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 39)) && defined(CONFIG_PM)
|
||||
.drv = {
|
||||
.pm = &bcmsdh_sdmmc_pm_ops,
|
||||
},
|
||||
#endif /* (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 39)) && defined(CONFIG_PM) */
|
||||
};
|
||||
|
||||
struct sdos_info {
|
||||
sdioh_info_t *sd;
|
||||
spinlock_t lock;
|
||||
};
|
||||
|
||||
/* Interrupt enable/disable */
|
||||
SDIOH_API_RC
|
||||
sdioh_interrupt_set(sdioh_info_t *sd, bool enable)
|
||||
{
|
||||
if (!sd)
|
||||
return BCME_BADARG;
|
||||
|
||||
sd_trace(("%s: %s\n", __FUNCTION__, enable ? "Enabling" : "Disabling"));
|
||||
return SDIOH_API_RC_SUCCESS;
|
||||
}
|
||||
|
||||
#ifdef BCMSDH_MODULE
|
||||
static int __init
|
||||
bcmsdh_module_init(void)
|
||||
{
|
||||
int error = 0;
|
||||
error = sdio_function_init();
|
||||
return error;
|
||||
}
|
||||
|
||||
static void __exit
|
||||
bcmsdh_module_cleanup(void)
|
||||
{
|
||||
sdio_function_cleanup();
|
||||
}
|
||||
|
||||
module_init(bcmsdh_module_init);
|
||||
module_exit(bcmsdh_module_cleanup);
|
||||
|
||||
MODULE_LICENSE("GPL v2");
|
||||
MODULE_DESCRIPTION(DESCRIPTION);
|
||||
MODULE_AUTHOR(AUTHOR);
|
||||
|
||||
#endif /* BCMSDH_MODULE */
|
||||
/*
|
||||
* module init
|
||||
*/
|
||||
int bcmsdh_register_client_driver(void)
|
||||
{
|
||||
return sdio_register_driver(&bcmsdh_sdmmc_driver);
|
||||
}
|
||||
|
||||
/*
|
||||
* module cleanup
|
||||
*/
|
||||
void bcmsdh_unregister_client_driver(void)
|
||||
{
|
||||
sdio_unregister_driver(&bcmsdh_sdmmc_driver);
|
||||
}
|
||||
@@ -0,0 +1,438 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Broadcom SPI Host Controller Driver - Linux Per-port
|
||||
*
|
||||
* Copyright (C) 1999-2019, 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.
|
||||
*
|
||||
* 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: bcmsdspi_linux.c 514727 2014-11-12 03:02:48Z $
|
||||
*/
|
||||
|
||||
#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
|
||||
#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())
|
||||
#endif // 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 // 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 // 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;
|
||||
#else
|
||||
write = msg_out[1] & 0x80;
|
||||
#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;
|
||||
#else
|
||||
write = msg_out[3] & 0x80;
|
||||
#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 */
|
||||
1800
drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd_wifi6/bcmspibrcm.c
Normal file
1800
drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd_wifi6/bcmspibrcm.c
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,307 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Broadcom Secure Standard Library.
|
||||
*
|
||||
* Copyright (C) 1999-2019, 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.
|
||||
*
|
||||
* 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 $
|
||||
*/
|
||||
|
||||
#include <bcm_cfg.h>
|
||||
#include <typedefs.h>
|
||||
#include <bcmdefs.h>
|
||||
#ifdef BCMDRIVER
|
||||
#include <osl.h>
|
||||
#else /* BCMDRIVER */
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
#endif /* else BCMDRIVER */
|
||||
|
||||
#include <bcmstdlib_s.h>
|
||||
#include <bcmutils.h>
|
||||
|
||||
/*
|
||||
* __SIZE_MAX__ value is depending on platform:
|
||||
* Firmware Dongle: RAMSIZE (Dongle Specific Limit).
|
||||
* LINUX NIC/Windows/MACOSX/Application: OS Native or
|
||||
* 0xFFFFFFFFu if not defined.
|
||||
*/
|
||||
#ifndef SIZE_MAX
|
||||
#ifndef __SIZE_MAX__
|
||||
#define __SIZE_MAX__ 0xFFFFFFFFu
|
||||
#endif /* __SIZE_MAX__ */
|
||||
#define SIZE_MAX __SIZE_MAX__
|
||||
#endif /* SIZE_MAX */
|
||||
#define RSIZE_MAX (SIZE_MAX >> 1u)
|
||||
|
||||
#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
|
||||
* destsz : size of the destination buffer
|
||||
* src : pointer to the object to copy from
|
||||
* n : number of bytes to copy
|
||||
* Return Value : zero on success and non-zero on error
|
||||
* Also on error, if dest is not a null pointer and destsz not greater
|
||||
* 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)
|
||||
{
|
||||
int err = BCME_OK;
|
||||
|
||||
if ((!dest) || (((char *)dest + destsz) < (char *)dest)) {
|
||||
err = BCME_BADARG;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (destsz > RSIZE_MAX) {
|
||||
err = BCME_BADLEN;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (destsz < n) {
|
||||
memset(dest, 0, destsz);
|
||||
err = BCME_BADLEN;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if ((!src) || (((const char *)src + n) < (const char *)src)) {
|
||||
memset(dest, 0, destsz);
|
||||
err = BCME_BADARG;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
memmove(dest, src, n);
|
||||
exit:
|
||||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
* memcpy_s - secure memcpy
|
||||
* dest : pointer to the object to copy to
|
||||
* destsz : size of the destination buffer
|
||||
* src : pointer to the object to copy from
|
||||
* n : number of bytes to copy
|
||||
* Return Value : zero on success and non-zero on error
|
||||
* Also on error, if dest is not a null pointer and destsz not greater
|
||||
* than RSIZE_MAX, writes destsz zero bytes into the dest object.
|
||||
*/
|
||||
int
|
||||
memcpy_s(void *dest, size_t destsz, const void *src, size_t n)
|
||||
{
|
||||
int err = BCME_OK;
|
||||
char *d = dest;
|
||||
const char *s = src;
|
||||
|
||||
if ((!d) || ((d + destsz) < d)) {
|
||||
err = BCME_BADARG;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (destsz > RSIZE_MAX) {
|
||||
err = BCME_BADLEN;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (destsz < n) {
|
||||
memset(dest, 0, destsz);
|
||||
err = BCME_BADLEN;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if ((!s) || ((s + n) < s)) {
|
||||
memset(dest, 0, destsz);
|
||||
err = BCME_BADARG;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* overlap checking between dest and src */
|
||||
if (!(((d + destsz) <= s) || (d >= (s + n)))) {
|
||||
memset(dest, 0, destsz);
|
||||
err = BCME_BADARG;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
(void)memcpy(dest, src, n);
|
||||
exit:
|
||||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
* memset_s - secure memset
|
||||
* dest : pointer to the object to be set
|
||||
* destsz : size of the destination buffer
|
||||
* c : byte value
|
||||
* n : number of bytes to be set
|
||||
* Return Value : zero on success and non-zero on error
|
||||
* Also on error, if dest is not a null pointer and destsz not greater
|
||||
* than RSIZE_MAX, writes destsz bytes with value c into the dest object.
|
||||
*/
|
||||
int
|
||||
memset_s(void *dest, size_t destsz, int c, size_t n)
|
||||
{
|
||||
int err = BCME_OK;
|
||||
if ((!dest) || (((char *)dest + destsz) < (char *)dest)) {
|
||||
err = BCME_BADARG;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (destsz > RSIZE_MAX) {
|
||||
err = BCME_BADLEN;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (destsz < n) {
|
||||
(void)memset(dest, c, destsz);
|
||||
err = BCME_BADLEN;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
(void)memset(dest, c, n);
|
||||
exit:
|
||||
return err;
|
||||
}
|
||||
#endif /* !__STDC_WANT_SECURE_LIB__ && !(__STDC_LIB_EXT1__ && __STDC_WANT_LIB_EXT1__) */
|
||||
|
||||
#if 0
|
||||
/**
|
||||
* strlcpy - Copy a %NUL terminated string into a sized buffer
|
||||
* @dest: Where to copy the string to
|
||||
* @src: Where to copy the string from
|
||||
* @size: size of destination buffer 0 if input parameters are NOK
|
||||
* return: string leng of src (assume src is NUL terminated)
|
||||
*
|
||||
* Compatible with *BSD: the result is always a valid
|
||||
* NUL-terminated string that fits in the buffer (unless,
|
||||
* 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)
|
||||
{
|
||||
const char *s = src;
|
||||
size_t n;
|
||||
|
||||
if (dest == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* terminate dest if src is NULL and return 0 as only NULL was added */
|
||||
if (s == NULL) {
|
||||
*dest = '\0';
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* allows us to handle size 0 */
|
||||
if (size == 0) {
|
||||
n = 0;
|
||||
} else {
|
||||
n = size - 1u;
|
||||
}
|
||||
|
||||
/* perform copy */
|
||||
while (*s && n != 0) {
|
||||
*dest++ = *s++;
|
||||
n--;
|
||||
}
|
||||
|
||||
*dest = '\0';
|
||||
|
||||
/* count to end of s or compensate for NULL */
|
||||
if (n == 0) {
|
||||
while (*s++)
|
||||
;
|
||||
} else {
|
||||
s++;
|
||||
}
|
||||
|
||||
/* return bytes copied not accounting NUL */
|
||||
return (s - src - 1u);
|
||||
}
|
||||
#endif // endif
|
||||
|
||||
/**
|
||||
* strlcat_s - Concatenate a %NUL terminated string with a sized buffer
|
||||
* @dest: Where to concatenate the string to
|
||||
* @src: Where to copy the string from
|
||||
* @size: size of destination buffer
|
||||
* return: string length of created string (i.e. the initial length of dest plus the length of src)
|
||||
* not including the NUL char, up until size
|
||||
*
|
||||
* Unlike strncat(), strlcat() take the full size of the buffer (not just the number of bytes to
|
||||
* copy) and guarantee to NUL-terminate the result (even when there's nothing to concat).
|
||||
* If the length of dest string concatinated with the src string >= size, truncation occurs.
|
||||
*
|
||||
* Compatible with *BSD: the result is always a valid NUL-terminated string that fits in the buffer
|
||||
* (unless, of course, the buffer size is zero).
|
||||
*
|
||||
* If either src or dest is not NUL-terminated, dest[size-1] will be set to NUL.
|
||||
* If size < strlen(dest) + strlen(src), dest[size-1] will be set to NUL.
|
||||
* If size == 0, dest[0] will be set to NUL.
|
||||
*/
|
||||
size_t
|
||||
strlcat_s(char *dest, const char *src, size_t size)
|
||||
{
|
||||
char *d = dest;
|
||||
const char *s = src; /* point to the start of the src string */
|
||||
size_t n = size;
|
||||
size_t dlen;
|
||||
size_t bytes_to_copy = 0;
|
||||
|
||||
if (dest == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* set d to point to the end of dest string (up to size) */
|
||||
while (n != 0 && *d != '\0') {
|
||||
d++;
|
||||
n--;
|
||||
}
|
||||
dlen = (size_t)(d - dest);
|
||||
|
||||
if (s != NULL) {
|
||||
size_t slen = 0;
|
||||
|
||||
/* calculate src len in case it's not null-terminated */
|
||||
n = size;
|
||||
while (n-- != 0 && *(s + slen) != '\0') {
|
||||
++slen;
|
||||
}
|
||||
|
||||
n = size - dlen; /* maximum num of chars to copy */
|
||||
if (n != 0) {
|
||||
/* copy relevant chars (until end of src buf or given size is reached) */
|
||||
bytes_to_copy = MIN(slen - (size_t)(s - src), n - 1);
|
||||
(void)memcpy(d, s, bytes_to_copy);
|
||||
d += bytes_to_copy;
|
||||
}
|
||||
}
|
||||
if (n == 0 && dlen != 0) {
|
||||
--d; /* nothing to copy, but NUL-terminate dest anyway */
|
||||
}
|
||||
*d = '\0'; /* NUL-terminate dest */
|
||||
|
||||
return (dlen + bytes_to_copy);
|
||||
}
|
||||
4379
drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd_wifi6/bcmutils.c
Normal file
4379
drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd_wifi6/bcmutils.c
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,816 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Misc utility routines for WL and Apps
|
||||
* This header file housing the define and function prototype use by
|
||||
* both the wl driver, tools & Apps.
|
||||
*
|
||||
* Copyright (C) 1999-2019, 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.
|
||||
*
|
||||
* 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: bcmwifi_channels.h 806092 2019-02-21 08:19:13Z $
|
||||
*/
|
||||
|
||||
#ifndef _bcmwifi_channels_h_
|
||||
#define _bcmwifi_channels_h_
|
||||
|
||||
/* A chanspec holds the channel number, band, bandwidth and primary 20MHz sideband */
|
||||
typedef uint16 chanspec_t;
|
||||
typedef uint16 chanspec_band_t;
|
||||
typedef uint16 chanspec_bw_t;
|
||||
typedef uint16 chanspec_subband_t;
|
||||
|
||||
/* channel defines */
|
||||
#define CH_80MHZ_APART 16
|
||||
#define CH_40MHZ_APART 8
|
||||
#define CH_20MHZ_APART 4
|
||||
#define CH_10MHZ_APART 2
|
||||
#define CH_5MHZ_APART 1 /* 2G band channels are 5 Mhz apart */
|
||||
|
||||
#define CH_MIN_2G_CHANNEL 1u /* Min channel in 2G band */
|
||||
#define CH_MAX_2G_CHANNEL 14u /* Max channel in 2G band */
|
||||
#define CH_MIN_2G_40M_CHANNEL 3u /* Min 40MHz center channel in 2G band */
|
||||
#define CH_MAX_2G_40M_CHANNEL 11u /* Max 40MHz center channel in 2G band */
|
||||
|
||||
/* maximum # channels the s/w supports */
|
||||
#define MAXCHANNEL 224 /* max # supported channels. The max channel no is above,
|
||||
* this is that + 1 rounded up to a multiple of NBBY (8).
|
||||
* DO NOT MAKE it > 255: channels are uint8's all over
|
||||
*/
|
||||
#define MAXCHANNEL_NUM (MAXCHANNEL - 1) /* max channel number */
|
||||
|
||||
#define INVCHANNEL 255 /* error value for a bad channel */
|
||||
|
||||
/* channel bitvec */
|
||||
typedef struct {
|
||||
uint8 vec[MAXCHANNEL/8]; /* bitvec of channels */
|
||||
} chanvec_t;
|
||||
|
||||
/* make sure channel num is within valid range */
|
||||
#define CH_NUM_VALID_RANGE(ch_num) ((ch_num) > 0 && (ch_num) <= MAXCHANNEL_NUM)
|
||||
|
||||
#define CHSPEC_CTLOVLP(sp1, sp2, sep) \
|
||||
(ABS(wf_chspec_ctlchan(sp1) - wf_chspec_ctlchan(sp2)) < (sep))
|
||||
|
||||
/* All builds use the new 11ac ratespec/chanspec */
|
||||
#undef D11AC_IOTYPES
|
||||
#define D11AC_IOTYPES
|
||||
|
||||
#define WL_CHANSPEC_CHAN_MASK 0x00ff
|
||||
#define WL_CHANSPEC_CHAN_SHIFT 0
|
||||
#define WL_CHANSPEC_CHAN1_MASK 0x000f
|
||||
#define WL_CHANSPEC_CHAN1_SHIFT 0
|
||||
#define WL_CHANSPEC_CHAN2_MASK 0x00f0
|
||||
#define WL_CHANSPEC_CHAN2_SHIFT 4
|
||||
|
||||
#define WL_CHANSPEC_CTL_SB_MASK 0x0700
|
||||
#define WL_CHANSPEC_CTL_SB_SHIFT 8
|
||||
#define WL_CHANSPEC_CTL_SB_LLL 0x0000
|
||||
#define WL_CHANSPEC_CTL_SB_LLU 0x0100
|
||||
#define WL_CHANSPEC_CTL_SB_LUL 0x0200
|
||||
#define WL_CHANSPEC_CTL_SB_LUU 0x0300
|
||||
#define WL_CHANSPEC_CTL_SB_ULL 0x0400
|
||||
#define WL_CHANSPEC_CTL_SB_ULU 0x0500
|
||||
#define WL_CHANSPEC_CTL_SB_UUL 0x0600
|
||||
#define WL_CHANSPEC_CTL_SB_UUU 0x0700
|
||||
#define WL_CHANSPEC_CTL_SB_LL WL_CHANSPEC_CTL_SB_LLL
|
||||
#define WL_CHANSPEC_CTL_SB_LU WL_CHANSPEC_CTL_SB_LLU
|
||||
#define WL_CHANSPEC_CTL_SB_UL WL_CHANSPEC_CTL_SB_LUL
|
||||
#define WL_CHANSPEC_CTL_SB_UU WL_CHANSPEC_CTL_SB_LUU
|
||||
#define WL_CHANSPEC_CTL_SB_L WL_CHANSPEC_CTL_SB_LLL
|
||||
#define WL_CHANSPEC_CTL_SB_U WL_CHANSPEC_CTL_SB_LLU
|
||||
#define WL_CHANSPEC_CTL_SB_LOWER WL_CHANSPEC_CTL_SB_LLL
|
||||
#define WL_CHANSPEC_CTL_SB_UPPER WL_CHANSPEC_CTL_SB_LLU
|
||||
#define WL_CHANSPEC_CTL_SB_NONE WL_CHANSPEC_CTL_SB_LLL
|
||||
|
||||
#define WL_CHANSPEC_BW_MASK 0x3800u
|
||||
#define WL_CHANSPEC_BW_SHIFT 11u
|
||||
#define WL_CHANSPEC_BW_5 0x0000u
|
||||
#define WL_CHANSPEC_BW_10 0x0800u
|
||||
#define WL_CHANSPEC_BW_20 0x1000u
|
||||
#define WL_CHANSPEC_BW_40 0x1800u
|
||||
#define WL_CHANSPEC_BW_80 0x2000u
|
||||
#define WL_CHANSPEC_BW_160 0x2800u
|
||||
#define WL_CHANSPEC_BW_8080 0x3000u
|
||||
|
||||
#define WL_CHANSPEC_BAND_MASK 0xc000u
|
||||
#define WL_CHANSPEC_BAND_SHIFT 14u
|
||||
#define WL_CHANSPEC_BAND_2G 0x0000u
|
||||
#define WL_CHANSPEC_BAND_3G 0x4000u
|
||||
#define WL_CHANSPEC_BAND_4G 0x8000u
|
||||
#define WL_CHANSPEC_BAND_5G 0xc000u
|
||||
#define INVCHANSPEC 255u
|
||||
#define MAX_CHANSPEC 0xFFFFu
|
||||
|
||||
#define WL_CHANNEL_BAND(ch) (((ch) <= CH_MAX_2G_CHANNEL) ? \
|
||||
WL_CHANSPEC_BAND_2G : WL_CHANSPEC_BAND_5G)
|
||||
|
||||
/* channel defines */
|
||||
#define LOWER_20_SB(channel) (((channel) > CH_10MHZ_APART) ? \
|
||||
((channel) - CH_10MHZ_APART) : 0)
|
||||
#define UPPER_20_SB(channel) (((channel) < (MAXCHANNEL - CH_10MHZ_APART)) ? \
|
||||
((channel) + CH_10MHZ_APART) : 0)
|
||||
|
||||
/* pass a 80MHz channel number (uint8) to get respective LL, UU, LU, UL */
|
||||
#define LL_20_SB(channel) (((channel) > 3 * CH_10MHZ_APART) ? ((channel) - 3 * CH_10MHZ_APART) : 0)
|
||||
#define UU_20_SB(channel) (((channel) < (MAXCHANNEL - 3 * CH_10MHZ_APART)) ? \
|
||||
((channel) + 3 * CH_10MHZ_APART) : 0)
|
||||
#define LU_20_SB(channel) LOWER_20_SB(channel)
|
||||
#define UL_20_SB(channel) UPPER_20_SB(channel)
|
||||
|
||||
#define LOWER_40_SB(channel) ((channel) - CH_20MHZ_APART)
|
||||
#define UPPER_40_SB(channel) ((channel) + CH_20MHZ_APART)
|
||||
#define CHSPEC_WLCBANDUNIT(chspec) (CHSPEC_IS5G(chspec) ? BAND_5G_INDEX : BAND_2G_INDEX)
|
||||
#define CH20MHZ_CHSPEC(channel) (chanspec_t)((chanspec_t)(channel) | WL_CHANSPEC_BW_20 | \
|
||||
(((channel) <= CH_MAX_2G_CHANNEL) ? \
|
||||
WL_CHANSPEC_BAND_2G : WL_CHANSPEC_BAND_5G))
|
||||
#define NEXT_20MHZ_CHAN(channel) (((channel) < (MAXCHANNEL - CH_20MHZ_APART)) ? \
|
||||
((channel) + CH_20MHZ_APART) : 0)
|
||||
#define CH40MHZ_CHSPEC(channel, ctlsb) (chanspec_t) \
|
||||
((channel) | (ctlsb) | WL_CHANSPEC_BW_40 | \
|
||||
((channel) <= CH_MAX_2G_CHANNEL ? WL_CHANSPEC_BAND_2G : \
|
||||
WL_CHANSPEC_BAND_5G))
|
||||
#define CH80MHZ_CHSPEC(channel, ctlsb) (chanspec_t) \
|
||||
((channel) | (ctlsb) | \
|
||||
WL_CHANSPEC_BW_80 | WL_CHANSPEC_BAND_5G)
|
||||
#define CH160MHZ_CHSPEC(channel, ctlsb) (chanspec_t) \
|
||||
((channel) | (ctlsb) | \
|
||||
WL_CHANSPEC_BW_160 | WL_CHANSPEC_BAND_5G)
|
||||
|
||||
/* simple MACROs to get different fields of chanspec */
|
||||
#ifdef WL11AC_80P80
|
||||
#define CHSPEC_CHANNEL(chspec) wf_chspec_channel(chspec)
|
||||
#else
|
||||
#define CHSPEC_CHANNEL(chspec) ((uint8)((chspec) & WL_CHANSPEC_CHAN_MASK))
|
||||
#endif // endif
|
||||
#define CHSPEC_CHAN1(chspec) ((chspec) & WL_CHANSPEC_CHAN1_MASK) >> WL_CHANSPEC_CHAN1_SHIFT
|
||||
#define CHSPEC_CHAN2(chspec) ((chspec) & WL_CHANSPEC_CHAN2_MASK) >> WL_CHANSPEC_CHAN2_SHIFT
|
||||
#define CHSPEC_BAND(chspec) ((chspec) & WL_CHANSPEC_BAND_MASK)
|
||||
#define CHSPEC_CTL_SB(chspec) ((chspec) & WL_CHANSPEC_CTL_SB_MASK)
|
||||
#define CHSPEC_BW(chspec) ((chspec) & WL_CHANSPEC_BW_MASK)
|
||||
|
||||
#ifdef WL11N_20MHZONLY
|
||||
#define CHSPEC_IS20(chspec) 1
|
||||
#define CHSPEC_IS20_2G(chspec) ((((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_20) && \
|
||||
CHSPEC_IS2G(chspec))
|
||||
#ifndef CHSPEC_IS40
|
||||
#define CHSPEC_IS40(chspec) 0
|
||||
#endif // endif
|
||||
#ifndef CHSPEC_IS80
|
||||
#define CHSPEC_IS80(chspec) 0
|
||||
#endif // endif
|
||||
#ifndef CHSPEC_IS160
|
||||
#define CHSPEC_IS160(chspec) 0
|
||||
#endif // endif
|
||||
#ifndef CHSPEC_IS8080
|
||||
#define CHSPEC_IS8080(chspec) 0
|
||||
#endif // endif
|
||||
|
||||
/* see FOREACH_20_SB in !WL11N_20MHZONLY section */
|
||||
#define FOREACH_20_SB(chspec, channel) \
|
||||
for (channel = CHSPEC_CHANNEL(chspec); channel; channel = 0)
|
||||
|
||||
/* see GET_ALL_SB in !WL11N_20MHZONLY section */
|
||||
#define GET_ALL_SB(chspec, psb) do { \
|
||||
psb[0] = CHSPEC_CHANNEL(chspec); \
|
||||
} while (0)
|
||||
|
||||
#else /* !WL11N_20MHZONLY */
|
||||
|
||||
#define CHSPEC_IS20(chspec) (((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_20)
|
||||
#define CHSPEC_IS20_5G(chspec) ((((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_20) && \
|
||||
CHSPEC_IS5G(chspec))
|
||||
#ifndef CHSPEC_IS40
|
||||
#define CHSPEC_IS40(chspec) (((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_40)
|
||||
#endif // endif
|
||||
#ifndef CHSPEC_IS80
|
||||
#define CHSPEC_IS80(chspec) (((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_80)
|
||||
#endif // endif
|
||||
#ifndef CHSPEC_IS160
|
||||
#define CHSPEC_IS160(chspec) (((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_160)
|
||||
#endif // endif
|
||||
#ifndef CHSPEC_IS8080
|
||||
#define CHSPEC_IS8080(chspec) (((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_8080)
|
||||
#endif // endif
|
||||
|
||||
/* pass a center channel and get channel offset from it by 10MHz */
|
||||
#define CH_OFF_10MHZ_MULTIPLES(channel, offset) ((uint8) (((offset) < 0) ? \
|
||||
(((channel) > (WL_CHANSPEC_CHAN_MASK & ((uint16)((-(offset)) * CH_10MHZ_APART)))) ?\
|
||||
((channel) + (offset) * CH_10MHZ_APART) : 0) : \
|
||||
(((channel) < (uint16)(MAXCHANNEL - (offset) * CH_10MHZ_APART)) ? \
|
||||
((channel) + (offset) * CH_10MHZ_APART) : 0)))
|
||||
|
||||
#if defined(WL11AC_80P80) || defined(WL11AC_160)
|
||||
/* pass a 160MHz center channel to get 20MHz subband channel numbers */
|
||||
#define LLL_20_SB_160(channel) CH_OFF_10MHZ_MULTIPLES(channel, -7)
|
||||
#define LLU_20_SB_160(channel) CH_OFF_10MHZ_MULTIPLES(channel, -5)
|
||||
#define LUL_20_SB_160(channel) CH_OFF_10MHZ_MULTIPLES(channel, -3)
|
||||
#define LUU_20_SB_160(channel) CH_OFF_10MHZ_MULTIPLES(channel, -1)
|
||||
#define ULL_20_SB_160(channel) CH_OFF_10MHZ_MULTIPLES(channel, 1)
|
||||
#define ULU_20_SB_160(channel) CH_OFF_10MHZ_MULTIPLES(channel, 3)
|
||||
#define UUL_20_SB_160(channel) CH_OFF_10MHZ_MULTIPLES(channel, 5)
|
||||
#define UUU_20_SB_160(channel) CH_OFF_10MHZ_MULTIPLES(channel, 7)
|
||||
|
||||
/* given an 80p80 channel, return the lower 80MHz sideband */
|
||||
#define LOWER_80_SB(chspec) (wf_chspec_primary80_channel(chspec) < \
|
||||
wf_chspec_secondary80_channel(chspec) ? \
|
||||
wf_chspec_primary80_channel(chspec) : wf_chspec_secondary80_channel(chspec))
|
||||
|
||||
/* given an 80p80 channel, return the upper 80MHz sideband */
|
||||
#define UPPER_80_SB(chspec) (wf_chspec_primary80_channel(chspec) > \
|
||||
wf_chspec_secondary80_channel(chspec) ? \
|
||||
wf_chspec_primary80_channel(chspec) : wf_chspec_secondary80_channel(chspec))
|
||||
|
||||
/* pass an 80P80 chanspec (not channel) to get 20MHz subnand channel numbers */
|
||||
#define LLL_20_SB_8080(chspec) CH_OFF_10MHZ_MULTIPLES(LOWER_80_SB(chspec), -3)
|
||||
#define LLU_20_SB_8080(chspec) CH_OFF_10MHZ_MULTIPLES(LOWER_80_SB(chspec), -1)
|
||||
#define LUL_20_SB_8080(chspec) CH_OFF_10MHZ_MULTIPLES(LOWER_80_SB(chspec), 1)
|
||||
#define LUU_20_SB_8080(chspec) CH_OFF_10MHZ_MULTIPLES(LOWER_80_SB(chspec), 3)
|
||||
#define ULL_20_SB_8080(chspec) CH_OFF_10MHZ_MULTIPLES(UPPER_80_SB(chspec), -3)
|
||||
#define ULU_20_SB_8080(chspec) CH_OFF_10MHZ_MULTIPLES(UPPER_80_SB(chspec), -1)
|
||||
#define UUL_20_SB_8080(chspec) CH_OFF_10MHZ_MULTIPLES(UPPER_80_SB(chspec), 1)
|
||||
#define UUU_20_SB_8080(chspec) CH_OFF_10MHZ_MULTIPLES(UPPER_80_SB(chspec), 3)
|
||||
|
||||
/* get lowest 20MHz sideband of a given chspec
|
||||
* (works with 20, 40, 80, 160, 80p80)
|
||||
*/
|
||||
#define CH_FIRST_20_SB(chspec) ((uint8) (\
|
||||
CHSPEC_IS160(chspec) ? LLL_20_SB_160(CHSPEC_CHANNEL(chspec)) : (\
|
||||
CHSPEC_IS8080(chspec) ? LLL_20_SB_8080(chspec) : (\
|
||||
CHSPEC_IS80(chspec) ? LL_20_SB(CHSPEC_CHANNEL(chspec)) : (\
|
||||
CHSPEC_IS40(chspec) ? LOWER_20_SB(CHSPEC_CHANNEL(chspec)) : \
|
||||
CHSPEC_CHANNEL(chspec))))))
|
||||
|
||||
/* get upper most 20MHz sideband of a given chspec
|
||||
* (works with 20, 40, 80, 160, 80p80)
|
||||
*/
|
||||
#define CH_LAST_20_SB(chspec) ((uint8) (\
|
||||
CHSPEC_IS160(chspec) ? UUU_20_SB_160(CHSPEC_CHANNEL(chspec)) : (\
|
||||
CHSPEC_IS8080(chspec) ? UUU_20_SB_8080(chspec) : (\
|
||||
CHSPEC_IS80(chspec) ? UU_20_SB(CHSPEC_CHANNEL(chspec)) : (\
|
||||
CHSPEC_IS40(chspec) ? UPPER_20_SB(CHSPEC_CHANNEL(chspec)) : \
|
||||
CHSPEC_CHANNEL(chspec))))))
|
||||
|
||||
/* call this with chspec and a valid 20MHz sideband of this channel to get the next 20MHz sideband
|
||||
* (works with 80p80 only)
|
||||
* resolves to 0 if called with upper most channel
|
||||
*/
|
||||
#define CH_NEXT_20_SB_IN_8080(chspec, channel) ((uint8) (\
|
||||
((uint8) ((channel) + CH_20MHZ_APART) > CH_LAST_20_SB(chspec) ? 0 : \
|
||||
((channel) == LUU_20_SB_8080(chspec) ? ULL_20_SB_8080(chspec) : \
|
||||
(channel) + CH_20MHZ_APART))))
|
||||
|
||||
/* call this with chspec and a valid 20MHz sideband of this channel to get the next 20MHz sideband
|
||||
* (works with 20, 40, 80, 160, 80p80)
|
||||
* resolves to 0 if called with upper most channel
|
||||
*/
|
||||
#define CH_NEXT_20_SB(chspec, channel) ((uint8) (\
|
||||
(CHSPEC_IS8080(chspec) ? CH_NEXT_20_SB_IN_8080((chspec), (channel)) : \
|
||||
((uint8) ((channel) + CH_20MHZ_APART) > CH_LAST_20_SB(chspec) ? 0 : \
|
||||
((channel) + CH_20MHZ_APART)))))
|
||||
|
||||
#else /* WL11AC_80P80, WL11AC_160 */
|
||||
|
||||
#define LLL_20_SB_160(channel) 0
|
||||
#define LLU_20_SB_160(channel) 0
|
||||
#define LUL_20_SB_160(channel) 0
|
||||
#define LUU_20_SB_160(channel) 0
|
||||
#define ULL_20_SB_160(channel) 0
|
||||
#define ULU_20_SB_160(channel) 0
|
||||
#define UUL_20_SB_160(channel) 0
|
||||
#define UUU_20_SB_160(channel) 0
|
||||
|
||||
#define LOWER_80_SB(chspec) 0
|
||||
|
||||
#define UPPER_80_SB(chspec) 0
|
||||
|
||||
#define LLL_20_SB_8080(chspec) 0
|
||||
#define LLU_20_SB_8080(chspec) 0
|
||||
#define LUL_20_SB_8080(chspec) 0
|
||||
#define LUU_20_SB_8080(chspec) 0
|
||||
#define ULL_20_SB_8080(chspec) 0
|
||||
#define ULU_20_SB_8080(chspec) 0
|
||||
#define UUL_20_SB_8080(chspec) 0
|
||||
#define UUU_20_SB_8080(chspec) 0
|
||||
|
||||
/* get lowest 20MHz sideband of a given chspec
|
||||
* (works with 20, 40, 80)
|
||||
*/
|
||||
#define CH_FIRST_20_SB(chspec) ((uint8) (\
|
||||
CHSPEC_IS80(chspec) ? LL_20_SB(CHSPEC_CHANNEL(chspec)) : (\
|
||||
CHSPEC_IS40(chspec) ? LOWER_20_SB(CHSPEC_CHANNEL(chspec)) : \
|
||||
CHSPEC_CHANNEL(chspec))))
|
||||
/* get upper most 20MHz sideband of a given chspec
|
||||
* (works with 20, 40, 80, 160, 80p80)
|
||||
*/
|
||||
#define CH_LAST_20_SB(chspec) ((uint8) (\
|
||||
CHSPEC_IS80(chspec) ? UU_20_SB(CHSPEC_CHANNEL(chspec)) : (\
|
||||
CHSPEC_IS40(chspec) ? UPPER_20_SB(CHSPEC_CHANNEL(chspec)) : \
|
||||
CHSPEC_CHANNEL(chspec))))
|
||||
|
||||
/* call this with chspec and a valid 20MHz sideband of this channel to get the next 20MHz sideband
|
||||
* (works with 20, 40, 80, 160, 80p80)
|
||||
* resolves to 0 if called with upper most channel
|
||||
*/
|
||||
#define CH_NEXT_20_SB(chspec, channel) ((uint8) (\
|
||||
((uint8) ((channel) + CH_20MHZ_APART) > CH_LAST_20_SB(chspec) ? 0 : \
|
||||
((channel) + CH_20MHZ_APART))))
|
||||
|
||||
#endif /* WL11AC_80P80, WL11AC_160 */
|
||||
|
||||
/* Iterator for 20MHz side bands of a chanspec: (chanspec_t chspec, uint8 channel)
|
||||
* 'chspec' chanspec_t of interest (used in loop, better to pass a resolved value than a macro)
|
||||
* 'channel' must be a variable (not an expression).
|
||||
*/
|
||||
#define FOREACH_20_SB(chspec, channel) \
|
||||
for (channel = CH_FIRST_20_SB(chspec); channel; \
|
||||
channel = CH_NEXT_20_SB((chspec), channel))
|
||||
|
||||
/* Uses iterator to populate array with all side bands involved (sorted lower to upper).
|
||||
* 'chspec' chanspec_t of interest
|
||||
* 'psb' pointer to uint8 array of enough size to hold all side bands for the given chspec
|
||||
*/
|
||||
#define GET_ALL_SB(chspec, psb) do { \
|
||||
uint8 channel, idx = 0; \
|
||||
chanspec_t chspec_local = chspec; \
|
||||
FOREACH_20_SB(chspec_local, channel) \
|
||||
(psb)[idx++] = channel; \
|
||||
} while (0)
|
||||
|
||||
/* given a chanspec of any bw, tests if primary20 SB is in lower 20, 40, 80 respectively */
|
||||
#define IS_CTL_IN_L20(chspec) !((chspec) & WL_CHANSPEC_CTL_SB_U) /* CTL SB is in low 20 of any 40 */
|
||||
#define IS_CTL_IN_L40(chspec) !((chspec) & WL_CHANSPEC_CTL_SB_UL) /* in low 40 of any 80 */
|
||||
#define IS_CTL_IN_L80(chspec) !((chspec) & WL_CHANSPEC_CTL_SB_ULL) /* in low 80 of 80p80/160 */
|
||||
|
||||
#endif /* !WL11N_20MHZONLY */
|
||||
|
||||
/* ULB introduced macros. Remove once ULB is cleaned from phy code */
|
||||
#define CHSPEC_IS2P5(chspec) 0
|
||||
#define CHSPEC_IS5(chspec) 0
|
||||
#define CHSPEC_IS10(chspec) 0
|
||||
#define CHSPEC_ISLE20(chspec) (CHSPEC_IS20(chspec))
|
||||
#define CHSPEC_BW_LE20(chspec) (CHSPEC_IS20(chspec))
|
||||
|
||||
#define BW_LE40(bw) ((bw) == WL_CHANSPEC_BW_20 || ((bw) == WL_CHANSPEC_BW_40))
|
||||
#define BW_LE80(bw) (BW_LE40(bw) || ((bw) == WL_CHANSPEC_BW_80))
|
||||
#define BW_LE160(bw) (BW_LE80(bw) || ((bw) == WL_CHANSPEC_BW_160))
|
||||
|
||||
#define CHSPEC_IS5G(chspec) (((chspec) & WL_CHANSPEC_BAND_MASK) == WL_CHANSPEC_BAND_5G)
|
||||
#define CHSPEC_IS2G(chspec) (((chspec) & WL_CHANSPEC_BAND_MASK) == WL_CHANSPEC_BAND_2G)
|
||||
#define CHSPEC_SB_UPPER(chspec) \
|
||||
((((chspec) & WL_CHANSPEC_CTL_SB_MASK) == WL_CHANSPEC_CTL_SB_UPPER) && \
|
||||
(((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_40))
|
||||
#define CHSPEC_SB_LOWER(chspec) \
|
||||
((((chspec) & WL_CHANSPEC_CTL_SB_MASK) == WL_CHANSPEC_CTL_SB_LOWER) && \
|
||||
(((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_40))
|
||||
#define CHSPEC2WLC_BAND(chspec) (CHSPEC_IS5G(chspec) ? WLC_BAND_5G : WLC_BAND_2G)
|
||||
|
||||
/**
|
||||
* Number of chars needed for wf_chspec_ntoa() destination character buffer.
|
||||
*/
|
||||
#define CHANSPEC_STR_LEN 20
|
||||
|
||||
/*
|
||||
* This function returns TRUE if both the chanspec can co-exist in PHY.
|
||||
* Addition to primary20 channel, the function checks for side band for 2g 40 channels
|
||||
*/
|
||||
extern bool wf_chspec_coexist(chanspec_t chspec1, chanspec_t chspec2);
|
||||
|
||||
#define CHSPEC_IS_BW_160_WIDE(chspec) (CHSPEC_BW(chspec) == WL_CHANSPEC_BW_160 ||\
|
||||
CHSPEC_BW(chspec) == WL_CHANSPEC_BW_8080)
|
||||
|
||||
/* BW inequality comparisons, LE (<=), GE (>=), LT (<), GT (>), comparisons can be made
|
||||
* as simple numeric comparisons, with the exception that 160 is the same BW as 80+80,
|
||||
* but have different numeric values; (WL_CHANSPEC_BW_160 < WL_CHANSPEC_BW_8080).
|
||||
*
|
||||
* The LT/LE/GT/GE macros check first checks whether both chspec bandwidth and bw are 160 wide.
|
||||
* If both chspec bandwidth and bw is not 160 wide, then the comparison is made.
|
||||
*/
|
||||
#define CHSPEC_BW_GE(chspec, bw) \
|
||||
((CHSPEC_IS_BW_160_WIDE(chspec) &&\
|
||||
((bw) == WL_CHANSPEC_BW_160 || (bw) == WL_CHANSPEC_BW_8080)) ||\
|
||||
(CHSPEC_BW(chspec) >= (bw)))
|
||||
|
||||
#define CHSPEC_BW_LE(chspec, bw) \
|
||||
((CHSPEC_IS_BW_160_WIDE(chspec) &&\
|
||||
((bw) == WL_CHANSPEC_BW_160 || (bw) == WL_CHANSPEC_BW_8080)) ||\
|
||||
(CHSPEC_BW(chspec) <= (bw)))
|
||||
|
||||
#define CHSPEC_BW_GT(chspec, bw) \
|
||||
(!(CHSPEC_IS_BW_160_WIDE(chspec) &&\
|
||||
((bw) == WL_CHANSPEC_BW_160 || (bw) == WL_CHANSPEC_BW_8080)) &&\
|
||||
(CHSPEC_BW(chspec) > (bw)))
|
||||
|
||||
#define CHSPEC_BW_LT(chspec, bw) \
|
||||
(!(CHSPEC_IS_BW_160_WIDE(chspec) &&\
|
||||
((bw) == WL_CHANSPEC_BW_160 || (bw) == WL_CHANSPEC_BW_8080)) &&\
|
||||
(CHSPEC_BW(chspec) < (bw)))
|
||||
|
||||
/* Legacy Chanspec defines
|
||||
* These are the defines for the previous format of the chanspec_t
|
||||
*/
|
||||
#define WL_LCHANSPEC_CHAN_MASK 0x00ff
|
||||
#define WL_LCHANSPEC_CHAN_SHIFT 0
|
||||
|
||||
#define WL_LCHANSPEC_CTL_SB_MASK 0x0300
|
||||
#define WL_LCHANSPEC_CTL_SB_SHIFT 8
|
||||
#define WL_LCHANSPEC_CTL_SB_LOWER 0x0100
|
||||
#define WL_LCHANSPEC_CTL_SB_UPPER 0x0200
|
||||
#define WL_LCHANSPEC_CTL_SB_NONE 0x0300
|
||||
|
||||
#define WL_LCHANSPEC_BW_MASK 0x0C00
|
||||
#define WL_LCHANSPEC_BW_SHIFT 10
|
||||
#define WL_LCHANSPEC_BW_10 0x0400
|
||||
#define WL_LCHANSPEC_BW_20 0x0800
|
||||
#define WL_LCHANSPEC_BW_40 0x0C00
|
||||
|
||||
#define WL_LCHANSPEC_BAND_MASK 0xf000
|
||||
#define WL_LCHANSPEC_BAND_SHIFT 12
|
||||
#define WL_LCHANSPEC_BAND_5G 0x1000
|
||||
#define WL_LCHANSPEC_BAND_2G 0x2000
|
||||
|
||||
#define LCHSPEC_CHANNEL(chspec) ((uint8)((chspec) & WL_LCHANSPEC_CHAN_MASK))
|
||||
#define LCHSPEC_BAND(chspec) ((chspec) & WL_LCHANSPEC_BAND_MASK)
|
||||
#define LCHSPEC_CTL_SB(chspec) ((chspec) & WL_LCHANSPEC_CTL_SB_MASK)
|
||||
#define LCHSPEC_BW(chspec) ((chspec) & WL_LCHANSPEC_BW_MASK)
|
||||
#define LCHSPEC_IS10(chspec) (((chspec) & WL_LCHANSPEC_BW_MASK) == WL_LCHANSPEC_BW_10)
|
||||
#define LCHSPEC_IS20(chspec) (((chspec) & WL_LCHANSPEC_BW_MASK) == WL_LCHANSPEC_BW_20)
|
||||
#define LCHSPEC_IS40(chspec) (((chspec) & WL_LCHANSPEC_BW_MASK) == WL_LCHANSPEC_BW_40)
|
||||
#define LCHSPEC_IS5G(chspec) (((chspec) & WL_LCHANSPEC_BAND_MASK) == WL_LCHANSPEC_BAND_5G)
|
||||
#define LCHSPEC_IS2G(chspec) (((chspec) & WL_LCHANSPEC_BAND_MASK) == WL_LCHANSPEC_BAND_2G)
|
||||
|
||||
#define LCHSPEC_SB_UPPER(chspec) \
|
||||
((((chspec) & WL_LCHANSPEC_CTL_SB_MASK) == WL_LCHANSPEC_CTL_SB_UPPER) && \
|
||||
(((chspec) & WL_LCHANSPEC_BW_MASK) == WL_LCHANSPEC_BW_40))
|
||||
#define LCHSPEC_SB_LOWER(chspec) \
|
||||
((((chspec) & WL_LCHANSPEC_CTL_SB_MASK) == WL_LCHANSPEC_CTL_SB_LOWER) && \
|
||||
(((chspec) & WL_LCHANSPEC_BW_MASK) == WL_LCHANSPEC_BW_40))
|
||||
|
||||
#define LCHSPEC_CREATE(chan, band, bw, sb) ((uint16)((chan) | (sb) | (bw) | (band)))
|
||||
|
||||
#define CH20MHZ_LCHSPEC(channel) \
|
||||
(chanspec_t)((chanspec_t)(channel) | WL_LCHANSPEC_BW_20 | \
|
||||
WL_LCHANSPEC_CTL_SB_NONE | (((channel) <= CH_MAX_2G_CHANNEL) ? \
|
||||
WL_LCHANSPEC_BAND_2G : WL_LCHANSPEC_BAND_5G))
|
||||
|
||||
#define GET_ALL_EXT wf_get_all_ext
|
||||
|
||||
/*
|
||||
* WF_CHAN_FACTOR_* constants are used to calculate channel frequency
|
||||
* given a channel number.
|
||||
* chan_freq = chan_factor * 500Mhz + chan_number * 5
|
||||
*/
|
||||
|
||||
/**
|
||||
* Channel Factor for the starting frequence of 2.4 GHz channels.
|
||||
* The value corresponds to 2407 MHz.
|
||||
*/
|
||||
#define WF_CHAN_FACTOR_2_4_G 4814 /* 2.4 GHz band, 2407 MHz */
|
||||
|
||||
/**
|
||||
* Channel Factor for the starting frequence of 5 GHz channels.
|
||||
* The value corresponds to 5000 MHz.
|
||||
*/
|
||||
#define WF_CHAN_FACTOR_5_G 10000 /* 5 GHz band, 5000 MHz */
|
||||
|
||||
/**
|
||||
* Channel Factor for the starting frequence of 4.9 GHz channels.
|
||||
* The value corresponds to 4000 MHz.
|
||||
*/
|
||||
#define WF_CHAN_FACTOR_4_G 8000 /* 4.9 GHz band for Japan */
|
||||
|
||||
#define WLC_2G_25MHZ_OFFSET 5 /* 2.4GHz band channel offset */
|
||||
|
||||
/**
|
||||
* No of sub-band vlaue of the specified Mhz chanspec
|
||||
*/
|
||||
#define WF_NUM_SIDEBANDS_40MHZ 2
|
||||
#define WF_NUM_SIDEBANDS_80MHZ 4
|
||||
#define WF_NUM_SIDEBANDS_8080MHZ 4
|
||||
#define WF_NUM_SIDEBANDS_160MHZ 8
|
||||
|
||||
/**
|
||||
* Return the chanspec bandwidth in MHz
|
||||
* Bandwidth of 160 MHz will be returned for 80+80MHz chanspecs.
|
||||
*
|
||||
* @param chspec chanspec_t
|
||||
*
|
||||
* @return bandwidth of chspec in MHz units
|
||||
*/
|
||||
extern uint wf_bw_chspec_to_mhz(chanspec_t chspec);
|
||||
|
||||
/**
|
||||
* Convert chanspec to ascii string
|
||||
*
|
||||
* @param chspec chanspec format
|
||||
* @param buf ascii string of chanspec
|
||||
*
|
||||
* @return pointer to buf with room for at least CHANSPEC_STR_LEN bytes
|
||||
* Original chanspec in case of error
|
||||
*
|
||||
* @see CHANSPEC_STR_LEN
|
||||
*/
|
||||
extern char * wf_chspec_ntoa_ex(chanspec_t chspec, char *buf);
|
||||
|
||||
/**
|
||||
* Convert chanspec to ascii string
|
||||
*
|
||||
* @param chspec chanspec format
|
||||
* @param buf ascii string of chanspec
|
||||
*
|
||||
* @return pointer to buf with room for at least CHANSPEC_STR_LEN bytes
|
||||
* NULL in case of error
|
||||
*
|
||||
* @see CHANSPEC_STR_LEN
|
||||
*/
|
||||
extern char * wf_chspec_ntoa(chanspec_t chspec, char *buf);
|
||||
|
||||
/**
|
||||
* Convert ascii string to chanspec
|
||||
*
|
||||
* @param a pointer to input string
|
||||
*
|
||||
* @return >= 0 if successful or 0 otherwise
|
||||
*/
|
||||
extern chanspec_t wf_chspec_aton(const char *a);
|
||||
|
||||
/**
|
||||
* Verify the chanspec fields are valid.
|
||||
*
|
||||
* Verify the chanspec is using a legal set field values, i.e. that the chanspec
|
||||
* specified a band, bw, primary_sb, and channel and that the combination could be
|
||||
* legal given some set of circumstances.
|
||||
*
|
||||
* @param chanspec input chanspec to verify
|
||||
*
|
||||
* @return TRUE if the chanspec is malformed, FALSE if it looks good.
|
||||
*/
|
||||
extern bool wf_chspec_malformed(chanspec_t chanspec);
|
||||
|
||||
/**
|
||||
* Verify the chanspec specifies a valid channel according to 802.11.
|
||||
*
|
||||
* @param chanspec input chanspec to verify
|
||||
*
|
||||
* @return TRUE if the chanspec is a valid 802.11 channel
|
||||
*/
|
||||
extern bool wf_chspec_valid(chanspec_t chanspec);
|
||||
|
||||
/**
|
||||
* Return the primary 20MHz channel.
|
||||
*
|
||||
* This function returns the channel number of the primary 20MHz channel. For
|
||||
* 20MHz channels this is just the channel number. For 40MHz or wider channels
|
||||
* it is the primary 20MHz channel specified by the chanspec.
|
||||
*
|
||||
* @param chspec input chanspec
|
||||
*
|
||||
* @return Returns the channel number of the primary 20MHz channel
|
||||
*/
|
||||
extern uint8 wf_chspec_primary20_chan(chanspec_t chspec);
|
||||
|
||||
/* alias for old function name */
|
||||
#define wf_chspec_ctlchan(c) wf_chspec_primary20_chan(c)
|
||||
|
||||
/**
|
||||
* Return the bandwidth string.
|
||||
*
|
||||
* This function returns the bandwidth string for the passed chanspec.
|
||||
*
|
||||
* @param chspec input chanspec
|
||||
*
|
||||
* @return Returns the bandwidth string:
|
||||
* "5", "10", "20", "40", "80", "160", "80+80"
|
||||
*/
|
||||
extern const char *wf_chspec_to_bw_str(chanspec_t chspec);
|
||||
|
||||
/**
|
||||
* Create a 20MHz chanspec for the given band.
|
||||
*/
|
||||
chanspec_t wf_create_20MHz_chspec(uint channel, chanspec_band_t band);
|
||||
|
||||
/**
|
||||
* Return the primary 20MHz chanspec.
|
||||
*
|
||||
* This function returns the chanspec of the primary 20MHz channel. For 20MHz
|
||||
* channels this is just the chanspec. For 40MHz or wider channels it is the
|
||||
* chanspec of the primary 20MHZ channel specified by the chanspec.
|
||||
*
|
||||
* @param chspec input chanspec
|
||||
*
|
||||
* @return Returns the chanspec of the primary 20MHz channel
|
||||
*/
|
||||
extern chanspec_t wf_chspec_primary20_chspec(chanspec_t chspec);
|
||||
|
||||
/* alias for old function name */
|
||||
#define wf_chspec_ctlchspec(c) wf_chspec_primary20_chspec(c)
|
||||
|
||||
/**
|
||||
* Return the primary 40MHz chanspec.
|
||||
*
|
||||
* This function returns the chanspec for the primary 40MHz of an 80MHz or wider channel.
|
||||
* The primary 20MHz channel of the returned 40MHz chanspec is the same as the primary 20MHz
|
||||
* channel of the input chanspec.
|
||||
*/
|
||||
extern chanspec_t wf_chspec_primary40_chspec(chanspec_t chspec);
|
||||
|
||||
/*
|
||||
* Return the channel number for a given frequency and base frequency.
|
||||
* The returned channel number is relative to the given base frequency.
|
||||
* If the given base frequency is zero, a base frequency of 5 GHz is assumed for
|
||||
* frequencies from 5 - 6 GHz, and 2.407 GHz is assumed for 2.4 - 2.5 GHz.
|
||||
*
|
||||
* Frequency is specified in MHz.
|
||||
* The base frequency is specified as (start_factor * 500 kHz).
|
||||
* Constants WF_CHAN_FACTOR_2_4_G, WF_CHAN_FACTOR_5_G are defined for
|
||||
* 2.4 GHz and 5 GHz bands.
|
||||
*
|
||||
* The returned channel will be in the range [1, 14] in the 2.4 GHz band
|
||||
* and [0, 200] otherwise.
|
||||
* -1 is returned if the start_factor is WF_CHAN_FACTOR_2_4_G and the
|
||||
* frequency is not a 2.4 GHz channel, or if the frequency is not and even
|
||||
* multiple of 5 MHz from the base frequency to the base plus 1 GHz.
|
||||
*
|
||||
* Reference 802.11-2016, section 17.3.8.3 and section 16.3.6.3
|
||||
*
|
||||
* @param freq frequency in MHz
|
||||
* @param start_factor base frequency in 500 kHz units, e.g. 10000 for 5 GHz
|
||||
*
|
||||
* @return Returns a channel number
|
||||
*
|
||||
* @see WF_CHAN_FACTOR_2_4_G
|
||||
* @see WF_CHAN_FACTOR_5_G
|
||||
*/
|
||||
extern int wf_mhz2channel(uint freq, uint start_factor);
|
||||
|
||||
/**
|
||||
* Return the center frequency in MHz of the given channel and base frequency.
|
||||
*
|
||||
* Return the center frequency in MHz of the given channel and base frequency.
|
||||
* The channel number is interpreted relative to the given base frequency.
|
||||
*
|
||||
* The valid channel range is [1, 14] in the 2.4 GHz band and [0, 200] otherwise.
|
||||
* The base frequency is specified as (start_factor * 500 kHz).
|
||||
* Constants WF_CHAN_FACTOR_2_4_G, WF_CHAN_FACTOR_5_G are defined for
|
||||
* 2.4 GHz and 5 GHz bands.
|
||||
* The channel range of [1, 14] is only checked for a start_factor of
|
||||
* WF_CHAN_FACTOR_2_4_G (4814).
|
||||
* Odd start_factors produce channels on .5 MHz boundaries, in which case
|
||||
* the answer is rounded down to an integral MHz.
|
||||
* -1 is returned for an out of range channel.
|
||||
*
|
||||
* Reference 802.11-2016, section 17.3.8.3 and section 16.3.6.3
|
||||
*
|
||||
* @param channel input channel number
|
||||
* @param start_factor base frequency in 500 kHz units, e.g. 10000 for 5 GHz
|
||||
*
|
||||
* @return Returns a frequency in MHz
|
||||
*
|
||||
* @see WF_CHAN_FACTOR_2_4_G
|
||||
* @see WF_CHAN_FACTOR_5_G
|
||||
*/
|
||||
extern int wf_channel2mhz(uint channel, uint start_factor);
|
||||
|
||||
/**
|
||||
* Returns the chanspec 80Mhz channel corresponding to the following input
|
||||
* parameters
|
||||
*
|
||||
* primary_channel - primary 20Mhz channel
|
||||
* center_channel - center frequecny of the 80Mhz channel
|
||||
*
|
||||
* The center_channel can be one of {42, 58, 106, 122, 138, 155}
|
||||
*
|
||||
* returns INVCHANSPEC in case of error
|
||||
*/
|
||||
extern chanspec_t wf_chspec_80(uint8 center_channel, uint8 primary_channel);
|
||||
|
||||
/**
|
||||
* Convert ctl chan and bw to chanspec
|
||||
*
|
||||
* @param ctl_ch channel
|
||||
* @param bw bandwidth
|
||||
*
|
||||
* @return > 0 if successful or 0 otherwise
|
||||
*
|
||||
*/
|
||||
extern uint16 wf_channel2chspec(uint ctl_ch, uint bw);
|
||||
|
||||
extern uint wf_channel2freq(uint channel);
|
||||
extern uint wf_freq2channel(uint freq);
|
||||
|
||||
/*
|
||||
* Returns the 80+80 MHz chanspec corresponding to the following input parameters
|
||||
*
|
||||
* primary_20mhz - Primary 20 MHz channel
|
||||
* chan0_80MHz - center channel number of one frequency segment
|
||||
* chan1_80MHz - center channel number of the other frequency segment
|
||||
*
|
||||
* Parameters chan0_80MHz and chan1_80MHz are channel numbers in {42, 58, 106, 122, 138, 155}.
|
||||
* The primary channel must be contained in one of the 80MHz channels. This routine
|
||||
* will determine which frequency segment is the primary 80 MHz segment.
|
||||
*
|
||||
* Returns INVCHANSPEC in case of error.
|
||||
*
|
||||
* Refer to 802.11-2016 section 22.3.14 "Channelization".
|
||||
*/
|
||||
extern chanspec_t wf_chspec_get8080_chspec(uint8 primary_20mhz,
|
||||
uint8 chan0_80Mhz, uint8 chan1_80Mhz);
|
||||
|
||||
/**
|
||||
* Returns the center channel of the primary 80 MHz sub-band of the provided chanspec
|
||||
*
|
||||
* @param chspec input chanspec
|
||||
*
|
||||
* @return center channel number of the primary 80MHz sub-band of the input.
|
||||
* Will return the center channel of an input 80MHz chspec.
|
||||
* Will return INVCHANNEL if the chspec is malformed or less than 80MHz bw.
|
||||
*/
|
||||
extern uint8 wf_chspec_primary80_channel(chanspec_t chanspec);
|
||||
|
||||
/**
|
||||
* Returns the center channel of the secondary 80 MHz sub-band of the provided chanspec
|
||||
*
|
||||
* @param chspec input chanspec
|
||||
*
|
||||
* @return center channel number of the secondary 80MHz sub-band of the input.
|
||||
* Will return INVCHANNEL if the chspec is malformed or bw is not greater than 80MHz.
|
||||
*/
|
||||
extern uint8 wf_chspec_secondary80_channel(chanspec_t chanspec);
|
||||
|
||||
/**
|
||||
* Returns the chanspec for the primary 80MHz sub-band of an 160MHz or 80+80 channel
|
||||
*
|
||||
* @param chspec input chanspec
|
||||
*
|
||||
* @return An 80MHz chanspec describing the primary 80MHz sub-band of the input.
|
||||
* Will return an input 80MHz chspec as is.
|
||||
* Will return INVCHANSPEC if the chspec is malformed or less than 80MHz bw.
|
||||
*/
|
||||
extern chanspec_t wf_chspec_primary80_chspec(chanspec_t chspec);
|
||||
|
||||
/**
|
||||
* Returns the chanspec for the secondary 80MHz sub-band of an 160MHz or 80+80 channel
|
||||
* The sideband in the chanspec is always set to WL_CHANSPEC_CTL_SB_LL since this sub-band
|
||||
* does not contain the primary 20MHz channel.
|
||||
*
|
||||
* @param chspec input chanspec
|
||||
*
|
||||
* @return An 80MHz chanspec describing the secondary 80MHz sub-band of the input.
|
||||
* Will return INVCHANSPEC if the chspec is malformed or bw is not greater than 80MHz.
|
||||
*/
|
||||
extern chanspec_t wf_chspec_secondary80_chspec(chanspec_t chspec);
|
||||
|
||||
/*
|
||||
* For 160MHz or 80P80 chanspec, set ch[0]/ch[1] to be the low/high 80 Mhz channels
|
||||
*
|
||||
* For 20/40/80MHz chanspec, set ch[0] to be the center freq, and chan[1]=-1
|
||||
*/
|
||||
extern void wf_chspec_get_80p80_channels(chanspec_t chspec, uint8 *ch);
|
||||
|
||||
#ifdef WL11AC_80P80
|
||||
/*
|
||||
* This function returns the centre chanel for the given chanspec.
|
||||
* In case of 80+80 chanspec it returns the primary 80 Mhz centre channel
|
||||
*/
|
||||
extern uint8 wf_chspec_channel(chanspec_t chspec);
|
||||
#endif // endif
|
||||
extern chanspec_t wf_channel_create_chspec_frm_opclass(uint8 opclass, uint8 channel);
|
||||
extern int wf_channel_create_opclass_frm_chspec(chanspec_t chspec);
|
||||
|
||||
/* Populates array with all 20MHz side bands of a given chanspec_t in the following order:
|
||||
* primary20, ext20, two ext40s, four ext80s.
|
||||
* 'chspec' is the chanspec of interest
|
||||
* 'pext' must point to an uint8 array of long enough to hold all side bands of the given chspec
|
||||
*
|
||||
* Works with 20, 40, 80, 80p80 and 160MHz chspec
|
||||
*/
|
||||
|
||||
extern void wf_get_all_ext(chanspec_t chspec, uint8 *chan_ptr);
|
||||
|
||||
/*
|
||||
* Given two chanspecs, returns true if they overlap.
|
||||
* (Overlap: At least one 20MHz subband is common between the two chanspecs provided)
|
||||
*/
|
||||
extern bool wf_chspec_overlap(chanspec_t chspec0, chanspec_t chspec1);
|
||||
|
||||
extern uint8 channel_bw_to_width(chanspec_t chspec);
|
||||
#endif /* _bcmwifi_channels_h_ */
|
||||
@@ -0,0 +1,832 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Indices for 802.11 a/b/g/n/ac 1-3 chain symmetric transmit rates
|
||||
*
|
||||
* Copyright (C) 1999-2019, 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.
|
||||
*
|
||||
* 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: bcmwifi_rates.h 697006 2017-05-01 19:13:40Z $
|
||||
*/
|
||||
|
||||
#ifndef _bcmwifi_rates_h_
|
||||
#define _bcmwifi_rates_h_
|
||||
|
||||
#include <typedefs.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#define WL_RATESET_SZ_DSSS 4
|
||||
#define WL_RATESET_SZ_OFDM 8
|
||||
#define WL_RATESET_SZ_VHT_MCS 10
|
||||
#define WL_RATESET_SZ_VHT_MCS_P 12 /* 10 VHT rates + 2 proprietary rates */
|
||||
#define WL_RATESET_SZ_HE_MCS 12 /* 12 HE rates (mcs 0-11) */
|
||||
|
||||
#define WL_RATESET_SZ_HT_MCS 8
|
||||
|
||||
#define WL_RATESET_SZ_HT_IOCTL 8 /* MAC histogram, compatibility with wl utility */
|
||||
|
||||
#define WL_TX_CHAINS_MAX 4
|
||||
|
||||
#define WL_RATE_DISABLED (-128) /* Power value corresponding to unsupported rate */
|
||||
|
||||
/* Transmit channel bandwidths */
|
||||
typedef enum wl_tx_bw {
|
||||
WL_TX_BW_20,
|
||||
WL_TX_BW_40,
|
||||
WL_TX_BW_80,
|
||||
WL_TX_BW_20IN40,
|
||||
WL_TX_BW_20IN80,
|
||||
WL_TX_BW_40IN80,
|
||||
WL_TX_BW_160,
|
||||
WL_TX_BW_20IN160,
|
||||
WL_TX_BW_40IN160,
|
||||
WL_TX_BW_80IN160,
|
||||
WL_TX_BW_ALL,
|
||||
WL_TX_BW_8080,
|
||||
WL_TX_BW_8080CHAN2,
|
||||
WL_TX_BW_20IN8080,
|
||||
WL_TX_BW_40IN8080,
|
||||
WL_TX_BW_80IN8080,
|
||||
WL_TX_BW_2P5,
|
||||
WL_TX_BW_5,
|
||||
WL_TX_BW_10
|
||||
} wl_tx_bw_t;
|
||||
|
||||
/*
|
||||
* Transmit modes.
|
||||
* Not all modes are listed here, only those required for disambiguation. e.g. SPEXP is not listed
|
||||
*/
|
||||
typedef enum wl_tx_mode {
|
||||
WL_TX_MODE_NONE,
|
||||
WL_TX_MODE_STBC,
|
||||
WL_TX_MODE_CDD,
|
||||
WL_TX_MODE_TXBF,
|
||||
WL_NUM_TX_MODES
|
||||
} wl_tx_mode_t;
|
||||
|
||||
/* Number of transmit chains */
|
||||
typedef enum wl_tx_chains {
|
||||
WL_TX_CHAINS_1 = 1,
|
||||
WL_TX_CHAINS_2,
|
||||
WL_TX_CHAINS_3,
|
||||
WL_TX_CHAINS_4
|
||||
} wl_tx_chains_t;
|
||||
|
||||
/* Number of transmit streams */
|
||||
typedef enum wl_tx_nss {
|
||||
WL_TX_NSS_1 = 1,
|
||||
WL_TX_NSS_2,
|
||||
WL_TX_NSS_3,
|
||||
WL_TX_NSS_4
|
||||
} wl_tx_nss_t;
|
||||
|
||||
/* This enum maps each rate to a CLM index */
|
||||
|
||||
typedef enum clm_rates {
|
||||
/************
|
||||
* 1 chain *
|
||||
************
|
||||
*/
|
||||
|
||||
/* 1 Stream */
|
||||
WL_RATE_1X1_DSSS_1 = 0,
|
||||
WL_RATE_1X1_DSSS_2 = 1,
|
||||
WL_RATE_1X1_DSSS_5_5 = 2,
|
||||
WL_RATE_1X1_DSSS_11 = 3,
|
||||
|
||||
WL_RATE_1X1_OFDM_6 = 4,
|
||||
WL_RATE_1X1_OFDM_9 = 5,
|
||||
WL_RATE_1X1_OFDM_12 = 6,
|
||||
WL_RATE_1X1_OFDM_18 = 7,
|
||||
WL_RATE_1X1_OFDM_24 = 8,
|
||||
WL_RATE_1X1_OFDM_36 = 9,
|
||||
WL_RATE_1X1_OFDM_48 = 10,
|
||||
WL_RATE_1X1_OFDM_54 = 11,
|
||||
|
||||
WL_RATE_1X1_MCS0 = 12,
|
||||
WL_RATE_1X1_MCS1 = 13,
|
||||
WL_RATE_1X1_MCS2 = 14,
|
||||
WL_RATE_1X1_MCS3 = 15,
|
||||
WL_RATE_1X1_MCS4 = 16,
|
||||
WL_RATE_1X1_MCS5 = 17,
|
||||
WL_RATE_1X1_MCS6 = 18,
|
||||
WL_RATE_1X1_MCS7 = 19,
|
||||
WL_RATE_P_1X1_MCS87 = 20,
|
||||
WL_RATE_P_1X1_MCS88 = 21,
|
||||
|
||||
WL_RATE_1X1_VHT0SS1 = 12,
|
||||
WL_RATE_1X1_VHT1SS1 = 13,
|
||||
WL_RATE_1X1_VHT2SS1 = 14,
|
||||
WL_RATE_1X1_VHT3SS1 = 15,
|
||||
WL_RATE_1X1_VHT4SS1 = 16,
|
||||
WL_RATE_1X1_VHT5SS1 = 17,
|
||||
WL_RATE_1X1_VHT6SS1 = 18,
|
||||
WL_RATE_1X1_VHT7SS1 = 19,
|
||||
WL_RATE_1X1_VHT8SS1 = 20,
|
||||
WL_RATE_1X1_VHT9SS1 = 21,
|
||||
WL_RATE_P_1X1_VHT10SS1 = 22,
|
||||
WL_RATE_P_1X1_VHT11SS1 = 23,
|
||||
|
||||
/************
|
||||
* 2 chains *
|
||||
************
|
||||
*/
|
||||
|
||||
/* 1 Stream expanded + 1 */
|
||||
WL_RATE_1X2_DSSS_1 = 24,
|
||||
WL_RATE_1X2_DSSS_2 = 25,
|
||||
WL_RATE_1X2_DSSS_5_5 = 26,
|
||||
WL_RATE_1X2_DSSS_11 = 27,
|
||||
|
||||
WL_RATE_1X2_CDD_OFDM_6 = 28,
|
||||
WL_RATE_1X2_CDD_OFDM_9 = 29,
|
||||
WL_RATE_1X2_CDD_OFDM_12 = 30,
|
||||
WL_RATE_1X2_CDD_OFDM_18 = 31,
|
||||
WL_RATE_1X2_CDD_OFDM_24 = 32,
|
||||
WL_RATE_1X2_CDD_OFDM_36 = 33,
|
||||
WL_RATE_1X2_CDD_OFDM_48 = 34,
|
||||
WL_RATE_1X2_CDD_OFDM_54 = 35,
|
||||
|
||||
WL_RATE_1X2_CDD_MCS0 = 36,
|
||||
WL_RATE_1X2_CDD_MCS1 = 37,
|
||||
WL_RATE_1X2_CDD_MCS2 = 38,
|
||||
WL_RATE_1X2_CDD_MCS3 = 39,
|
||||
WL_RATE_1X2_CDD_MCS4 = 40,
|
||||
WL_RATE_1X2_CDD_MCS5 = 41,
|
||||
WL_RATE_1X2_CDD_MCS6 = 42,
|
||||
WL_RATE_1X2_CDD_MCS7 = 43,
|
||||
WL_RATE_P_1X2_CDD_MCS87 = 44,
|
||||
WL_RATE_P_1X2_CDD_MCS88 = 45,
|
||||
|
||||
WL_RATE_1X2_VHT0SS1 = 36,
|
||||
WL_RATE_1X2_VHT1SS1 = 37,
|
||||
WL_RATE_1X2_VHT2SS1 = 38,
|
||||
WL_RATE_1X2_VHT3SS1 = 39,
|
||||
WL_RATE_1X2_VHT4SS1 = 40,
|
||||
WL_RATE_1X2_VHT5SS1 = 41,
|
||||
WL_RATE_1X2_VHT6SS1 = 42,
|
||||
WL_RATE_1X2_VHT7SS1 = 43,
|
||||
WL_RATE_1X2_VHT8SS1 = 44,
|
||||
WL_RATE_1X2_VHT9SS1 = 45,
|
||||
WL_RATE_P_1X2_VHT10SS1 = 46,
|
||||
WL_RATE_P_1X2_VHT11SS1 = 47,
|
||||
|
||||
/* 2 Streams */
|
||||
WL_RATE_2X2_STBC_MCS0 = 48,
|
||||
WL_RATE_2X2_STBC_MCS1 = 49,
|
||||
WL_RATE_2X2_STBC_MCS2 = 50,
|
||||
WL_RATE_2X2_STBC_MCS3 = 51,
|
||||
WL_RATE_2X2_STBC_MCS4 = 52,
|
||||
WL_RATE_2X2_STBC_MCS5 = 53,
|
||||
WL_RATE_2X2_STBC_MCS6 = 54,
|
||||
WL_RATE_2X2_STBC_MCS7 = 55,
|
||||
WL_RATE_P_2X2_STBC_MCS87 = 56,
|
||||
WL_RATE_P_2X2_STBC_MCS88 = 57,
|
||||
|
||||
WL_RATE_2X2_STBC_VHT0SS1 = 48,
|
||||
WL_RATE_2X2_STBC_VHT1SS1 = 49,
|
||||
WL_RATE_2X2_STBC_VHT2SS1 = 50,
|
||||
WL_RATE_2X2_STBC_VHT3SS1 = 51,
|
||||
WL_RATE_2X2_STBC_VHT4SS1 = 52,
|
||||
WL_RATE_2X2_STBC_VHT5SS1 = 53,
|
||||
WL_RATE_2X2_STBC_VHT6SS1 = 54,
|
||||
WL_RATE_2X2_STBC_VHT7SS1 = 55,
|
||||
WL_RATE_2X2_STBC_VHT8SS1 = 56,
|
||||
WL_RATE_2X2_STBC_VHT9SS1 = 57,
|
||||
WL_RATE_P_2X2_STBC_VHT10SS1 = 58,
|
||||
WL_RATE_P_2X2_STBC_VHT11SS1 = 59,
|
||||
|
||||
WL_RATE_2X2_SDM_MCS8 = 60,
|
||||
WL_RATE_2X2_SDM_MCS9 = 61,
|
||||
WL_RATE_2X2_SDM_MCS10 = 62,
|
||||
WL_RATE_2X2_SDM_MCS11 = 63,
|
||||
WL_RATE_2X2_SDM_MCS12 = 64,
|
||||
WL_RATE_2X2_SDM_MCS13 = 65,
|
||||
WL_RATE_2X2_SDM_MCS14 = 66,
|
||||
WL_RATE_2X2_SDM_MCS15 = 67,
|
||||
WL_RATE_P_2X2_SDM_MCS99 = 68,
|
||||
WL_RATE_P_2X2_SDM_MCS100 = 69,
|
||||
|
||||
WL_RATE_2X2_VHT0SS2 = 60,
|
||||
WL_RATE_2X2_VHT1SS2 = 61,
|
||||
WL_RATE_2X2_VHT2SS2 = 62,
|
||||
WL_RATE_2X2_VHT3SS2 = 63,
|
||||
WL_RATE_2X2_VHT4SS2 = 64,
|
||||
WL_RATE_2X2_VHT5SS2 = 65,
|
||||
WL_RATE_2X2_VHT6SS2 = 66,
|
||||
WL_RATE_2X2_VHT7SS2 = 67,
|
||||
WL_RATE_2X2_VHT8SS2 = 68,
|
||||
WL_RATE_2X2_VHT9SS2 = 69,
|
||||
WL_RATE_P_2X2_VHT10SS2 = 70,
|
||||
WL_RATE_P_2X2_VHT11SS2 = 71,
|
||||
|
||||
/****************************
|
||||
* TX Beamforming, 2 chains *
|
||||
****************************
|
||||
*/
|
||||
|
||||
/* 1 Stream expanded + 1 */
|
||||
WL_RATE_1X2_TXBF_OFDM_6 = 72,
|
||||
WL_RATE_1X2_TXBF_OFDM_9 = 73,
|
||||
WL_RATE_1X2_TXBF_OFDM_12 = 74,
|
||||
WL_RATE_1X2_TXBF_OFDM_18 = 75,
|
||||
WL_RATE_1X2_TXBF_OFDM_24 = 76,
|
||||
WL_RATE_1X2_TXBF_OFDM_36 = 77,
|
||||
WL_RATE_1X2_TXBF_OFDM_48 = 78,
|
||||
WL_RATE_1X2_TXBF_OFDM_54 = 79,
|
||||
|
||||
WL_RATE_1X2_TXBF_MCS0 = 80,
|
||||
WL_RATE_1X2_TXBF_MCS1 = 81,
|
||||
WL_RATE_1X2_TXBF_MCS2 = 82,
|
||||
WL_RATE_1X2_TXBF_MCS3 = 83,
|
||||
WL_RATE_1X2_TXBF_MCS4 = 84,
|
||||
WL_RATE_1X2_TXBF_MCS5 = 85,
|
||||
WL_RATE_1X2_TXBF_MCS6 = 86,
|
||||
WL_RATE_1X2_TXBF_MCS7 = 87,
|
||||
WL_RATE_P_1X2_TXBF_MCS87 = 88,
|
||||
WL_RATE_P_1X2_TXBF_MCS88 = 89,
|
||||
|
||||
WL_RATE_1X2_TXBF_VHT0SS1 = 80,
|
||||
WL_RATE_1X2_TXBF_VHT1SS1 = 81,
|
||||
WL_RATE_1X2_TXBF_VHT2SS1 = 82,
|
||||
WL_RATE_1X2_TXBF_VHT3SS1 = 83,
|
||||
WL_RATE_1X2_TXBF_VHT4SS1 = 84,
|
||||
WL_RATE_1X2_TXBF_VHT5SS1 = 85,
|
||||
WL_RATE_1X2_TXBF_VHT6SS1 = 86,
|
||||
WL_RATE_1X2_TXBF_VHT7SS1 = 87,
|
||||
WL_RATE_1X2_TXBF_VHT8SS1 = 88,
|
||||
WL_RATE_1X2_TXBF_VHT9SS1 = 89,
|
||||
WL_RATE_P_1X2_TXBF_VHT10SS1 = 90,
|
||||
WL_RATE_P_1X2_TXBF_VHT11SS1 = 91,
|
||||
|
||||
/* 2 Streams */
|
||||
WL_RATE_2X2_TXBF_SDM_MCS8 = 92,
|
||||
WL_RATE_2X2_TXBF_SDM_MCS9 = 93,
|
||||
WL_RATE_2X2_TXBF_SDM_MCS10 = 94,
|
||||
WL_RATE_2X2_TXBF_SDM_MCS11 = 95,
|
||||
WL_RATE_2X2_TXBF_SDM_MCS12 = 96,
|
||||
WL_RATE_2X2_TXBF_SDM_MCS13 = 97,
|
||||
WL_RATE_2X2_TXBF_SDM_MCS14 = 98,
|
||||
WL_RATE_2X2_TXBF_SDM_MCS15 = 99,
|
||||
WL_RATE_P_2X2_TXBF_SDM_MCS99 = 100,
|
||||
WL_RATE_P_2X2_TXBF_SDM_MCS100 = 101,
|
||||
|
||||
WL_RATE_2X2_TXBF_VHT0SS2 = 92,
|
||||
WL_RATE_2X2_TXBF_VHT1SS2 = 93,
|
||||
WL_RATE_2X2_TXBF_VHT2SS2 = 94,
|
||||
WL_RATE_2X2_TXBF_VHT3SS2 = 95,
|
||||
WL_RATE_2X2_TXBF_VHT4SS2 = 96,
|
||||
WL_RATE_2X2_TXBF_VHT5SS2 = 97,
|
||||
WL_RATE_2X2_TXBF_VHT6SS2 = 98,
|
||||
WL_RATE_2X2_TXBF_VHT7SS2 = 99,
|
||||
WL_RATE_2X2_TXBF_VHT8SS2 = 100,
|
||||
WL_RATE_2X2_TXBF_VHT9SS2 = 101,
|
||||
WL_RATE_P_2X2_TXBF_VHT10SS2 = 102,
|
||||
WL_RATE_P_2X2_TXBF_VHT11SS2 = 103,
|
||||
|
||||
/************
|
||||
* 3 chains *
|
||||
************
|
||||
*/
|
||||
|
||||
/* 1 Stream expanded + 2 */
|
||||
WL_RATE_1X3_DSSS_1 = 104,
|
||||
WL_RATE_1X3_DSSS_2 = 105,
|
||||
WL_RATE_1X3_DSSS_5_5 = 106,
|
||||
WL_RATE_1X3_DSSS_11 = 107,
|
||||
|
||||
WL_RATE_1X3_CDD_OFDM_6 = 108,
|
||||
WL_RATE_1X3_CDD_OFDM_9 = 109,
|
||||
WL_RATE_1X3_CDD_OFDM_12 = 110,
|
||||
WL_RATE_1X3_CDD_OFDM_18 = 111,
|
||||
WL_RATE_1X3_CDD_OFDM_24 = 112,
|
||||
WL_RATE_1X3_CDD_OFDM_36 = 113,
|
||||
WL_RATE_1X3_CDD_OFDM_48 = 114,
|
||||
WL_RATE_1X3_CDD_OFDM_54 = 115,
|
||||
|
||||
WL_RATE_1X3_CDD_MCS0 = 116,
|
||||
WL_RATE_1X3_CDD_MCS1 = 117,
|
||||
WL_RATE_1X3_CDD_MCS2 = 118,
|
||||
WL_RATE_1X3_CDD_MCS3 = 119,
|
||||
WL_RATE_1X3_CDD_MCS4 = 120,
|
||||
WL_RATE_1X3_CDD_MCS5 = 121,
|
||||
WL_RATE_1X3_CDD_MCS6 = 122,
|
||||
WL_RATE_1X3_CDD_MCS7 = 123,
|
||||
WL_RATE_P_1X3_CDD_MCS87 = 124,
|
||||
WL_RATE_P_1X3_CDD_MCS88 = 125,
|
||||
|
||||
WL_RATE_1X3_VHT0SS1 = 116,
|
||||
WL_RATE_1X3_VHT1SS1 = 117,
|
||||
WL_RATE_1X3_VHT2SS1 = 118,
|
||||
WL_RATE_1X3_VHT3SS1 = 119,
|
||||
WL_RATE_1X3_VHT4SS1 = 120,
|
||||
WL_RATE_1X3_VHT5SS1 = 121,
|
||||
WL_RATE_1X3_VHT6SS1 = 122,
|
||||
WL_RATE_1X3_VHT7SS1 = 123,
|
||||
WL_RATE_1X3_VHT8SS1 = 124,
|
||||
WL_RATE_1X3_VHT9SS1 = 125,
|
||||
WL_RATE_P_1X3_VHT10SS1 = 126,
|
||||
WL_RATE_P_1X3_VHT11SS1 = 127,
|
||||
|
||||
/* 2 Streams expanded + 1 */
|
||||
WL_RATE_2X3_STBC_MCS0 = 128,
|
||||
WL_RATE_2X3_STBC_MCS1 = 129,
|
||||
WL_RATE_2X3_STBC_MCS2 = 130,
|
||||
WL_RATE_2X3_STBC_MCS3 = 131,
|
||||
WL_RATE_2X3_STBC_MCS4 = 132,
|
||||
WL_RATE_2X3_STBC_MCS5 = 133,
|
||||
WL_RATE_2X3_STBC_MCS6 = 134,
|
||||
WL_RATE_2X3_STBC_MCS7 = 135,
|
||||
WL_RATE_P_2X3_STBC_MCS87 = 136,
|
||||
WL_RATE_P_2X3_STBC_MCS88 = 137,
|
||||
|
||||
WL_RATE_2X3_STBC_VHT0SS1 = 128,
|
||||
WL_RATE_2X3_STBC_VHT1SS1 = 129,
|
||||
WL_RATE_2X3_STBC_VHT2SS1 = 130,
|
||||
WL_RATE_2X3_STBC_VHT3SS1 = 131,
|
||||
WL_RATE_2X3_STBC_VHT4SS1 = 132,
|
||||
WL_RATE_2X3_STBC_VHT5SS1 = 133,
|
||||
WL_RATE_2X3_STBC_VHT6SS1 = 134,
|
||||
WL_RATE_2X3_STBC_VHT7SS1 = 135,
|
||||
WL_RATE_2X3_STBC_VHT8SS1 = 136,
|
||||
WL_RATE_2X3_STBC_VHT9SS1 = 137,
|
||||
WL_RATE_P_2X3_STBC_VHT10SS1 = 138,
|
||||
WL_RATE_P_2X3_STBC_VHT11SS1 = 139,
|
||||
|
||||
WL_RATE_2X3_SDM_MCS8 = 140,
|
||||
WL_RATE_2X3_SDM_MCS9 = 141,
|
||||
WL_RATE_2X3_SDM_MCS10 = 142,
|
||||
WL_RATE_2X3_SDM_MCS11 = 143,
|
||||
WL_RATE_2X3_SDM_MCS12 = 144,
|
||||
WL_RATE_2X3_SDM_MCS13 = 145,
|
||||
WL_RATE_2X3_SDM_MCS14 = 146,
|
||||
WL_RATE_2X3_SDM_MCS15 = 147,
|
||||
WL_RATE_P_2X3_SDM_MCS99 = 148,
|
||||
WL_RATE_P_2X3_SDM_MCS100 = 149,
|
||||
|
||||
WL_RATE_2X3_VHT0SS2 = 140,
|
||||
WL_RATE_2X3_VHT1SS2 = 141,
|
||||
WL_RATE_2X3_VHT2SS2 = 142,
|
||||
WL_RATE_2X3_VHT3SS2 = 143,
|
||||
WL_RATE_2X3_VHT4SS2 = 144,
|
||||
WL_RATE_2X3_VHT5SS2 = 145,
|
||||
WL_RATE_2X3_VHT6SS2 = 146,
|
||||
WL_RATE_2X3_VHT7SS2 = 147,
|
||||
WL_RATE_2X3_VHT8SS2 = 148,
|
||||
WL_RATE_2X3_VHT9SS2 = 149,
|
||||
WL_RATE_P_2X3_VHT10SS2 = 150,
|
||||
WL_RATE_P_2X3_VHT11SS2 = 151,
|
||||
|
||||
/* 3 Streams */
|
||||
WL_RATE_3X3_SDM_MCS16 = 152,
|
||||
WL_RATE_3X3_SDM_MCS17 = 153,
|
||||
WL_RATE_3X3_SDM_MCS18 = 154,
|
||||
WL_RATE_3X3_SDM_MCS19 = 155,
|
||||
WL_RATE_3X3_SDM_MCS20 = 156,
|
||||
WL_RATE_3X3_SDM_MCS21 = 157,
|
||||
WL_RATE_3X3_SDM_MCS22 = 158,
|
||||
WL_RATE_3X3_SDM_MCS23 = 159,
|
||||
WL_RATE_P_3X3_SDM_MCS101 = 160,
|
||||
WL_RATE_P_3X3_SDM_MCS102 = 161,
|
||||
|
||||
WL_RATE_3X3_VHT0SS3 = 152,
|
||||
WL_RATE_3X3_VHT1SS3 = 153,
|
||||
WL_RATE_3X3_VHT2SS3 = 154,
|
||||
WL_RATE_3X3_VHT3SS3 = 155,
|
||||
WL_RATE_3X3_VHT4SS3 = 156,
|
||||
WL_RATE_3X3_VHT5SS3 = 157,
|
||||
WL_RATE_3X3_VHT6SS3 = 158,
|
||||
WL_RATE_3X3_VHT7SS3 = 159,
|
||||
WL_RATE_3X3_VHT8SS3 = 160,
|
||||
WL_RATE_3X3_VHT9SS3 = 161,
|
||||
WL_RATE_P_3X3_VHT10SS3 = 162,
|
||||
WL_RATE_P_3X3_VHT11SS3 = 163,
|
||||
|
||||
/****************************
|
||||
* TX Beamforming, 3 chains *
|
||||
****************************
|
||||
*/
|
||||
|
||||
/* 1 Stream expanded + 2 */
|
||||
WL_RATE_1X3_TXBF_OFDM_6 = 164,
|
||||
WL_RATE_1X3_TXBF_OFDM_9 = 165,
|
||||
WL_RATE_1X3_TXBF_OFDM_12 = 166,
|
||||
WL_RATE_1X3_TXBF_OFDM_18 = 167,
|
||||
WL_RATE_1X3_TXBF_OFDM_24 = 168,
|
||||
WL_RATE_1X3_TXBF_OFDM_36 = 169,
|
||||
WL_RATE_1X3_TXBF_OFDM_48 = 170,
|
||||
WL_RATE_1X3_TXBF_OFDM_54 = 171,
|
||||
|
||||
WL_RATE_1X3_TXBF_MCS0 = 172,
|
||||
WL_RATE_1X3_TXBF_MCS1 = 173,
|
||||
WL_RATE_1X3_TXBF_MCS2 = 174,
|
||||
WL_RATE_1X3_TXBF_MCS3 = 175,
|
||||
WL_RATE_1X3_TXBF_MCS4 = 176,
|
||||
WL_RATE_1X3_TXBF_MCS5 = 177,
|
||||
WL_RATE_1X3_TXBF_MCS6 = 178,
|
||||
WL_RATE_1X3_TXBF_MCS7 = 179,
|
||||
WL_RATE_P_1X3_TXBF_MCS87 = 180,
|
||||
WL_RATE_P_1X3_TXBF_MCS88 = 181,
|
||||
|
||||
WL_RATE_1X3_TXBF_VHT0SS1 = 172,
|
||||
WL_RATE_1X3_TXBF_VHT1SS1 = 173,
|
||||
WL_RATE_1X3_TXBF_VHT2SS1 = 174,
|
||||
WL_RATE_1X3_TXBF_VHT3SS1 = 175,
|
||||
WL_RATE_1X3_TXBF_VHT4SS1 = 176,
|
||||
WL_RATE_1X3_TXBF_VHT5SS1 = 177,
|
||||
WL_RATE_1X3_TXBF_VHT6SS1 = 178,
|
||||
WL_RATE_1X3_TXBF_VHT7SS1 = 179,
|
||||
WL_RATE_1X3_TXBF_VHT8SS1 = 180,
|
||||
WL_RATE_1X3_TXBF_VHT9SS1 = 181,
|
||||
WL_RATE_P_1X3_TXBF_VHT10SS1 = 182,
|
||||
WL_RATE_P_1X3_TXBF_VHT11SS1 = 183,
|
||||
|
||||
/* 2 Streams expanded + 1 */
|
||||
WL_RATE_2X3_TXBF_SDM_MCS8 = 184,
|
||||
WL_RATE_2X3_TXBF_SDM_MCS9 = 185,
|
||||
WL_RATE_2X3_TXBF_SDM_MCS10 = 186,
|
||||
WL_RATE_2X3_TXBF_SDM_MCS11 = 187,
|
||||
WL_RATE_2X3_TXBF_SDM_MCS12 = 188,
|
||||
WL_RATE_2X3_TXBF_SDM_MCS13 = 189,
|
||||
WL_RATE_2X3_TXBF_SDM_MCS14 = 190,
|
||||
WL_RATE_2X3_TXBF_SDM_MCS15 = 191,
|
||||
WL_RATE_P_2X3_TXBF_SDM_MCS99 = 192,
|
||||
WL_RATE_P_2X3_TXBF_SDM_MCS100 = 193,
|
||||
|
||||
WL_RATE_2X3_TXBF_VHT0SS2 = 184,
|
||||
WL_RATE_2X3_TXBF_VHT1SS2 = 185,
|
||||
WL_RATE_2X3_TXBF_VHT2SS2 = 186,
|
||||
WL_RATE_2X3_TXBF_VHT3SS2 = 187,
|
||||
WL_RATE_2X3_TXBF_VHT4SS2 = 188,
|
||||
WL_RATE_2X3_TXBF_VHT5SS2 = 189,
|
||||
WL_RATE_2X3_TXBF_VHT6SS2 = 190,
|
||||
WL_RATE_2X3_TXBF_VHT7SS2 = 191,
|
||||
WL_RATE_2X3_TXBF_VHT8SS2 = 192,
|
||||
WL_RATE_2X3_TXBF_VHT9SS2 = 193,
|
||||
WL_RATE_P_2X3_TXBF_VHT10SS2 = 194,
|
||||
WL_RATE_P_2X3_TXBF_VHT11SS2 = 195,
|
||||
|
||||
/* 3 Streams */
|
||||
WL_RATE_3X3_TXBF_SDM_MCS16 = 196,
|
||||
WL_RATE_3X3_TXBF_SDM_MCS17 = 197,
|
||||
WL_RATE_3X3_TXBF_SDM_MCS18 = 198,
|
||||
WL_RATE_3X3_TXBF_SDM_MCS19 = 199,
|
||||
WL_RATE_3X3_TXBF_SDM_MCS20 = 200,
|
||||
WL_RATE_3X3_TXBF_SDM_MCS21 = 201,
|
||||
WL_RATE_3X3_TXBF_SDM_MCS22 = 202,
|
||||
WL_RATE_3X3_TXBF_SDM_MCS23 = 203,
|
||||
WL_RATE_P_3X3_TXBF_SDM_MCS101 = 204,
|
||||
WL_RATE_P_3X3_TXBF_SDM_MCS102 = 205,
|
||||
|
||||
WL_RATE_3X3_TXBF_VHT0SS3 = 196,
|
||||
WL_RATE_3X3_TXBF_VHT1SS3 = 197,
|
||||
WL_RATE_3X3_TXBF_VHT2SS3 = 198,
|
||||
WL_RATE_3X3_TXBF_VHT3SS3 = 199,
|
||||
WL_RATE_3X3_TXBF_VHT4SS3 = 200,
|
||||
WL_RATE_3X3_TXBF_VHT5SS3 = 201,
|
||||
WL_RATE_3X3_TXBF_VHT6SS3 = 202,
|
||||
WL_RATE_3X3_TXBF_VHT7SS3 = 203,
|
||||
WL_RATE_3X3_TXBF_VHT8SS3 = 204,
|
||||
WL_RATE_3X3_TXBF_VHT9SS3 = 205,
|
||||
WL_RATE_P_3X3_TXBF_VHT10SS3 = 206,
|
||||
WL_RATE_P_3X3_TXBF_VHT11SS3 = 207,
|
||||
|
||||
/************
|
||||
* 4 chains *
|
||||
************
|
||||
*/
|
||||
|
||||
/* 1 Stream expanded + 3 */
|
||||
WL_RATE_1X4_DSSS_1 = 208,
|
||||
WL_RATE_1X4_DSSS_2 = 209,
|
||||
WL_RATE_1X4_DSSS_5_5 = 210,
|
||||
WL_RATE_1X4_DSSS_11 = 211,
|
||||
|
||||
WL_RATE_1X4_CDD_OFDM_6 = 212,
|
||||
WL_RATE_1X4_CDD_OFDM_9 = 213,
|
||||
WL_RATE_1X4_CDD_OFDM_12 = 214,
|
||||
WL_RATE_1X4_CDD_OFDM_18 = 215,
|
||||
WL_RATE_1X4_CDD_OFDM_24 = 216,
|
||||
WL_RATE_1X4_CDD_OFDM_36 = 217,
|
||||
WL_RATE_1X4_CDD_OFDM_48 = 218,
|
||||
WL_RATE_1X4_CDD_OFDM_54 = 219,
|
||||
|
||||
WL_RATE_1X4_CDD_MCS0 = 220,
|
||||
WL_RATE_1X4_CDD_MCS1 = 221,
|
||||
WL_RATE_1X4_CDD_MCS2 = 222,
|
||||
WL_RATE_1X4_CDD_MCS3 = 223,
|
||||
WL_RATE_1X4_CDD_MCS4 = 224,
|
||||
WL_RATE_1X4_CDD_MCS5 = 225,
|
||||
WL_RATE_1X4_CDD_MCS6 = 226,
|
||||
WL_RATE_1X4_CDD_MCS7 = 227,
|
||||
WL_RATE_P_1X4_CDD_MCS87 = 228,
|
||||
WL_RATE_P_1X4_CDD_MCS88 = 229,
|
||||
|
||||
WL_RATE_1X4_VHT0SS1 = 220,
|
||||
WL_RATE_1X4_VHT1SS1 = 221,
|
||||
WL_RATE_1X4_VHT2SS1 = 222,
|
||||
WL_RATE_1X4_VHT3SS1 = 223,
|
||||
WL_RATE_1X4_VHT4SS1 = 224,
|
||||
WL_RATE_1X4_VHT5SS1 = 225,
|
||||
WL_RATE_1X4_VHT6SS1 = 226,
|
||||
WL_RATE_1X4_VHT7SS1 = 227,
|
||||
WL_RATE_1X4_VHT8SS1 = 228,
|
||||
WL_RATE_1X4_VHT9SS1 = 229,
|
||||
WL_RATE_P_1X4_VHT10SS1 = 230,
|
||||
WL_RATE_P_1X4_VHT11SS1 = 231,
|
||||
|
||||
/* 2 Streams expanded + 2 */
|
||||
WL_RATE_2X4_STBC_MCS0 = 232,
|
||||
WL_RATE_2X4_STBC_MCS1 = 233,
|
||||
WL_RATE_2X4_STBC_MCS2 = 234,
|
||||
WL_RATE_2X4_STBC_MCS3 = 235,
|
||||
WL_RATE_2X4_STBC_MCS4 = 236,
|
||||
WL_RATE_2X4_STBC_MCS5 = 237,
|
||||
WL_RATE_2X4_STBC_MCS6 = 238,
|
||||
WL_RATE_2X4_STBC_MCS7 = 239,
|
||||
WL_RATE_P_2X4_STBC_MCS87 = 240,
|
||||
WL_RATE_P_2X4_STBC_MCS88 = 241,
|
||||
|
||||
WL_RATE_2X4_STBC_VHT0SS1 = 232,
|
||||
WL_RATE_2X4_STBC_VHT1SS1 = 233,
|
||||
WL_RATE_2X4_STBC_VHT2SS1 = 234,
|
||||
WL_RATE_2X4_STBC_VHT3SS1 = 235,
|
||||
WL_RATE_2X4_STBC_VHT4SS1 = 236,
|
||||
WL_RATE_2X4_STBC_VHT5SS1 = 237,
|
||||
WL_RATE_2X4_STBC_VHT6SS1 = 238,
|
||||
WL_RATE_2X4_STBC_VHT7SS1 = 239,
|
||||
WL_RATE_2X4_STBC_VHT8SS1 = 240,
|
||||
WL_RATE_2X4_STBC_VHT9SS1 = 241,
|
||||
WL_RATE_P_2X4_STBC_VHT10SS1 = 242,
|
||||
WL_RATE_P_2X4_STBC_VHT11SS1 = 243,
|
||||
|
||||
WL_RATE_2X4_SDM_MCS8 = 244,
|
||||
WL_RATE_2X4_SDM_MCS9 = 245,
|
||||
WL_RATE_2X4_SDM_MCS10 = 246,
|
||||
WL_RATE_2X4_SDM_MCS11 = 247,
|
||||
WL_RATE_2X4_SDM_MCS12 = 248,
|
||||
WL_RATE_2X4_SDM_MCS13 = 249,
|
||||
WL_RATE_2X4_SDM_MCS14 = 250,
|
||||
WL_RATE_2X4_SDM_MCS15 = 251,
|
||||
WL_RATE_P_2X4_SDM_MCS99 = 252,
|
||||
WL_RATE_P_2X4_SDM_MCS100 = 253,
|
||||
|
||||
WL_RATE_2X4_VHT0SS2 = 244,
|
||||
WL_RATE_2X4_VHT1SS2 = 245,
|
||||
WL_RATE_2X4_VHT2SS2 = 246,
|
||||
WL_RATE_2X4_VHT3SS2 = 247,
|
||||
WL_RATE_2X4_VHT4SS2 = 248,
|
||||
WL_RATE_2X4_VHT5SS2 = 249,
|
||||
WL_RATE_2X4_VHT6SS2 = 250,
|
||||
WL_RATE_2X4_VHT7SS2 = 251,
|
||||
WL_RATE_2X4_VHT8SS2 = 252,
|
||||
WL_RATE_2X4_VHT9SS2 = 253,
|
||||
WL_RATE_P_2X4_VHT10SS2 = 254,
|
||||
WL_RATE_P_2X4_VHT11SS2 = 255,
|
||||
|
||||
/* 3 Streams expanded + 1 */
|
||||
WL_RATE_3X4_SDM_MCS16 = 256,
|
||||
WL_RATE_3X4_SDM_MCS17 = 257,
|
||||
WL_RATE_3X4_SDM_MCS18 = 258,
|
||||
WL_RATE_3X4_SDM_MCS19 = 259,
|
||||
WL_RATE_3X4_SDM_MCS20 = 260,
|
||||
WL_RATE_3X4_SDM_MCS21 = 261,
|
||||
WL_RATE_3X4_SDM_MCS22 = 262,
|
||||
WL_RATE_3X4_SDM_MCS23 = 263,
|
||||
WL_RATE_P_3X4_SDM_MCS101 = 264,
|
||||
WL_RATE_P_3X4_SDM_MCS102 = 265,
|
||||
|
||||
WL_RATE_3X4_VHT0SS3 = 256,
|
||||
WL_RATE_3X4_VHT1SS3 = 257,
|
||||
WL_RATE_3X4_VHT2SS3 = 258,
|
||||
WL_RATE_3X4_VHT3SS3 = 259,
|
||||
WL_RATE_3X4_VHT4SS3 = 260,
|
||||
WL_RATE_3X4_VHT5SS3 = 261,
|
||||
WL_RATE_3X4_VHT6SS3 = 262,
|
||||
WL_RATE_3X4_VHT7SS3 = 263,
|
||||
WL_RATE_3X4_VHT8SS3 = 264,
|
||||
WL_RATE_3X4_VHT9SS3 = 265,
|
||||
WL_RATE_P_3X4_VHT10SS3 = 266,
|
||||
WL_RATE_P_3X4_VHT11SS3 = 267,
|
||||
|
||||
/* 4 Streams */
|
||||
WL_RATE_4X4_SDM_MCS24 = 268,
|
||||
WL_RATE_4X4_SDM_MCS25 = 269,
|
||||
WL_RATE_4X4_SDM_MCS26 = 270,
|
||||
WL_RATE_4X4_SDM_MCS27 = 271,
|
||||
WL_RATE_4X4_SDM_MCS28 = 272,
|
||||
WL_RATE_4X4_SDM_MCS29 = 273,
|
||||
WL_RATE_4X4_SDM_MCS30 = 274,
|
||||
WL_RATE_4X4_SDM_MCS31 = 275,
|
||||
WL_RATE_P_4X4_SDM_MCS103 = 276,
|
||||
WL_RATE_P_4X4_SDM_MCS104 = 277,
|
||||
|
||||
WL_RATE_4X4_VHT0SS4 = 268,
|
||||
WL_RATE_4X4_VHT1SS4 = 269,
|
||||
WL_RATE_4X4_VHT2SS4 = 270,
|
||||
WL_RATE_4X4_VHT3SS4 = 271,
|
||||
WL_RATE_4X4_VHT4SS4 = 272,
|
||||
WL_RATE_4X4_VHT5SS4 = 273,
|
||||
WL_RATE_4X4_VHT6SS4 = 274,
|
||||
WL_RATE_4X4_VHT7SS4 = 275,
|
||||
WL_RATE_4X4_VHT8SS4 = 276,
|
||||
WL_RATE_4X4_VHT9SS4 = 277,
|
||||
WL_RATE_P_4X4_VHT10SS4 = 278,
|
||||
WL_RATE_P_4X4_VHT11SS4 = 279,
|
||||
|
||||
/****************************
|
||||
* TX Beamforming, 4 chains *
|
||||
****************************
|
||||
*/
|
||||
|
||||
/* 1 Stream expanded + 3 */
|
||||
WL_RATE_1X4_TXBF_OFDM_6 = 280,
|
||||
WL_RATE_1X4_TXBF_OFDM_9 = 281,
|
||||
WL_RATE_1X4_TXBF_OFDM_12 = 282,
|
||||
WL_RATE_1X4_TXBF_OFDM_18 = 283,
|
||||
WL_RATE_1X4_TXBF_OFDM_24 = 284,
|
||||
WL_RATE_1X4_TXBF_OFDM_36 = 285,
|
||||
WL_RATE_1X4_TXBF_OFDM_48 = 286,
|
||||
WL_RATE_1X4_TXBF_OFDM_54 = 287,
|
||||
|
||||
WL_RATE_1X4_TXBF_MCS0 = 288,
|
||||
WL_RATE_1X4_TXBF_MCS1 = 289,
|
||||
WL_RATE_1X4_TXBF_MCS2 = 290,
|
||||
WL_RATE_1X4_TXBF_MCS3 = 291,
|
||||
WL_RATE_1X4_TXBF_MCS4 = 292,
|
||||
WL_RATE_1X4_TXBF_MCS5 = 293,
|
||||
WL_RATE_1X4_TXBF_MCS6 = 294,
|
||||
WL_RATE_1X4_TXBF_MCS7 = 295,
|
||||
WL_RATE_P_1X4_TXBF_MCS87 = 296,
|
||||
WL_RATE_P_1X4_TXBF_MCS88 = 297,
|
||||
|
||||
WL_RATE_1X4_TXBF_VHT0SS1 = 288,
|
||||
WL_RATE_1X4_TXBF_VHT1SS1 = 289,
|
||||
WL_RATE_1X4_TXBF_VHT2SS1 = 290,
|
||||
WL_RATE_1X4_TXBF_VHT3SS1 = 291,
|
||||
WL_RATE_1X4_TXBF_VHT4SS1 = 292,
|
||||
WL_RATE_1X4_TXBF_VHT5SS1 = 293,
|
||||
WL_RATE_1X4_TXBF_VHT6SS1 = 294,
|
||||
WL_RATE_1X4_TXBF_VHT7SS1 = 295,
|
||||
WL_RATE_1X4_TXBF_VHT8SS1 = 296,
|
||||
WL_RATE_1X4_TXBF_VHT9SS1 = 297,
|
||||
WL_RATE_P_1X4_TXBF_VHT10SS1 = 298,
|
||||
WL_RATE_P_1X4_TXBF_VHT11SS1 = 299,
|
||||
|
||||
/* 2 Streams expanded + 2 */
|
||||
WL_RATE_2X4_TXBF_SDM_MCS8 = 300,
|
||||
WL_RATE_2X4_TXBF_SDM_MCS9 = 301,
|
||||
WL_RATE_2X4_TXBF_SDM_MCS10 = 302,
|
||||
WL_RATE_2X4_TXBF_SDM_MCS11 = 303,
|
||||
WL_RATE_2X4_TXBF_SDM_MCS12 = 304,
|
||||
WL_RATE_2X4_TXBF_SDM_MCS13 = 305,
|
||||
WL_RATE_2X4_TXBF_SDM_MCS14 = 306,
|
||||
WL_RATE_2X4_TXBF_SDM_MCS15 = 307,
|
||||
WL_RATE_P_2X4_TXBF_SDM_MCS99 = 308,
|
||||
WL_RATE_P_2X4_TXBF_SDM_MCS100 = 309,
|
||||
|
||||
WL_RATE_2X4_TXBF_VHT0SS2 = 300,
|
||||
WL_RATE_2X4_TXBF_VHT1SS2 = 301,
|
||||
WL_RATE_2X4_TXBF_VHT2SS2 = 302,
|
||||
WL_RATE_2X4_TXBF_VHT3SS2 = 303,
|
||||
WL_RATE_2X4_TXBF_VHT4SS2 = 304,
|
||||
WL_RATE_2X4_TXBF_VHT5SS2 = 305,
|
||||
WL_RATE_2X4_TXBF_VHT6SS2 = 306,
|
||||
WL_RATE_2X4_TXBF_VHT7SS2 = 307,
|
||||
WL_RATE_2X4_TXBF_VHT8SS2 = 308,
|
||||
WL_RATE_2X4_TXBF_VHT9SS2 = 309,
|
||||
WL_RATE_P_2X4_TXBF_VHT10SS2 = 310,
|
||||
WL_RATE_P_2X4_TXBF_VHT11SS2 = 311,
|
||||
|
||||
/* 3 Streams expanded + 1 */
|
||||
WL_RATE_3X4_TXBF_SDM_MCS16 = 312,
|
||||
WL_RATE_3X4_TXBF_SDM_MCS17 = 313,
|
||||
WL_RATE_3X4_TXBF_SDM_MCS18 = 314,
|
||||
WL_RATE_3X4_TXBF_SDM_MCS19 = 315,
|
||||
WL_RATE_3X4_TXBF_SDM_MCS20 = 316,
|
||||
WL_RATE_3X4_TXBF_SDM_MCS21 = 317,
|
||||
WL_RATE_3X4_TXBF_SDM_MCS22 = 318,
|
||||
WL_RATE_3X4_TXBF_SDM_MCS23 = 319,
|
||||
WL_RATE_P_3X4_TXBF_SDM_MCS101 = 320,
|
||||
WL_RATE_P_3X4_TXBF_SDM_MCS102 = 321,
|
||||
|
||||
WL_RATE_3X4_TXBF_VHT0SS3 = 312,
|
||||
WL_RATE_3X4_TXBF_VHT1SS3 = 313,
|
||||
WL_RATE_3X4_TXBF_VHT2SS3 = 314,
|
||||
WL_RATE_3X4_TXBF_VHT3SS3 = 315,
|
||||
WL_RATE_3X4_TXBF_VHT4SS3 = 316,
|
||||
WL_RATE_3X4_TXBF_VHT5SS3 = 317,
|
||||
WL_RATE_3X4_TXBF_VHT6SS3 = 318,
|
||||
WL_RATE_3X4_TXBF_VHT7SS3 = 319,
|
||||
WL_RATE_P_3X4_TXBF_VHT8SS3 = 320,
|
||||
WL_RATE_P_3X4_TXBF_VHT9SS3 = 321,
|
||||
WL_RATE_P_3X4_TXBF_VHT10SS3 = 322,
|
||||
WL_RATE_P_3X4_TXBF_VHT11SS3 = 323,
|
||||
|
||||
/* 4 Streams */
|
||||
WL_RATE_4X4_TXBF_SDM_MCS24 = 324,
|
||||
WL_RATE_4X4_TXBF_SDM_MCS25 = 325,
|
||||
WL_RATE_4X4_TXBF_SDM_MCS26 = 326,
|
||||
WL_RATE_4X4_TXBF_SDM_MCS27 = 327,
|
||||
WL_RATE_4X4_TXBF_SDM_MCS28 = 328,
|
||||
WL_RATE_4X4_TXBF_SDM_MCS29 = 329,
|
||||
WL_RATE_4X4_TXBF_SDM_MCS30 = 330,
|
||||
WL_RATE_4X4_TXBF_SDM_MCS31 = 331,
|
||||
WL_RATE_P_4X4_TXBF_SDM_MCS103 = 332,
|
||||
WL_RATE_P_4X4_TXBF_SDM_MCS104 = 333,
|
||||
|
||||
WL_RATE_4X4_TXBF_VHT0SS4 = 324,
|
||||
WL_RATE_4X4_TXBF_VHT1SS4 = 325,
|
||||
WL_RATE_4X4_TXBF_VHT2SS4 = 326,
|
||||
WL_RATE_4X4_TXBF_VHT3SS4 = 327,
|
||||
WL_RATE_4X4_TXBF_VHT4SS4 = 328,
|
||||
WL_RATE_4X4_TXBF_VHT5SS4 = 329,
|
||||
WL_RATE_4X4_TXBF_VHT6SS4 = 330,
|
||||
WL_RATE_4X4_TXBF_VHT7SS4 = 331,
|
||||
WL_RATE_P_4X4_TXBF_VHT8SS4 = 332,
|
||||
WL_RATE_P_4X4_TXBF_VHT9SS4 = 333,
|
||||
WL_RATE_P_4X4_TXBF_VHT10SS4 = 334,
|
||||
WL_RATE_P_4X4_TXBF_VHT11SS4 = 335
|
||||
|
||||
} clm_rates_t;
|
||||
|
||||
/* Number of rate codes */
|
||||
#define WL_NUMRATES 336
|
||||
|
||||
/* MCS rates */
|
||||
#define WLC_MAX_VHT_MCS 11 /**< Std VHT MCS 0-9 plus prop VHT MCS 10-11 */
|
||||
#define WLC_MAX_HE_MCS 11 /**< Std HE MCS 0-11 */
|
||||
|
||||
/* Convert encoded rate value in plcp header to numerical rates in 500 KHz increments */
|
||||
#define OFDM_PHY2MAC_RATE(rlpt) plcp_ofdm_rate_tbl[(rlpt) & 0x7]
|
||||
#define CCK_PHY2MAC_RATE(signal) ((signal)/5)
|
||||
|
||||
/* given a proprietary MCS, get number of spatial streams */
|
||||
#define GET_PROPRIETARY_11N_MCS_NSS(mcs) (1 + ((mcs) - 85) / 8)
|
||||
|
||||
#define GET_11N_MCS_NSS(mcs) ((mcs) < 32 ? (1 + ((mcs) / 8)) : \
|
||||
((mcs) == 32 ? 1 : GET_PROPRIETARY_11N_MCS_NSS(mcs)))
|
||||
|
||||
#define IS_PROPRIETARY_11N_MCS(mcs) FALSE
|
||||
#define IS_PROPRIETARY_11N_SS_MCS(mcs) FALSE /**< is proprietary HT single stream MCS */
|
||||
|
||||
/* Store HE mcs map for all NSS in a compact form:
|
||||
*
|
||||
* bit[0:2] mcs code for NSS 1
|
||||
* bit[3:5] mcs code for NSS 2
|
||||
* ...
|
||||
* bit[21:23] mcs code for NSS 8
|
||||
*/
|
||||
|
||||
/**
|
||||
* 3 bits are used for encoding each NSS mcs map (HE MCS MAP is 24 bits)
|
||||
*/
|
||||
#define HE_CAP_MCS_CODE_NONE 7
|
||||
|
||||
/* macros to access above compact format */
|
||||
#define HE_CAP_MCS_NSS_SET_MASK 0x00ffffff /* Field is to be 24 bits long */
|
||||
#define HE_CAP_MCS_NSS_GET_SS_IDX(nss) (((nss)-1) * HE_CAP_MCS_CODE_SIZE)
|
||||
#define HE_CAP_MCS_NSS_GET_MCS(nss, mcs_nss_map) \
|
||||
(((mcs_nss_map) >> HE_CAP_MCS_NSS_GET_SS_IDX(nss)) & HE_CAP_MCS_CODE_MASK)
|
||||
#define HE_CAP_MCS_NSS_SET_MCS(nss, mcs_code, mcs_nss_map) \
|
||||
do { \
|
||||
(mcs_nss_map) &= (~(HE_CAP_MCS_CODE_MASK << HE_CAP_MCS_NSS_GET_SS_IDX(nss))); \
|
||||
(mcs_nss_map) |= (((mcs_code) & HE_CAP_MCS_CODE_MASK) << HE_CAP_MCS_NSS_GET_SS_IDX(nss)); \
|
||||
(mcs_nss_map) &= (HE_CAP_MCS_NSS_SET_MASK); \
|
||||
} while (0)
|
||||
|
||||
extern const uint8 plcp_ofdm_rate_tbl[];
|
||||
|
||||
uint8 wf_get_single_stream_mcs(uint mcs);
|
||||
|
||||
uint8 wf_vht_plcp_to_rate(uint8 *plcp);
|
||||
uint wf_mcs_to_rate(uint mcs, uint nss, uint bw, int sgi);
|
||||
uint wf_he_mcs_to_rate(uint mcs, uint nss, uint bw, uint gi, bool dcm);
|
||||
uint wf_mcs_to_Ndbps(uint mcs, uint nss, uint bw);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* _bcmwifi_rates_h_ */
|
||||
@@ -0,0 +1,213 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Common OS-independent driver header for rate management.
|
||||
*
|
||||
* Copyright (C) 1999-2019, 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.
|
||||
*
|
||||
* 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: bcmwifi_rspec.h 736703 2017-12-18 06:55:37Z $
|
||||
*/
|
||||
|
||||
#ifndef _bcmwifi_rspec_h_
|
||||
#define _bcmwifi_rspec_h_
|
||||
|
||||
#include <typedefs.h>
|
||||
|
||||
/**
|
||||
* ===================================================================================
|
||||
* rate spec : holds rate and mode specific information required to generate a tx frame.
|
||||
* Legacy CCK and OFDM information is held in the same manner as was done in the past.
|
||||
* (in the lower byte) the upper 3 bytes primarily hold MIMO specific information
|
||||
* ===================================================================================
|
||||
*/
|
||||
typedef uint32 ratespec_t;
|
||||
|
||||
/* Rate spec. definitions */
|
||||
#define WL_RSPEC_RATE_MASK 0x000000FF /**< Legacy rate or MCS or MCS + NSS */
|
||||
#define WL_RSPEC_TXEXP_MASK 0x00000300 /**< Tx chain expansion beyond Nsts */
|
||||
#define WL_RSPEC_TXEXP_SHIFT 8
|
||||
#define WL_RSPEC_HE_GI_MASK 0x00000C00 /* HE GI indices */
|
||||
#define WL_RSPEC_HE_GI_SHIFT 10
|
||||
#define WL_RSPEC_BW_MASK 0x00070000 /**< Band width */
|
||||
#define WL_RSPEC_BW_SHIFT 16
|
||||
#define WL_RSPEC_DCM 0x00080000 /**< Dual Carrier Modulation */
|
||||
#define WL_RSPEC_STBC 0x00100000 /**< STBC expansion, Nsts = 2 * Nss */
|
||||
#define WL_RSPEC_TXBF 0x00200000
|
||||
#define WL_RSPEC_LDPC 0x00400000
|
||||
#define WL_RSPEC_SGI 0x00800000
|
||||
#define WL_RSPEC_SHORT_PREAMBLE 0x00800000 /**< DSSS short preable - Encoding 0 */
|
||||
#define WL_RSPEC_ENCODING_MASK 0x03000000 /**< Encoding of RSPEC_RATE field */
|
||||
#define WL_RSPEC_ENCODING_SHIFT 24
|
||||
|
||||
#define WL_RSPEC_OVERRIDE_RATE 0x40000000 /**< override rate only */
|
||||
#define WL_RSPEC_OVERRIDE_MODE 0x80000000 /**< override both rate & mode */
|
||||
|
||||
/* ======== RSPEC_HE_GI|RSPEC_SGI fields for HE ======== */
|
||||
|
||||
/* GI for HE */
|
||||
#define RSPEC_HE_LTF_GI(rspec) (((rspec) & WL_RSPEC_HE_GI_MASK) >> WL_RSPEC_HE_GI_SHIFT)
|
||||
#define WL_RSPEC_HE_1x_LTF_GI_0_8us (0x0)
|
||||
#define WL_RSPEC_HE_2x_LTF_GI_0_8us (0x1)
|
||||
#define WL_RSPEC_HE_2x_LTF_GI_1_6us (0x2)
|
||||
#define WL_RSPEC_HE_4x_LTF_GI_3_2us (0x3)
|
||||
#define RSPEC_ISHEGI(rspec) (RSPEC_HE_LTF_GI(rspec) > WL_RSPEC_HE_1x_LTF_GI_0_8us)
|
||||
#define HE_GI_TO_RSPEC(gi) (((gi) << WL_RSPEC_HE_GI_SHIFT) & WL_RSPEC_HE_GI_MASK)
|
||||
/* ======== RSPEC_RATE field ======== */
|
||||
|
||||
/* Encoding 0 - legacy rate */
|
||||
/* DSSS, CCK, and OFDM rates in [500kbps] units */
|
||||
#define WL_RSPEC_LEGACY_RATE_MASK 0x0000007F
|
||||
#define WLC_RATE_1M 2
|
||||
#define WLC_RATE_2M 4
|
||||
#define WLC_RATE_5M5 11
|
||||
#define WLC_RATE_11M 22
|
||||
#define WLC_RATE_6M 12
|
||||
#define WLC_RATE_9M 18
|
||||
#define WLC_RATE_12M 24
|
||||
#define WLC_RATE_18M 36
|
||||
#define WLC_RATE_24M 48
|
||||
#define WLC_RATE_36M 72
|
||||
#define WLC_RATE_48M 96
|
||||
#define WLC_RATE_54M 108
|
||||
|
||||
/* Encoding 1 - HT MCS */
|
||||
#define WL_RSPEC_HT_MCS_MASK 0x0000007F /**< HT MCS value mask in rspec */
|
||||
|
||||
/* Encoding 2 - VHT MCS + NSS */
|
||||
#define WL_RSPEC_VHT_MCS_MASK 0x0000000F /**< VHT MCS value mask in rspec */
|
||||
#define WL_RSPEC_VHT_NSS_MASK 0x000000F0 /**< VHT Nss value mask in rspec */
|
||||
#define WL_RSPEC_VHT_NSS_SHIFT 4 /**< VHT Nss value shift in rspec */
|
||||
|
||||
/* Encoding 3 - HE MCS + NSS */
|
||||
#define WL_RSPEC_HE_MCS_MASK 0x0000000F /**< HE MCS value mask in rspec */
|
||||
#define WL_RSPEC_HE_NSS_MASK 0x000000F0 /**< HE Nss value mask in rspec */
|
||||
#define WL_RSPEC_HE_NSS_SHIFT 4 /**< HE Nss value shift in rpsec */
|
||||
|
||||
/* ======== RSPEC_BW field ======== */
|
||||
|
||||
#define WL_RSPEC_BW_UNSPECIFIED 0
|
||||
#define WL_RSPEC_BW_20MHZ 0x00010000
|
||||
#define WL_RSPEC_BW_40MHZ 0x00020000
|
||||
#define WL_RSPEC_BW_80MHZ 0x00030000
|
||||
#define WL_RSPEC_BW_160MHZ 0x00040000
|
||||
|
||||
/* ======== RSPEC_ENCODING field ======== */
|
||||
|
||||
#define WL_RSPEC_ENCODE_RATE 0x00000000 /**< Legacy rate is stored in RSPEC_RATE */
|
||||
#define WL_RSPEC_ENCODE_HT 0x01000000 /**< HT MCS is stored in RSPEC_RATE */
|
||||
#define WL_RSPEC_ENCODE_VHT 0x02000000 /**< VHT MCS and NSS are stored in RSPEC_RATE */
|
||||
#define WL_RSPEC_ENCODE_HE 0x03000000 /**< HE MCS and NSS are stored in RSPEC_RATE */
|
||||
|
||||
/**
|
||||
* ===============================
|
||||
* Handy macros to parse rate spec
|
||||
* ===============================
|
||||
*/
|
||||
#define RSPEC_BW(rspec) ((rspec) & WL_RSPEC_BW_MASK)
|
||||
#define RSPEC_IS20MHZ(rspec) (RSPEC_BW(rspec) == WL_RSPEC_BW_20MHZ)
|
||||
#define RSPEC_IS40MHZ(rspec) (RSPEC_BW(rspec) == WL_RSPEC_BW_40MHZ)
|
||||
#define RSPEC_IS80MHZ(rspec) (RSPEC_BW(rspec) == WL_RSPEC_BW_80MHZ)
|
||||
#define RSPEC_IS160MHZ(rspec) (RSPEC_BW(rspec) == WL_RSPEC_BW_160MHZ)
|
||||
|
||||
#define RSPEC_ISSGI(rspec) (((rspec) & WL_RSPEC_SGI) != 0)
|
||||
#define RSPEC_ISLDPC(rspec) (((rspec) & WL_RSPEC_LDPC) != 0)
|
||||
#define RSPEC_ISSTBC(rspec) (((rspec) & WL_RSPEC_STBC) != 0)
|
||||
#define RSPEC_ISTXBF(rspec) (((rspec) & WL_RSPEC_TXBF) != 0)
|
||||
|
||||
#define RSPEC_TXEXP(rspec) (((rspec) & WL_RSPEC_TXEXP_MASK) >> WL_RSPEC_TXEXP_SHIFT)
|
||||
|
||||
#define RSPEC_ENCODE(rspec) (((rspec) & WL_RSPEC_ENCODING_MASK) >> WL_RSPEC_ENCODING_SHIFT)
|
||||
#define RSPEC_ISLEGACY(rspec) (((rspec) & WL_RSPEC_ENCODING_MASK) == WL_RSPEC_ENCODE_RATE)
|
||||
|
||||
#define RSPEC_ISCCK(rspec) (RSPEC_ISLEGACY(rspec) && \
|
||||
(int8)rate_info[(rspec) & WL_RSPEC_LEGACY_RATE_MASK] > 0)
|
||||
#define RSPEC_ISOFDM(rspec) (RSPEC_ISLEGACY(rspec) && \
|
||||
(int8)rate_info[(rspec) & WL_RSPEC_LEGACY_RATE_MASK] < 0)
|
||||
|
||||
#define RSPEC_ISHT(rspec) (((rspec) & WL_RSPEC_ENCODING_MASK) == WL_RSPEC_ENCODE_HT)
|
||||
#ifdef WL11AC
|
||||
#define RSPEC_ISVHT(rspec) (((rspec) & WL_RSPEC_ENCODING_MASK) == WL_RSPEC_ENCODE_VHT)
|
||||
#else /* WL11AC */
|
||||
#define RSPEC_ISVHT(rspec) 0
|
||||
#endif /* WL11AC */
|
||||
#ifdef WL11AX
|
||||
#define RSPEC_ISHE(rspec) (((rspec) & WL_RSPEC_ENCODING_MASK) == WL_RSPEC_ENCODE_HE)
|
||||
#else /* WL11AX */
|
||||
#define RSPEC_ISHE(rspec) 0
|
||||
#endif /* WL11AX */
|
||||
|
||||
/**
|
||||
* ================================
|
||||
* Handy macros to create rate spec
|
||||
* ================================
|
||||
*/
|
||||
/* create ratespecs */
|
||||
#define LEGACY_RSPEC(rate) (WL_RSPEC_ENCODE_RATE | WL_RSPEC_BW_20MHZ | \
|
||||
((rate) & WL_RSPEC_LEGACY_RATE_MASK))
|
||||
#define CCK_RSPEC(cck) LEGACY_RSPEC(cck)
|
||||
#define OFDM_RSPEC(ofdm) LEGACY_RSPEC(ofdm)
|
||||
#define HT_RSPEC(mcs) (WL_RSPEC_ENCODE_HT | ((mcs) & WL_RSPEC_HT_MCS_MASK))
|
||||
#define VHT_RSPEC(mcs, nss) (WL_RSPEC_ENCODE_VHT | \
|
||||
(((nss) << WL_RSPEC_VHT_NSS_SHIFT) & WL_RSPEC_VHT_NSS_MASK) | \
|
||||
((mcs) & WL_RSPEC_VHT_MCS_MASK))
|
||||
#define HE_RSPEC(mcs, nss) (WL_RSPEC_ENCODE_HE | \
|
||||
(((nss) << WL_RSPEC_HE_NSS_SHIFT) & WL_RSPEC_HE_NSS_MASK) | \
|
||||
((mcs) & WL_RSPEC_HE_MCS_MASK))
|
||||
|
||||
/**
|
||||
* ==================
|
||||
* Other handy macros
|
||||
* ==================
|
||||
*/
|
||||
|
||||
/* return rate in unit of Kbps */
|
||||
#define RSPEC2KBPS(rspec) wf_rspec_to_rate(rspec)
|
||||
|
||||
/* return rate in unit of 500Kbps */
|
||||
#define RSPEC2RATE(rspec) ((rspec) & WL_RSPEC_LEGACY_RATE_MASK)
|
||||
|
||||
/**
|
||||
* =================================
|
||||
* Macros to use the rate_info table
|
||||
* =================================
|
||||
*/
|
||||
/* phy_rate table index is in [500kbps] units */
|
||||
#define WLC_MAXRATE 108 /**< in 500kbps units */
|
||||
extern const uint8 rate_info[];
|
||||
/* phy_rate table value is encoded */
|
||||
#define RATE_INFO_OFDM_MASK 0x80 /* ofdm mask */
|
||||
#define RATE_INFO_RATE_MASK 0x7f /* rate signal index mask */
|
||||
#define RATE_INFO_M_RATE_MASK 0x0f /* M_RATE_TABLE index mask */
|
||||
#define RATE_INFO_RATE_ISCCK(r) ((r) <= WLC_MAXRATE && (int8)rate_info[r] > 0)
|
||||
#define RATE_INFO_RATE_ISOFDM(r) ((r) <= WLC_MAXRATE && (int8)rate_info[r] < 0)
|
||||
|
||||
/**
|
||||
* ===================
|
||||
* function prototypes
|
||||
* ===================
|
||||
*/
|
||||
ratespec_t wf_vht_plcp_to_rspec(uint8 *plcp);
|
||||
ratespec_t wf_he_plcp_to_rspec(uint8 *plcp);
|
||||
uint wf_rspec_to_rate(ratespec_t rspec);
|
||||
|
||||
#endif /* _bcmwifi_rspec_h_ */
|
||||
623
drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd_wifi6/bcmxtlv.c
Normal file
623
drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd_wifi6/bcmxtlv.c
Normal file
@@ -0,0 +1,623 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Driver O/S-independent utility routines
|
||||
*
|
||||
* Copyright (C) 1999-2019, 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.
|
||||
*
|
||||
* 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: bcmxtlv.c 788740 2018-11-13 21:45:01Z $
|
||||
*/
|
||||
|
||||
#include <bcm_cfg.h>
|
||||
|
||||
#include <typedefs.h>
|
||||
#include <bcmdefs.h>
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#ifdef BCMDRIVER
|
||||
#include <osl.h>
|
||||
#else /* !BCMDRIVER */
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#ifndef ASSERT
|
||||
#define ASSERT(exp)
|
||||
#endif // endif
|
||||
#endif /* !BCMDRIVER */
|
||||
|
||||
#include <bcmtlv.h>
|
||||
#include <bcmendian.h>
|
||||
#include <bcmutils.h>
|
||||
|
||||
int
|
||||
bcm_xtlv_hdr_size(bcm_xtlv_opts_t opts)
|
||||
{
|
||||
int len = (int)OFFSETOF(bcm_xtlv_t, data); /* nominal */
|
||||
if (opts & BCM_XTLV_OPTION_LENU8) --len;
|
||||
if (opts & BCM_XTLV_OPTION_IDU8) --len;
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
bool
|
||||
bcm_valid_xtlv(const bcm_xtlv_t *elt, int buf_len, bcm_xtlv_opts_t opts)
|
||||
{
|
||||
return elt != NULL &&
|
||||
buf_len >= bcm_xtlv_hdr_size(opts) &&
|
||||
buf_len >= bcm_xtlv_size(elt, opts);
|
||||
}
|
||||
|
||||
int
|
||||
bcm_xtlv_size_for_data(int dlen, bcm_xtlv_opts_t opts)
|
||||
{
|
||||
int hsz;
|
||||
|
||||
hsz = bcm_xtlv_hdr_size(opts);
|
||||
return ((opts & BCM_XTLV_OPTION_ALIGN32) ? ALIGN_SIZE(dlen + hsz, 4)
|
||||
: (dlen + hsz));
|
||||
}
|
||||
|
||||
int
|
||||
bcm_xtlv_size(const bcm_xtlv_t *elt, bcm_xtlv_opts_t opts)
|
||||
{
|
||||
int size; /* size including header, data, and any pad */
|
||||
int len; /* length wthout padding */
|
||||
|
||||
len = BCM_XTLV_LEN_EX(elt, opts);
|
||||
size = bcm_xtlv_size_for_data(len, opts);
|
||||
return size;
|
||||
}
|
||||
|
||||
int
|
||||
bcm_xtlv_len(const bcm_xtlv_t *elt, bcm_xtlv_opts_t opts)
|
||||
{
|
||||
const uint8 *lenp;
|
||||
int len;
|
||||
|
||||
lenp = (const uint8 *)&elt->len; /* nominal */
|
||||
if (opts & BCM_XTLV_OPTION_IDU8) {
|
||||
--lenp;
|
||||
}
|
||||
|
||||
if (opts & BCM_XTLV_OPTION_LENU8) {
|
||||
len = *lenp;
|
||||
} else if (opts & BCM_XTLV_OPTION_LENBE) {
|
||||
len = (uint32)hton16(elt->len);
|
||||
} else {
|
||||
len = ltoh16_ua(lenp);
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
int
|
||||
bcm_xtlv_id(const bcm_xtlv_t *elt, bcm_xtlv_opts_t opts)
|
||||
{
|
||||
int id = 0;
|
||||
if (opts & BCM_XTLV_OPTION_IDU8) {
|
||||
id = *(const uint8 *)elt;
|
||||
} else if (opts & BCM_XTLV_OPTION_IDBE) {
|
||||
id = (uint32)hton16(elt->id);
|
||||
} else {
|
||||
id = ltoh16_ua((const uint8 *)elt);
|
||||
}
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
bcm_xtlv_t *
|
||||
bcm_next_xtlv(const bcm_xtlv_t *elt, int *buflen, bcm_xtlv_opts_t opts)
|
||||
{
|
||||
int sz;
|
||||
/* advance to next elt */
|
||||
sz = BCM_XTLV_SIZE_EX(elt, opts);
|
||||
elt = (const bcm_xtlv_t*)((const uint8 *)elt + sz);
|
||||
*buflen -= sz;
|
||||
|
||||
/* validate next elt */
|
||||
if (!bcm_valid_xtlv(elt, *buflen, opts))
|
||||
return NULL;
|
||||
|
||||
GCC_DIAGNOSTIC_PUSH_SUPPRESS_CAST();
|
||||
return (bcm_xtlv_t *)(elt);
|
||||
GCC_DIAGNOSTIC_POP();
|
||||
}
|
||||
|
||||
int
|
||||
bcm_xtlv_buf_init(bcm_xtlvbuf_t *tlv_buf, uint8 *buf, uint16 len, bcm_xtlv_opts_t opts)
|
||||
{
|
||||
if (!tlv_buf || !buf || !len)
|
||||
return BCME_BADARG;
|
||||
|
||||
tlv_buf->opts = opts;
|
||||
tlv_buf->size = len;
|
||||
tlv_buf->head = buf;
|
||||
tlv_buf->buf = buf;
|
||||
return BCME_OK;
|
||||
}
|
||||
|
||||
uint16
|
||||
bcm_xtlv_buf_len(bcm_xtlvbuf_t *tbuf)
|
||||
{
|
||||
uint16 len;
|
||||
|
||||
if (tbuf)
|
||||
len = (uint16)(tbuf->buf - tbuf->head);
|
||||
else
|
||||
len = 0;
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
uint16
|
||||
bcm_xtlv_buf_rlen(bcm_xtlvbuf_t *tbuf)
|
||||
{
|
||||
uint16 rlen;
|
||||
if (tbuf)
|
||||
rlen = tbuf->size - bcm_xtlv_buf_len(tbuf);
|
||||
else
|
||||
rlen = 0;
|
||||
|
||||
return rlen;
|
||||
}
|
||||
|
||||
uint8 *
|
||||
bcm_xtlv_buf(bcm_xtlvbuf_t *tbuf)
|
||||
{
|
||||
return tbuf ? tbuf->buf : NULL;
|
||||
}
|
||||
|
||||
uint8 *
|
||||
bcm_xtlv_head(bcm_xtlvbuf_t *tbuf)
|
||||
{
|
||||
return tbuf ? tbuf->head : NULL;
|
||||
}
|
||||
|
||||
void
|
||||
bcm_xtlv_pack_xtlv(bcm_xtlv_t *xtlv, uint16 type, uint16 len, const uint8 *data,
|
||||
bcm_xtlv_opts_t opts)
|
||||
{
|
||||
uint8 *data_buf;
|
||||
bcm_xtlv_opts_t mask = BCM_XTLV_OPTION_IDU8 | BCM_XTLV_OPTION_LENU8;
|
||||
|
||||
if (!(opts & mask)) { /* default */
|
||||
uint8 *idp = (uint8 *)xtlv;
|
||||
uint8 *lenp = idp + sizeof(xtlv->id);
|
||||
htol16_ua_store(type, idp);
|
||||
htol16_ua_store(len, lenp);
|
||||
data_buf = lenp + sizeof(uint16);
|
||||
} else if ((opts & mask) == mask) { /* u8 id and u8 len */
|
||||
uint8 *idp = (uint8 *)xtlv;
|
||||
uint8 *lenp = idp + 1;
|
||||
*idp = (uint8)type;
|
||||
*lenp = (uint8)len;
|
||||
data_buf = lenp + sizeof(uint8);
|
||||
} else if (opts & BCM_XTLV_OPTION_IDU8) { /* u8 id, u16 len */
|
||||
uint8 *idp = (uint8 *)xtlv;
|
||||
uint8 *lenp = idp + 1;
|
||||
*idp = (uint8)type;
|
||||
htol16_ua_store(len, lenp);
|
||||
data_buf = lenp + sizeof(uint16);
|
||||
} else if (opts & BCM_XTLV_OPTION_LENU8) { /* u16 id, u8 len */
|
||||
uint8 *idp = (uint8 *)xtlv;
|
||||
uint8 *lenp = idp + sizeof(uint16);
|
||||
htol16_ua_store(type, idp);
|
||||
*lenp = (uint8)len;
|
||||
data_buf = lenp + sizeof(uint8);
|
||||
} else {
|
||||
bool Unexpected_xtlv_option = TRUE;
|
||||
BCM_REFERENCE(Unexpected_xtlv_option);
|
||||
ASSERT(!Unexpected_xtlv_option);
|
||||
return;
|
||||
}
|
||||
|
||||
if (opts & BCM_XTLV_OPTION_LENU8) {
|
||||
ASSERT(len <= 0x00ff);
|
||||
len &= 0xff;
|
||||
}
|
||||
|
||||
if (data != NULL)
|
||||
memcpy(data_buf, data, len);
|
||||
}
|
||||
|
||||
/* xtlv header is always packed in LE order */
|
||||
void
|
||||
bcm_xtlv_unpack_xtlv(const bcm_xtlv_t *xtlv, uint16 *type, uint16 *len,
|
||||
const uint8 **data, bcm_xtlv_opts_t opts)
|
||||
{
|
||||
if (type)
|
||||
*type = (uint16)bcm_xtlv_id(xtlv, opts);
|
||||
if (len)
|
||||
*len = (uint16)bcm_xtlv_len(xtlv, opts);
|
||||
if (data)
|
||||
*data = (const uint8 *)xtlv + BCM_XTLV_HDR_SIZE_EX(opts);
|
||||
}
|
||||
|
||||
int
|
||||
bcm_xtlv_put_data(bcm_xtlvbuf_t *tbuf, uint16 type, const uint8 *data, int n)
|
||||
{
|
||||
bcm_xtlv_t *xtlv;
|
||||
int size;
|
||||
|
||||
if (tbuf == NULL)
|
||||
return BCME_BADARG;
|
||||
|
||||
size = bcm_xtlv_size_for_data(n, tbuf->opts);
|
||||
if (bcm_xtlv_buf_rlen(tbuf) < size)
|
||||
return BCME_NOMEM;
|
||||
|
||||
xtlv = (bcm_xtlv_t *)bcm_xtlv_buf(tbuf);
|
||||
bcm_xtlv_pack_xtlv(xtlv, type, (uint16)n, data, tbuf->opts);
|
||||
tbuf->buf += size; /* note: data may be NULL, reserves space */
|
||||
return BCME_OK;
|
||||
}
|
||||
|
||||
static int
|
||||
bcm_xtlv_put_int(bcm_xtlvbuf_t *tbuf, uint16 type, const uint8 *data, int n, int int_sz)
|
||||
{
|
||||
bcm_xtlv_t *xtlv;
|
||||
int xtlv_len;
|
||||
uint8 *xtlv_data;
|
||||
int err = BCME_OK;
|
||||
|
||||
if (tbuf == NULL) {
|
||||
err = BCME_BADARG;
|
||||
goto done;
|
||||
}
|
||||
|
||||
xtlv = (bcm_xtlv_t *)bcm_xtlv_buf(tbuf);
|
||||
|
||||
/* put type and length in xtlv and reserve data space */
|
||||
xtlv_len = n * int_sz;
|
||||
err = bcm_xtlv_put_data(tbuf, type, NULL, xtlv_len);
|
||||
if (err != BCME_OK)
|
||||
goto done;
|
||||
|
||||
xtlv_data = (uint8 *)xtlv + bcm_xtlv_hdr_size(tbuf->opts);
|
||||
|
||||
/* write data w/ little-endianness into buffer - single loop, aligned access */
|
||||
for (; n != 0; --n, xtlv_data += int_sz, data += int_sz) {
|
||||
switch (int_sz) {
|
||||
case sizeof(uint8):
|
||||
break;
|
||||
case sizeof(uint16):
|
||||
{
|
||||
uint16 v = load16_ua(data);
|
||||
htol16_ua_store(v, xtlv_data);
|
||||
break;
|
||||
}
|
||||
case sizeof(uint32):
|
||||
{
|
||||
uint32 v = load32_ua(data);
|
||||
htol32_ua_store(v, xtlv_data);
|
||||
break;
|
||||
}
|
||||
case sizeof(uint64):
|
||||
{
|
||||
uint64 v = load64_ua(data);
|
||||
htol64_ua_store(v, xtlv_data);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
err = BCME_UNSUPPORTED;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
done:
|
||||
return err;
|
||||
}
|
||||
|
||||
int
|
||||
bcm_xtlv_put16(bcm_xtlvbuf_t *tbuf, uint16 type, const uint16 *data, int n)
|
||||
{
|
||||
return bcm_xtlv_put_int(tbuf, type, (const uint8 *)data, n, sizeof(uint16));
|
||||
}
|
||||
|
||||
int
|
||||
bcm_xtlv_put32(bcm_xtlvbuf_t *tbuf, uint16 type, const uint32 *data, int n)
|
||||
{
|
||||
return bcm_xtlv_put_int(tbuf, type, (const uint8 *)data, n, sizeof(uint32));
|
||||
}
|
||||
|
||||
int
|
||||
bcm_xtlv_put64(bcm_xtlvbuf_t *tbuf, uint16 type, const uint64 *data, int n)
|
||||
{
|
||||
return bcm_xtlv_put_int(tbuf, type, (const uint8 *)data, n, sizeof(uint64));
|
||||
}
|
||||
|
||||
/*
|
||||
* upacks xtlv record from buf checks the type
|
||||
* copies data to callers buffer
|
||||
* advances tlv pointer to next record
|
||||
* caller's resposible for dst space check
|
||||
*/
|
||||
int
|
||||
bcm_unpack_xtlv_entry(const uint8 **tlv_buf, uint16 xpct_type, uint16 xpct_len,
|
||||
uint8 *dst_data, bcm_xtlv_opts_t opts)
|
||||
{
|
||||
const bcm_xtlv_t *ptlv = (const bcm_xtlv_t *)*tlv_buf;
|
||||
uint16 len;
|
||||
uint16 type;
|
||||
const uint8 *data;
|
||||
|
||||
ASSERT(ptlv);
|
||||
|
||||
bcm_xtlv_unpack_xtlv(ptlv, &type, &len, &data, opts);
|
||||
if (len) {
|
||||
if ((type != xpct_type) || (len > xpct_len))
|
||||
return BCME_BADARG;
|
||||
if (dst_data && data)
|
||||
memcpy(dst_data, data, len); /* copy data to dst */
|
||||
}
|
||||
|
||||
*tlv_buf += BCM_XTLV_SIZE_EX(ptlv, opts);
|
||||
return BCME_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* packs user data into tlv record and advances tlv pointer to next xtlv slot
|
||||
* buflen is used for tlv_buf space check
|
||||
*/
|
||||
int
|
||||
bcm_pack_xtlv_entry(uint8 **tlv_buf, uint16 *buflen, uint16 type, uint16 len,
|
||||
const uint8 *src_data, bcm_xtlv_opts_t opts)
|
||||
{
|
||||
bcm_xtlv_t *ptlv = (bcm_xtlv_t *)*tlv_buf;
|
||||
int size;
|
||||
|
||||
ASSERT(ptlv);
|
||||
|
||||
size = bcm_xtlv_size_for_data(len, opts);
|
||||
|
||||
/* copy data from tlv buffer to dst provided by user */
|
||||
if (size > *buflen)
|
||||
return BCME_BADLEN;
|
||||
|
||||
bcm_xtlv_pack_xtlv(ptlv, type, len, src_data, opts);
|
||||
|
||||
/* advance callers pointer to tlv buff */
|
||||
*tlv_buf = (uint8*)(*tlv_buf) + size;
|
||||
/* decrement the len */
|
||||
*buflen -= (uint16)size;
|
||||
return BCME_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* unpack all xtlv records from the issue a callback
|
||||
* to set function one call per found tlv record
|
||||
*/
|
||||
int
|
||||
bcm_unpack_xtlv_buf(void *ctx, const uint8 *tlv_buf, uint16 buflen, bcm_xtlv_opts_t opts,
|
||||
bcm_xtlv_unpack_cbfn_t *cbfn)
|
||||
{
|
||||
uint16 len;
|
||||
uint16 type;
|
||||
int res = BCME_OK;
|
||||
int size;
|
||||
const bcm_xtlv_t *ptlv;
|
||||
int sbuflen = buflen;
|
||||
const uint8 *data;
|
||||
int hdr_size;
|
||||
|
||||
ASSERT(!buflen || tlv_buf);
|
||||
ASSERT(!buflen || cbfn);
|
||||
|
||||
hdr_size = BCM_XTLV_HDR_SIZE_EX(opts);
|
||||
while (sbuflen >= hdr_size) {
|
||||
ptlv = (const bcm_xtlv_t *)tlv_buf;
|
||||
|
||||
bcm_xtlv_unpack_xtlv(ptlv, &type, &len, &data, opts);
|
||||
size = bcm_xtlv_size_for_data(len, opts);
|
||||
|
||||
sbuflen -= size;
|
||||
if (sbuflen < 0) /* check for buffer overrun */
|
||||
break;
|
||||
|
||||
if ((res = cbfn(ctx, data, type, len)) != BCME_OK)
|
||||
break;
|
||||
tlv_buf += size;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
int
|
||||
bcm_pack_xtlv_buf(void *ctx, uint8 *tlv_buf, uint16 buflen, bcm_xtlv_opts_t opts,
|
||||
bcm_pack_xtlv_next_info_cbfn_t get_next, bcm_pack_xtlv_pack_next_cbfn_t pack_next,
|
||||
int *outlen)
|
||||
{
|
||||
int res = BCME_OK;
|
||||
uint16 tlv_id;
|
||||
uint16 tlv_len;
|
||||
uint8 *startp;
|
||||
uint8 *endp;
|
||||
uint8 *buf;
|
||||
bool more;
|
||||
int size;
|
||||
int hdr_size;
|
||||
|
||||
ASSERT(get_next && pack_next);
|
||||
|
||||
buf = tlv_buf;
|
||||
startp = buf;
|
||||
endp = (uint8 *)buf + buflen;
|
||||
more = TRUE;
|
||||
hdr_size = BCM_XTLV_HDR_SIZE_EX(opts);
|
||||
|
||||
while (more && (buf < endp)) {
|
||||
more = get_next(ctx, &tlv_id, &tlv_len);
|
||||
size = bcm_xtlv_size_for_data(tlv_len, opts);
|
||||
if ((buf + size) > endp) {
|
||||
res = BCME_BUFTOOSHORT;
|
||||
goto done;
|
||||
}
|
||||
|
||||
bcm_xtlv_pack_xtlv((bcm_xtlv_t *)buf, tlv_id, tlv_len, NULL, opts);
|
||||
pack_next(ctx, tlv_id, tlv_len, buf + hdr_size);
|
||||
buf += size;
|
||||
}
|
||||
|
||||
if (more)
|
||||
res = BCME_BUFTOOSHORT;
|
||||
|
||||
done:
|
||||
if (outlen) {
|
||||
*outlen = (int)(buf - startp);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
/*
|
||||
* pack xtlv buffer from memory according to xtlv_desc_t
|
||||
*/
|
||||
int
|
||||
bcm_pack_xtlv_buf_from_mem(uint8 **tlv_buf, uint16 *buflen, const xtlv_desc_t *items,
|
||||
bcm_xtlv_opts_t opts)
|
||||
{
|
||||
int res = BCME_OK;
|
||||
uint8 *ptlv = *tlv_buf;
|
||||
|
||||
while (items->type != 0) {
|
||||
if (items->len && items->ptr) {
|
||||
res = bcm_pack_xtlv_entry(&ptlv, buflen, items->type,
|
||||
items->len, items->ptr, opts);
|
||||
if (res != BCME_OK)
|
||||
break;
|
||||
}
|
||||
items++;
|
||||
}
|
||||
|
||||
*tlv_buf = ptlv; /* update the external pointer */
|
||||
return res;
|
||||
}
|
||||
|
||||
/*
|
||||
* unpack xtlv buffer to memory according to xtlv_desc_t
|
||||
*
|
||||
*/
|
||||
int
|
||||
bcm_unpack_xtlv_buf_to_mem(uint8 *tlv_buf, int *buflen, xtlv_desc_t *items,
|
||||
bcm_xtlv_opts_t opts)
|
||||
{
|
||||
int res = BCME_OK;
|
||||
bcm_xtlv_t *elt;
|
||||
|
||||
elt = bcm_valid_xtlv((bcm_xtlv_t *)tlv_buf, *buflen, opts) ? (bcm_xtlv_t *)tlv_buf : NULL;
|
||||
if (!elt || !items) {
|
||||
res = BCME_BADARG;
|
||||
return res;
|
||||
}
|
||||
|
||||
for (; elt != NULL && res == BCME_OK; elt = bcm_next_xtlv(elt, buflen, opts)) {
|
||||
/* find matches in desc_t items */
|
||||
xtlv_desc_t *dst_desc = items;
|
||||
uint16 len, type;
|
||||
const uint8 *data;
|
||||
|
||||
bcm_xtlv_unpack_xtlv(elt, &type, &len, &data, opts);
|
||||
while (dst_desc->type != 0) {
|
||||
if (type == dst_desc->type) {
|
||||
if (len != dst_desc->len) {
|
||||
res = BCME_BADLEN;
|
||||
} else {
|
||||
memcpy(dst_desc->ptr, data, len);
|
||||
}
|
||||
break;
|
||||
}
|
||||
dst_desc++;
|
||||
}
|
||||
}
|
||||
|
||||
if (res == BCME_OK && *buflen != 0)
|
||||
res = BCME_BUFTOOSHORT;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/*
|
||||
* return data pointer of a given ID from xtlv buffer.
|
||||
* If the specified xTLV ID is found, on return *datalen will contain
|
||||
* the the data length of the xTLV ID.
|
||||
*/
|
||||
const uint8*
|
||||
bcm_get_data_from_xtlv_buf(const uint8 *tlv_buf, uint16 buflen, uint16 id,
|
||||
uint16 *datalen, bcm_xtlv_opts_t opts)
|
||||
{
|
||||
const uint8 *retptr = NULL;
|
||||
uint16 type, len;
|
||||
int size;
|
||||
const bcm_xtlv_t *ptlv;
|
||||
int sbuflen = buflen;
|
||||
const uint8 *data;
|
||||
int hdr_size;
|
||||
|
||||
hdr_size = BCM_XTLV_HDR_SIZE_EX(opts);
|
||||
|
||||
/* Init the datalength */
|
||||
if (datalen) {
|
||||
*datalen = 0;
|
||||
}
|
||||
while (sbuflen >= hdr_size) {
|
||||
ptlv = (const bcm_xtlv_t *)tlv_buf;
|
||||
bcm_xtlv_unpack_xtlv(ptlv, &type, &len, &data, opts);
|
||||
|
||||
size = bcm_xtlv_size_for_data(len, opts);
|
||||
sbuflen -= size;
|
||||
if (sbuflen < 0) /* buffer overrun? */
|
||||
break;
|
||||
|
||||
if (id == type) {
|
||||
retptr = data;
|
||||
if (datalen)
|
||||
*datalen = len;
|
||||
break;
|
||||
}
|
||||
|
||||
tlv_buf += size;
|
||||
}
|
||||
|
||||
return retptr;
|
||||
}
|
||||
|
||||
bcm_xtlv_t*
|
||||
bcm_xtlv_bcopy(const bcm_xtlv_t *src, bcm_xtlv_t *dst,
|
||||
int src_buf_len, int dst_buf_len, bcm_xtlv_opts_t opts)
|
||||
{
|
||||
bcm_xtlv_t *dst_next = NULL;
|
||||
src = (src && bcm_valid_xtlv(src, src_buf_len, opts)) ? src : NULL;
|
||||
if (src && dst) {
|
||||
uint16 type;
|
||||
uint16 len;
|
||||
const uint8 *data;
|
||||
int size;
|
||||
bcm_xtlv_unpack_xtlv(src, &type, &len, &data, opts);
|
||||
size = bcm_xtlv_size_for_data(len, opts);
|
||||
if (size <= dst_buf_len) {
|
||||
bcm_xtlv_pack_xtlv(dst, type, len, data, opts);
|
||||
dst_next = (bcm_xtlv_t *)((uint8 *)dst + size);
|
||||
}
|
||||
}
|
||||
|
||||
return dst_next;
|
||||
}
|
||||
2905
drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd_wifi6/dbus.c
Normal file
2905
drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd_wifi6/dbus.c
Normal file
File diff suppressed because it is too large
Load Diff
1173
drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd_wifi6/dbus_usb.c
Normal file
1173
drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd_wifi6/dbus_usb.c
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
3414
drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd_wifi6/dhd.h
Normal file
3414
drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd_wifi6/dhd.h
Normal file
File diff suppressed because it is too large
Load Diff
352
drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd_wifi6/dhd_bus.h
Normal file
352
drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd_wifi6/dhd_bus.h
Normal file
@@ -0,0 +1,352 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Header file describing the internal (inter-module) DHD interfaces.
|
||||
*
|
||||
* Provides type definitions and function prototypes used to link the
|
||||
* DHD OS, bus, and protocol modules.
|
||||
*
|
||||
* Copyright (C) 1999-2019, 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.
|
||||
*
|
||||
* Notwithstanding the above, under no circumstances may you combine this
|
||||
* software in any way with any other Broadcom software provided under a license
|
||||
* other than the GPL, without Broadcom's express prior written consent.
|
||||
*
|
||||
*
|
||||
* <<Broadcom-WL-IPTag/Open:>>
|
||||
*
|
||||
* $Id: dhd_bus.h 814378 2019-04-11 02:21:31Z $
|
||||
*/
|
||||
|
||||
#ifndef _dhd_bus_h_
|
||||
#define _dhd_bus_h_
|
||||
|
||||
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)
|
||||
*/
|
||||
|
||||
/* global variable for the bus */
|
||||
extern struct dhd_bus *g_dhd_bus;
|
||||
|
||||
/* Indicate (dis)interest in finding dongles. */
|
||||
extern int dhd_bus_register(void);
|
||||
extern void dhd_bus_unregister(void);
|
||||
|
||||
/* Download firmware image and nvram image */
|
||||
extern int dhd_bus_download_firmware(struct dhd_bus *bus, osl_t *osh,
|
||||
char *fw_path, char *nv_path, char *clm_path, char *conf_path);
|
||||
#if defined(BT_OVER_SDIO)
|
||||
extern int dhd_bus_download_btfw(struct dhd_bus *bus, osl_t *osh, char *btfw_path);
|
||||
#endif /* defined (BT_OVER_SDIO) */
|
||||
|
||||
/* Stop bus module: clear pending frames, disable data flow */
|
||||
extern void dhd_bus_stop(struct dhd_bus *bus, bool enforce_mutex);
|
||||
|
||||
/* Initialize bus module: prepare for communication w/dongle */
|
||||
extern int dhd_bus_init(dhd_pub_t *dhdp, bool enforce_mutex);
|
||||
|
||||
/* Get the Bus Idle Time */
|
||||
extern void dhd_bus_getidletime(dhd_pub_t *dhdp, int *idletime);
|
||||
|
||||
/* Set the Bus Idle Time */
|
||||
extern void dhd_bus_setidletime(dhd_pub_t *dhdp, int idle_time);
|
||||
|
||||
/* Send a data frame to the dongle. Callee disposes of txp. */
|
||||
#ifdef BCMPCIE
|
||||
extern int dhd_bus_txdata(struct dhd_bus *bus, void *txp, uint8 ifidx);
|
||||
#else
|
||||
extern int dhd_bus_txdata(struct dhd_bus *bus, void *txp);
|
||||
#endif // endif
|
||||
|
||||
#ifdef BCMPCIE
|
||||
extern void dhdpcie_cto_recovery_handler(dhd_pub_t *dhd);
|
||||
#endif /* BCMPCIE */
|
||||
|
||||
/* Send/receive a control message to/from the dongle.
|
||||
* Expects caller to enforce a single outstanding transaction.
|
||||
*/
|
||||
extern int dhd_bus_txctl(struct dhd_bus *bus, uchar *msg, uint msglen);
|
||||
extern int dhd_bus_rxctl(struct dhd_bus *bus, uchar *msg, uint msglen);
|
||||
|
||||
/* Watchdog timer function */
|
||||
extern bool dhd_bus_watchdog(dhd_pub_t *dhd);
|
||||
|
||||
extern int dhd_bus_oob_intr_register(dhd_pub_t *dhdp);
|
||||
extern void dhd_bus_oob_intr_unregister(dhd_pub_t *dhdp);
|
||||
extern void dhd_bus_oob_intr_set(dhd_pub_t *dhdp, bool enable);
|
||||
extern void dhd_bus_dev_pm_stay_awake(dhd_pub_t *dhdpub);
|
||||
extern void dhd_bus_dev_pm_relax(dhd_pub_t *dhdpub);
|
||||
extern bool dhd_bus_dev_pm_enabled(dhd_pub_t *dhdpub);
|
||||
|
||||
/* Device console input function */
|
||||
extern int dhd_bus_console_in(dhd_pub_t *dhd, uchar *msg, uint msglen);
|
||||
#ifdef CONSOLE_DPC
|
||||
extern int dhd_bus_txcons(dhd_pub_t *dhd, uchar *msg, uint msglen);
|
||||
#endif
|
||||
|
||||
/* Deferred processing for the bus, return TRUE requests reschedule */
|
||||
extern bool dhd_bus_dpc(struct dhd_bus *bus);
|
||||
extern void dhd_bus_isr(bool * InterruptRecognized, bool * QueueMiniportHandleInterrupt, void *arg);
|
||||
|
||||
/* Check for and handle local prot-specific iovar commands */
|
||||
extern int dhd_bus_iovar_op(dhd_pub_t *dhdp, const char *name,
|
||||
void *params, int plen, void *arg, int len, bool set);
|
||||
|
||||
/* Add bus dump output to a buffer */
|
||||
extern void dhd_bus_dump(dhd_pub_t *dhdp, struct bcmstrbuf *strbuf);
|
||||
|
||||
/* Clear any bus counters */
|
||||
extern void dhd_bus_clearcounts(dhd_pub_t *dhdp);
|
||||
|
||||
/* return the dongle chipid */
|
||||
extern uint dhd_bus_chip(struct dhd_bus *bus);
|
||||
|
||||
/* return the dongle chiprev */
|
||||
extern uint dhd_bus_chiprev(struct dhd_bus *bus);
|
||||
|
||||
/* Set user-specified nvram parameters. */
|
||||
extern void dhd_bus_set_nvram_params(struct dhd_bus * bus, const char *nvram_params);
|
||||
|
||||
extern void *dhd_bus_pub(struct dhd_bus *bus);
|
||||
extern void *dhd_bus_txq(struct dhd_bus *bus);
|
||||
extern void *dhd_bus_sih(struct dhd_bus *bus);
|
||||
extern uint dhd_bus_hdrlen(struct dhd_bus *bus);
|
||||
#ifdef BCMSDIO
|
||||
extern void dhd_bus_set_dotxinrx(struct dhd_bus *bus, bool val);
|
||||
/* return sdio io status */
|
||||
extern uint8 dhd_bus_is_ioready(struct dhd_bus *bus);
|
||||
#else
|
||||
#define dhd_bus_set_dotxinrx(a, b) do {} while (0)
|
||||
#endif // endif
|
||||
|
||||
#define DHD_SET_BUS_STATE_DOWN(_bus) do { \
|
||||
(_bus)->dhd->busstate = DHD_BUS_DOWN; \
|
||||
} while (0)
|
||||
|
||||
/* Register a dummy SDIO client driver in order to be notified of new SDIO device */
|
||||
extern int dhd_bus_reg_sdio_notify(void* semaphore);
|
||||
extern void dhd_bus_unreg_sdio_notify(void);
|
||||
extern void dhd_txglom_enable(dhd_pub_t *dhdp, bool enable);
|
||||
extern int dhd_bus_get_ids(struct dhd_bus *bus, uint32 *bus_type, uint32 *bus_num,
|
||||
uint32 *slot_num);
|
||||
|
||||
#if defined(DHD_FW_COREDUMP) && (defined(BCMPCIE) || defined(BCMSDIO))
|
||||
extern int dhd_bus_mem_dump(dhd_pub_t *dhd);
|
||||
extern int dhd_bus_get_mem_dump(dhd_pub_t *dhdp);
|
||||
#else
|
||||
#define dhd_bus_mem_dump(x)
|
||||
#define dhd_bus_get_mem_dump(x)
|
||||
#endif /* DHD_FW_COREDUMP && (BCMPCIE || BCMSDIO) */
|
||||
|
||||
#ifdef BCMPCIE
|
||||
enum {
|
||||
/* Scratch buffer confiuguration update */
|
||||
D2H_DMA_SCRATCH_BUF,
|
||||
D2H_DMA_SCRATCH_BUF_LEN,
|
||||
|
||||
/* DMA Indices array buffers for: H2D WR and RD, and D2H WR and RD */
|
||||
H2D_DMA_INDX_WR_BUF, /* update H2D WR dma indices buf base addr to dongle */
|
||||
H2D_DMA_INDX_RD_BUF, /* update H2D RD dma indices buf base addr to dongle */
|
||||
D2H_DMA_INDX_WR_BUF, /* update D2H WR dma indices buf base addr to dongle */
|
||||
D2H_DMA_INDX_RD_BUF, /* update D2H RD dma indices buf base addr to dongle */
|
||||
|
||||
/* DHD sets/gets WR or RD index, in host's H2D and D2H DMA indices buffer */
|
||||
H2D_DMA_INDX_WR_UPD, /* update H2D WR index in H2D WR dma indices buf */
|
||||
H2D_DMA_INDX_RD_UPD, /* update H2D RD index in H2D RD dma indices buf */
|
||||
D2H_DMA_INDX_WR_UPD, /* update D2H WR index in D2H WR dma indices buf */
|
||||
D2H_DMA_INDX_RD_UPD, /* update D2H RD index in D2H RD dma indices buf */
|
||||
|
||||
/* DHD Indices array buffers and update for: H2D flow ring WR */
|
||||
H2D_IFRM_INDX_WR_BUF, /* update H2D WR dma indices buf base addr to dongle */
|
||||
H2D_IFRM_INDX_WR_UPD, /* update H2D WR dma indices buf base addr to dongle */
|
||||
|
||||
/* H2D and D2H Mailbox data update */
|
||||
H2D_MB_DATA,
|
||||
D2H_MB_DATA,
|
||||
|
||||
/* (Common) MsgBuf Ring configuration update */
|
||||
RING_BUF_ADDR, /* update ring base address to dongle */
|
||||
RING_ITEM_LEN, /* update ring item size to dongle */
|
||||
RING_MAX_ITEMS, /* update ring max items to dongle */
|
||||
|
||||
/* Update of WR or RD index, for a MsgBuf Ring */
|
||||
RING_RD_UPD, /* update ring read index from/to dongle */
|
||||
RING_WR_UPD, /* update ring write index from/to dongle */
|
||||
|
||||
TOTAL_LFRAG_PACKET_CNT,
|
||||
MAX_HOST_RXBUFS,
|
||||
HOST_API_VERSION,
|
||||
DNGL_TO_HOST_TRAP_ADDR,
|
||||
HOST_SCB_ADDR, /* update host scb base address to dongle */
|
||||
};
|
||||
|
||||
typedef void (*dhd_mb_ring_t) (struct dhd_bus *, uint32);
|
||||
typedef void (*dhd_mb_ring_2_t) (struct dhd_bus *, uint32, bool);
|
||||
extern void dhd_bus_cmn_writeshared(struct dhd_bus *bus, void * data, uint32 len, uint8 type,
|
||||
uint16 ringid);
|
||||
extern void dhd_bus_ringbell(struct dhd_bus *bus, uint32 value);
|
||||
extern void dhd_bus_ringbell_2(struct dhd_bus *bus, uint32 value, bool devwake);
|
||||
extern void dhd_bus_cmn_readshared(struct dhd_bus *bus, void* data, uint8 type, uint16 ringid);
|
||||
extern uint32 dhd_bus_get_sharedflags(struct dhd_bus *bus);
|
||||
extern void dhd_bus_rx_frame(struct dhd_bus *bus, void* pkt, int ifidx, uint pkt_count);
|
||||
extern void dhd_bus_start_queue(struct dhd_bus *bus);
|
||||
extern void dhd_bus_stop_queue(struct dhd_bus *bus);
|
||||
extern dhd_mb_ring_t dhd_bus_get_mbintr_fn(struct dhd_bus *bus);
|
||||
extern dhd_mb_ring_2_t dhd_bus_get_mbintr_2_fn(struct dhd_bus *bus);
|
||||
extern void dhd_bus_write_flow_ring_states(struct dhd_bus *bus,
|
||||
void * data, uint16 flowid);
|
||||
extern void dhd_bus_read_flow_ring_states(struct dhd_bus *bus,
|
||||
void * data, uint8 flowid);
|
||||
extern int dhd_bus_flow_ring_create_request(struct dhd_bus *bus, void *flow_ring_node);
|
||||
extern void dhd_bus_clean_flow_ring(struct dhd_bus *bus, void *flow_ring_node);
|
||||
extern void dhd_bus_flow_ring_create_response(struct dhd_bus *bus, uint16 flow_id, int32 status);
|
||||
extern int dhd_bus_flow_ring_delete_request(struct dhd_bus *bus, void *flow_ring_node);
|
||||
extern void dhd_bus_flow_ring_delete_response(struct dhd_bus *bus, uint16 flowid, uint32 status);
|
||||
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);
|
||||
|
||||
#ifdef IDLE_TX_FLOW_MGMT
|
||||
extern void dhd_bus_flow_ring_resume_response(struct dhd_bus *bus, uint16 flowid, int32 status);
|
||||
#endif /* IDLE_TX_FLOW_MGMT */
|
||||
|
||||
extern int dhdpcie_bus_clock_start(struct dhd_bus *bus);
|
||||
extern int dhdpcie_bus_clock_stop(struct dhd_bus *bus);
|
||||
extern int dhdpcie_bus_enable_device(struct dhd_bus *bus);
|
||||
extern int dhdpcie_bus_disable_device(struct dhd_bus *bus);
|
||||
extern int dhdpcie_bus_alloc_resource(struct dhd_bus *bus);
|
||||
extern void dhdpcie_bus_free_resource(struct dhd_bus *bus);
|
||||
extern bool dhdpcie_bus_dongle_attach(struct dhd_bus *bus);
|
||||
extern int dhd_bus_release_dongle(struct dhd_bus *bus);
|
||||
extern int dhd_bus_request_irq(struct dhd_bus *bus);
|
||||
extern int dhdpcie_get_pcieirq(struct dhd_bus *bus, unsigned int *irq);
|
||||
extern void dhd_bus_aer_config(struct dhd_bus *bus);
|
||||
|
||||
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);
|
||||
|
||||
extern void dhdpcie_ssreset_dis_enum_rst(struct dhd_bus *bus);
|
||||
|
||||
#ifdef DHD_FW_COREDUMP
|
||||
extern int dhd_dongle_mem_dump(void);
|
||||
#endif /* DHD_FW_COREDUMP */
|
||||
|
||||
#ifdef IDLE_TX_FLOW_MGMT
|
||||
extern void dhd_bus_idle_tx_ring_suspend(dhd_pub_t *dhd, uint16 flow_ring_id);
|
||||
#endif /* IDLE_TX_FLOW_MGMT */
|
||||
extern void dhd_bus_handle_mb_data(struct dhd_bus *bus, uint32 d2h_mb_data);
|
||||
#endif /* BCMPCIE */
|
||||
|
||||
/* dump the device trap informtation */
|
||||
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);
|
||||
/* Function to set default min res mask */
|
||||
extern bool dhd_bus_set_default_min_res_mask(struct dhd_bus *bus);
|
||||
|
||||
/* Function to reset PMU registers */
|
||||
extern void dhd_bus_pmu_reg_reset(dhd_pub_t *dhdp);
|
||||
|
||||
extern void dhd_bus_ucode_download(struct dhd_bus *bus);
|
||||
|
||||
#ifdef DHD_ULP
|
||||
extern void dhd_bus_ulp_disable_console(dhd_pub_t *dhdp);
|
||||
#endif /* DHD_ULP */
|
||||
extern int dhd_bus_readwrite_bp_addr(dhd_pub_t *dhdp, uint addr, uint size, uint* data, bool read);
|
||||
extern int dhd_get_idletime(dhd_pub_t *dhd);
|
||||
#ifdef BCMPCIE
|
||||
extern void dhd_bus_dump_console_buffer(struct dhd_bus *bus);
|
||||
extern void dhd_bus_intr_count_dump(dhd_pub_t *dhdp);
|
||||
extern void dhd_bus_set_dpc_sched_time(dhd_pub_t *dhdp);
|
||||
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 void dhd_bus_set_linkdown(dhd_pub_t *dhdp, bool val);
|
||||
extern int dhd_bus_get_linkdown(dhd_pub_t *dhdp);
|
||||
#else
|
||||
#define dhd_bus_dump_console_buffer(x)
|
||||
static INLINE void dhd_bus_intr_count_dump(dhd_pub_t *dhdp) { UNUSED_PARAMETER(dhdp); }
|
||||
static INLINE void dhd_bus_set_dpc_sched_time(dhd_pub_t *dhdp) { }
|
||||
static INLINE bool dhd_bus_query_dpc_sched_errors(dhd_pub_t *dhdp) { return 0; }
|
||||
static INLINE int dhd_bus_dmaxfer_lpbk(dhd_pub_t *dhdp, uint32 type) { return 0; }
|
||||
static INLINE bool dhd_bus_check_driver_up(void) { return FALSE; }
|
||||
extern INLINE void dhd_bus_set_linkdown(dhd_pub_t *dhdp, bool val) { }
|
||||
extern 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; }
|
||||
#endif /* BCMPCIE */
|
||||
|
||||
#if defined(BCMPCIE) && defined(EWP_ETD_PRSRV_LOGS)
|
||||
void dhdpcie_get_etd_preserve_logs(dhd_pub_t *dhd, uint8 *ext_trap_data,
|
||||
void *event_decode_data);
|
||||
#endif // endif
|
||||
|
||||
extern uint16 dhd_get_chipid(dhd_pub_t *dhd);
|
||||
|
||||
#ifdef DHD_WAKE_STATUS
|
||||
extern wake_counts_t* dhd_bus_get_wakecount(dhd_pub_t *dhd);
|
||||
extern int dhd_bus_get_bus_wake(dhd_pub_t * dhd);
|
||||
#endif /* DHD_WAKE_STATUS */
|
||||
|
||||
#ifdef BT_OVER_SDIO
|
||||
/*
|
||||
* SDIO layer clock control functions exposed to be called from other layers.
|
||||
* This is required especially in the case where the BUS is shared between
|
||||
* BT and SDIO and we have to control the clock. The callers of this function
|
||||
* are expected to hold the sdlock
|
||||
*/
|
||||
int __dhdsdio_clk_enable(struct dhd_bus *bus, bus_owner_t owner, int can_wait);
|
||||
int __dhdsdio_clk_disable(struct dhd_bus *bus, bus_owner_t owner, int can_wait);
|
||||
void dhdsdio_reset_bt_use_count(struct dhd_bus *bus);
|
||||
#endif /* BT_OVER_SDIO */
|
||||
|
||||
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 void dhd_bus_l1ss_enable_rc_ep(struct dhd_bus *bus, bool enable);
|
||||
|
||||
bool dhd_bus_is_multibp_capable(struct dhd_bus *bus);
|
||||
|
||||
#ifdef BCMPCIE
|
||||
extern void dhdpcie_advertise_bus_cleanup(dhd_pub_t *dhdp);
|
||||
extern void dhd_msgbuf_iovar_timeout_dump(dhd_pub_t *dhd);
|
||||
#endif /* BCMPCIE */
|
||||
|
||||
extern bool dhd_bus_force_bt_quiesce_enabled(struct dhd_bus *bus);
|
||||
|
||||
#ifdef DHD_SSSR_DUMP
|
||||
extern int dhd_bus_fis_trigger(dhd_pub_t *dhd);
|
||||
extern int dhd_bus_fis_dump(dhd_pub_t *dhd);
|
||||
#endif /* DHD_SSSR_DUMP */
|
||||
|
||||
#ifdef PCIE_FULL_DONGLE
|
||||
extern int dhdpcie_set_dma_ring_indices(dhd_pub_t *dhd, int32 int_val);
|
||||
#endif /* PCIE_FULL_DONGLE */
|
||||
|
||||
#ifdef DHD_USE_BP_RESET
|
||||
extern int dhd_bus_perform_bp_reset(struct dhd_bus *bus);
|
||||
#endif /* DHD_USE_BP_RESET */
|
||||
|
||||
extern void dhd_bwm_bt_quiesce(struct dhd_bus *bus);
|
||||
extern void dhd_bwm_bt_resume(struct dhd_bus *bus);
|
||||
#endif /* _dhd_bus_h_ */
|
||||
@@ -0,0 +1,38 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef _DHD_BUZZZ_H_INCLUDED_
|
||||
#define _DHD_BUZZZ_H_INCLUDED_
|
||||
|
||||
/*
|
||||
* Broadcom logging system - Empty implementaiton
|
||||
* Copyright (C) 1999-2019, 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.
|
||||
*
|
||||
* 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$
|
||||
*/
|
||||
|
||||
#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_H_INCLUDED_ */
|
||||
981
drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd_wifi6/dhd_cdc.c
Normal file
981
drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd_wifi6/dhd_cdc.c
Normal file
@@ -0,0 +1,981 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* DHD Protocol Module for CDC and BDC.
|
||||
*
|
||||
* Copyright (C) 1999-2019, 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.
|
||||
*
|
||||
* Notwithstanding the above, under no circumstances may you combine this
|
||||
* software in any way with any other Broadcom software provided under a license
|
||||
* other than the GPL, without Broadcom's express prior written consent.
|
||||
*
|
||||
*
|
||||
* <<Broadcom-WL-IPTag/Open:>>
|
||||
*
|
||||
* $Id: dhd_cdc.c 752794 2018-03-19 04:00:31Z $
|
||||
*
|
||||
* BDC is like CDC, except it includes a header for data packets to convey
|
||||
* packet priority over the bus, and flags (e.g. to indicate checksum status
|
||||
* for dongle offload.)
|
||||
*/
|
||||
|
||||
#include <typedefs.h>
|
||||
#include <osl.h>
|
||||
|
||||
#include <bcmutils.h>
|
||||
#include <bcmcdc.h>
|
||||
#include <bcmendian.h>
|
||||
|
||||
#include <dngl_stats.h>
|
||||
#include <dhd.h>
|
||||
#include <dhd_proto.h>
|
||||
#include <dhd_bus.h>
|
||||
#include <dhd_dbg.h>
|
||||
|
||||
#ifdef PROP_TXSTATUS
|
||||
#include <wlfc_proto.h>
|
||||
#include <dhd_wlfc.h>
|
||||
#endif // endif
|
||||
#ifdef BCMDBUS
|
||||
#include <dhd_config.h>
|
||||
#endif /* BCMDBUS */
|
||||
|
||||
#ifdef DHD_ULP
|
||||
#include <dhd_ulp.h>
|
||||
#endif /* DHD_ULP */
|
||||
|
||||
#define RETRIES 2 /* # of retries to retrieve matching ioctl response */
|
||||
#define BUS_HEADER_LEN (24+DHD_SDALIGN) /* Must be at least SDPCM_RESERVE
|
||||
* defined in dhd_sdio.c (amount of header tha might be added)
|
||||
* plus any space that might be needed for alignment padding.
|
||||
*/
|
||||
#define ROUND_UP_MARGIN 2048 /* Biggest SDIO block size possible for
|
||||
* round off at the end of buffer
|
||||
*/
|
||||
|
||||
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];
|
||||
} dhd_prot_t;
|
||||
|
||||
uint16
|
||||
dhd_prot_get_ioctl_trans_id(dhd_pub_t *dhdp)
|
||||
{
|
||||
/* SDIO does not have ioctl_trans_id yet, so return -1 */
|
||||
return -1;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
DHD_TRACE(("%s: Enter\n", __FUNCTION__));
|
||||
|
||||
DHD_OS_WAKE_LOCK(dhd);
|
||||
|
||||
/* NOTE : cdc->msg.len holds the desired length of the buffer to be
|
||||
* returned. Only up to CDC_MAX_MSG_SIZE of this buffer area
|
||||
* is actually sent to the dongle
|
||||
*/
|
||||
if (len > CDC_MAX_MSG_SIZE)
|
||||
len = CDC_MAX_MSG_SIZE;
|
||||
|
||||
/* Send request */
|
||||
#ifdef BCMDBUS
|
||||
DHD_OS_IOCTL_RESP_LOCK(dhd);
|
||||
prot->ctl_completed = FALSE;
|
||||
err = dbus_send_ctl(dhd->bus, (void *)&prot->msg, len);
|
||||
if (err) {
|
||||
DHD_ERROR(("dbus_send_ctl error=%d\n", err));
|
||||
DHD_OS_IOCTL_RESP_UNLOCK(dhd);
|
||||
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;
|
||||
}
|
||||
DHD_OS_IOCTL_RESP_UNLOCK(dhd);
|
||||
#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) {
|
||||
DHD_OS_IOCTL_RESP_LOCK(dhd);
|
||||
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"));
|
||||
}
|
||||
}
|
||||
DHD_OS_IOCTL_RESP_UNLOCK(dhd);
|
||||
}
|
||||
#endif /* defined(BCMDBUS) && defined(INTR_EP_ENABLE) */
|
||||
DHD_OS_WAKE_UNLOCK(dhd);
|
||||
return err;
|
||||
}
|
||||
|
||||
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__));
|
||||
|
||||
do {
|
||||
#ifdef BCMDBUS
|
||||
DHD_OS_IOCTL_RESP_LOCK(dhd);
|
||||
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));
|
||||
DHD_OS_IOCTL_RESP_UNLOCK(dhd);
|
||||
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 = -1;
|
||||
DHD_OS_IOCTL_RESP_UNLOCK(dhd);
|
||||
|
||||
goto done;
|
||||
}
|
||||
DHD_OS_IOCTL_RESP_UNLOCK(dhd);
|
||||
|
||||
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);
|
||||
|
||||
#ifdef BCMDBUS
|
||||
done:
|
||||
#endif /* BCMDBUS */
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
dhdcdc_query_ioctl(dhd_pub_t *dhd, int ifidx, uint cmd, void *buf, uint len, uint8 action)
|
||||
{
|
||||
dhd_prot_t *prot = dhd->prot;
|
||||
cdc_ioctl_t *msg = &prot->msg;
|
||||
int ret = 0, retries = 0;
|
||||
uint32 id, flags = 0;
|
||||
|
||||
DHD_TRACE(("%s: Enter\n", __FUNCTION__));
|
||||
DHD_CTL(("%s: cmd %d len %d\n", __FUNCTION__, cmd, len));
|
||||
|
||||
/* Respond "bcmerror" and "bcmerrorstr" with local cache */
|
||||
if (cmd == WLC_GET_VAR && buf)
|
||||
{
|
||||
if (!strcmp((char *)buf, "bcmerrorstr"))
|
||||
{
|
||||
strncpy((char *)buf, bcmerrorstr(dhd->dongle_error), BCME_STRLEN);
|
||||
goto done;
|
||||
}
|
||||
else if (!strcmp((char *)buf, "bcmerror"))
|
||||
{
|
||||
*(int *)buf = dhd->dongle_error;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
memset(msg, 0, sizeof(cdc_ioctl_t));
|
||||
|
||||
#ifdef BCMSPI
|
||||
/* 11bit gSPI bus allows 2048bytes of max-data. We restrict 'len'
|
||||
* value which is 8Kbytes for various 'get' commands to 2000. 48 bytes are
|
||||
* left for sw headers and misc.
|
||||
*/
|
||||
if (len > 2000) {
|
||||
DHD_ERROR(("dhdcdc_query_ioctl: len is truncated to 2000 bytes\n"));
|
||||
len = 2000;
|
||||
}
|
||||
#endif /* BCMSPI */
|
||||
msg->cmd = htol32(cmd);
|
||||
msg->len = htol32(len);
|
||||
msg->flags = (++prot->reqid << CDCF_IOC_ID_SHIFT);
|
||||
CDC_SET_IF_IDX(msg, ifidx);
|
||||
/* add additional action bits */
|
||||
action &= WL_IOCTL_ACTION_MASK;
|
||||
msg->flags |= (action << CDCF_IOC_ACTION_SHIFT);
|
||||
msg->flags = htol32(msg->flags);
|
||||
|
||||
if (buf)
|
||||
memcpy(prot->buf, buf, len);
|
||||
|
||||
if ((ret = dhdcdc_msg(dhd)) < 0) {
|
||||
if (!dhd->hang_was_sent)
|
||||
DHD_ERROR(("dhdcdc_query_ioctl: dhdcdc_msg failed w/status %d\n", ret));
|
||||
goto done;
|
||||
}
|
||||
|
||||
retry:
|
||||
/* wait for interrupt and get first fragment */
|
||||
if ((ret = dhdcdc_cmplt(dhd, prot->reqid, len)) < 0)
|
||||
goto done;
|
||||
|
||||
flags = ltoh32(msg->flags);
|
||||
id = (flags & CDCF_IOC_ID_MASK) >> CDCF_IOC_ID_SHIFT;
|
||||
|
||||
if ((id < prot->reqid) && (++retries < RETRIES))
|
||||
goto retry;
|
||||
if (id != prot->reqid) {
|
||||
DHD_ERROR(("%s: %s: unexpected request id %d (expected %d)\n",
|
||||
dhd_ifname(dhd, ifidx), __FUNCTION__, id, prot->reqid));
|
||||
ret = -EINVAL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Copy info buffer */
|
||||
if (buf)
|
||||
{
|
||||
if (ret < (int)len)
|
||||
len = ret;
|
||||
memcpy(buf, (void*) prot->buf, len);
|
||||
}
|
||||
|
||||
/* Check the ERROR flag */
|
||||
if (flags & CDCF_IOC_ERROR)
|
||||
{
|
||||
ret = ltoh32(msg->status);
|
||||
/* Cache error from dongle */
|
||||
dhd->dongle_error = ret;
|
||||
}
|
||||
|
||||
done:
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef DHD_PM_CONTROL_FROM_FILE
|
||||
extern bool g_pm_control;
|
||||
#endif /* DHD_PM_CONTROL_FROM_FILE */
|
||||
|
||||
static int
|
||||
dhdcdc_set_ioctl(dhd_pub_t *dhd, int ifidx, uint cmd, void *buf, uint len, uint8 action)
|
||||
{
|
||||
dhd_prot_t *prot = dhd->prot;
|
||||
cdc_ioctl_t *msg = &prot->msg;
|
||||
int ret = 0;
|
||||
uint32 flags, id;
|
||||
|
||||
DHD_TRACE(("%s: Enter\n", __FUNCTION__));
|
||||
DHD_CTL(("%s: cmd %d len %d\n", __FUNCTION__, cmd, len));
|
||||
|
||||
if (dhd->busstate == DHD_BUS_DOWN) {
|
||||
DHD_ERROR(("%s : bus is down. we have nothing to do\n", __FUNCTION__));
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
/* don't talk to the dongle if fw is about to be reloaded */
|
||||
if (dhd->hang_was_sent) {
|
||||
DHD_ERROR(("%s: HANG was sent up earlier. Not talking to the chip\n",
|
||||
__FUNCTION__));
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
if (cmd == WLC_SET_PM) {
|
||||
#ifdef DHD_PM_CONTROL_FROM_FILE
|
||||
if (g_pm_control == TRUE) {
|
||||
DHD_ERROR(("%s: SET PM ignored!(Requested:%d)\n",
|
||||
__FUNCTION__, buf ? *(char *)buf : 0));
|
||||
goto done;
|
||||
}
|
||||
#endif /* DHD_PM_CONTROL_FROM_FILE */
|
||||
DHD_TRACE_HW4(("%s: SET PM to %d\n", __FUNCTION__, buf ? *(char *)buf : 0));
|
||||
}
|
||||
|
||||
memset(msg, 0, sizeof(cdc_ioctl_t));
|
||||
|
||||
msg->cmd = htol32(cmd);
|
||||
msg->len = htol32(len);
|
||||
msg->flags = (++prot->reqid << CDCF_IOC_ID_SHIFT);
|
||||
CDC_SET_IF_IDX(msg, ifidx);
|
||||
/* add additional action bits */
|
||||
action &= WL_IOCTL_ACTION_MASK;
|
||||
msg->flags |= (action << CDCF_IOC_ACTION_SHIFT) | CDCF_IOC_SET;
|
||||
msg->flags = htol32(msg->flags);
|
||||
|
||||
if (buf)
|
||||
memcpy(prot->buf, buf, len);
|
||||
|
||||
#ifdef DHD_ULP
|
||||
if (buf && (!strncmp(buf, "ulp", sizeof("ulp")))) {
|
||||
/* force all the writes after this point to NOT to use cached sbwad value */
|
||||
dhd_ulp_disable_cached_sbwad(dhd);
|
||||
}
|
||||
#endif /* DHD_ULP */
|
||||
|
||||
if ((ret = dhdcdc_msg(dhd)) < 0) {
|
||||
DHD_ERROR(("%s: dhdcdc_msg failed w/status %d\n", __FUNCTION__, ret));
|
||||
goto done;
|
||||
}
|
||||
|
||||
if ((ret = dhdcdc_cmplt(dhd, prot->reqid, len)) < 0)
|
||||
goto done;
|
||||
|
||||
flags = ltoh32(msg->flags);
|
||||
id = (flags & CDCF_IOC_ID_MASK) >> CDCF_IOC_ID_SHIFT;
|
||||
|
||||
if (id != prot->reqid) {
|
||||
DHD_ERROR(("%s: %s: unexpected request id %d (expected %d)\n",
|
||||
dhd_ifname(dhd, ifidx), __FUNCTION__, id, prot->reqid));
|
||||
ret = -EINVAL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
#ifdef DHD_ULP
|
||||
/* For ulp prototyping temporary */
|
||||
if ((ret = dhd_ulp_check_ulp_request(dhd, buf)) < 0)
|
||||
goto done;
|
||||
#endif /* DHD_ULP */
|
||||
|
||||
/* Check the ERROR flag */
|
||||
if (flags & CDCF_IOC_ERROR)
|
||||
{
|
||||
ret = ltoh32(msg->status);
|
||||
/* Cache error from dongle */
|
||||
dhd->dongle_error = ret;
|
||||
}
|
||||
|
||||
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);
|
||||
DHD_OS_IOCTL_RESP_LOCK(dhd);
|
||||
prot->ctl_completed = TRUE;
|
||||
dhd_os_ioctl_resp_wake(dhd);
|
||||
DHD_OS_IOCTL_RESP_UNLOCK(dhd);
|
||||
return 0;
|
||||
}
|
||||
#endif /* BCMDBUS */
|
||||
|
||||
int
|
||||
dhd_prot_ioctl(dhd_pub_t *dhd, int ifidx, wl_ioctl_t * ioc, void * buf, int len)
|
||||
{
|
||||
dhd_prot_t *prot = dhd->prot;
|
||||
int ret = -1;
|
||||
uint8 action;
|
||||
static int error_cnt = 0;
|
||||
|
||||
if ((dhd->busstate == DHD_BUS_DOWN) || dhd->hang_was_sent) {
|
||||
DHD_ERROR(("%s : bus is down. we have nothing to do - bs: %d, has: %d\n",
|
||||
__FUNCTION__, dhd->busstate, dhd->hang_was_sent));
|
||||
goto done;
|
||||
}
|
||||
|
||||
DHD_TRACE(("%s: Enter\n", __FUNCTION__));
|
||||
|
||||
ASSERT(len <= WLC_IOCTL_MAXLEN);
|
||||
|
||||
if (len > WLC_IOCTL_MAXLEN)
|
||||
goto done;
|
||||
|
||||
if (prot->pending == TRUE) {
|
||||
DHD_ERROR(("CDC packet is pending!!!! cmd=0x%x (%lu) lastcmd=0x%x (%lu)\n",
|
||||
ioc->cmd, (unsigned long)ioc->cmd, prot->lastcmd,
|
||||
(unsigned long)prot->lastcmd));
|
||||
if ((ioc->cmd == WLC_SET_VAR) || (ioc->cmd == WLC_GET_VAR)) {
|
||||
DHD_TRACE(("iovar cmd=%s\n", buf ? (char*)buf : "\0"));
|
||||
}
|
||||
goto done;
|
||||
}
|
||||
|
||||
prot->pending = TRUE;
|
||||
prot->lastcmd = ioc->cmd;
|
||||
action = ioc->set;
|
||||
if (action & WL_IOCTL_ACTION_SET)
|
||||
ret = dhdcdc_set_ioctl(dhd, ifidx, ioc->cmd, buf, len, action);
|
||||
else {
|
||||
ret = dhdcdc_query_ioctl(dhd, ifidx, ioc->cmd, buf, len, action);
|
||||
if (ret > 0)
|
||||
ioc->used = ret - sizeof(cdc_ioctl_t);
|
||||
}
|
||||
// terence 20130805: send hang event to wpa_supplicant
|
||||
if (ret == -EIO) {
|
||||
error_cnt++;
|
||||
if (error_cnt > 2)
|
||||
ret = -ETIMEDOUT;
|
||||
} else
|
||||
error_cnt = 0;
|
||||
|
||||
/* Too many programs assume ioctl() returns 0 on success */
|
||||
if (ret >= 0)
|
||||
ret = 0;
|
||||
else {
|
||||
cdc_ioctl_t *msg = &prot->msg;
|
||||
ioc->needed = ltoh32(msg->len); /* len == needed when set/query fails from dongle */
|
||||
}
|
||||
|
||||
/* Intercept the wme_dp ioctl here */
|
||||
if ((!ret) && (ioc->cmd == WLC_SET_VAR) && (!strcmp(buf, "wme_dp"))) {
|
||||
int slen, val = 0;
|
||||
|
||||
slen = strlen("wme_dp") + 1;
|
||||
if (len >= (int)(slen + sizeof(int)))
|
||||
bcopy(((char *)buf + slen), &val, sizeof(int));
|
||||
dhd->wme_dp = (uint8) ltoh32(val);
|
||||
}
|
||||
|
||||
prot->pending = FALSE;
|
||||
|
||||
done:
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
dhd_prot_iovar_op(dhd_pub_t *dhdp, const char *name,
|
||||
void *params, int plen, void *arg, int len, bool set)
|
||||
{
|
||||
return BCME_UNSUPPORTED;
|
||||
}
|
||||
|
||||
void
|
||||
dhd_prot_dump(dhd_pub_t *dhdp, struct bcmstrbuf *strbuf)
|
||||
{
|
||||
if (!dhdp || !dhdp->prot) {
|
||||
return;
|
||||
}
|
||||
|
||||
bcm_bprintf(strbuf, "Protocol CDC: reqid %d\n", dhdp->prot->reqid);
|
||||
#ifdef PROP_TXSTATUS
|
||||
dhd_wlfc_dump(dhdp, strbuf);
|
||||
#endif // endif
|
||||
}
|
||||
|
||||
/* The FreeBSD PKTPUSH could change the packet buf pinter
|
||||
so we need to make it changable
|
||||
*/
|
||||
#define PKTBUF pktbuf
|
||||
void
|
||||
dhd_prot_hdrpush(dhd_pub_t *dhd, int ifidx, void *PKTBUF)
|
||||
{
|
||||
#ifdef BDC
|
||||
struct bdc_header *h;
|
||||
#endif /* BDC */
|
||||
|
||||
DHD_TRACE(("%s: Enter\n", __FUNCTION__));
|
||||
|
||||
#ifdef BDC
|
||||
/* Push BDC header used to convey priority for buses that don't */
|
||||
|
||||
PKTPUSH(dhd->osh, PKTBUF, BDC_HEADER_LEN);
|
||||
|
||||
h = (struct bdc_header *)PKTDATA(dhd->osh, PKTBUF);
|
||||
|
||||
h->flags = (BDC_PROTO_VER << BDC_FLAG_VER_SHIFT);
|
||||
if (PKTSUMNEEDED(PKTBUF))
|
||||
h->flags |= BDC_FLAG_SUM_NEEDED;
|
||||
|
||||
h->priority = (PKTPRIO(PKTBUF) & BDC_PRIORITY_MASK);
|
||||
h->flags2 = 0;
|
||||
h->dataOffset = 0;
|
||||
#endif /* BDC */
|
||||
BDC_SET_IF_IDX(h, ifidx);
|
||||
}
|
||||
#undef PKTBUF /* Only defined in the above routine */
|
||||
|
||||
uint
|
||||
dhd_prot_hdrlen(dhd_pub_t *dhd, void *PKTBUF)
|
||||
{
|
||||
uint hdrlen = 0;
|
||||
#ifdef BDC
|
||||
/* Length of BDC(+WLFC) headers pushed */
|
||||
hdrlen = BDC_HEADER_LEN + (((struct bdc_header *)PKTBUF)->dataOffset * 4);
|
||||
#endif // endif
|
||||
return hdrlen;
|
||||
}
|
||||
|
||||
int
|
||||
dhd_prot_hdrpull(dhd_pub_t *dhd, int *ifidx, void *pktbuf, uchar *reorder_buf_info,
|
||||
uint *reorder_info_len)
|
||||
{
|
||||
#ifdef BDC
|
||||
struct bdc_header *h;
|
||||
#endif // endif
|
||||
uint8 data_offset = 0;
|
||||
|
||||
DHD_TRACE(("%s: Enter\n", __FUNCTION__));
|
||||
|
||||
#ifdef BDC
|
||||
if (reorder_info_len)
|
||||
*reorder_info_len = 0;
|
||||
/* Pop BDC header used to convey priority for buses that don't */
|
||||
|
||||
if (PKTLEN(dhd->osh, pktbuf) < BDC_HEADER_LEN) {
|
||||
DHD_ERROR(("%s: rx data too short (%d < %d)\n", __FUNCTION__,
|
||||
PKTLEN(dhd->osh, pktbuf), BDC_HEADER_LEN));
|
||||
return BCME_ERROR;
|
||||
}
|
||||
|
||||
h = (struct bdc_header *)PKTDATA(dhd->osh, pktbuf);
|
||||
|
||||
if (!ifidx) {
|
||||
/* for tx packet, skip the analysis */
|
||||
data_offset = h->dataOffset;
|
||||
PKTPULL(dhd->osh, pktbuf, BDC_HEADER_LEN);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
*ifidx = BDC_GET_IF_IDX(h);
|
||||
|
||||
if (((h->flags & BDC_FLAG_VER_MASK) >> BDC_FLAG_VER_SHIFT) != BDC_PROTO_VER) {
|
||||
DHD_ERROR(("%s: non-BDC packet received, flags = 0x%x\n",
|
||||
dhd_ifname(dhd, *ifidx), h->flags));
|
||||
if (((h->flags & BDC_FLAG_VER_MASK) >> BDC_FLAG_VER_SHIFT) == BDC_PROTO_VER_1)
|
||||
h->dataOffset = 0;
|
||||
else
|
||||
return BCME_ERROR;
|
||||
}
|
||||
|
||||
if (h->flags & BDC_FLAG_SUM_GOOD) {
|
||||
DHD_INFO(("%s: BDC packet received with good rx-csum, flags 0x%x\n",
|
||||
dhd_ifname(dhd, *ifidx), h->flags));
|
||||
PKTSETSUMGOOD(pktbuf, TRUE);
|
||||
}
|
||||
|
||||
PKTSETPRIO(pktbuf, (h->priority & BDC_PRIORITY_MASK));
|
||||
data_offset = h->dataOffset;
|
||||
PKTPULL(dhd->osh, pktbuf, BDC_HEADER_LEN);
|
||||
#endif /* BDC */
|
||||
|
||||
#ifdef PROP_TXSTATUS
|
||||
if (!DHD_PKTTAG_PKTDIR(PKTTAG(pktbuf))) {
|
||||
/*
|
||||
- parse txstatus only for packets that came from the firmware
|
||||
*/
|
||||
dhd_wlfc_parse_header_info(dhd, pktbuf, (data_offset << 2),
|
||||
reorder_buf_info, reorder_info_len);
|
||||
|
||||
#ifdef BCMDBUS
|
||||
#ifndef DHD_WLFC_THREAD
|
||||
dhd_wlfc_commit_packets(dhd,
|
||||
(f_commitpkt_t)dhd_bus_txdata, dhd->bus, NULL, FALSE);
|
||||
#endif /* DHD_WLFC_THREAD */
|
||||
#endif /* BCMDBUS */
|
||||
}
|
||||
#endif /* PROP_TXSTATUS */
|
||||
|
||||
exit:
|
||||
PKTPULL(dhd->osh, pktbuf, (data_offset << 2));
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
dhd_prot_attach(dhd_pub_t *dhd)
|
||||
{
|
||||
dhd_prot_t *cdc;
|
||||
|
||||
if (!(cdc = (dhd_prot_t *)DHD_OS_PREALLOC(dhd, DHD_PREALLOC_PROT, sizeof(dhd_prot_t)))) {
|
||||
DHD_ERROR(("%s: kmalloc failed\n", __FUNCTION__));
|
||||
goto fail;
|
||||
}
|
||||
memset(cdc, 0, sizeof(dhd_prot_t));
|
||||
|
||||
/* ensure that the msg buf directly follows the cdc msg struct */
|
||||
if ((uintptr)(&cdc->msg + 1) != (uintptr)cdc->buf) {
|
||||
DHD_ERROR(("dhd_prot_t is not correctly defined\n"));
|
||||
goto fail;
|
||||
}
|
||||
|
||||
dhd->prot = cdc;
|
||||
#ifdef BDC
|
||||
dhd->hdrlen += BDC_HEADER_LEN;
|
||||
#endif // endif
|
||||
dhd->maxctl = WLC_IOCTL_MAXLEN + sizeof(cdc_ioctl_t) + ROUND_UP_MARGIN;
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
if (cdc != NULL)
|
||||
DHD_OS_PREFREE(dhd, cdc, sizeof(dhd_prot_t));
|
||||
return BCME_NOMEM;
|
||||
}
|
||||
|
||||
/* ~NOTE~ What if another thread is waiting on the semaphore? Holding it? */
|
||||
void
|
||||
dhd_prot_detach(dhd_pub_t *dhd)
|
||||
{
|
||||
#ifdef PROP_TXSTATUS
|
||||
dhd_wlfc_deinit(dhd);
|
||||
#endif // endif
|
||||
DHD_OS_PREFREE(dhd, dhd->prot, sizeof(dhd_prot_t));
|
||||
dhd->prot = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
dhd_prot_dstats(dhd_pub_t *dhd)
|
||||
{
|
||||
/* copy bus stats */
|
||||
|
||||
dhd->dstats.tx_packets = dhd->tx_packets;
|
||||
dhd->dstats.tx_errors = dhd->tx_errors;
|
||||
dhd->dstats.rx_packets = dhd->rx_packets;
|
||||
dhd->dstats.rx_errors = dhd->rx_errors;
|
||||
dhd->dstats.rx_dropped = dhd->rx_dropped;
|
||||
dhd->dstats.multicast = dhd->rx_multicast;
|
||||
return;
|
||||
}
|
||||
|
||||
int
|
||||
dhd_sync_with_dongle(dhd_pub_t *dhd)
|
||||
{
|
||||
int ret = 0;
|
||||
wlc_rev_info_t revinfo;
|
||||
DHD_TRACE(("%s: Enter\n", __FUNCTION__));
|
||||
|
||||
#ifdef DHD_FW_COREDUMP
|
||||
/* Check the memdump capability */
|
||||
dhd_get_memdump_info(dhd);
|
||||
#endif /* DHD_FW_COREDUMP */
|
||||
|
||||
#ifdef BCMASSERT_LOG
|
||||
dhd_get_assert_info(dhd);
|
||||
#endif /* BCMASSERT_LOG */
|
||||
|
||||
/* Get the device rev info */
|
||||
memset(&revinfo, 0, sizeof(revinfo));
|
||||
ret = dhd_wl_ioctl_cmd(dhd, WLC_GET_REVINFO, &revinfo, sizeof(revinfo), FALSE, 0);
|
||||
if (ret < 0)
|
||||
goto done;
|
||||
#if defined(BCMDBUS)
|
||||
if (dhd_download_fw_on_driverload) {
|
||||
dhd_conf_reset(dhd);
|
||||
dhd_conf_set_chiprev(dhd, revinfo.chipnum, revinfo.chiprev);
|
||||
dhd_conf_preinit(dhd);
|
||||
dhd_conf_read_config(dhd, dhd->conf_path);
|
||||
}
|
||||
#endif /* BCMDBUS */
|
||||
|
||||
DHD_SSSR_DUMP_INIT(dhd);
|
||||
|
||||
dhd_process_cid_mac(dhd, TRUE);
|
||||
ret = dhd_preinit_ioctls(dhd);
|
||||
dhd_process_cid_mac(dhd, FALSE);
|
||||
|
||||
/* Always assumes wl for now */
|
||||
dhd->iswl = TRUE;
|
||||
|
||||
done:
|
||||
return ret;
|
||||
}
|
||||
|
||||
int dhd_prot_init(dhd_pub_t *dhd)
|
||||
{
|
||||
return BCME_OK;
|
||||
}
|
||||
|
||||
void
|
||||
dhd_prot_stop(dhd_pub_t *dhd)
|
||||
{
|
||||
/* Nothing to do for CDC */
|
||||
}
|
||||
|
||||
static void
|
||||
dhd_get_hostreorder_pkts(void *osh, struct reorder_info *ptr, void **pkt,
|
||||
uint32 *pkt_count, void **pplast, uint8 start, uint8 end)
|
||||
{
|
||||
void *plast = NULL, *p;
|
||||
uint32 pkt_cnt = 0;
|
||||
|
||||
if (ptr->pend_pkts == 0) {
|
||||
DHD_REORDER(("%s: no packets in reorder queue \n", __FUNCTION__));
|
||||
*pplast = NULL;
|
||||
*pkt_count = 0;
|
||||
*pkt = NULL;
|
||||
return;
|
||||
}
|
||||
do {
|
||||
p = (void *)(ptr->p[start]);
|
||||
ptr->p[start] = NULL;
|
||||
|
||||
if (p != NULL) {
|
||||
if (plast == NULL)
|
||||
*pkt = p;
|
||||
else
|
||||
PKTSETNEXT(osh, plast, p);
|
||||
|
||||
plast = p;
|
||||
pkt_cnt++;
|
||||
}
|
||||
start++;
|
||||
if (start > ptr->max_idx)
|
||||
start = 0;
|
||||
} while (start != end);
|
||||
*pplast = plast;
|
||||
*pkt_count = pkt_cnt;
|
||||
ptr->pend_pkts -= (uint8)pkt_cnt;
|
||||
}
|
||||
|
||||
int
|
||||
dhd_process_pkt_reorder_info(dhd_pub_t *dhd, uchar *reorder_info_buf, uint reorder_info_len,
|
||||
void **pkt, uint32 *pkt_count)
|
||||
{
|
||||
uint8 flow_id, max_idx, cur_idx, exp_idx;
|
||||
struct reorder_info *ptr;
|
||||
uint8 flags;
|
||||
void *cur_pkt, *plast = NULL;
|
||||
uint32 cnt = 0;
|
||||
|
||||
if (pkt == NULL) {
|
||||
if (pkt_count != NULL)
|
||||
*pkt_count = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
flow_id = reorder_info_buf[WLHOST_REORDERDATA_FLOWID_OFFSET];
|
||||
flags = reorder_info_buf[WLHOST_REORDERDATA_FLAGS_OFFSET];
|
||||
|
||||
DHD_REORDER(("flow_id %d, flags 0x%02x, idx(%d, %d, %d)\n", flow_id, flags,
|
||||
reorder_info_buf[WLHOST_REORDERDATA_CURIDX_OFFSET],
|
||||
reorder_info_buf[WLHOST_REORDERDATA_EXPIDX_OFFSET],
|
||||
reorder_info_buf[WLHOST_REORDERDATA_MAXIDX_OFFSET]));
|
||||
|
||||
/* validate flags and flow id */
|
||||
if (flags == 0xFF) {
|
||||
DHD_ERROR(("%s: invalid flags...so ignore this packet\n", __FUNCTION__));
|
||||
*pkt_count = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
cur_pkt = *pkt;
|
||||
*pkt = NULL;
|
||||
|
||||
ptr = dhd->reorder_bufs[flow_id];
|
||||
if (flags & WLHOST_REORDERDATA_DEL_FLOW) {
|
||||
uint32 buf_size = sizeof(struct reorder_info);
|
||||
|
||||
DHD_REORDER(("%s: Flags indicating to delete a flow id %d\n",
|
||||
__FUNCTION__, flow_id));
|
||||
|
||||
if (ptr == NULL) {
|
||||
DHD_REORDER(("%s: received flags to cleanup, but no flow (%d) yet\n",
|
||||
__FUNCTION__, flow_id));
|
||||
*pkt_count = 1;
|
||||
*pkt = cur_pkt;
|
||||
return 0;
|
||||
}
|
||||
|
||||
dhd_get_hostreorder_pkts(dhd->osh, ptr, pkt, &cnt, &plast,
|
||||
ptr->exp_idx, ptr->exp_idx);
|
||||
/* set it to the last packet */
|
||||
if (plast) {
|
||||
PKTSETNEXT(dhd->osh, plast, cur_pkt);
|
||||
cnt++;
|
||||
}
|
||||
else {
|
||||
if (cnt != 0) {
|
||||
DHD_ERROR(("%s: del flow: something fishy, pending packets %d\n",
|
||||
__FUNCTION__, cnt));
|
||||
}
|
||||
*pkt = cur_pkt;
|
||||
cnt = 1;
|
||||
}
|
||||
buf_size += ((ptr->max_idx + 1) * sizeof(void *));
|
||||
MFREE(dhd->osh, ptr, buf_size);
|
||||
dhd->reorder_bufs[flow_id] = NULL;
|
||||
*pkt_count = cnt;
|
||||
return 0;
|
||||
}
|
||||
/* all the other cases depend on the existance of the reorder struct for that flow id */
|
||||
if (ptr == NULL) {
|
||||
uint32 buf_size_alloc = sizeof(reorder_info_t);
|
||||
max_idx = reorder_info_buf[WLHOST_REORDERDATA_MAXIDX_OFFSET];
|
||||
|
||||
buf_size_alloc += ((max_idx + 1) * sizeof(void*));
|
||||
/* allocate space to hold the buffers, index etc */
|
||||
|
||||
DHD_REORDER(("%s: alloc buffer of size %d size, reorder info id %d, maxidx %d\n",
|
||||
__FUNCTION__, buf_size_alloc, flow_id, max_idx));
|
||||
ptr = (struct reorder_info *)MALLOC(dhd->osh, buf_size_alloc);
|
||||
if (ptr == NULL) {
|
||||
DHD_ERROR(("%s: Malloc failed to alloc buffer\n", __FUNCTION__));
|
||||
*pkt_count = 1;
|
||||
return 0;
|
||||
}
|
||||
bzero(ptr, buf_size_alloc);
|
||||
dhd->reorder_bufs[flow_id] = ptr;
|
||||
ptr->p = (void *)(ptr+1);
|
||||
ptr->max_idx = max_idx;
|
||||
}
|
||||
if (flags & WLHOST_REORDERDATA_NEW_HOLE) {
|
||||
DHD_REORDER(("%s: new hole, so cleanup pending buffers\n", __FUNCTION__));
|
||||
if (ptr->pend_pkts) {
|
||||
dhd_get_hostreorder_pkts(dhd->osh, ptr, pkt, &cnt, &plast,
|
||||
ptr->exp_idx, ptr->exp_idx);
|
||||
ptr->pend_pkts = 0;
|
||||
}
|
||||
ptr->cur_idx = reorder_info_buf[WLHOST_REORDERDATA_CURIDX_OFFSET];
|
||||
ptr->exp_idx = reorder_info_buf[WLHOST_REORDERDATA_EXPIDX_OFFSET];
|
||||
ptr->max_idx = reorder_info_buf[WLHOST_REORDERDATA_MAXIDX_OFFSET];
|
||||
ptr->p[ptr->cur_idx] = cur_pkt;
|
||||
ptr->pend_pkts++;
|
||||
*pkt_count = cnt;
|
||||
}
|
||||
else if (flags & WLHOST_REORDERDATA_CURIDX_VALID) {
|
||||
cur_idx = reorder_info_buf[WLHOST_REORDERDATA_CURIDX_OFFSET];
|
||||
exp_idx = reorder_info_buf[WLHOST_REORDERDATA_EXPIDX_OFFSET];
|
||||
|
||||
if ((exp_idx == ptr->exp_idx) && (cur_idx != ptr->exp_idx)) {
|
||||
/* still in the current hole */
|
||||
/* enqueue the current on the buffer chain */
|
||||
if (ptr->p[cur_idx] != NULL) {
|
||||
DHD_REORDER(("%s: HOLE: ERROR buffer pending..free it\n",
|
||||
__FUNCTION__));
|
||||
PKTFREE(dhd->osh, ptr->p[cur_idx], TRUE);
|
||||
ptr->p[cur_idx] = NULL;
|
||||
}
|
||||
ptr->p[cur_idx] = cur_pkt;
|
||||
ptr->pend_pkts++;
|
||||
ptr->cur_idx = cur_idx;
|
||||
DHD_REORDER(("%s: fill up a hole..pending packets is %d\n",
|
||||
__FUNCTION__, ptr->pend_pkts));
|
||||
*pkt_count = 0;
|
||||
*pkt = NULL;
|
||||
}
|
||||
else if (ptr->exp_idx == cur_idx) {
|
||||
/* got the right one ..flush from cur to exp and update exp */
|
||||
DHD_REORDER(("%s: got the right one now, cur_idx is %d\n",
|
||||
__FUNCTION__, cur_idx));
|
||||
if (ptr->p[cur_idx] != NULL) {
|
||||
DHD_REORDER(("%s: Error buffer pending..free it\n",
|
||||
__FUNCTION__));
|
||||
PKTFREE(dhd->osh, ptr->p[cur_idx], TRUE);
|
||||
ptr->p[cur_idx] = NULL;
|
||||
}
|
||||
ptr->p[cur_idx] = cur_pkt;
|
||||
ptr->pend_pkts++;
|
||||
|
||||
ptr->cur_idx = cur_idx;
|
||||
ptr->exp_idx = exp_idx;
|
||||
|
||||
dhd_get_hostreorder_pkts(dhd->osh, ptr, pkt, &cnt, &plast,
|
||||
cur_idx, exp_idx);
|
||||
*pkt_count = cnt;
|
||||
DHD_REORDER(("%s: freeing up buffers %d, still pending %d\n",
|
||||
__FUNCTION__, cnt, ptr->pend_pkts));
|
||||
}
|
||||
else {
|
||||
uint8 end_idx;
|
||||
bool flush_current = FALSE;
|
||||
/* both cur and exp are moved now .. */
|
||||
DHD_REORDER(("%s:, flow %d, both moved, cur %d(%d), exp %d(%d)\n",
|
||||
__FUNCTION__, flow_id, ptr->cur_idx, cur_idx,
|
||||
ptr->exp_idx, exp_idx));
|
||||
if (flags & WLHOST_REORDERDATA_FLUSH_ALL)
|
||||
end_idx = ptr->exp_idx;
|
||||
else
|
||||
end_idx = exp_idx;
|
||||
|
||||
/* flush pkts first */
|
||||
dhd_get_hostreorder_pkts(dhd->osh, ptr, pkt, &cnt, &plast,
|
||||
ptr->exp_idx, end_idx);
|
||||
|
||||
if (cur_idx == ptr->max_idx) {
|
||||
if (exp_idx == 0)
|
||||
flush_current = TRUE;
|
||||
} else {
|
||||
if (exp_idx == cur_idx + 1)
|
||||
flush_current = TRUE;
|
||||
}
|
||||
if (flush_current) {
|
||||
if (plast)
|
||||
PKTSETNEXT(dhd->osh, plast, cur_pkt);
|
||||
else
|
||||
*pkt = cur_pkt;
|
||||
cnt++;
|
||||
}
|
||||
else {
|
||||
ptr->p[cur_idx] = cur_pkt;
|
||||
ptr->pend_pkts++;
|
||||
}
|
||||
ptr->exp_idx = exp_idx;
|
||||
ptr->cur_idx = cur_idx;
|
||||
*pkt_count = cnt;
|
||||
}
|
||||
}
|
||||
else {
|
||||
uint8 end_idx;
|
||||
/* no real packet but update to exp_seq...that means explicit window move */
|
||||
exp_idx = reorder_info_buf[WLHOST_REORDERDATA_EXPIDX_OFFSET];
|
||||
|
||||
DHD_REORDER(("%s: move the window, cur_idx is %d, exp is %d, new exp is %d\n",
|
||||
__FUNCTION__, ptr->cur_idx, ptr->exp_idx, exp_idx));
|
||||
if (flags & WLHOST_REORDERDATA_FLUSH_ALL)
|
||||
end_idx = ptr->exp_idx;
|
||||
else
|
||||
end_idx = exp_idx;
|
||||
|
||||
dhd_get_hostreorder_pkts(dhd->osh, ptr, pkt, &cnt, &plast, ptr->exp_idx, end_idx);
|
||||
if (plast)
|
||||
PKTSETNEXT(dhd->osh, plast, cur_pkt);
|
||||
else
|
||||
*pkt = cur_pkt;
|
||||
cnt++;
|
||||
*pkt_count = cnt;
|
||||
/* set the new expected idx */
|
||||
ptr->exp_idx = exp_idx;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,305 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Linux cfg80211 driver - Dongle Host Driver (DHD) related
|
||||
*
|
||||
* Copyright (C) 1999-2019, 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.
|
||||
*
|
||||
* Notwithstanding the above, under no circumstances may you combine this
|
||||
* software in any way with any other Broadcom software provided under a license
|
||||
* other than the GPL, without Broadcom's express prior written consent.
|
||||
*
|
||||
*
|
||||
* <<Broadcom-WL-IPTag/Open:>>
|
||||
*
|
||||
* $Id: dhd_cfg80211.c 807961 2019-03-05 05:47:47Z $
|
||||
*/
|
||||
|
||||
#include <linux/vmalloc.h>
|
||||
#include <net/rtnetlink.h>
|
||||
|
||||
#include <bcmutils.h>
|
||||
#include <wldev_common.h>
|
||||
#include <wl_cfg80211.h>
|
||||
#include <dhd_cfg80211.h>
|
||||
|
||||
#ifdef PKT_FILTER_SUPPORT
|
||||
#include <dngl_stats.h>
|
||||
#include <dhd.h>
|
||||
#endif // endif
|
||||
|
||||
#ifdef PKT_FILTER_SUPPORT
|
||||
extern uint dhd_pkt_filter_enable;
|
||||
extern uint dhd_master_mode;
|
||||
extern void dhd_pktfilter_offload_enable(dhd_pub_t * dhd, char *arg, int enable, int master_mode);
|
||||
#endif // endif
|
||||
|
||||
static int dhd_dongle_up = FALSE;
|
||||
|
||||
#include <dngl_stats.h>
|
||||
#include <dhd.h>
|
||||
#include <dhdioctl.h>
|
||||
#include <wlioctl.h>
|
||||
#include <brcm_nl80211.h>
|
||||
#include <dhd_cfg80211.h>
|
||||
|
||||
static s32 wl_dongle_up(struct net_device *ndev);
|
||||
static s32 wl_dongle_down(struct net_device *ndev);
|
||||
|
||||
/**
|
||||
* Function implementations
|
||||
*/
|
||||
|
||||
s32 dhd_cfg80211_init(struct bcm_cfg80211 *cfg)
|
||||
{
|
||||
dhd_dongle_up = FALSE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
s32 dhd_cfg80211_deinit(struct bcm_cfg80211 *cfg)
|
||||
{
|
||||
dhd_dongle_up = FALSE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
s32 dhd_cfg80211_down(struct bcm_cfg80211 *cfg)
|
||||
{
|
||||
struct net_device *ndev;
|
||||
s32 err = 0;
|
||||
dhd_pub_t *dhd = (dhd_pub_t *)(cfg->pub);
|
||||
|
||||
WL_TRACE(("In\n"));
|
||||
if ((!dhd_dongle_up) || (!dhd->up)) {
|
||||
WL_INFORM_MEM(("Dongle is already down\n"));
|
||||
err = 0;
|
||||
goto done;
|
||||
}
|
||||
ndev = bcmcfg_to_prmry_ndev(cfg);
|
||||
wl_dongle_down(ndev);
|
||||
done:
|
||||
dhd_dongle_up = FALSE;
|
||||
return err;
|
||||
}
|
||||
|
||||
s32 dhd_cfg80211_set_p2p_info(struct bcm_cfg80211 *cfg, int val)
|
||||
{
|
||||
dhd_pub_t *dhd = (dhd_pub_t *)(cfg->pub);
|
||||
dhd->op_mode |= val;
|
||||
WL_ERR(("Set : op_mode=0x%04x\n", dhd->op_mode));
|
||||
#ifdef ARP_OFFLOAD_SUPPORT
|
||||
if (dhd->arp_version == 1) {
|
||||
/* IF P2P is enabled, disable arpoe */
|
||||
dhd_arp_offload_set(dhd, 0);
|
||||
dhd_arp_offload_enable(dhd, false);
|
||||
}
|
||||
#endif /* ARP_OFFLOAD_SUPPORT */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
s32 dhd_cfg80211_clean_p2p_info(struct bcm_cfg80211 *cfg)
|
||||
{
|
||||
dhd_pub_t *dhd = (dhd_pub_t *)(cfg->pub);
|
||||
dhd->op_mode &= ~(DHD_FLAG_P2P_GC_MODE | DHD_FLAG_P2P_GO_MODE);
|
||||
WL_ERR(("Clean : op_mode=0x%04x\n", dhd->op_mode));
|
||||
|
||||
#ifdef ARP_OFFLOAD_SUPPORT
|
||||
if (dhd->arp_version == 1) {
|
||||
/* IF P2P is disabled, enable arpoe back for STA mode. */
|
||||
dhd_arp_offload_set(dhd, dhd_arp_mode);
|
||||
dhd_arp_offload_enable(dhd, true);
|
||||
}
|
||||
#endif /* ARP_OFFLOAD_SUPPORT */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef WL_STATIC_IF
|
||||
int32
|
||||
wl_cfg80211_update_iflist_info(struct bcm_cfg80211 *cfg, struct net_device *ndev,
|
||||
int ifidx, uint8 *addr, int bssidx, char *name, int if_state)
|
||||
{
|
||||
return dhd_update_iflist_info(cfg->pub, ndev, ifidx, addr, bssidx, name, if_state);
|
||||
}
|
||||
#endif /* WL_STATIC_IF */
|
||||
|
||||
struct net_device* wl_cfg80211_allocate_if(struct bcm_cfg80211 *cfg, int ifidx, const char *name,
|
||||
uint8 *mac, uint8 bssidx, const char *dngl_name)
|
||||
{
|
||||
return dhd_allocate_if(cfg->pub, ifidx, name, mac, bssidx, FALSE, dngl_name);
|
||||
}
|
||||
|
||||
int wl_cfg80211_register_if(struct bcm_cfg80211 *cfg,
|
||||
int ifidx, struct net_device* ndev, bool rtnl_lock_reqd)
|
||||
{
|
||||
return dhd_register_if(cfg->pub, ifidx, rtnl_lock_reqd);
|
||||
}
|
||||
|
||||
int wl_cfg80211_remove_if(struct bcm_cfg80211 *cfg,
|
||||
int ifidx, struct net_device* ndev, bool rtnl_lock_reqd)
|
||||
{
|
||||
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);
|
||||
BCM_REFERENCE(cfg);
|
||||
dhd_cleanup_if(net);
|
||||
}
|
||||
|
||||
struct net_device * dhd_cfg80211_netdev_free(struct net_device *ndev)
|
||||
{
|
||||
struct bcm_cfg80211 *cfg;
|
||||
|
||||
if (ndev) {
|
||||
cfg = wl_get_cfg(ndev);
|
||||
if (ndev->ieee80211_ptr) {
|
||||
MFREE(cfg->osh, ndev->ieee80211_ptr, sizeof(struct wireless_dev));
|
||||
ndev->ieee80211_ptr = NULL;
|
||||
}
|
||||
free_netdev(ndev);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return ndev;
|
||||
}
|
||||
|
||||
void dhd_netdev_free(struct net_device *ndev)
|
||||
{
|
||||
#ifdef WL_CFG80211
|
||||
ndev = dhd_cfg80211_netdev_free(ndev);
|
||||
#endif // endif
|
||||
if (ndev)
|
||||
free_netdev(ndev);
|
||||
}
|
||||
|
||||
static s32
|
||||
wl_dongle_up(struct net_device *ndev)
|
||||
{
|
||||
s32 err = 0;
|
||||
u32 local_up = 0;
|
||||
|
||||
err = wldev_ioctl_set(ndev, WLC_UP, &local_up, sizeof(local_up));
|
||||
if (unlikely(err)) {
|
||||
WL_ERR(("WLC_UP error (%d)\n", err));
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
static s32
|
||||
wl_dongle_down(struct net_device *ndev)
|
||||
{
|
||||
s32 err = 0;
|
||||
u32 local_down = 0;
|
||||
|
||||
err = wldev_ioctl_set(ndev, WLC_DOWN, &local_down, sizeof(local_down));
|
||||
if (unlikely(err)) {
|
||||
WL_ERR(("WLC_DOWN error (%d)\n", err));
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
s32
|
||||
wl_dongle_roam(struct net_device *ndev, u32 roamvar, u32 bcn_timeout)
|
||||
{
|
||||
s32 err = 0;
|
||||
|
||||
/* Setup timeout if Beacons are lost and roam is off to report link down */
|
||||
if (roamvar) {
|
||||
err = wldev_iovar_setint(ndev, "bcn_timeout", bcn_timeout);
|
||||
if (unlikely(err)) {
|
||||
WL_ERR(("bcn_timeout error (%d)\n", err));
|
||||
goto dongle_rom_out;
|
||||
}
|
||||
}
|
||||
/* Enable/Disable built-in roaming to allow supplicant to take care of roaming */
|
||||
err = wldev_iovar_setint(ndev, "roam_off", roamvar);
|
||||
if (unlikely(err)) {
|
||||
WL_ERR(("roam_off error (%d)\n", err));
|
||||
goto dongle_rom_out;
|
||||
}
|
||||
dongle_rom_out:
|
||||
return err;
|
||||
}
|
||||
|
||||
s32 dhd_config_dongle(struct bcm_cfg80211 *cfg)
|
||||
{
|
||||
#ifndef DHD_SDALIGN
|
||||
#define DHD_SDALIGN 32
|
||||
#endif // endif
|
||||
struct net_device *ndev;
|
||||
s32 err = 0;
|
||||
|
||||
WL_TRACE(("In\n"));
|
||||
if (dhd_dongle_up) {
|
||||
WL_ERR(("Dongle is already up\n"));
|
||||
return err;
|
||||
}
|
||||
|
||||
ndev = bcmcfg_to_prmry_ndev(cfg);
|
||||
|
||||
err = wl_dongle_up(ndev);
|
||||
if (unlikely(err)) {
|
||||
WL_ERR(("wl_dongle_up failed\n"));
|
||||
goto default_conf_out;
|
||||
}
|
||||
dhd_dongle_up = true;
|
||||
|
||||
default_conf_out:
|
||||
|
||||
return err;
|
||||
|
||||
}
|
||||
|
||||
int dhd_cfgvendor_priv_string_handler(struct bcm_cfg80211 *cfg, struct wireless_dev *wdev,
|
||||
const struct bcm_nlmsg_hdr *nlioc, void *buf)
|
||||
{
|
||||
struct net_device *ndev = NULL;
|
||||
dhd_pub_t *dhd;
|
||||
dhd_ioctl_t ioc = { 0, NULL, 0, 0, 0, 0, 0};
|
||||
int ret = 0;
|
||||
int8 index;
|
||||
|
||||
WL_TRACE(("entry: cmd = %d\n", nlioc->cmd));
|
||||
|
||||
dhd = cfg->pub;
|
||||
DHD_OS_WAKE_LOCK(dhd);
|
||||
|
||||
ndev = wdev_to_wlc_ndev(wdev, cfg);
|
||||
index = dhd_net2idx(dhd->info, ndev);
|
||||
if (index == DHD_BAD_IF) {
|
||||
WL_ERR(("Bad ifidx from wdev:%p\n", wdev));
|
||||
ret = BCME_ERROR;
|
||||
goto done;
|
||||
}
|
||||
|
||||
ioc.cmd = nlioc->cmd;
|
||||
ioc.len = nlioc->len;
|
||||
ioc.set = nlioc->set;
|
||||
ioc.driver = nlioc->magic;
|
||||
ioc.buf = buf;
|
||||
ret = dhd_ioctl_process(dhd, index, &ioc, buf);
|
||||
if (ret) {
|
||||
WL_TRACE(("dhd_ioctl_process return err %d\n", ret));
|
||||
ret = OSL_ERROR(ret);
|
||||
goto done;
|
||||
}
|
||||
|
||||
done:
|
||||
DHD_OS_WAKE_UNLOCK(dhd);
|
||||
return ret;
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Linux cfg80211 driver - Dongle Host Driver (DHD) related
|
||||
*
|
||||
* Copyright (C) 1999-2019, 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.
|
||||
*
|
||||
* Notwithstanding the above, under no circumstances may you combine this
|
||||
* software in any way with any other Broadcom software provided under a license
|
||||
* other than the GPL, without Broadcom's express prior written consent.
|
||||
*
|
||||
*
|
||||
* <<Broadcom-WL-IPTag/Open:>>
|
||||
*
|
||||
* $Id: dhd_cfg80211.h 763539 2018-05-19 06:39:21Z $
|
||||
*/
|
||||
|
||||
#ifndef __DHD_CFG80211__
|
||||
#define __DHD_CFG80211__
|
||||
|
||||
#include <wl_cfg80211.h>
|
||||
#include <wl_cfgp2p.h>
|
||||
#include <brcm_nl80211.h>
|
||||
|
||||
#ifndef WL_ERR
|
||||
#define WL_ERR CFG80211_ERR
|
||||
#endif // endif
|
||||
#ifndef WL_TRACE
|
||||
#define WL_TRACE CFG80211_TRACE
|
||||
#endif // endif
|
||||
|
||||
s32 dhd_cfg80211_init(struct bcm_cfg80211 *cfg);
|
||||
s32 dhd_cfg80211_deinit(struct bcm_cfg80211 *cfg);
|
||||
s32 dhd_cfg80211_down(struct bcm_cfg80211 *cfg);
|
||||
s32 dhd_cfg80211_set_p2p_info(struct bcm_cfg80211 *cfg, int val);
|
||||
s32 dhd_cfg80211_clean_p2p_info(struct bcm_cfg80211 *cfg);
|
||||
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);
|
||||
#endif /* __DHD_CFG80211__ */
|
||||
7475
drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd_wifi6/dhd_common.c
Normal file
7475
drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd_wifi6/dhd_common.c
Normal file
File diff suppressed because it is too large
Load Diff
3953
drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd_wifi6/dhd_config.c
Normal file
3953
drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd_wifi6/dhd_config.c
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,327 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef _dhd_config_
|
||||
#define _dhd_config_
|
||||
|
||||
#include <bcmdevs.h>
|
||||
#include <siutils.h>
|
||||
#include <dngl_stats.h>
|
||||
#include <dhd.h>
|
||||
#include <wlioctl.h>
|
||||
#include <802.11.h>
|
||||
|
||||
#define FW_TYPE_STA 0
|
||||
#define FW_TYPE_APSTA 1
|
||||
#define FW_TYPE_P2P 2
|
||||
#define FW_TYPE_MESH 3
|
||||
#define FW_TYPE_ES 4
|
||||
#define FW_TYPE_MFG 5
|
||||
#define FW_TYPE_G 0
|
||||
#define FW_TYPE_AG 1
|
||||
|
||||
#define FW_PATH_AUTO_SELECT 1
|
||||
//#define CONFIG_PATH_AUTO_SELECT
|
||||
extern char firmware_path[MOD_PARAM_PATHLEN];
|
||||
#if defined(BCMSDIO) || defined(BCMPCIE)
|
||||
extern uint dhd_rxbound;
|
||||
extern uint dhd_txbound;
|
||||
#endif
|
||||
#ifdef BCMSDIO
|
||||
#define TXGLOM_RECV_OFFSET 8
|
||||
extern uint dhd_doflow;
|
||||
extern uint dhd_slpauto;
|
||||
#endif
|
||||
|
||||
typedef struct wl_mac_range {
|
||||
uint32 oui;
|
||||
uint32 nic_start;
|
||||
uint32 nic_end;
|
||||
} wl_mac_range_t;
|
||||
|
||||
typedef struct wl_mac_list {
|
||||
int count;
|
||||
wl_mac_range_t *mac;
|
||||
char name[MOD_PARAM_PATHLEN];
|
||||
} wl_mac_list_t;
|
||||
|
||||
typedef struct wl_mac_list_ctrl {
|
||||
int count;
|
||||
struct wl_mac_list *m_mac_list_head;
|
||||
} wl_mac_list_ctrl_t;
|
||||
|
||||
typedef struct wl_chip_nv_path {
|
||||
uint chip;
|
||||
uint chiprev;
|
||||
char name[MOD_PARAM_PATHLEN];
|
||||
} wl_chip_nv_path_t;
|
||||
|
||||
typedef struct wl_chip_nv_path_list_ctrl {
|
||||
int count;
|
||||
struct wl_chip_nv_path *m_chip_nv_path_head;
|
||||
} wl_chip_nv_path_list_ctrl_t;
|
||||
|
||||
typedef struct wl_channel_list {
|
||||
uint32 count;
|
||||
uint32 channel[WL_NUMCHANNELS];
|
||||
} wl_channel_list_t;
|
||||
|
||||
typedef struct wmes_param {
|
||||
int aifsn[AC_COUNT];
|
||||
int ecwmin[AC_COUNT];
|
||||
int ecwmax[AC_COUNT];
|
||||
int txop[AC_COUNT];
|
||||
} wme_param_t;
|
||||
|
||||
#ifdef PKT_FILTER_SUPPORT
|
||||
#define DHD_CONF_FILTER_MAX 8
|
||||
#define PKT_FILTER_LEN 300
|
||||
#define MAGIC_PKT_FILTER_LEN 450
|
||||
typedef struct conf_pkt_filter_add {
|
||||
uint32 count;
|
||||
char filter[DHD_CONF_FILTER_MAX][PKT_FILTER_LEN];
|
||||
} conf_pkt_filter_add_t;
|
||||
|
||||
typedef struct conf_pkt_filter_del {
|
||||
uint32 count;
|
||||
uint32 id[DHD_CONF_FILTER_MAX];
|
||||
} conf_pkt_filter_del_t;
|
||||
#endif
|
||||
|
||||
#define CONFIG_COUNTRY_LIST_SIZE 500
|
||||
typedef struct country_list {
|
||||
struct country_list *next;
|
||||
wl_country_t cspec;
|
||||
} country_list_t;
|
||||
|
||||
/* mchan_params */
|
||||
#define MCHAN_MAX_NUM 4
|
||||
#define MIRACAST_SOURCE 1
|
||||
#define MIRACAST_SINK 2
|
||||
typedef struct mchan_params {
|
||||
struct mchan_params *next;
|
||||
int bw;
|
||||
int p2p_mode;
|
||||
int miracast_mode;
|
||||
} mchan_params_t;
|
||||
|
||||
enum in4way_flags {
|
||||
NO_SCAN_IN4WAY = (1 << (0)),
|
||||
NO_BTC_IN4WAY = (1 << (1)),
|
||||
DONT_DELETE_GC_AFTER_WPS = (1 << (2)),
|
||||
WAIT_DISCONNECTED = (1 << (3)),
|
||||
};
|
||||
|
||||
enum in_suspend_flags {
|
||||
NO_EVENT_IN_SUSPEND = (1 << (0)),
|
||||
NO_TXDATA_IN_SUSPEND = (1 << (1)),
|
||||
NO_TXCTL_IN_SUSPEND = (1 << (2)),
|
||||
AP_DOWN_IN_SUSPEND = (1 << (3)),
|
||||
ROAM_OFFLOAD_IN_SUSPEND = (1 << (4)),
|
||||
AP_FILTER_IN_SUSPEND = (1 << (5)),
|
||||
WOWL_IN_SUSPEND = (1 << (6)),
|
||||
ALL_IN_SUSPEND = 0xFFFFFFFF,
|
||||
};
|
||||
|
||||
enum in_suspend_mode {
|
||||
EARLY_SUSPEND = 0,
|
||||
PM_NOTIFIER = 1
|
||||
};
|
||||
|
||||
enum eapol_status {
|
||||
EAPOL_STATUS_NONE = 0,
|
||||
EAPOL_STATUS_REQID = 1,
|
||||
EAPOL_STATUS_RSPID = 2,
|
||||
EAPOL_STATUS_WSC_START = 3,
|
||||
EAPOL_STATUS_WPS_M1 = 4,
|
||||
EAPOL_STATUS_WPS_M2 = 5,
|
||||
EAPOL_STATUS_WPS_M3 = 6,
|
||||
EAPOL_STATUS_WPS_M4 = 7,
|
||||
EAPOL_STATUS_WPS_M5 = 8,
|
||||
EAPOL_STATUS_WPS_M6 = 9,
|
||||
EAPOL_STATUS_WPS_M7 = 10,
|
||||
EAPOL_STATUS_WPS_M8 = 11,
|
||||
EAPOL_STATUS_WSC_DONE = 12,
|
||||
EAPOL_STATUS_4WAY_START = 13,
|
||||
EAPOL_STATUS_4WAY_M1 = 14,
|
||||
EAPOL_STATUS_4WAY_M2 = 15,
|
||||
EAPOL_STATUS_4WAY_M3 = 16,
|
||||
EAPOL_STATUS_4WAY_M4 = 17,
|
||||
EAPOL_STATUS_GROUPKEY_M1 = 18,
|
||||
EAPOL_STATUS_GROUPKEY_M2 = 19,
|
||||
EAPOL_STATUS_4WAY_DONE = 20
|
||||
};
|
||||
|
||||
typedef struct dhd_conf {
|
||||
uint chip;
|
||||
uint chiprev;
|
||||
#ifdef GET_OTP_MODULE_NAME
|
||||
char module_name[16];
|
||||
#endif
|
||||
struct ether_addr otp_mac;
|
||||
int fw_type;
|
||||
#ifdef BCMSDIO
|
||||
wl_mac_list_ctrl_t fw_by_mac;
|
||||
wl_mac_list_ctrl_t nv_by_mac;
|
||||
#endif
|
||||
wl_chip_nv_path_list_ctrl_t nv_by_chip;
|
||||
country_list_t *country_head;
|
||||
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];
|
||||
int roam_scan_period[2];
|
||||
int roam_delta[2];
|
||||
int fullroamperiod;
|
||||
uint keep_alive_period;
|
||||
#ifdef ARP_OFFLOAD_SUPPORT
|
||||
bool garp;
|
||||
#endif
|
||||
int force_wme_ac;
|
||||
wme_param_t wme_sta;
|
||||
wme_param_t wme_ap;
|
||||
#ifdef PKT_FILTER_SUPPORT
|
||||
conf_pkt_filter_add_t pkt_filter_add;
|
||||
conf_pkt_filter_del_t pkt_filter_del;
|
||||
char *magic_pkt_filter_add;
|
||||
#endif
|
||||
int srl;
|
||||
int lrl;
|
||||
uint bcn_timeout;
|
||||
int disable_proptx;
|
||||
int dhd_poll;
|
||||
#ifdef BCMSDIO
|
||||
int use_rxchain;
|
||||
bool bus_rxglom;
|
||||
bool txglom_ext; /* Only for 43362/4330/43340/43341/43241 */
|
||||
/* terence 20161011:
|
||||
1) conf->tx_max_offset = 1 to fix credict issue in adaptivity testing
|
||||
2) conf->tx_max_offset = 1 will cause to UDP Tx not work in rxglom supported,
|
||||
but not happened in sw txglom
|
||||
*/
|
||||
int tx_max_offset;
|
||||
uint txglomsize;
|
||||
int txctl_tmo_fix;
|
||||
bool txglom_mode;
|
||||
uint deferred_tx_len;
|
||||
/*txglom_bucket_size:
|
||||
* 43362/4330: 1680
|
||||
* 43340/43341/43241: 1684
|
||||
*/
|
||||
int txglom_bucket_size;
|
||||
int txinrx_thres;
|
||||
int dhd_txminmax; // -1=DATABUFCNT(bus)
|
||||
bool oob_enabled_later;
|
||||
#if defined(SDIO_ISR_THREAD)
|
||||
bool intr_extn;
|
||||
#endif
|
||||
#ifdef BCMSDIO_RXLIM_POST
|
||||
bool rxlim_en;
|
||||
#endif
|
||||
#endif
|
||||
#ifdef BCMPCIE
|
||||
int bus_deepsleep_disable;
|
||||
#endif
|
||||
int dpc_cpucore;
|
||||
int rxf_cpucore;
|
||||
int frameburst;
|
||||
bool deepsleep;
|
||||
int pm;
|
||||
int pm_in_suspend;
|
||||
int suspend_mode;
|
||||
int suspend_bcn_li_dtim;
|
||||
#ifdef DHDTCPACK_SUPPRESS
|
||||
uint8 tcpack_sup_mode;
|
||||
#endif
|
||||
int pktprio8021x;
|
||||
uint insuspend;
|
||||
bool suspended;
|
||||
#ifdef SUSPEND_EVENT
|
||||
char resume_eventmask[WL_EVENTING_MASK_LEN];
|
||||
struct ether_addr bssid_insuspend;
|
||||
bool wlfc;
|
||||
#endif
|
||||
#ifdef IDHCP
|
||||
int dhcpc_enable;
|
||||
int dhcpd_enable;
|
||||
struct ipv4_addr dhcpd_ip_addr;
|
||||
struct ipv4_addr dhcpd_ip_mask;
|
||||
struct ipv4_addr dhcpd_ip_start;
|
||||
struct ipv4_addr dhcpd_ip_end;
|
||||
#endif
|
||||
#ifdef ISAM_PREINIT
|
||||
char isam_init[50];
|
||||
char isam_config[300];
|
||||
char isam_enable[50];
|
||||
#endif
|
||||
int ctrl_resched;
|
||||
mchan_params_t *mchan;
|
||||
char *wl_preinit;
|
||||
char *wl_suspend;
|
||||
char *wl_resume;
|
||||
int tsq;
|
||||
int orphan_move;
|
||||
uint eapol_status;
|
||||
uint in4way;
|
||||
#ifdef WL_EXT_WOWL
|
||||
uint wowl;
|
||||
#endif
|
||||
#ifdef GET_CUSTOM_MAC_FROM_CONFIG
|
||||
char hw_ether[62];
|
||||
#endif
|
||||
wait_queue_head_t event_complete;
|
||||
} dhd_conf_t;
|
||||
|
||||
#ifdef BCMSDIO
|
||||
void dhd_conf_get_otp(dhd_pub_t *dhd, bcmsdh_info_t *sdh, si_t *sih);
|
||||
#if defined(HW_OOB) || defined(FORCE_WOWLAN)
|
||||
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);
|
||||
int dhd_conf_set_blksize(bcmsdh_info_t *sdh);
|
||||
#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, 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);
|
||||
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);
|
||||
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);
|
||||
bool dhd_conf_del_pkt_filter(dhd_pub_t *dhd, uint32 id);
|
||||
void dhd_conf_discard_pkt_filter(dhd_pub_t *dhd);
|
||||
int dhd_conf_read_config(dhd_pub_t *dhd, char *conf_path);
|
||||
int dhd_conf_set_chiprev(dhd_pub_t *dhd, uint chip, uint chiprev);
|
||||
uint dhd_conf_get_chip(void *context);
|
||||
uint dhd_conf_get_chiprev(void *context);
|
||||
int dhd_conf_get_pm(dhd_pub_t *dhd);
|
||||
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,
|
||||
int hostsleep_set, int hostsleep_val, int ret);
|
||||
int dhd_conf_mkeep_alive(dhd_pub_t *dhd, int ifidx, int id, int period,
|
||||
char *packet, bool bcast);
|
||||
#ifdef ARP_OFFLOAD_SUPPORT
|
||||
void dhd_conf_set_garp(dhd_pub_t *dhd, int ifidx, uint32 ipa, bool enable);
|
||||
#endif
|
||||
#ifdef PROP_TXSTATUS
|
||||
int dhd_conf_get_disable_proptx(dhd_pub_t *dhd);
|
||||
#endif
|
||||
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);
|
||||
int dhd_conf_preinit(dhd_pub_t *dhd);
|
||||
int dhd_conf_reset(dhd_pub_t *dhd);
|
||||
int dhd_conf_attach(dhd_pub_t *dhd);
|
||||
void dhd_conf_detach(dhd_pub_t *dhd);
|
||||
void *dhd_get_pub(struct net_device *dev);
|
||||
int wl_pattern_atoh(char *src, char *dst);
|
||||
#ifdef BCMSDIO
|
||||
extern int dhd_bus_sleep(dhd_pub_t *dhdp, bool sleep, uint32 *intstatus);
|
||||
#endif
|
||||
#endif /* _dhd_config_ */
|
||||
@@ -0,0 +1,279 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Customer code to add GPIO control during WLAN start/stop
|
||||
*
|
||||
* Copyright (C) 1999-2019, 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.
|
||||
*
|
||||
* Notwithstanding the above, under no circumstances may you combine this
|
||||
* software in any way with any other Broadcom software provided under a license
|
||||
* other than the GPL, without Broadcom's express prior written consent.
|
||||
*
|
||||
*
|
||||
* <<Broadcom-WL-IPTag/Open:>>
|
||||
*
|
||||
* $Id: dhd_custom_gpio.c 717227 2017-08-23 13:51:13Z $
|
||||
*/
|
||||
|
||||
#include <typedefs.h>
|
||||
#include <linuxver.h>
|
||||
#include <osl.h>
|
||||
#include <bcmutils.h>
|
||||
#include <dngl_stats.h>
|
||||
#include <dhd.h>
|
||||
#include <dhd_linux.h>
|
||||
|
||||
#include <wlioctl.h>
|
||||
#if defined(WL_WIRELESS_EXT)
|
||||
#include <wl_iw.h>
|
||||
#endif // endif
|
||||
|
||||
#define WL_ERROR(x) printf x
|
||||
#define WL_TRACE(x)
|
||||
|
||||
#if defined(OOB_INTR_ONLY) || defined(BCMSPI_ANDROID)
|
||||
|
||||
#if defined(BCMLXSDMMC)
|
||||
extern int sdioh_mmc_irq(int irq);
|
||||
#endif /* (BCMLXSDMMC) */
|
||||
|
||||
/* Customer specific Host GPIO defintion */
|
||||
static int dhd_oob_gpio_num = -1;
|
||||
|
||||
module_param(dhd_oob_gpio_num, int, 0644);
|
||||
MODULE_PARM_DESC(dhd_oob_gpio_num, "DHD oob gpio number");
|
||||
|
||||
/* This function will return:
|
||||
* 1) return : Host gpio interrupt number per customer platform
|
||||
* 2) irq_flags_ptr : Type of Host interrupt as Level or Edge
|
||||
*
|
||||
* NOTE :
|
||||
* Customer should check his platform definitions
|
||||
* and his Host Interrupt spec
|
||||
* to figure out the proper setting for his platform.
|
||||
* Broadcom provides just reference settings as example.
|
||||
*
|
||||
*/
|
||||
int dhd_customer_oob_irq_map(void *adapter, unsigned long *irq_flags_ptr)
|
||||
{
|
||||
int host_oob_irq = 0;
|
||||
|
||||
host_oob_irq = wifi_platform_get_irq_number(adapter, irq_flags_ptr);
|
||||
|
||||
return (host_oob_irq);
|
||||
}
|
||||
#endif /* defined(OOB_INTR_ONLY) || defined(BCMSPI_ANDROID) */
|
||||
|
||||
/* Customer function to control hw specific wlan gpios */
|
||||
int
|
||||
dhd_customer_gpio_wlan_ctrl(void *adapter, int onoff)
|
||||
{
|
||||
int err = 0;
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* Function to get custom MAC address */
|
||||
int
|
||||
dhd_custom_get_mac_address(void *adapter, unsigned char *buf)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
WL_TRACE(("%s Enter\n", __FUNCTION__));
|
||||
if (!buf)
|
||||
return -EINVAL;
|
||||
|
||||
/* Customer access to MAC address stored outside of DHD driver */
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35))
|
||||
ret = wifi_platform_get_mac_addr(adapter, buf);
|
||||
#endif // endif
|
||||
|
||||
#ifdef EXAMPLE_GET_MAC
|
||||
/* EXAMPLE code */
|
||||
{
|
||||
struct ether_addr ea_example = {{0x00, 0x11, 0x22, 0x33, 0x44, 0xFF}};
|
||||
bcopy((char *)&ea_example, buf, sizeof(struct ether_addr));
|
||||
}
|
||||
#endif /* EXAMPLE_GET_MAC */
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif /* GET_CUSTOM_MAC_ENABLE */
|
||||
|
||||
/* Customized Locale table : OPTIONAL feature */
|
||||
const struct cntry_locales_custom translate_custom_table[] = {
|
||||
/* Table should be filled out based on custom platform regulatory requirement */
|
||||
#ifdef EXAMPLE_TABLE
|
||||
{"", "XY", 4}, /* Universal if Country code is unknown or empty */
|
||||
{"US", "US", 69}, /* input ISO "US" to : US regrev 69 */
|
||||
{"CA", "US", 69}, /* input ISO "CA" to : US regrev 69 */
|
||||
{"EU", "EU", 5}, /* European union countries to : EU regrev 05 */
|
||||
{"AT", "EU", 5},
|
||||
{"BE", "EU", 5},
|
||||
{"BG", "EU", 5},
|
||||
{"CY", "EU", 5},
|
||||
{"CZ", "EU", 5},
|
||||
{"DK", "EU", 5},
|
||||
{"EE", "EU", 5},
|
||||
{"FI", "EU", 5},
|
||||
{"FR", "EU", 5},
|
||||
{"DE", "EU", 5},
|
||||
{"GR", "EU", 5},
|
||||
{"HU", "EU", 5},
|
||||
{"IE", "EU", 5},
|
||||
{"IT", "EU", 5},
|
||||
{"LV", "EU", 5},
|
||||
{"LI", "EU", 5},
|
||||
{"LT", "EU", 5},
|
||||
{"LU", "EU", 5},
|
||||
{"MT", "EU", 5},
|
||||
{"NL", "EU", 5},
|
||||
{"PL", "EU", 5},
|
||||
{"PT", "EU", 5},
|
||||
{"RO", "EU", 5},
|
||||
{"SK", "EU", 5},
|
||||
{"SI", "EU", 5},
|
||||
{"ES", "EU", 5},
|
||||
{"SE", "EU", 5},
|
||||
{"GB", "EU", 5},
|
||||
{"KR", "XY", 3},
|
||||
{"AU", "XY", 3},
|
||||
{"CN", "XY", 3}, /* input ISO "CN" to : XY regrev 03 */
|
||||
{"TW", "XY", 3},
|
||||
{"AR", "XY", 3},
|
||||
{"MX", "XY", 3},
|
||||
{"IL", "IL", 0},
|
||||
{"CH", "CH", 0},
|
||||
{"TR", "TR", 0},
|
||||
{"NO", "NO", 0},
|
||||
#endif /* EXMAPLE_TABLE */
|
||||
#if defined(BCM4335_CHIP)
|
||||
{"", "XZ", 11}, /* Universal if Country code is unknown or empty */
|
||||
#endif // endif
|
||||
{"AE", "AE", 1},
|
||||
{"AR", "AR", 1},
|
||||
{"AT", "AT", 1},
|
||||
{"AU", "AU", 2},
|
||||
{"BE", "BE", 1},
|
||||
{"BG", "BG", 1},
|
||||
{"BN", "BN", 1},
|
||||
{"CA", "CA", 2},
|
||||
{"CH", "CH", 1},
|
||||
{"CY", "CY", 1},
|
||||
{"CZ", "CZ", 1},
|
||||
{"DE", "DE", 3},
|
||||
{"DK", "DK", 1},
|
||||
{"EE", "EE", 1},
|
||||
{"ES", "ES", 1},
|
||||
{"FI", "FI", 1},
|
||||
{"FR", "FR", 1},
|
||||
{"GB", "GB", 1},
|
||||
{"GR", "GR", 1},
|
||||
{"HR", "HR", 1},
|
||||
{"HU", "HU", 1},
|
||||
{"IE", "IE", 1},
|
||||
{"IS", "IS", 1},
|
||||
{"IT", "IT", 1},
|
||||
{"ID", "ID", 1},
|
||||
{"JP", "JP", 8},
|
||||
{"KR", "KR", 24},
|
||||
{"KW", "KW", 1},
|
||||
{"LI", "LI", 1},
|
||||
{"LT", "LT", 1},
|
||||
{"LU", "LU", 1},
|
||||
{"LV", "LV", 1},
|
||||
{"MA", "MA", 1},
|
||||
{"MT", "MT", 1},
|
||||
{"MX", "MX", 1},
|
||||
{"NL", "NL", 1},
|
||||
{"NO", "NO", 1},
|
||||
{"PL", "PL", 1},
|
||||
{"PT", "PT", 1},
|
||||
{"PY", "PY", 1},
|
||||
{"RO", "RO", 1},
|
||||
{"SE", "SE", 1},
|
||||
{"SI", "SI", 1},
|
||||
{"SK", "SK", 1},
|
||||
{"TR", "TR", 7},
|
||||
{"TW", "TW", 1},
|
||||
{"IR", "XZ", 11}, /* Universal if Country code is IRAN, (ISLAMIC REPUBLIC OF) */
|
||||
{"SD", "XZ", 11}, /* Universal if Country code is SUDAN */
|
||||
{"SY", "XZ", 11}, /* Universal if Country code is SYRIAN ARAB REPUBLIC */
|
||||
{"GL", "XZ", 11}, /* Universal if Country code is GREENLAND */
|
||||
{"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 */
|
||||
};
|
||||
|
||||
/* Customized Locale convertor
|
||||
* input : ISO 3166-1 country abbreviation
|
||||
* output: customized cspec
|
||||
*/
|
||||
void
|
||||
#ifdef CUSTOM_COUNTRY_CODE
|
||||
get_customized_country_code(void *adapter, char *country_iso_code,
|
||||
wl_country_t *cspec, u32 flags)
|
||||
#else
|
||||
get_customized_country_code(void *adapter, char *country_iso_code, wl_country_t *cspec)
|
||||
#endif /* CUSTOM_COUNTRY_CODE */
|
||||
{
|
||||
#if (defined(CUSTOMER_HW) || defined(CUSTOMER_HW2)) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 39))
|
||||
|
||||
struct cntry_locales_custom *cloc_ptr;
|
||||
|
||||
if (!cspec)
|
||||
return;
|
||||
#ifdef CUSTOM_COUNTRY_CODE
|
||||
cloc_ptr = wifi_platform_get_country_code(adapter, country_iso_code, flags);
|
||||
#else
|
||||
cloc_ptr = wifi_platform_get_country_code(adapter, country_iso_code);
|
||||
#endif /* CUSTOM_COUNTRY_CODE */
|
||||
|
||||
if (cloc_ptr) {
|
||||
strlcpy(cspec->ccode, cloc_ptr->custom_locale, WLC_CNTRY_BUF_SZ);
|
||||
cspec->rev = cloc_ptr->custom_locale_rev;
|
||||
}
|
||||
return;
|
||||
#else
|
||||
int size, i;
|
||||
|
||||
size = ARRAYSIZE(translate_custom_table);
|
||||
|
||||
if (cspec == 0)
|
||||
return;
|
||||
|
||||
if (size == 0)
|
||||
return;
|
||||
|
||||
for (i = 0; i < size; i++) {
|
||||
if (strcmp(country_iso_code, translate_custom_table[i].iso_abbrev) == 0) {
|
||||
memcpy(cspec->ccode,
|
||||
translate_custom_table[i].custom_locale, WLC_CNTRY_BUF_SZ);
|
||||
cspec->rev = translate_custom_table[i].custom_locale_rev;
|
||||
return;
|
||||
}
|
||||
}
|
||||
#ifdef EXAMPLE_TABLE
|
||||
/* if no country code matched return first universal code from translate_custom_table */
|
||||
memcpy(cspec->ccode, translate_custom_table[0].custom_locale, WLC_CNTRY_BUF_SZ);
|
||||
cspec->rev = translate_custom_table[0].custom_locale_rev;
|
||||
#endif /* EXMAPLE_TABLE */
|
||||
return;
|
||||
#endif /* (defined(CUSTOMER_HW2) || defined(BOARD_HIKEY)) &&
|
||||
* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 36))
|
||||
*/
|
||||
}
|
||||
@@ -0,0 +1,294 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Platform Dependent file for Hikey
|
||||
*
|
||||
* Copyright (C) 1999-2019, 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.
|
||||
*
|
||||
* 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$
|
||||
*
|
||||
*/
|
||||
|
||||
#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/wlan_plat.h>
|
||||
#include <linux/fcntl.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/of_gpio.h>
|
||||
|
||||
#ifdef CONFIG_BROADCOM_WIFI_RESERVED_MEM
|
||||
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
|
||||
#define WLAN_REG_ON_GPIO 491
|
||||
#define WLAN_HOST_WAKE_GPIO 493
|
||||
|
||||
static int wlan_reg_on = -1;
|
||||
#define DHD_DT_COMPAT_ENTRY "android,bcmdhd_wlan"
|
||||
#define WIFI_WL_REG_ON_PROPNAME "wl_reg_on"
|
||||
|
||||
static int wlan_host_wake_up = -1;
|
||||
static int wlan_host_wake_irq = 0;
|
||||
#define WIFI_WLAN_HOST_WAKE_PROPNAME "wl_host_wake"
|
||||
|
||||
int
|
||||
dhd_wifi_init_gpio(void)
|
||||
{
|
||||
int gpio_reg_on_val;
|
||||
/* ========== WLAN_PWR_EN ============ */
|
||||
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) {
|
||||
wlan_reg_on = of_get_named_gpio(root_node, WIFI_WL_REG_ON_PROPNAME, 0);
|
||||
wlan_host_wake_up = of_get_named_gpio(root_node, WIFI_WLAN_HOST_WAKE_PROPNAME, 0);
|
||||
} else {
|
||||
printk(KERN_ERR "failed to get device node of BRCM WLAN, use default GPIOs\n");
|
||||
wlan_reg_on = WLAN_REG_ON_GPIO;
|
||||
wlan_host_wake_up = WLAN_HOST_WAKE_GPIO;
|
||||
}
|
||||
|
||||
/* ========== WLAN_PWR_EN ============ */
|
||||
printk(KERN_INFO "%s: gpio_wlan_power : %d\n", __FUNCTION__, wlan_reg_on);
|
||||
|
||||
/*
|
||||
* 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")) {
|
||||
printk(KERN_ERR "%s: Failed to request gpio %d for WL_REG_ON, "
|
||||
"might have configured in the dts\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);
|
||||
}
|
||||
|
||||
gpio_reg_on_val = gpio_get_value(wlan_reg_on);
|
||||
printk(KERN_INFO "%s: Initial WL_REG_ON: [%d]\n",
|
||||
__FUNCTION__, gpio_get_value(wlan_reg_on));
|
||||
|
||||
if (gpio_reg_on_val == 0) {
|
||||
printk(KERN_INFO "%s: WL_REG_ON is LOW, drive it HIGH\n", __FUNCTION__);
|
||||
if (gpio_direction_output(wlan_reg_on, 1)) {
|
||||
printk(KERN_ERR "%s: WL_REG_ON is failed to pull up\n", __FUNCTION__);
|
||||
return -EIO;
|
||||
}
|
||||
}
|
||||
|
||||
printk(KERN_ERR "%s: WL_REG_ON is pulled up\n", __FUNCTION__);
|
||||
|
||||
/* Wait for WIFI_TURNON_DELAY due to power stability */
|
||||
msleep(WIFI_TURNON_DELAY);
|
||||
|
||||
/* ========== WLAN_HOST_WAKE ============ */
|
||||
printk(KERN_INFO "%s: gpio_wlan_host_wake : %d\n", __FUNCTION__, wlan_host_wake_up);
|
||||
|
||||
if (gpio_request_one(wlan_host_wake_up, GPIOF_IN, "WLAN_HOST_WAKE")) {
|
||||
printk(KERN_ERR "%s: Failed 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);
|
||||
}
|
||||
|
||||
if (gpio_direction_input(wlan_host_wake_up)) {
|
||||
printk(KERN_ERR "%s: Failed to set WL_HOST_WAKE gpio direction\n", __FUNCTION__);
|
||||
}
|
||||
|
||||
wlan_host_wake_irq = gpio_to_irq(wlan_host_wake_up);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern void kirin_pcie_power_on_atu_fixup(void) __attribute__ ((weak));
|
||||
extern int kirin_pcie_lp_ctrl(u32 enable) __attribute__ ((weak));
|
||||
|
||||
#ifndef BOARD_HIKEY_MODULAR
|
||||
int
|
||||
dhd_wlan_power(int onoff)
|
||||
{
|
||||
printk(KERN_INFO"------------------------------------------------");
|
||||
printk(KERN_INFO"------------------------------------------------\n");
|
||||
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__);
|
||||
}
|
||||
}
|
||||
|
||||
/* 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 {
|
||||
printk(KERN_ERR "[%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(onoff);
|
||||
} else {
|
||||
printk(KERN_ERR "[%s] kirin_pcie_lp_ctrl is NULL. "
|
||||
"ASPM may not work\n", __func__);
|
||||
}
|
||||
} else {
|
||||
/* Disable ASPM before powering off */
|
||||
if (kirin_pcie_lp_ctrl) {
|
||||
kirin_pcie_lp_ctrl(onoff);
|
||||
} else {
|
||||
printk(KERN_ERR "[%s] kirin_pcie_lp_ctrl is NULL. "
|
||||
"ASPM may not work\n", __func__);
|
||||
}
|
||||
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);
|
||||
#endif /* BOARD_HIKEY_MODULAR */
|
||||
|
||||
static int
|
||||
dhd_wlan_reset(int onoff)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
dhd_wlan_set_carddetect(int val)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef BCMSDIO
|
||||
static int dhd_wlan_get_wake_irq(void)
|
||||
{
|
||||
return gpio_to_irq(wlan_host_wake_up);
|
||||
}
|
||||
#endif /* BCMSDIO */
|
||||
|
||||
#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 |
|
||||
IORESOURCE_IRQ_HIGHEDGE,
|
||||
};
|
||||
EXPORT_SYMBOL(dhd_wlan_resources);
|
||||
|
||||
struct wifi_platform_data dhd_wlan_control = {
|
||||
#ifndef BOARD_HIKEY_MODULAR
|
||||
.set_power = dhd_wlan_power,
|
||||
#endif /* BOARD_HIKEY_MODULAR */
|
||||
.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 */
|
||||
#ifdef BCMSDIO
|
||||
.get_wake_irq = dhd_wlan_get_wake_irq,
|
||||
#endif // endif
|
||||
};
|
||||
EXPORT_SYMBOL(dhd_wlan_control);
|
||||
|
||||
int
|
||||
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;
|
||||
}
|
||||
|
||||
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) {
|
||||
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)
|
||||
{
|
||||
gpio_free(wlan_host_wake_up);
|
||||
gpio_free(wlan_reg_on);
|
||||
return 0;
|
||||
}
|
||||
#ifndef BOARD_HIKEY_MODULAR
|
||||
/* Required only for Built-in DHD */
|
||||
device_initcall(dhd_wlan_init);
|
||||
#endif /* BOARD_HIKEY_MODULAR */
|
||||
@@ -0,0 +1,562 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Platform Dependent file for usage of Preallocted Memory
|
||||
*
|
||||
* Copyright (C) 1999-2019, 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.
|
||||
*
|
||||
* Notwithstanding the above, under no circumstances may you combine this
|
||||
* software in any way with any other Broadcom software provided under a license
|
||||
* other than the GPL, without Broadcom's express prior written consent.
|
||||
*
|
||||
* <<Broadcom-WL-IPTag/Open:>>
|
||||
*
|
||||
* $Id: dhd_custom_memprealloc.c 805764 2019-02-20 08:46:57Z $
|
||||
*/
|
||||
|
||||
#include <linux/device.h>
|
||||
#include <linux/slab.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>
|
||||
|
||||
#ifdef CONFIG_BROADCOM_WIFI_RESERVED_MEM
|
||||
|
||||
#define WLAN_STATIC_SCAN_BUF0 5
|
||||
#define WLAN_STATIC_SCAN_BUF1 6
|
||||
#define WLAN_STATIC_DHD_INFO_BUF 7
|
||||
#define WLAN_STATIC_DHD_WLFC_BUF 8
|
||||
#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_LOG_DUMP_BUF 15
|
||||
#define WLAN_STATIC_DHD_LOG_DUMP_BUF_EX 16
|
||||
#define WLAN_STATIC_DHD_PKTLOG_DUMP_BUF 17
|
||||
|
||||
#define WLAN_SCAN_BUF_SIZE (64 * 1024)
|
||||
|
||||
#if defined(CONFIG_64BIT)
|
||||
#define WLAN_DHD_INFO_BUF_SIZE (32 * 1024)
|
||||
#define WLAN_DHD_WLFC_BUF_SIZE (64 * 1024)
|
||||
#define WLAN_DHD_IF_FLOW_LKUP_SIZE (64 * 1024)
|
||||
#else
|
||||
#define WLAN_DHD_INFO_BUF_SIZE (32 * 1024)
|
||||
#define WLAN_DHD_WLFC_BUF_SIZE (16 * 1024)
|
||||
#define WLAN_DHD_IF_FLOW_LKUP_SIZE (20 * 1024)
|
||||
#endif /* CONFIG_64BIT */
|
||||
/* Have 2MB ramsize to accomodate future chips */
|
||||
#define WLAN_DHD_MEMDUMP_SIZE (2048 * 1024)
|
||||
|
||||
#define PREALLOC_WLAN_SEC_NUM 4
|
||||
#define PREALLOC_WLAN_BUF_NUM 160
|
||||
#define PREALLOC_WLAN_SECTION_HEADER 24
|
||||
|
||||
#ifdef CONFIG_BCMDHD_PCIE
|
||||
#define DHD_SKB_1PAGE_BUFSIZE (PAGE_SIZE*1)
|
||||
#define DHD_SKB_2PAGE_BUFSIZE (PAGE_SIZE*2)
|
||||
#define DHD_SKB_4PAGE_BUFSIZE (PAGE_SIZE*4)
|
||||
|
||||
#define WLAN_SECTION_SIZE_0 (PREALLOC_WLAN_BUF_NUM * 128)
|
||||
#define WLAN_SECTION_SIZE_1 0
|
||||
#define WLAN_SECTION_SIZE_2 0
|
||||
#define WLAN_SECTION_SIZE_3 (PREALLOC_WLAN_BUF_NUM * 1024)
|
||||
|
||||
#define DHD_SKB_1PAGE_BUF_NUM 0
|
||||
#define DHD_SKB_2PAGE_BUF_NUM 128
|
||||
#define DHD_SKB_4PAGE_BUF_NUM 0
|
||||
|
||||
#else
|
||||
#define DHD_SKB_HDRSIZE 336
|
||||
#define DHD_SKB_1PAGE_BUFSIZE ((PAGE_SIZE*1)-DHD_SKB_HDRSIZE)
|
||||
#define DHD_SKB_2PAGE_BUFSIZE ((PAGE_SIZE*2)-DHD_SKB_HDRSIZE)
|
||||
#define DHD_SKB_4PAGE_BUFSIZE ((PAGE_SIZE*4)-DHD_SKB_HDRSIZE)
|
||||
|
||||
#define WLAN_SECTION_SIZE_0 (PREALLOC_WLAN_BUF_NUM * 128)
|
||||
#define WLAN_SECTION_SIZE_1 (PREALLOC_WLAN_BUF_NUM * 128)
|
||||
#define WLAN_SECTION_SIZE_2 (PREALLOC_WLAN_BUF_NUM * 512)
|
||||
#define WLAN_SECTION_SIZE_3 (PREALLOC_WLAN_BUF_NUM * 1024)
|
||||
|
||||
#define DHD_SKB_1PAGE_BUF_NUM 8
|
||||
#define DHD_SKB_2PAGE_BUF_NUM 8
|
||||
#define DHD_SKB_4PAGE_BUF_NUM 1
|
||||
#endif /* CONFIG_BCMDHD_PCIE */
|
||||
|
||||
#define WLAN_SKB_1_2PAGE_BUF_NUM ((DHD_SKB_1PAGE_BUF_NUM) + \
|
||||
(DHD_SKB_2PAGE_BUF_NUM))
|
||||
#define WLAN_SKB_BUF_NUM ((WLAN_SKB_1_2PAGE_BUF_NUM) + \
|
||||
(DHD_SKB_4PAGE_BUF_NUM))
|
||||
|
||||
#define WLAN_MAX_PKTID_ITEMS (8192)
|
||||
#define WLAN_DHD_PKTID_MAP_HDR_SIZE (20 + 4*(WLAN_MAX_PKTID_ITEMS + 1))
|
||||
#define WLAN_DHD_PKTID_MAP_ITEM_SIZE (32)
|
||||
#define WLAN_DHD_PKTID_MAP_SIZE ((WLAN_DHD_PKTID_MAP_HDR_SIZE) + \
|
||||
((WLAN_MAX_PKTID_ITEMS+1) * WLAN_DHD_PKTID_MAP_ITEM_SIZE))
|
||||
|
||||
#define WLAN_MAX_PKTID_IOCTL_ITEMS (32)
|
||||
#define WLAN_DHD_PKTID_IOCTL_MAP_HDR_SIZE (20 + 4*(WLAN_MAX_PKTID_IOCTL_ITEMS + 1))
|
||||
#define WLAN_DHD_PKTID_IOCTL_MAP_ITEM_SIZE (32)
|
||||
#define WLAN_DHD_PKTID_IOCTL_MAP_SIZE ((WLAN_DHD_PKTID_IOCTL_MAP_HDR_SIZE) + \
|
||||
((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 * 4)
|
||||
|
||||
#define DHD_PKTLOG_DUMP_BUF_SIZE (64 * 1024)
|
||||
|
||||
#define WLAN_DHD_WLFC_HANGER_MAXITEMS 3072
|
||||
#define WLAN_DHD_WLFC_HANGER_ITEM_SIZE 32
|
||||
#define WLAN_DHD_WLFC_HANGER_SIZE ((WLAN_DHD_WLFC_HANGER_ITEM_SIZE) + \
|
||||
((WLAN_DHD_WLFC_HANGER_MAXITEMS) * (WLAN_DHD_WLFC_HANGER_ITEM_SIZE)))
|
||||
|
||||
static struct sk_buff *wlan_static_skb[WLAN_SKB_BUF_NUM];
|
||||
|
||||
struct wlan_mem_prealloc {
|
||||
void *mem_ptr;
|
||||
unsigned long size;
|
||||
};
|
||||
|
||||
static struct wlan_mem_prealloc wlan_mem_array[PREALLOC_WLAN_SEC_NUM] = {
|
||||
{NULL, (WLAN_SECTION_SIZE_0 + PREALLOC_WLAN_SECTION_HEADER)},
|
||||
{NULL, (WLAN_SECTION_SIZE_1 + PREALLOC_WLAN_SECTION_HEADER)},
|
||||
{NULL, (WLAN_SECTION_SIZE_2 + PREALLOC_WLAN_SECTION_HEADER)},
|
||||
{NULL, (WLAN_SECTION_SIZE_3 + PREALLOC_WLAN_SECTION_HEADER)}
|
||||
};
|
||||
|
||||
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;
|
||||
static void *wlan_static_if_flow_lkup = NULL;
|
||||
static void *wlan_static_dhd_memdump_ram = 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;
|
||||
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_wlan_mem_prealloc(int section, unsigned long size)
|
||||
{
|
||||
if (section == PREALLOC_WLAN_SEC_NUM) {
|
||||
return wlan_static_skb;
|
||||
}
|
||||
|
||||
if (section == WLAN_STATIC_SCAN_BUF0) {
|
||||
return wlan_static_scan_buf0;
|
||||
}
|
||||
|
||||
if (section == WLAN_STATIC_SCAN_BUF1) {
|
||||
return wlan_static_scan_buf1;
|
||||
}
|
||||
|
||||
if (section == WLAN_STATIC_DHD_INFO_BUF) {
|
||||
if (size > WLAN_DHD_INFO_BUF_SIZE) {
|
||||
pr_err("request DHD_INFO size(%lu) is bigger than"
|
||||
" static size(%d).\n", size,
|
||||
WLAN_DHD_INFO_BUF_SIZE);
|
||||
return NULL;
|
||||
}
|
||||
return wlan_static_dhd_info_buf;
|
||||
}
|
||||
|
||||
if (section == WLAN_STATIC_DHD_WLFC_BUF) {
|
||||
if (size > WLAN_DHD_WLFC_BUF_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_dhd_wlfc_buf;
|
||||
}
|
||||
|
||||
if (section == WLAN_STATIC_DHD_WLFC_HANGER) {
|
||||
if (size > WLAN_DHD_WLFC_HANGER_SIZE) {
|
||||
pr_err("request DHD_WLFC_HANGER size(%lu) is bigger than"
|
||||
" static size(%d).\n",
|
||||
size, WLAN_DHD_WLFC_HANGER_SIZE);
|
||||
return NULL;
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
if (section == WLAN_STATIC_DHD_MEMDUMP_RAM) {
|
||||
if (size > WLAN_DHD_MEMDUMP_SIZE) {
|
||||
pr_err("request DHD_MEMDUMP_RAM size(%lu) is bigger"
|
||||
" than static size(%d).\n",
|
||||
size, WLAN_DHD_MEMDUMP_SIZE);
|
||||
return NULL;
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
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"
|
||||
" static size(%d).\n",
|
||||
size, DHD_LOG_DUMP_BUF_SIZE);
|
||||
return NULL;
|
||||
}
|
||||
return wlan_static_dhd_log_dump_buf;
|
||||
}
|
||||
|
||||
if (section == WLAN_STATIC_DHD_LOG_DUMP_BUF_EX) {
|
||||
if (size > DHD_LOG_DUMP_BUF_EX_SIZE) {
|
||||
pr_err("request DHD_LOG_DUMP_BUF_EX size(%lu) is bigger then"
|
||||
" static size(%d).\n",
|
||||
size, DHD_LOG_DUMP_BUF_EX_SIZE);
|
||||
return NULL;
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
if (wlan_mem_array[section].size < size) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return wlan_mem_array[section].mem_ptr;
|
||||
}
|
||||
EXPORT_SYMBOL(dhd_wlan_mem_prealloc);
|
||||
|
||||
int
|
||||
dhd_init_wlan_mem(void)
|
||||
{
|
||||
int i;
|
||||
int j;
|
||||
|
||||
#if !defined(CONFIG_BCMDHD_PCIE)
|
||||
for (i = 0; i < DHD_SKB_1PAGE_BUF_NUM; i++) {
|
||||
wlan_static_skb[i] = __dev_alloc_skb(DHD_SKB_1PAGE_BUFSIZE, GFP_KERNEL);
|
||||
if (!wlan_static_skb[i]) {
|
||||
goto err_skb_alloc;
|
||||
}
|
||||
}
|
||||
#endif /* !CONFIG_BCMDHD_PCIE */
|
||||
|
||||
for (i = DHD_SKB_1PAGE_BUF_NUM; i < WLAN_SKB_1_2PAGE_BUF_NUM; i++) {
|
||||
wlan_static_skb[i] = __dev_alloc_skb(DHD_SKB_2PAGE_BUFSIZE, GFP_KERNEL);
|
||||
if (!wlan_static_skb[i]) {
|
||||
goto err_skb_alloc;
|
||||
}
|
||||
}
|
||||
|
||||
#if !defined(CONFIG_BCMDHD_PCIE)
|
||||
wlan_static_skb[i] = __dev_alloc_skb(DHD_SKB_4PAGE_BUFSIZE, GFP_KERNEL);
|
||||
if (!wlan_static_skb[i]) {
|
||||
goto err_skb_alloc;
|
||||
}
|
||||
#endif /* !CONFIG_BCMDHD_PCIE */
|
||||
|
||||
for (i = 0; i < PREALLOC_WLAN_SEC_NUM; i++) {
|
||||
if (wlan_mem_array[i].size > 0) {
|
||||
wlan_mem_array[i].mem_ptr =
|
||||
kmalloc(wlan_mem_array[i].size, GFP_KERNEL);
|
||||
|
||||
if (!wlan_mem_array[i].mem_ptr) {
|
||||
goto err_mem_alloc;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
wlan_static_scan_buf0 = kmalloc(WLAN_SCAN_BUF_SIZE, GFP_KERNEL);
|
||||
if (!wlan_static_scan_buf0) {
|
||||
pr_err("Failed to alloc wlan_static_scan_buf0\n");
|
||||
goto err_mem_alloc;
|
||||
}
|
||||
|
||||
wlan_static_scan_buf1 = kmalloc(WLAN_SCAN_BUF_SIZE, GFP_KERNEL);
|
||||
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);
|
||||
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);
|
||||
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;
|
||||
}
|
||||
|
||||
wlan_static_dhd_info_buf = kmalloc(WLAN_DHD_INFO_BUF_SIZE, GFP_KERNEL);
|
||||
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,
|
||||
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);
|
||||
if (!wlan_static_dhd_wlfc_buf) {
|
||||
pr_err("Failed to alloc wlan_static_dhd_wlfc_buf\n");
|
||||
goto err_mem_alloc;
|
||||
}
|
||||
|
||||
wlan_static_dhd_wlfc_hanger = kmalloc(WLAN_DHD_WLFC_HANGER_SIZE,
|
||||
GFP_KERNEL);
|
||||
if (!wlan_static_dhd_wlfc_hanger) {
|
||||
pr_err("Failed to alloc wlan_static_dhd_wlfc_hanger\n");
|
||||
goto err_mem_alloc;
|
||||
}
|
||||
#endif /* CONFIG_BCMDHD_PCIE */
|
||||
|
||||
#ifdef CONFIG_BCMDHD_PREALLOC_MEMDUMP
|
||||
wlan_static_dhd_memdump_ram = kmalloc(WLAN_DHD_MEMDUMP_SIZE, GFP_KERNEL);
|
||||
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;
|
||||
|
||||
err_mem_alloc:
|
||||
#ifdef CONFIG_BCMDHD_PREALLOC_MEMDUMP
|
||||
if (wlan_static_dhd_memdump_ram) {
|
||||
kfree(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);
|
||||
}
|
||||
|
||||
#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);
|
||||
}
|
||||
|
||||
if (wlan_static_dhd_wlfc_hanger) {
|
||||
kfree(wlan_static_dhd_wlfc_hanger);
|
||||
}
|
||||
#endif /* CONFIG_BCMDHD_PCIE */
|
||||
if (wlan_static_dhd_info_buf) {
|
||||
kfree(wlan_static_dhd_info_buf);
|
||||
}
|
||||
|
||||
if (wlan_static_dhd_log_dump_buf) {
|
||||
kfree(wlan_static_dhd_log_dump_buf);
|
||||
}
|
||||
|
||||
if (wlan_static_dhd_log_dump_buf_ex) {
|
||||
kfree(wlan_static_dhd_log_dump_buf_ex);
|
||||
}
|
||||
|
||||
if (wlan_static_scan_buf1) {
|
||||
kfree(wlan_static_scan_buf1);
|
||||
}
|
||||
|
||||
if (wlan_static_scan_buf0) {
|
||||
kfree(wlan_static_scan_buf0);
|
||||
}
|
||||
|
||||
if (wlan_static_dhd_pktlog_dump_buf) {
|
||||
kfree(wlan_static_dhd_pktlog_dump_buf);
|
||||
}
|
||||
|
||||
pr_err("Failed to mem_alloc for WLAN\n");
|
||||
|
||||
for (j = 0; j < i; j++) {
|
||||
kfree(wlan_mem_array[j].mem_ptr);
|
||||
}
|
||||
|
||||
i = WLAN_SKB_BUF_NUM;
|
||||
|
||||
err_skb_alloc:
|
||||
pr_err("Failed to skb_alloc for WLAN\n");
|
||||
for (j = 0; j < i; j++) {
|
||||
dev_kfree_skb(wlan_static_skb[j]);
|
||||
}
|
||||
|
||||
return -ENOMEM;
|
||||
}
|
||||
EXPORT_SYMBOL(dhd_init_wlan_mem);
|
||||
|
||||
void
|
||||
dhd_exit_wlan_mem(void)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
#ifdef CONFIG_BCMDHD_PREALLOC_MEMDUMP
|
||||
if (wlan_static_dhd_memdump_ram) {
|
||||
kfree(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);
|
||||
}
|
||||
|
||||
#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);
|
||||
}
|
||||
|
||||
if (wlan_static_dhd_wlfc_hanger) {
|
||||
kfree(wlan_static_dhd_wlfc_hanger);
|
||||
}
|
||||
#endif /* CONFIG_BCMDHD_PCIE */
|
||||
if (wlan_static_dhd_info_buf) {
|
||||
kfree(wlan_static_dhd_info_buf);
|
||||
}
|
||||
|
||||
if (wlan_static_dhd_log_dump_buf) {
|
||||
kfree(wlan_static_dhd_log_dump_buf);
|
||||
}
|
||||
|
||||
if (wlan_static_dhd_log_dump_buf_ex) {
|
||||
kfree(wlan_static_dhd_log_dump_buf_ex);
|
||||
}
|
||||
|
||||
if (wlan_static_scan_buf1) {
|
||||
kfree(wlan_static_scan_buf1);
|
||||
}
|
||||
|
||||
if (wlan_static_scan_buf0) {
|
||||
kfree(wlan_static_scan_buf0);
|
||||
}
|
||||
|
||||
if (wlan_static_dhd_pktlog_dump_buf) {
|
||||
kfree(wlan_static_dhd_pktlog_dump_buf);
|
||||
}
|
||||
|
||||
pr_err("Failed to mem_alloc for WLAN\n");
|
||||
|
||||
for (i = 0; i < PREALLOC_WLAN_SEC_NUM; i++) {
|
||||
if (wlan_mem_array[i].mem_ptr) {
|
||||
kfree(wlan_mem_array[i].mem_ptr);
|
||||
}
|
||||
}
|
||||
|
||||
pr_err("Failed to skb_alloc for WLAN\n");
|
||||
for (i = 0; i < WLAN_SKB_BUF_NUM; i++) {
|
||||
dev_kfree_skb(wlan_static_skb[i]);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
EXPORT_SYMBOL(dhd_exit_wlan_mem);
|
||||
#endif /* CONFIG_BROADCOM_WIFI_RESERVED_MEM */
|
||||
367
drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd_wifi6/dhd_dbg.h
Normal file
367
drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd_wifi6/dhd_dbg.h
Normal file
@@ -0,0 +1,367 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Debug/trace/assert driver definitions for Dongle Host Driver.
|
||||
*
|
||||
* Copyright (C) 1999-2019, 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.
|
||||
*
|
||||
* Notwithstanding the above, under no circumstances may you combine this
|
||||
* software in any way with any other Broadcom software provided under a license
|
||||
* other than the GPL, without Broadcom's express prior written consent.
|
||||
*
|
||||
*
|
||||
* <<Broadcom-WL-IPTag/Open:>>
|
||||
*
|
||||
* $Id: dhd_dbg.h 798329 2019-01-08 05:40:39Z $
|
||||
*/
|
||||
|
||||
#ifndef _dhd_dbg_
|
||||
#define _dhd_dbg_
|
||||
|
||||
#ifdef DHD_LOG_DUMP
|
||||
extern char *dhd_log_dump_get_timestamp(void);
|
||||
extern void dhd_log_dump_write(int type, char *binary_data,
|
||||
int binary_len, const char *fmt, ...);
|
||||
#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_WRITE(fmt, ...) \
|
||||
dhd_log_dump_write(DLD_BUF_TYPE_GENERAL, NULL, 0, fmt, ##__VA_ARGS__)
|
||||
#define DHD_LOG_DUMP_WRITE_EX(fmt, ...) \
|
||||
dhd_log_dump_write(DLD_BUF_TYPE_SPECIAL, NULL, 0, fmt, ##__VA_ARGS__)
|
||||
#define DHD_LOG_DUMP_WRITE_PRSRV(fmt, ...) \
|
||||
dhd_log_dump_write(DLD_BUF_TYPE_PRESERVE, NULL, 0, fmt, ##__VA_ARGS__)
|
||||
#endif /* !_DHD_LOG_DUMP_DEFINITIONS_ */
|
||||
#define CONCISE_DUMP_BUFLEN 16 * 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 COOKIE_LOG_HDR "\n-------------------- Cookie List ----------------------------\n"
|
||||
#endif /* DHD_LOG_DUMP */
|
||||
|
||||
#if defined(DHD_DEBUG)
|
||||
|
||||
/* NON-NDIS cases */
|
||||
#ifdef DHD_LOG_DUMP
|
||||
/* Common case for EFI and non EFI */
|
||||
#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)
|
||||
|
||||
/* !defined(DHD_EFI) and defined(DHD_LOG_DUMP) */
|
||||
#define DHD_INFO(args) do {if (dhd_msg_level & DHD_INFO_VAL) printf args;} while (0)
|
||||
#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)
|
||||
#define DHD_INFO(args) do {if (dhd_msg_level & DHD_INFO_VAL) printf args;} while (0)
|
||||
#endif /* DHD_LOG_DUMP */
|
||||
|
||||
#define DHD_TRACE(args) do {if (dhd_msg_level & DHD_TRACE_VAL) printf args;} while (0)
|
||||
|
||||
#ifdef DHD_LOG_DUMP
|
||||
/* LOG_DUMP defines common to EFI and NON-EFI */
|
||||
#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)
|
||||
/* NON-EFI builds with LOG DUMP enabled */
|
||||
#define DHD_EVENT(args) \
|
||||
do { \
|
||||
if (dhd_msg_level & DHD_EVENT_VAL) { \
|
||||
printf args; \
|
||||
DHD_LOG_DUMP_WRITE("[%s]: ", dhd_log_dump_get_timestamp()); \
|
||||
DHD_LOG_DUMP_WRITE args; \
|
||||
} \
|
||||
} while (0)
|
||||
#define DHD_PRSRV_MEM(args) \
|
||||
do { \
|
||||
if (dhd_msg_level & DHD_EVENT_VAL) { \
|
||||
if (dhd_msg_level & DHD_PRSRV_MEM_VAL) \
|
||||
printf args; \
|
||||
DHD_LOG_DUMP_WRITE_PRSRV("[%s]: ", dhd_log_dump_get_timestamp()); \
|
||||
DHD_LOG_DUMP_WRITE_PRSRV args; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/* Re-using 'DHD_MSGTRACE_VAL' for controlling printing of ecounter binary event
|
||||
* logs to console and debug dump -- need to cleanup in the future to use separate
|
||||
* 'DHD_ECNTR_VAL' bitmap flag. 'DHD_MSGTRACE_VAL' will be defined only
|
||||
* for non-android builds.
|
||||
*/
|
||||
#define DHD_ECNTR_LOG(args) \
|
||||
do { \
|
||||
if (dhd_msg_level & DHD_EVENT_VAL) { \
|
||||
if (dhd_msg_level & DHD_MSGTRACE_VAL) { \
|
||||
printf args; \
|
||||
DHD_LOG_DUMP_WRITE("[%s]: ", dhd_log_dump_get_timestamp()); \
|
||||
DHD_LOG_DUMP_WRITE args; \
|
||||
} \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define DHD_ERROR_EX(args) \
|
||||
do { \
|
||||
if (dhd_msg_level & DHD_ERROR_VAL) { \
|
||||
printf args; \
|
||||
DHD_LOG_DUMP_WRITE_EX("[%s]: ", dhd_log_dump_get_timestamp()); \
|
||||
DHD_LOG_DUMP_WRITE_EX args; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define DHD_MSGTRACE_LOG(args) \
|
||||
do { \
|
||||
if (dhd_msg_level & DHD_MSGTRACE_VAL) { \
|
||||
printf args; \
|
||||
} \
|
||||
DHD_LOG_DUMP_WRITE("[%s]: ", dhd_log_dump_get_timestamp()); \
|
||||
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)
|
||||
#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_EVENT(args) do {if (dhd_msg_level & DHD_EVENT_VAL) printf args;} while (0)
|
||||
#define DHD_ECNTR_LOG(args) DHD_EVENT(args)
|
||||
#define DHD_PRSRV_MEM(args) DHD_EVENT(args)
|
||||
#define DHD_ERROR_EX(args) DHD_ERROR(args)
|
||||
#endif /* DHD_LOG_DUMP */
|
||||
|
||||
#define DHD_DATA(args) do {if (dhd_msg_level & DHD_DATA_VAL) printf args;} while (0)
|
||||
#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_PKT_MON(args) do {if (dhd_msg_level & DHD_PKT_MON_VAL) printf args;} while (0)
|
||||
|
||||
#if defined(DHD_LOG_DUMP)
|
||||
#if defined(DHD_LOG_PRINT_RATE_LIMIT)
|
||||
#define DHD_FWLOG(args) \
|
||||
do { \
|
||||
if (dhd_msg_level & DHD_FWLOG_VAL) { \
|
||||
if (!log_print_threshold) \
|
||||
printf args; \
|
||||
DHD_LOG_DUMP_WRITE args; \
|
||||
} \
|
||||
} while (0)
|
||||
#else
|
||||
#define DHD_FWLOG(args) \
|
||||
do { \
|
||||
if (dhd_msg_level & DHD_FWLOG_VAL) { \
|
||||
printf args; \
|
||||
DHD_LOG_DUMP_WRITE args; \
|
||||
} \
|
||||
} while (0)
|
||||
#endif // endif
|
||||
#else /* DHD_LOG_DUMP */
|
||||
#define DHD_FWLOG(args) do {if (dhd_msg_level & DHD_FWLOG_VAL) printf args;} while (0)
|
||||
#endif /* DHD_LOG_DUMP */
|
||||
|
||||
#define DHD_DBGIF(args) do {if (dhd_msg_level & DHD_DBGIF_VAL) printf args;} while (0)
|
||||
|
||||
#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 */
|
||||
|
||||
#define DHD_TRACE_HW4 DHD_TRACE
|
||||
#define DHD_INFO_HW4 DHD_INFO
|
||||
#define DHD_ERROR_NO_HW4 DHD_ERROR
|
||||
|
||||
#define DHD_ERROR_ON() (dhd_msg_level & DHD_ERROR_VAL)
|
||||
#define DHD_TRACE_ON() (dhd_msg_level & DHD_TRACE_VAL)
|
||||
#define DHD_INFO_ON() (dhd_msg_level & DHD_INFO_VAL)
|
||||
#define DHD_DATA_ON() (dhd_msg_level & DHD_DATA_VAL)
|
||||
#define DHD_CTL_ON() (dhd_msg_level & DHD_CTL_VAL)
|
||||
#define DHD_TIMER_ON() (dhd_msg_level & DHD_TIMER_VAL)
|
||||
#define DHD_HDRS_ON() (dhd_msg_level & DHD_HDRS_VAL)
|
||||
#define DHD_BYTES_ON() (dhd_msg_level & DHD_BYTES_VAL)
|
||||
#define DHD_INTR_ON() (dhd_msg_level & DHD_INTR_VAL)
|
||||
#define DHD_GLOM_ON() (dhd_msg_level & DHD_GLOM_VAL)
|
||||
#define DHD_EVENT_ON() (dhd_msg_level & DHD_EVENT_VAL)
|
||||
#define DHD_BTA_ON() (dhd_msg_level & DHD_BTA_VAL)
|
||||
#define DHD_ISCAN_ON() (dhd_msg_level & DHD_ISCAN_VAL)
|
||||
#define DHD_ARPOE_ON() (dhd_msg_level & DHD_ARPOE_VAL)
|
||||
#define DHD_REORDER_ON() (dhd_msg_level & DHD_REORDER_VAL)
|
||||
#define DHD_NOCHECKDIED_ON() (dhd_msg_level & DHD_NOCHECKDIED_VAL)
|
||||
#define DHD_PNO_ON() (dhd_msg_level & DHD_PNO_VAL)
|
||||
#define DHD_RTT_ON() (dhd_msg_level & DHD_RTT_VAL)
|
||||
#define DHD_MSGTRACE_ON() (dhd_msg_level & DHD_MSGTRACE_VAL)
|
||||
#define DHD_FWLOG_ON() (dhd_msg_level & DHD_FWLOG_VAL)
|
||||
#define DHD_DBGIF_ON() (dhd_msg_level & DHD_DBGIF_VAL)
|
||||
#define DHD_PKT_MON_ON() (dhd_msg_level & DHD_PKT_MON_VAL)
|
||||
#define DHD_PKT_MON_DUMP_ON() (dhd_msg_level & DHD_PKT_MON_DUMP_VAL)
|
||||
#ifdef DHD_PCIE_NATIVE_RUNTIMEPM
|
||||
#define DHD_RPM_ON() (dhd_msg_level & DHD_RPM_VAL)
|
||||
#endif /* DHD_PCIE_NATIVE_RUNTIMEPM */
|
||||
|
||||
#else /* defined(BCMDBG) || defined(DHD_DEBUG) */
|
||||
|
||||
#define DHD_ERROR(args) do {if (dhd_msg_level & DHD_ERROR_VAL) \
|
||||
printf args;} while (0)
|
||||
#define DHD_TRACE(args)
|
||||
#define DHD_INFO(args)
|
||||
|
||||
#define DHD_DATA(args)
|
||||
#define DHD_CTL(args)
|
||||
#define DHD_TIMER(args)
|
||||
#define DHD_HDRS(args)
|
||||
#define DHD_BYTES(args)
|
||||
#define DHD_INTR(args)
|
||||
#define DHD_GLOM(args)
|
||||
|
||||
#define DHD_EVENT(args)
|
||||
#define DHD_ECNTR_LOG(args) DHD_EVENT(args)
|
||||
|
||||
#define DHD_PRSRV_MEM(args) DHD_EVENT(args)
|
||||
|
||||
#define DHD_BTA(args)
|
||||
#define DHD_ISCAN(args)
|
||||
#define DHD_ARPOE(args)
|
||||
#define DHD_REORDER(args)
|
||||
#define DHD_PNO(args)
|
||||
#define DHD_RTT(args)
|
||||
#define DHD_PKT_MON(args)
|
||||
|
||||
#define DHD_MSGTRACE_LOG(args)
|
||||
#define DHD_FWLOG(args)
|
||||
|
||||
#define DHD_DBGIF(args)
|
||||
|
||||
#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)
|
||||
|
||||
#define DHD_TRACE_HW4 DHD_TRACE
|
||||
#define DHD_INFO_HW4 DHD_INFO
|
||||
#define DHD_ERROR_NO_HW4 DHD_ERROR
|
||||
|
||||
#define DHD_ERROR_ON() 0
|
||||
#define DHD_TRACE_ON() 0
|
||||
#define DHD_INFO_ON() 0
|
||||
#define DHD_DATA_ON() 0
|
||||
#define DHD_CTL_ON() 0
|
||||
#define DHD_TIMER_ON() 0
|
||||
#define DHD_HDRS_ON() 0
|
||||
#define DHD_BYTES_ON() 0
|
||||
#define DHD_INTR_ON() 0
|
||||
#define DHD_GLOM_ON() 0
|
||||
#define DHD_EVENT_ON() 0
|
||||
#define DHD_BTA_ON() 0
|
||||
#define DHD_ISCAN_ON() 0
|
||||
#define DHD_ARPOE_ON() 0
|
||||
#define DHD_REORDER_ON() 0
|
||||
#define DHD_NOCHECKDIED_ON() 0
|
||||
#define DHD_PNO_ON() 0
|
||||
#define DHD_RTT_ON() 0
|
||||
#define DHD_PKT_MON_ON() 0
|
||||
#define DHD_PKT_MON_DUMP_ON() 0
|
||||
#define DHD_MSGTRACE_ON() 0
|
||||
#define DHD_FWLOG_ON() 0
|
||||
#define DHD_DBGIF_ON() 0
|
||||
#ifdef DHD_PCIE_NATIVE_RUNTIMEPM
|
||||
#define DHD_RPM_ON() 0
|
||||
#endif /* DHD_PCIE_NATIVE_RUNTIMEPM */
|
||||
#endif // endif
|
||||
|
||||
#define PRINT_RATE_LIMIT_PERIOD 5000000u /* 5s in units of us */
|
||||
#define DHD_ERROR_RLMT(args) \
|
||||
do { \
|
||||
if (dhd_msg_level & DHD_ERROR_VAL) { \
|
||||
static uint64 __err_ts = 0; \
|
||||
static uint32 __err_cnt = 0; \
|
||||
uint64 __cur_ts = 0; \
|
||||
__cur_ts = OSL_SYSUPTIME_US(); \
|
||||
if (__err_ts == 0 || (__cur_ts > __err_ts && \
|
||||
(__cur_ts - __err_ts > PRINT_RATE_LIMIT_PERIOD))) { \
|
||||
__err_ts = __cur_ts; \
|
||||
DHD_ERROR(args); \
|
||||
DHD_ERROR(("[Repeats %u times]\n", __err_cnt)); \
|
||||
__err_cnt = 0; \
|
||||
} else { \
|
||||
++__err_cnt; \
|
||||
} \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/* even in non-BCMDBG builds, logging of dongle iovars should be available */
|
||||
#define DHD_DNGL_IOVAR_SET(args) \
|
||||
do {if (dhd_msg_level & DHD_DNGL_IOVAR_SET_VAL) printf args;} while (0)
|
||||
|
||||
#define DHD_LOG(args)
|
||||
|
||||
#define DHD_BLOG(cp, size)
|
||||
|
||||
#define DHD_NONE(args)
|
||||
extern int dhd_msg_level;
|
||||
#ifdef DHD_LOG_PRINT_RATE_LIMIT
|
||||
extern int log_print_threshold;
|
||||
#endif /* DHD_LOG_PRINT_RATE_LIMIT */
|
||||
|
||||
#define DHD_RTT_MEM(args) DHD_LOG_MEM(args)
|
||||
#define DHD_RTT_ERR(args) DHD_ERROR(args)
|
||||
|
||||
/* Defines msg bits */
|
||||
#include <dhdioctl.h>
|
||||
|
||||
#endif /* _dhd_dbg_ */
|
||||
@@ -0,0 +1,426 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* DHD debug ring API and structures
|
||||
*
|
||||
* <<Broadcom-WL-IPTag/Open:>>
|
||||
*
|
||||
* Copyright (C) 1999-2019, 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.
|
||||
*
|
||||
* 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_dbg_ring.c 792099 2018-12-03 15:45:56Z $
|
||||
*/
|
||||
#include <typedefs.h>
|
||||
#include <osl.h>
|
||||
#include <bcmutils.h>
|
||||
#include <bcmendian.h>
|
||||
#include <dngl_stats.h>
|
||||
#include <dhd.h>
|
||||
#include <dhd_dbg.h>
|
||||
#include <dhd_dbg_ring.h>
|
||||
|
||||
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 *buf;
|
||||
unsigned long flags = 0;
|
||||
|
||||
if (allocd_buf == NULL) {
|
||||
return BCME_NOMEM;
|
||||
} else {
|
||||
buf = allocd_buf;
|
||||
}
|
||||
|
||||
ring->lock = DHD_DBG_RING_LOCK_INIT(dhdp->osh);
|
||||
if (!ring->lock)
|
||||
return BCME_NOMEM;
|
||||
|
||||
DHD_DBG_RING_LOCK(ring->lock, flags);
|
||||
ring->id = id;
|
||||
strncpy(ring->name, name, DBGRING_NAME_MAX);
|
||||
ring->name[DBGRING_NAME_MAX - 1] = 0;
|
||||
ring->ring_size = ring_sz;
|
||||
ring->wp = ring->rp = 0;
|
||||
ring->ring_buf = buf;
|
||||
ring->threshold = DBGRING_FLUSH_THRESHOLD(ring);
|
||||
ring->state = RING_SUSPEND;
|
||||
ring->rem_len = 0;
|
||||
ring->sched_pull = TRUE;
|
||||
ring->pull_inactive = pull_inactive;
|
||||
DHD_DBG_RING_UNLOCK(ring->lock, flags);
|
||||
|
||||
return BCME_OK;
|
||||
}
|
||||
|
||||
void
|
||||
dhd_dbg_ring_deinit(dhd_pub_t *dhdp, dhd_dbg_ring_t *ring)
|
||||
{
|
||||
unsigned long flags = 0;
|
||||
DHD_DBG_RING_LOCK(ring->lock, flags);
|
||||
ring->id = 0;
|
||||
ring->name[0] = 0;
|
||||
ring->wp = ring->rp = 0;
|
||||
memset(&ring->stat, 0, sizeof(ring->stat));
|
||||
ring->threshold = 0;
|
||||
ring->state = RING_STOP;
|
||||
DHD_DBG_RING_UNLOCK(ring->lock, flags);
|
||||
|
||||
DHD_DBG_RING_LOCK_DEINIT(dhdp->osh, ring->lock);
|
||||
}
|
||||
|
||||
void
|
||||
dhd_dbg_ring_sched_pull(dhd_dbg_ring_t *ring, uint32 pending_len,
|
||||
os_pullreq_t pull_fn, void *os_pvt, const int id)
|
||||
{
|
||||
unsigned long flags = 0;
|
||||
DHD_DBG_RING_LOCK(ring->lock, flags);
|
||||
/* if the current pending size is bigger than threshold and
|
||||
* threshold is set
|
||||
*/
|
||||
if (ring->threshold > 0 &&
|
||||
(pending_len >= ring->threshold) && ring->sched_pull) {
|
||||
/*
|
||||
* Update the state and release the lock before calling
|
||||
* the pull_fn. Do not transfer control to other layers
|
||||
* with locks held. If the call back again calls into
|
||||
* the same layer fro this context, can lead to deadlock.
|
||||
*/
|
||||
ring->sched_pull = FALSE;
|
||||
DHD_DBG_RING_UNLOCK(ring->lock, flags);
|
||||
pull_fn(os_pvt, id);
|
||||
} else {
|
||||
DHD_DBG_RING_UNLOCK(ring->lock, flags);
|
||||
}
|
||||
}
|
||||
|
||||
uint32
|
||||
dhd_dbg_ring_get_pending_len(dhd_dbg_ring_t *ring)
|
||||
{
|
||||
uint32 pending_len = 0;
|
||||
unsigned long flags = 0;
|
||||
DHD_DBG_RING_LOCK(ring->lock, flags);
|
||||
if (ring->stat.written_bytes > ring->stat.read_bytes) {
|
||||
pending_len = ring->stat.written_bytes - ring->stat.read_bytes;
|
||||
} else if (ring->stat.written_bytes < ring->stat.read_bytes) {
|
||||
pending_len = PENDING_LEN_MAX - ring->stat.read_bytes + ring->stat.written_bytes;
|
||||
} else {
|
||||
pending_len = 0;
|
||||
}
|
||||
DHD_DBG_RING_UNLOCK(ring->lock, flags);
|
||||
|
||||
return pending_len;
|
||||
}
|
||||
|
||||
int
|
||||
dhd_dbg_ring_push(dhd_dbg_ring_t *ring, dhd_dbg_ring_entry_t *hdr, void *data)
|
||||
{
|
||||
unsigned long flags;
|
||||
uint32 w_len;
|
||||
uint32 avail_size;
|
||||
dhd_dbg_ring_entry_t *w_entry, *r_entry;
|
||||
|
||||
if (!ring || !hdr || !data) {
|
||||
return BCME_BADARG;
|
||||
}
|
||||
|
||||
DHD_DBG_RING_LOCK(ring->lock, flags);
|
||||
|
||||
if (ring->state != RING_ACTIVE) {
|
||||
DHD_DBG_RING_UNLOCK(ring->lock, flags);
|
||||
return BCME_OK;
|
||||
}
|
||||
|
||||
w_len = ENTRY_LENGTH(hdr);
|
||||
|
||||
DHD_DBGIF(("%s: RING%d[%s] hdr->len=%u, w_len=%u, wp=%d, rp=%d, ring_start=0x%p;"
|
||||
" ring_size=%u\n",
|
||||
__FUNCTION__, ring->id, ring->name, hdr->len, w_len, ring->wp, ring->rp,
|
||||
ring->ring_buf, ring->ring_size));
|
||||
|
||||
if (w_len > ring->ring_size) {
|
||||
DHD_DBG_RING_UNLOCK(ring->lock, flags);
|
||||
DHD_ERROR(("%s: RING%d[%s] w_len=%u, ring_size=%u,"
|
||||
" write size exceeds ring size !\n",
|
||||
__FUNCTION__, ring->id, ring->name, w_len, ring->ring_size));
|
||||
return BCME_BUFTOOLONG;
|
||||
}
|
||||
/* Claim the space */
|
||||
do {
|
||||
avail_size = DBG_RING_CHECK_WRITE_SPACE(ring->rp, ring->wp, ring->ring_size);
|
||||
if (avail_size <= w_len) {
|
||||
/* Prepare the space */
|
||||
if (ring->rp <= ring->wp) {
|
||||
ring->tail_padded = TRUE;
|
||||
ring->rem_len = ring->ring_size - ring->wp;
|
||||
DHD_DBGIF(("%s: RING%d[%s] Insuffient tail space,"
|
||||
" rp=%d, wp=%d, rem_len=%d, ring_size=%d,"
|
||||
" avail_size=%d, w_len=%d\n", __FUNCTION__,
|
||||
ring->id, ring->name, ring->rp, ring->wp,
|
||||
ring->rem_len, ring->ring_size, avail_size,
|
||||
w_len));
|
||||
|
||||
/* 0 pad insufficient tail space */
|
||||
memset((uint8 *)ring->ring_buf + ring->wp, 0, ring->rem_len);
|
||||
/* If read pointer is still at the beginning, make some room */
|
||||
if (ring->rp == 0) {
|
||||
r_entry = (dhd_dbg_ring_entry_t *)((uint8 *)ring->ring_buf +
|
||||
ring->rp);
|
||||
ring->rp += ENTRY_LENGTH(r_entry);
|
||||
ring->stat.read_bytes += ENTRY_LENGTH(r_entry);
|
||||
DHD_DBGIF(("%s: rp at 0, move by one entry length"
|
||||
" (%u bytes)\n",
|
||||
__FUNCTION__, (uint32)ENTRY_LENGTH(r_entry)));
|
||||
}
|
||||
if (ring->rp == ring->wp) {
|
||||
ring->rp = 0;
|
||||
}
|
||||
ring->wp = 0;
|
||||
DHD_DBGIF(("%s: new rp=%u, wp=%u\n",
|
||||
__FUNCTION__, ring->rp, ring->wp));
|
||||
} else {
|
||||
/* Not enough space for new entry, free some up */
|
||||
r_entry = (dhd_dbg_ring_entry_t *)((uint8 *)ring->ring_buf +
|
||||
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, "
|
||||
"ring->wp=%u, ring->rp=%u, ring->ring_size=%d\n",
|
||||
__FUNCTION__, ring->id, ring->name, ring->wp,
|
||||
ring->rp, ring->ring_size));
|
||||
ASSERT(0);
|
||||
DHD_DBG_RING_UNLOCK(ring->lock, flags);
|
||||
return BCME_BUFTOOSHORT;
|
||||
}
|
||||
ring->rp += ENTRY_LENGTH(r_entry);
|
||||
/* skip padding if there is one */
|
||||
if (ring->tail_padded &&
|
||||
((ring->rp + ring->rem_len) == ring->ring_size)) {
|
||||
DHD_DBGIF(("%s: RING%d[%s] Found padding,"
|
||||
" avail_size=%d, w_len=%d, set rp=0\n",
|
||||
__FUNCTION__, ring->id, ring->name,
|
||||
avail_size, w_len));
|
||||
ring->rp = 0;
|
||||
ring->tail_padded = FALSE;
|
||||
ring->rem_len = 0;
|
||||
}
|
||||
ring->stat.read_bytes += ENTRY_LENGTH(r_entry);
|
||||
DHD_DBGIF(("%s: RING%d[%s] read_bytes=%d, wp=%d, rp=%d\n",
|
||||
__FUNCTION__, ring->id, ring->name, ring->stat.read_bytes,
|
||||
ring->wp, ring->rp));
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
} while (TRUE);
|
||||
|
||||
/* 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, "
|
||||
"wp=%d, ring_size=%d, w_len=%u\n", __FUNCTION__, ring->id,
|
||||
ring->name, ring->wp, ring->ring_size, w_len));
|
||||
ASSERT(0);
|
||||
DHD_DBG_RING_UNLOCK(ring->lock, flags);
|
||||
return BCME_BUFTOOLONG;
|
||||
}
|
||||
|
||||
w_entry = (dhd_dbg_ring_entry_t *)((uint8 *)ring->ring_buf + ring->wp);
|
||||
/* header */
|
||||
memcpy(w_entry, hdr, DBG_RING_ENTRY_SIZE);
|
||||
w_entry->len = hdr->len;
|
||||
/* payload */
|
||||
memcpy((char *)w_entry + DBG_RING_ENTRY_SIZE, data, w_entry->len);
|
||||
/* update write pointer */
|
||||
ring->wp += w_len;
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/*
|
||||
* This function folds ring->lock, so callers of this function
|
||||
* should not hold ring->lock.
|
||||
*/
|
||||
int
|
||||
dhd_dbg_ring_pull_single(dhd_dbg_ring_t *ring, void *data, uint32 buf_len, bool strip_header)
|
||||
{
|
||||
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
|
||||
* pulled to dump it to a file. For other rings if ring is
|
||||
* not in active state return without processing (as before)
|
||||
*/
|
||||
if (!ring->pull_inactive && (ring->state != RING_ACTIVE)) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (ring->rp == ring->wp) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
DHD_DBGIF(("%s: RING%d[%s] buf_len=%u, wp=%d, rp=%d, ring_start=0x%p; ring_size=%u\n",
|
||||
__FUNCTION__, ring->id, ring->name, buf_len, ring->wp, ring->rp,
|
||||
ring->ring_buf, ring->ring_size));
|
||||
|
||||
r_entry = (dhd_dbg_ring_entry_t *)((uint8 *)ring->ring_buf + ring->rp);
|
||||
|
||||
/* 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,"
|
||||
" current ring %d[%s] - rp=%d\n", __FUNCTION__, rlen,
|
||||
ring->ring_size, ring->id, ring->name, ring->rp));
|
||||
rlen = 0;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (strip_header) {
|
||||
rlen = r_entry->len;
|
||||
buf = (char *)r_entry + DBG_RING_ENTRY_SIZE;
|
||||
} else {
|
||||
rlen = ENTRY_LENGTH(r_entry);
|
||||
buf = (char *)r_entry;
|
||||
}
|
||||
if (rlen > buf_len) {
|
||||
DHD_ERROR(("%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",
|
||||
__FUNCTION__, ring->id, ring->name, ring->ring_size,
|
||||
ring->wp, ring->rp));
|
||||
ASSERT(0);
|
||||
rlen = 0;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
memcpy(data, buf, rlen);
|
||||
/* update ring context */
|
||||
ring->rp += ENTRY_LENGTH(r_entry);
|
||||
/* don't pass wp but skip padding if there is one */
|
||||
if (ring->rp != ring->wp &&
|
||||
ring->tail_padded && ((ring->rp + ring->rem_len) >= ring->ring_size)) {
|
||||
DHD_DBGIF(("%s: RING%d[%s] Found padding, rp=%d, wp=%d\n",
|
||||
__FUNCTION__, ring->id, ring->name, ring->rp, ring->wp));
|
||||
ring->rp = 0;
|
||||
ring->tail_padded = FALSE;
|
||||
ring->rem_len = 0;
|
||||
}
|
||||
if (ring->rp >= ring->ring_size) {
|
||||
DHD_ERROR(("%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);
|
||||
rlen = 0;
|
||||
goto exit;
|
||||
}
|
||||
ring->stat.read_bytes += ENTRY_LENGTH(r_entry);
|
||||
DHD_DBGIF(("%s RING%d[%s]read_bytes %d, wp=%d, rp=%d\n", __FUNCTION__,
|
||||
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)
|
||||
{
|
||||
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);
|
||||
if (r_len == 0)
|
||||
break;
|
||||
data = (uint8 *)data + r_len;
|
||||
buf_len -= r_len;
|
||||
total_r_len += r_len;
|
||||
}
|
||||
|
||||
return total_r_len;
|
||||
}
|
||||
|
||||
int
|
||||
dhd_dbg_ring_config(dhd_dbg_ring_t *ring, int log_level, uint32 threshold)
|
||||
{
|
||||
unsigned long flags = 0;
|
||||
if (!ring)
|
||||
return BCME_BADADDR;
|
||||
|
||||
if (ring->state == RING_STOP)
|
||||
return BCME_UNSUPPORTED;
|
||||
|
||||
DHD_DBG_RING_LOCK(ring->lock, flags);
|
||||
|
||||
if (log_level == 0)
|
||||
ring->state = RING_SUSPEND;
|
||||
else
|
||||
ring->state = RING_ACTIVE;
|
||||
|
||||
ring->log_level = log_level;
|
||||
ring->threshold = MIN(threshold, DBGRING_FLUSH_THRESHOLD(ring));
|
||||
|
||||
DHD_DBG_RING_UNLOCK(ring->lock, flags);
|
||||
|
||||
return BCME_OK;
|
||||
}
|
||||
|
||||
void
|
||||
dhd_dbg_ring_start(dhd_dbg_ring_t *ring)
|
||||
{
|
||||
if (!ring)
|
||||
return;
|
||||
|
||||
/* Initialize the information for the ring */
|
||||
ring->state = RING_SUSPEND;
|
||||
ring->log_level = 0;
|
||||
ring->rp = ring->wp = 0;
|
||||
ring->threshold = 0;
|
||||
memset(&ring->stat, 0, sizeof(struct ring_statistics));
|
||||
memset(ring->ring_buf, 0, ring->ring_size);
|
||||
}
|
||||
@@ -0,0 +1,141 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* DHD debug ring header file
|
||||
*
|
||||
* <<Broadcom-WL-IPTag/Open:>>
|
||||
*
|
||||
* Copyright (C) 1999-2019, 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.
|
||||
*
|
||||
* 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_dbg_ring.h 795094 2018-12-17 08:56:58Z $
|
||||
*/
|
||||
|
||||
#ifndef __DHD_DBG_RING_H__
|
||||
#define __DHD_DBG_RING_H__
|
||||
|
||||
#include <bcmutils.h>
|
||||
|
||||
#define PACKED_STRUCT __attribute__ ((packed))
|
||||
|
||||
#define DBGRING_NAME_MAX 32
|
||||
|
||||
enum dbg_ring_state {
|
||||
RING_STOP = 0, /* ring is not initialized */
|
||||
RING_ACTIVE, /* ring is live and logging */
|
||||
RING_SUSPEND /* ring is initialized but not logging */
|
||||
};
|
||||
|
||||
/* each entry in dbg ring has below header, to handle
|
||||
* variable length records in ring
|
||||
*/
|
||||
typedef struct dhd_dbg_ring_entry {
|
||||
uint16 len; /* payload length excluding the header */
|
||||
uint8 flags;
|
||||
uint8 type; /* Per ring specific */
|
||||
uint64 timestamp; /* present if has_timestamp bit is set. */
|
||||
} PACKED_STRUCT dhd_dbg_ring_entry_t;
|
||||
|
||||
struct ring_statistics {
|
||||
/* number of bytes that was written to the buffer by driver */
|
||||
uint32 written_bytes;
|
||||
/* number of bytes that was read from the buffer by user land */
|
||||
uint32 read_bytes;
|
||||
/* number of records that was written to the buffer by driver */
|
||||
uint32 written_records;
|
||||
};
|
||||
|
||||
typedef struct dhd_dbg_ring_status {
|
||||
uint8 name[DBGRING_NAME_MAX];
|
||||
uint32 flags;
|
||||
int ring_id; /* unique integer representing the ring */
|
||||
/* total memory size allocated for the buffer */
|
||||
uint32 ring_buffer_byte_size;
|
||||
uint32 verbose_level;
|
||||
/* number of bytes that was written to the buffer by driver */
|
||||
uint32 written_bytes;
|
||||
/* number of bytes that was read from the buffer by user land */
|
||||
uint32 read_bytes;
|
||||
/* number of records that was read from the buffer by user land */
|
||||
uint32 written_records;
|
||||
} dhd_dbg_ring_status_t;
|
||||
|
||||
typedef struct dhd_dbg_ring {
|
||||
int id; /* ring id */
|
||||
uint8 name[DBGRING_NAME_MAX]; /* name string */
|
||||
uint32 ring_size; /* numbers of item in ring */
|
||||
uint32 wp; /* write pointer */
|
||||
uint32 rp; /* read pointer */
|
||||
uint32 rp_tmp; /* tmp read pointer */
|
||||
uint32 log_level; /* log_level */
|
||||
uint32 threshold; /* threshold bytes */
|
||||
void * ring_buf; /* pointer of actually ring buffer */
|
||||
void * lock; /* lock for ring access */
|
||||
struct ring_statistics stat; /* statistics */
|
||||
enum dbg_ring_state state; /* ring state enum */
|
||||
bool tail_padded; /* writer does not have enough space */
|
||||
uint32 rem_len; /* number of bytes from wp_pad to end */
|
||||
bool sched_pull; /* schedule reader immediately */
|
||||
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 RING_STAT_TO_STATUS(ring, status) \
|
||||
do { \
|
||||
strncpy(status.name, ring->name, \
|
||||
sizeof(status.name) - 1); \
|
||||
status.ring_id = ring->id; \
|
||||
status.ring_buffer_byte_size = ring->ring_size; \
|
||||
status.written_bytes = ring->stat.written_bytes; \
|
||||
status.written_records = ring->stat.written_records; \
|
||||
status.read_bytes = ring->stat.read_bytes; \
|
||||
status.verbose_level = ring->log_level; \
|
||||
} while (0)
|
||||
|
||||
#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 PENDING_LEN_MAX 0xFFFFFFFF
|
||||
#define DBG_RING_STATUS_SIZE (sizeof(dhd_dbg_ring_status_t))
|
||||
|
||||
#define TXACTIVESZ(r, w, d) (((r) <= (w)) ? ((w) - (r)) : ((d) - (r) + (w)))
|
||||
#define DBG_RING_READ_AVAIL_SPACE(w, r, d) (((w) >= (r)) ? ((w) - (r)) : ((d) - (r)))
|
||||
#define DBG_RING_WRITE_SPACE_AVAIL_CONT(r, w, d) (((w) >= (r)) ? ((d) - (w)) : ((r) - (w)))
|
||||
#define DBG_RING_WRITE_SPACE_AVAIL(r, w, d) (d - (TXACTIVESZ(r, w, d)))
|
||||
#define DBG_RING_CHECK_WRITE_SPACE(r, w, d) \
|
||||
MIN(DBG_RING_WRITE_SPACE_AVAIL(r, w, d), DBG_RING_WRITE_SPACE_AVAIL_CONT(r, w, d))
|
||||
|
||||
typedef void (*os_pullreq_t)(void *os_priv, const int ring_id);
|
||||
|
||||
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_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);
|
||||
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);
|
||||
void dhd_dbg_ring_sched_pull(dhd_dbg_ring_t *ring, uint32 pending_len,
|
||||
os_pullreq_t pull_fn, void *os_pvt, const int id);
|
||||
int dhd_dbg_ring_config(dhd_dbg_ring_t *ring, int log_level, uint32 threshold);
|
||||
void dhd_dbg_ring_start(dhd_dbg_ring_t *ring);
|
||||
#endif /* __DHD_DBG_RING_H__ */
|
||||
2411
drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd_wifi6/dhd_debug.c
Normal file
2411
drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd_wifi6/dhd_debug.c
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,853 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* DHD debugability header file
|
||||
*
|
||||
* <<Broadcom-WL-IPTag/Open:>>
|
||||
*
|
||||
* Copyright (C) 1999-2019, 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.
|
||||
*
|
||||
* 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_debug.h 783721 2018-10-08 13:05:26Z $
|
||||
*/
|
||||
|
||||
#ifndef _dhd_debug_h_
|
||||
#define _dhd_debug_h_
|
||||
#include <event_log.h>
|
||||
#include <bcmutils.h>
|
||||
#include <dhd_dbg_ring.h>
|
||||
|
||||
enum {
|
||||
DEBUG_RING_ID_INVALID = 0,
|
||||
FW_VERBOSE_RING_ID,
|
||||
DHD_EVENT_RING_ID,
|
||||
/* add new id here */
|
||||
DEBUG_RING_ID_MAX
|
||||
};
|
||||
|
||||
enum {
|
||||
/* Feature set */
|
||||
DBG_MEMORY_DUMP_SUPPORTED = (1 << (0)), /* Memory dump of FW */
|
||||
DBG_PER_PACKET_TX_RX_STATUS_SUPPORTED = (1 << (1)), /* PKT Status */
|
||||
DBG_CONNECT_EVENT_SUPPORTED = (1 << (2)), /* Connectivity Event */
|
||||
DBG_POWER_EVENT_SUPOORTED = (1 << (3)), /* POWER of Driver */
|
||||
DBG_WAKE_LOCK_SUPPORTED = (1 << (4)), /* WAKE LOCK of Driver */
|
||||
DBG_VERBOSE_LOG_SUPPORTED = (1 << (5)), /* verbose log of FW */
|
||||
DBG_HEALTH_CHECK_SUPPORTED = (1 << (6)), /* monitor the health of FW */
|
||||
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 */
|
||||
};
|
||||
|
||||
enum {
|
||||
/* set for binary entries */
|
||||
DBG_RING_ENTRY_FLAGS_HAS_BINARY = (1 << (0)),
|
||||
/* set if 64 bits timestamp is present */
|
||||
DBG_RING_ENTRY_FLAGS_HAS_TIMESTAMP = (1 << (1))
|
||||
};
|
||||
|
||||
/* firmware verbose ring, ring id 1 */
|
||||
#define FW_VERBOSE_RING_NAME "fw_verbose"
|
||||
#define FW_VERBOSE_RING_SIZE (256 * 1024)
|
||||
/* firmware event ring, ring id 2 */
|
||||
#define FW_EVENT_RING_NAME "fw_event"
|
||||
#define FW_EVENT_RING_SIZE (64 * 1024)
|
||||
/* DHD connection event ring, ring id 3 */
|
||||
#define DHD_EVENT_RING_NAME "dhd_event"
|
||||
#define DHD_EVENT_RING_SIZE (64 * 1024)
|
||||
/* NAN event ring, ring id 4 */
|
||||
#define NAN_EVENT_RING_NAME "nan_event"
|
||||
#define NAN_EVENT_RING_SIZE (64 * 1024)
|
||||
|
||||
#define TLV_LOG_SIZE(tlv) ((tlv) ? (sizeof(tlv_log) + (tlv)->len) : 0)
|
||||
|
||||
#define TLV_LOG_NEXT(tlv) \
|
||||
((tlv) ? ((tlv_log *)((uint8 *)tlv + TLV_LOG_SIZE(tlv))) : 0)
|
||||
|
||||
#define VALID_RING(id) \
|
||||
((id > DEBUG_RING_ID_INVALID) && (id < DEBUG_RING_ID_MAX))
|
||||
|
||||
#ifdef DEBUGABILITY
|
||||
#define DBG_RING_ACTIVE(dhdp, ring_id) \
|
||||
((dhdp)->dbg->dbg_rings[(ring_id)].state == RING_ACTIVE)
|
||||
#else
|
||||
#define DBG_RING_ACTIVE(dhdp, ring_id) 0
|
||||
#endif /* DEBUGABILITY */
|
||||
|
||||
enum {
|
||||
/* driver receive association command from kernel */
|
||||
WIFI_EVENT_ASSOCIATION_REQUESTED = 0,
|
||||
WIFI_EVENT_AUTH_COMPLETE,
|
||||
WIFI_EVENT_ASSOC_COMPLETE,
|
||||
/* received firmware event indicating auth frames are sent */
|
||||
WIFI_EVENT_FW_AUTH_STARTED,
|
||||
/* received firmware event indicating assoc frames are sent */
|
||||
WIFI_EVENT_FW_ASSOC_STARTED,
|
||||
/* received firmware event indicating reassoc frames are sent */
|
||||
WIFI_EVENT_FW_RE_ASSOC_STARTED,
|
||||
WIFI_EVENT_DRIVER_SCAN_REQUESTED,
|
||||
WIFI_EVENT_DRIVER_SCAN_RESULT_FOUND,
|
||||
WIFI_EVENT_DRIVER_SCAN_COMPLETE,
|
||||
WIFI_EVENT_G_SCAN_STARTED,
|
||||
WIFI_EVENT_G_SCAN_COMPLETE,
|
||||
WIFI_EVENT_DISASSOCIATION_REQUESTED,
|
||||
WIFI_EVENT_RE_ASSOCIATION_REQUESTED,
|
||||
WIFI_EVENT_ROAM_REQUESTED,
|
||||
/* received beacon from AP (event enabled only in verbose mode) */
|
||||
WIFI_EVENT_BEACON_RECEIVED,
|
||||
/* firmware has triggered a roam scan (not g-scan) */
|
||||
WIFI_EVENT_ROAM_SCAN_STARTED,
|
||||
/* firmware has completed a roam scan (not g-scan) */
|
||||
WIFI_EVENT_ROAM_SCAN_COMPLETE,
|
||||
/* firmware has started searching for roam candidates (with reason =xx) */
|
||||
WIFI_EVENT_ROAM_SEARCH_STARTED,
|
||||
/* firmware has stopped searching for roam candidates (with reason =xx) */
|
||||
WIFI_EVENT_ROAM_SEARCH_STOPPED,
|
||||
WIFI_EVENT_UNUSED_0,
|
||||
/* received channel switch anouncement from AP */
|
||||
WIFI_EVENT_CHANNEL_SWITCH_ANOUNCEMENT,
|
||||
/* fw start transmit eapol frame, with EAPOL index 1-4 */
|
||||
WIFI_EVENT_FW_EAPOL_FRAME_TRANSMIT_START,
|
||||
/* fw gives up eapol frame, with rate, success/failure and number retries */
|
||||
WIFI_EVENT_FW_EAPOL_FRAME_TRANSMIT_STOP,
|
||||
/* kernel queue EAPOL for transmission in driver with EAPOL index 1-4 */
|
||||
WIFI_EVENT_DRIVER_EAPOL_FRAME_TRANSMIT_REQUESTED,
|
||||
/* with rate, regardless of the fact that EAPOL frame is accepted or
|
||||
* rejected by firmware
|
||||
*/
|
||||
WIFI_EVENT_FW_EAPOL_FRAME_RECEIVED,
|
||||
WIFI_EVENT_UNUSED_1,
|
||||
/* with rate, and eapol index, driver has received */
|
||||
/* EAPOL frame and will queue it up to wpa_supplicant */
|
||||
WIFI_EVENT_DRIVER_EAPOL_FRAME_RECEIVED,
|
||||
/* with success/failure, parameters */
|
||||
WIFI_EVENT_BLOCK_ACK_NEGOTIATION_COMPLETE,
|
||||
WIFI_EVENT_BT_COEX_BT_SCO_START,
|
||||
WIFI_EVENT_BT_COEX_BT_SCO_STOP,
|
||||
/* for paging/scan etc..., when BT starts transmiting twice per BT slot */
|
||||
WIFI_EVENT_BT_COEX_BT_SCAN_START,
|
||||
WIFI_EVENT_BT_COEX_BT_SCAN_STOP,
|
||||
WIFI_EVENT_BT_COEX_BT_HID_START,
|
||||
WIFI_EVENT_BT_COEX_BT_HID_STOP,
|
||||
/* firmware sends auth frame in roaming to next candidate */
|
||||
WIFI_EVENT_ROAM_AUTH_STARTED,
|
||||
/* firmware receive auth confirm from ap */
|
||||
WIFI_EVENT_ROAM_AUTH_COMPLETE,
|
||||
/* firmware sends assoc/reassoc frame in */
|
||||
WIFI_EVENT_ROAM_ASSOC_STARTED,
|
||||
/* firmware receive assoc/reassoc confirm from ap */
|
||||
WIFI_EVENT_ROAM_ASSOC_COMPLETE,
|
||||
/* firmware sends stop G_SCAN */
|
||||
WIFI_EVENT_G_SCAN_STOP,
|
||||
/* firmware indicates G_SCAN scan cycle started */
|
||||
WIFI_EVENT_G_SCAN_CYCLE_STARTED,
|
||||
/* firmware indicates G_SCAN scan cycle completed */
|
||||
WIFI_EVENT_G_SCAN_CYCLE_COMPLETED,
|
||||
/* firmware indicates G_SCAN scan start for a particular bucket */
|
||||
WIFI_EVENT_G_SCAN_BUCKET_STARTED,
|
||||
/* firmware indicates G_SCAN scan completed for particular bucket */
|
||||
WIFI_EVENT_G_SCAN_BUCKET_COMPLETED,
|
||||
/* Event received from firmware about G_SCAN scan results being available */
|
||||
WIFI_EVENT_G_SCAN_RESULTS_AVAILABLE,
|
||||
/* Event received from firmware with G_SCAN capabilities */
|
||||
WIFI_EVENT_G_SCAN_CAPABILITIES,
|
||||
/* Event received from firmware when eligible candidate is found */
|
||||
WIFI_EVENT_ROAM_CANDIDATE_FOUND,
|
||||
/* Event received from firmware when roam scan configuration gets enabled or disabled */
|
||||
WIFI_EVENT_ROAM_SCAN_CONFIG,
|
||||
/* firmware/driver timed out authentication */
|
||||
WIFI_EVENT_AUTH_TIMEOUT,
|
||||
/* firmware/driver timed out association */
|
||||
WIFI_EVENT_ASSOC_TIMEOUT,
|
||||
/* firmware/driver encountered allocation failure */
|
||||
WIFI_EVENT_MEM_ALLOC_FAILURE,
|
||||
/* driver added a PNO network in firmware */
|
||||
WIFI_EVENT_DRIVER_PNO_ADD,
|
||||
/* driver removed a PNO network in firmware */
|
||||
WIFI_EVENT_DRIVER_PNO_REMOVE,
|
||||
/* driver received PNO networks found indication from firmware */
|
||||
WIFI_EVENT_DRIVER_PNO_NETWORK_FOUND,
|
||||
/* driver triggered a scan for PNO networks */
|
||||
WIFI_EVENT_DRIVER_PNO_SCAN_REQUESTED,
|
||||
/* driver received scan results of PNO networks */
|
||||
WIFI_EVENT_DRIVER_PNO_SCAN_RESULT_FOUND,
|
||||
/* driver updated scan results from PNO candidates to cfg */
|
||||
WIFI_EVENT_DRIVER_PNO_SCAN_COMPLETE
|
||||
};
|
||||
|
||||
enum {
|
||||
WIFI_TAG_VENDOR_SPECIFIC = 0, /* take a byte stream as parameter */
|
||||
WIFI_TAG_BSSID, /* takes a 6 bytes MAC address as parameter */
|
||||
WIFI_TAG_ADDR, /* takes a 6 bytes MAC address as parameter */
|
||||
WIFI_TAG_SSID, /* takes a 32 bytes SSID address as parameter */
|
||||
WIFI_TAG_STATUS, /* takes an integer as parameter */
|
||||
WIFI_TAG_CHANNEL_SPEC, /* takes one or more wifi_channel_spec as parameter */
|
||||
WIFI_TAG_WAKE_LOCK_EVENT, /* takes a wake_lock_event struct as parameter */
|
||||
WIFI_TAG_ADDR1, /* takes a 6 bytes MAC address as parameter */
|
||||
WIFI_TAG_ADDR2, /* takes a 6 bytes MAC address as parameter */
|
||||
WIFI_TAG_ADDR3, /* takes a 6 bytes MAC address as parameter */
|
||||
WIFI_TAG_ADDR4, /* takes a 6 bytes MAC address as parameter */
|
||||
WIFI_TAG_TSF, /* take a 64 bits TSF value as parameter */
|
||||
WIFI_TAG_IE,
|
||||
/* take one or more specific 802.11 IEs parameter, IEs are in turn
|
||||
* indicated in TLV format as per 802.11 spec
|
||||
*/
|
||||
WIFI_TAG_INTERFACE, /* take interface name as parameter */
|
||||
WIFI_TAG_REASON_CODE, /* take a reason code as per 802.11 as parameter */
|
||||
WIFI_TAG_RATE_MBPS, /* take a wifi rate in 0.5 mbps */
|
||||
WIFI_TAG_REQUEST_ID, /* take an integer as parameter */
|
||||
WIFI_TAG_BUCKET_ID, /* take an integer as parameter */
|
||||
WIFI_TAG_GSCAN_PARAMS, /* takes a wifi_scan_cmd_params struct as parameter */
|
||||
WIFI_TAG_GSCAN_CAPABILITIES, /* takes a wifi_gscan_capabilities struct as parameter */
|
||||
WIFI_TAG_SCAN_ID, /* take an integer as parameter */
|
||||
WIFI_TAG_RSSI, /* takes s16 as parameter */
|
||||
WIFI_TAG_CHANNEL, /* takes u16 as parameter */
|
||||
WIFI_TAG_LINK_ID, /* take an integer as parameter */
|
||||
WIFI_TAG_LINK_ROLE, /* take an integer as parameter */
|
||||
WIFI_TAG_LINK_STATE, /* take an integer as parameter */
|
||||
WIFI_TAG_LINK_TYPE, /* take an integer as parameter */
|
||||
WIFI_TAG_TSCO, /* take an integer as parameter */
|
||||
WIFI_TAG_RSCO, /* take an integer as parameter */
|
||||
WIFI_TAG_EAPOL_MESSAGE_TYPE /* take an integer as parameter */
|
||||
};
|
||||
|
||||
/* NAN events */
|
||||
typedef enum {
|
||||
NAN_EVENT_INVALID = 0,
|
||||
NAN_EVENT_CLUSTER_STARTED = 1,
|
||||
NAN_EVENT_CLUSTER_JOINED = 2,
|
||||
NAN_EVENT_CLUSTER_MERGED = 3,
|
||||
NAN_EVENT_ROLE_CHANGED = 4,
|
||||
NAN_EVENT_SCAN_COMPLETE = 5,
|
||||
NAN_EVENT_STATUS_CHNG = 6,
|
||||
/* ADD new events before this line */
|
||||
NAN_EVENT_MAX
|
||||
} nan_event_id_t;
|
||||
|
||||
typedef struct {
|
||||
uint16 tag;
|
||||
uint16 len; /* length of value */
|
||||
uint8 value[0];
|
||||
} tlv_log;
|
||||
|
||||
typedef struct per_packet_status_entry {
|
||||
uint8 flags;
|
||||
uint8 tid; /* transmit or received tid */
|
||||
uint16 MCS; /* modulation and bandwidth */
|
||||
/*
|
||||
* TX: RSSI of ACK for that packet
|
||||
* RX: RSSI of packet
|
||||
*/
|
||||
uint8 rssi;
|
||||
uint8 num_retries; /* number of attempted retries */
|
||||
uint16 last_transmit_rate; /* last transmit rate in .5 mbps */
|
||||
/* transmit/reeive sequence for that MPDU packet */
|
||||
uint16 link_layer_transmit_sequence;
|
||||
/*
|
||||
* TX: firmware timestamp (us) when packet is queued within firmware buffer
|
||||
* for SDIO/HSIC or into PCIe buffer
|
||||
* RX : firmware receive timestamp
|
||||
*/
|
||||
uint64 firmware_entry_timestamp;
|
||||
/*
|
||||
* firmware timestamp (us) when packet start contending for the
|
||||
* medium for the first time, at head of its AC queue,
|
||||
* or as part of an MPDU or A-MPDU. This timestamp is not updated
|
||||
* for each retry, only the first transmit attempt.
|
||||
*/
|
||||
uint64 start_contention_timestamp;
|
||||
/*
|
||||
* fimrware timestamp (us) when packet is successfully transmitted
|
||||
* or aborted because it has exhausted its maximum number of retries
|
||||
*/
|
||||
uint64 transmit_success_timestamp;
|
||||
/*
|
||||
* packet data. The length of packet data is determined by the entry_size field of
|
||||
* the wifi_ring_buffer_entry structure. It is expected that first bytes of the
|
||||
* packet, or packet headers only (up to TCP or RTP/UDP headers) will be copied into the ring
|
||||
*/
|
||||
uint8 *data;
|
||||
} per_packet_status_entry_t;
|
||||
|
||||
#define PACKED_STRUCT __attribute__ ((packed))
|
||||
|
||||
typedef struct log_conn_event {
|
||||
uint16 event;
|
||||
tlv_log *tlvs;
|
||||
/*
|
||||
* separate parameter structure per event to be provided and optional data
|
||||
* the event_data is expected to include an official android part, with some
|
||||
* parameter as transmit rate, num retries, num scan result found etc...
|
||||
* as well, event_data can include a vendor proprietary part which is
|
||||
* understood by the developer only.
|
||||
*/
|
||||
} PACKED_STRUCT log_conn_event_t;
|
||||
|
||||
/*
|
||||
* Ring buffer name for power events ring. note that power event are extremely frequents
|
||||
* and thus should be stored in their own ring/file so as not to clobber connectivity events
|
||||
*/
|
||||
|
||||
typedef struct wake_lock_event {
|
||||
uint32 status; /* 0 taken, 1 released */
|
||||
uint32 reason; /* reason why this wake lock is taken */
|
||||
char *name; /* null terminated */
|
||||
} wake_lock_event_t;
|
||||
|
||||
typedef struct wifi_power_event {
|
||||
uint16 event;
|
||||
tlv_log *tlvs;
|
||||
} wifi_power_event_t;
|
||||
|
||||
#define NAN_EVENT_VERSION 1
|
||||
typedef struct log_nan_event {
|
||||
uint8 version;
|
||||
uint8 pad;
|
||||
uint16 event;
|
||||
tlv_log *tlvs;
|
||||
} log_nan_event_t;
|
||||
|
||||
/* entry type */
|
||||
enum {
|
||||
DBG_RING_ENTRY_EVENT_TYPE = 1,
|
||||
DBG_RING_ENTRY_PKT_TYPE,
|
||||
DBG_RING_ENTRY_WAKE_LOCK_EVENT_TYPE,
|
||||
DBG_RING_ENTRY_POWER_EVENT_TYPE,
|
||||
DBG_RING_ENTRY_DATA_TYPE,
|
||||
DBG_RING_ENTRY_NAN_EVENT_TYPE
|
||||
};
|
||||
|
||||
struct log_level_table {
|
||||
int log_level;
|
||||
uint16 tag;
|
||||
char *desc;
|
||||
};
|
||||
|
||||
/*
|
||||
* Assuming that the Ring lock is mutex, bailing out if the
|
||||
* callers are from atomic context. On a long term, one has to
|
||||
* schedule a job to execute in sleepable context so that
|
||||
* contents are pushed to the ring.
|
||||
*/
|
||||
#define DBG_EVENT_LOG(dhdp, connect_state) \
|
||||
{ \
|
||||
do { \
|
||||
uint16 state = connect_state; \
|
||||
if (CAN_SLEEP() && DBG_RING_ACTIVE(dhdp, DHD_EVENT_RING_ID)) \
|
||||
dhd_os_push_push_ring_data(dhdp, DHD_EVENT_RING_ID, \
|
||||
&state, sizeof(state)); \
|
||||
} while (0); \
|
||||
}
|
||||
|
||||
#define MD5_PREFIX_LEN 4
|
||||
#define MAX_FATE_LOG_LEN 32
|
||||
#define MAX_FRAME_LEN_ETHERNET 1518
|
||||
#define MAX_FRAME_LEN_80211_MGMT 2352 /* 802.11-2012 Fig. 8-34 */
|
||||
|
||||
typedef enum {
|
||||
/* Sent over air and ACKed. */
|
||||
TX_PKT_FATE_ACKED,
|
||||
|
||||
/* Sent over air but not ACKed. (Normal for broadcast/multicast.) */
|
||||
TX_PKT_FATE_SENT,
|
||||
|
||||
/* Queued within firmware, but not yet sent over air. */
|
||||
TX_PKT_FATE_FW_QUEUED,
|
||||
|
||||
/*
|
||||
* Dropped by firmware as invalid. E.g. bad source address,
|
||||
* bad checksum, or invalid for current state.
|
||||
*/
|
||||
TX_PKT_FATE_FW_DROP_INVALID,
|
||||
|
||||
/* Dropped by firmware due to lifetime expiration. */
|
||||
TX_PKT_FATE_FW_DROP_EXPTIME,
|
||||
|
||||
/*
|
||||
* Dropped by firmware for any other reason. Includes
|
||||
* frames that were sent by driver to firmware, but
|
||||
* unaccounted for by firmware.
|
||||
*/
|
||||
TX_PKT_FATE_FW_DROP_OTHER,
|
||||
|
||||
/* Queued within driver, not yet sent to firmware. */
|
||||
TX_PKT_FATE_DRV_QUEUED,
|
||||
|
||||
/*
|
||||
* Dropped by driver as invalid. E.g. bad source address,
|
||||
* or invalid for current state.
|
||||
*/
|
||||
TX_PKT_FATE_DRV_DROP_INVALID,
|
||||
|
||||
/* Dropped by driver due to lack of buffer space. */
|
||||
TX_PKT_FATE_DRV_DROP_NOBUFS,
|
||||
|
||||
/* Dropped by driver for any other reason. */
|
||||
TX_PKT_FATE_DRV_DROP_OTHER,
|
||||
|
||||
/* Packet free by firmware. */
|
||||
TX_PKT_FATE_FW_PKT_FREE,
|
||||
|
||||
} wifi_tx_packet_fate;
|
||||
|
||||
typedef enum {
|
||||
/* Valid and delivered to network stack (e.g., netif_rx()). */
|
||||
RX_PKT_FATE_SUCCESS,
|
||||
|
||||
/* Queued within firmware, but not yet sent to driver. */
|
||||
RX_PKT_FATE_FW_QUEUED,
|
||||
|
||||
/* Dropped by firmware due to host-programmable filters. */
|
||||
RX_PKT_FATE_FW_DROP_FILTER,
|
||||
|
||||
/*
|
||||
* Dropped by firmware as invalid. E.g. bad checksum,
|
||||
* decrypt failed, or invalid for current state.
|
||||
*/
|
||||
RX_PKT_FATE_FW_DROP_INVALID,
|
||||
|
||||
/* Dropped by firmware due to lack of buffer space. */
|
||||
RX_PKT_FATE_FW_DROP_NOBUFS,
|
||||
|
||||
/* Dropped by firmware for any other reason. */
|
||||
RX_PKT_FATE_FW_DROP_OTHER,
|
||||
|
||||
/* Queued within driver, not yet delivered to network stack. */
|
||||
RX_PKT_FATE_DRV_QUEUED,
|
||||
|
||||
/* Dropped by driver due to filter rules. */
|
||||
RX_PKT_FATE_DRV_DROP_FILTER,
|
||||
|
||||
/* Dropped by driver as invalid. E.g. not permitted in current state. */
|
||||
RX_PKT_FATE_DRV_DROP_INVALID,
|
||||
|
||||
/* Dropped by driver due to lack of buffer space. */
|
||||
RX_PKT_FATE_DRV_DROP_NOBUFS,
|
||||
|
||||
/* Dropped by driver for any other reason. */
|
||||
RX_PKT_FATE_DRV_DROP_OTHER,
|
||||
|
||||
} wifi_rx_packet_fate;
|
||||
|
||||
typedef enum {
|
||||
FRAME_TYPE_UNKNOWN,
|
||||
FRAME_TYPE_ETHERNET_II,
|
||||
FRAME_TYPE_80211_MGMT,
|
||||
} frame_type;
|
||||
|
||||
typedef struct wifi_frame_info {
|
||||
/*
|
||||
* The type of MAC-layer frame that this frame_info holds.
|
||||
* - For data frames, use FRAME_TYPE_ETHERNET_II.
|
||||
* - For management frames, use FRAME_TYPE_80211_MGMT.
|
||||
* - If the type of the frame is unknown, use FRAME_TYPE_UNKNOWN.
|
||||
*/
|
||||
frame_type payload_type;
|
||||
|
||||
/*
|
||||
* The number of bytes included in |frame_content|. If the frame
|
||||
* contents are missing (e.g. RX frame dropped in firmware),
|
||||
* |frame_len| should be set to 0.
|
||||
*/
|
||||
size_t frame_len;
|
||||
|
||||
/*
|
||||
* Host clock when this frame was received by the driver (either
|
||||
* outbound from the host network stack, or inbound from the
|
||||
* firmware).
|
||||
* - The timestamp should be taken from a clock which includes time
|
||||
* the host spent suspended (e.g. ktime_get_boottime()).
|
||||
* - If no host timestamp is available (e.g. RX frame was dropped in
|
||||
* firmware), this field should be set to 0.
|
||||
*/
|
||||
uint32 driver_timestamp_usec;
|
||||
|
||||
/*
|
||||
* Firmware clock when this frame was received by the firmware
|
||||
* (either outbound from the host, or inbound from a remote
|
||||
* station).
|
||||
* - The timestamp should be taken from a clock which includes time
|
||||
* firmware spent suspended (if applicable).
|
||||
* - If no firmware timestamp is available (e.g. TX frame was
|
||||
* dropped by driver), this field should be set to 0.
|
||||
* - Consumers of |frame_info| should _not_ assume any
|
||||
* synchronization between driver and firmware clocks.
|
||||
*/
|
||||
uint32 firmware_timestamp_usec;
|
||||
|
||||
/*
|
||||
* Actual frame content.
|
||||
* - Should be provided for TX frames originated by the host.
|
||||
* - Should be provided for RX frames received by the driver.
|
||||
* - Optionally provided for TX frames originated by firmware. (At
|
||||
* discretion of HAL implementation.)
|
||||
* - Optionally provided for RX frames dropped in firmware. (At
|
||||
* discretion of HAL implementation.)
|
||||
* - If frame content is not provided, |frame_len| should be set
|
||||
* to 0.
|
||||
*/
|
||||
union {
|
||||
char ethernet_ii[MAX_FRAME_LEN_ETHERNET];
|
||||
char ieee_80211_mgmt[MAX_FRAME_LEN_80211_MGMT];
|
||||
} frame_content;
|
||||
} wifi_frame_info_t;
|
||||
|
||||
typedef struct wifi_tx_report {
|
||||
/*
|
||||
* Prefix of MD5 hash of |frame_inf.frame_content|. If frame
|
||||
* content is not provided, prefix of MD5 hash over the same data
|
||||
* that would be in frame_content, if frame content were provided.
|
||||
*/
|
||||
char md5_prefix[MD5_PREFIX_LEN];
|
||||
wifi_tx_packet_fate fate;
|
||||
wifi_frame_info_t frame_inf;
|
||||
} wifi_tx_report_t;
|
||||
|
||||
typedef struct wifi_rx_report {
|
||||
/*
|
||||
* Prefix of MD5 hash of |frame_inf.frame_content|. If frame
|
||||
* content is not provided, prefix of MD5 hash over the same data
|
||||
* that would be in frame_content, if frame content were provided.
|
||||
*/
|
||||
char md5_prefix[MD5_PREFIX_LEN];
|
||||
wifi_rx_packet_fate fate;
|
||||
wifi_frame_info_t frame_inf;
|
||||
} wifi_rx_report_t;
|
||||
|
||||
typedef struct compat_wifi_frame_info {
|
||||
frame_type payload_type;
|
||||
|
||||
uint32 frame_len;
|
||||
|
||||
uint32 driver_timestamp_usec;
|
||||
|
||||
uint32 firmware_timestamp_usec;
|
||||
|
||||
union {
|
||||
char ethernet_ii[MAX_FRAME_LEN_ETHERNET];
|
||||
char ieee_80211_mgmt[MAX_FRAME_LEN_80211_MGMT];
|
||||
} frame_content;
|
||||
} compat_wifi_frame_info_t;
|
||||
|
||||
typedef struct compat_wifi_tx_report {
|
||||
char md5_prefix[MD5_PREFIX_LEN];
|
||||
wifi_tx_packet_fate fate;
|
||||
compat_wifi_frame_info_t frame_inf;
|
||||
} compat_wifi_tx_report_t;
|
||||
|
||||
typedef struct compat_wifi_rx_report {
|
||||
char md5_prefix[MD5_PREFIX_LEN];
|
||||
wifi_rx_packet_fate fate;
|
||||
compat_wifi_frame_info_t frame_inf;
|
||||
} compat_wifi_rx_report_t;
|
||||
|
||||
/*
|
||||
* Packet logging - internal data
|
||||
*/
|
||||
|
||||
typedef enum dhd_dbg_pkt_mon_state {
|
||||
PKT_MON_INVALID = 0,
|
||||
PKT_MON_ATTACHED,
|
||||
PKT_MON_STARTING,
|
||||
PKT_MON_STARTED,
|
||||
PKT_MON_STOPPING,
|
||||
PKT_MON_STOPPED,
|
||||
PKT_MON_DETACHED,
|
||||
} dhd_dbg_pkt_mon_state_t;
|
||||
|
||||
typedef struct dhd_dbg_pkt_info {
|
||||
frame_type payload_type;
|
||||
size_t pkt_len;
|
||||
uint32 driver_ts;
|
||||
uint32 firmware_ts;
|
||||
uint32 pkt_hash;
|
||||
void *pkt;
|
||||
} dhd_dbg_pkt_info_t;
|
||||
|
||||
typedef struct compat_dhd_dbg_pkt_info {
|
||||
frame_type payload_type;
|
||||
uint32 pkt_len;
|
||||
uint32 driver_ts;
|
||||
uint32 firmware_ts;
|
||||
uint32 pkt_hash;
|
||||
void *pkt;
|
||||
} compat_dhd_dbg_pkt_info_t;
|
||||
|
||||
typedef struct dhd_dbg_tx_info
|
||||
{
|
||||
wifi_tx_packet_fate fate;
|
||||
dhd_dbg_pkt_info_t info;
|
||||
} dhd_dbg_tx_info_t;
|
||||
|
||||
typedef struct dhd_dbg_rx_info
|
||||
{
|
||||
wifi_rx_packet_fate fate;
|
||||
dhd_dbg_pkt_info_t info;
|
||||
} dhd_dbg_rx_info_t;
|
||||
|
||||
typedef struct dhd_dbg_tx_report
|
||||
{
|
||||
dhd_dbg_tx_info_t *tx_pkts;
|
||||
uint16 pkt_pos;
|
||||
uint16 status_pos;
|
||||
} dhd_dbg_tx_report_t;
|
||||
|
||||
typedef struct dhd_dbg_rx_report
|
||||
{
|
||||
dhd_dbg_rx_info_t *rx_pkts;
|
||||
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_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 struct dhd_dbg_pkt_mon
|
||||
{
|
||||
dhd_dbg_tx_report_t *tx_report;
|
||||
dhd_dbg_rx_report_t *rx_report;
|
||||
dhd_dbg_pkt_mon_state_t tx_pkt_state;
|
||||
dhd_dbg_pkt_mon_state_t tx_status_state;
|
||||
dhd_dbg_pkt_mon_state_t rx_pkt_state;
|
||||
|
||||
/* call backs */
|
||||
dbg_mon_tx_pkts_t tx_pkt_mon;
|
||||
dbg_mon_tx_status_t tx_status_mon;
|
||||
dbg_mon_rx_pkts_t rx_pkt_mon;
|
||||
} dhd_dbg_pkt_mon_t;
|
||||
|
||||
typedef struct dhd_dbg {
|
||||
dhd_dbg_ring_t dbg_rings[DEBUG_RING_ID_MAX];
|
||||
void *private; /* os private_data */
|
||||
dhd_dbg_pkt_mon_t pkt_mon;
|
||||
void *pkt_mon_lock; /* spin lock for packet monitoring */
|
||||
dbg_pullreq_t pullreq;
|
||||
dbg_urgent_noti_t urgent_notifier;
|
||||
} dhd_dbg_t;
|
||||
|
||||
#define PKT_MON_ATTACHED(state) \
|
||||
(((state) > PKT_MON_INVALID) && ((state) < PKT_MON_DETACHED))
|
||||
#define PKT_MON_DETACHED(state) \
|
||||
(((state) == PKT_MON_INVALID) || ((state) == PKT_MON_DETACHED))
|
||||
#define PKT_MON_STARTED(state) ((state) == PKT_MON_STARTED)
|
||||
#define PKT_MON_STOPPED(state) ((state) == PKT_MON_STOPPED)
|
||||
#define PKT_MON_NOT_OPERATIONAL(state) \
|
||||
(((state) != PKT_MON_STARTED) && ((state) != PKT_MON_STOPPED))
|
||||
#define PKT_MON_SAFE_TO_FREE(state) \
|
||||
(((state) == PKT_MON_STARTING) || ((state) == PKT_MON_STOPPED))
|
||||
#define PKT_MON_PKT_FULL(pkt_count) ((pkt_count) >= MAX_FATE_LOG_LEN)
|
||||
#define PKT_MON_STATUS_FULL(pkt_count, status_count) \
|
||||
(((status_count) >= (pkt_count)) || ((status_count) >= MAX_FATE_LOG_LEN))
|
||||
|
||||
#ifdef DBG_PKT_MON
|
||||
#define DHD_DBG_PKT_MON_TX(dhdp, pkt, pktid) \
|
||||
do { \
|
||||
if ((dhdp) && (dhdp)->dbg && (dhdp)->dbg->pkt_mon.tx_pkt_mon && (pkt)) { \
|
||||
(dhdp)->dbg->pkt_mon.tx_pkt_mon((dhdp), (pkt), (pktid)); \
|
||||
} \
|
||||
} while (0);
|
||||
#define DHD_DBG_PKT_MON_TX_STATUS(dhdp, pkt, pktid, status) \
|
||||
do { \
|
||||
if ((dhdp) && (dhdp)->dbg && (dhdp)->dbg->pkt_mon.tx_status_mon && (pkt)) { \
|
||||
(dhdp)->dbg->pkt_mon.tx_status_mon((dhdp), (pkt), (pktid), (status)); \
|
||||
} \
|
||||
} while (0);
|
||||
#define DHD_DBG_PKT_MON_RX(dhdp, pkt) \
|
||||
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)); \
|
||||
} \
|
||||
} \
|
||||
} while (0);
|
||||
|
||||
#define DHD_DBG_PKT_MON_START(dhdp) \
|
||||
dhd_os_dbg_start_pkt_monitor((dhdp));
|
||||
#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_STATUS(dhdp, pkt, pktid, status)
|
||||
#define DHD_DBG_PKT_MON_RX(dhdp, pkt)
|
||||
#define DHD_DBG_PKT_MON_START(dhdp)
|
||||
#define DHD_DBG_PKT_MON_STOP(dhdp)
|
||||
#endif /* DBG_PKT_MON */
|
||||
|
||||
#ifdef DUMP_IOCTL_IOV_LIST
|
||||
typedef struct dhd_iov_li {
|
||||
dll_t list;
|
||||
uint32 cmd; /* command number */
|
||||
char buff[100]; /* command name */
|
||||
} dhd_iov_li_t;
|
||||
#endif /* DUMP_IOCTL_IOV_LIST */
|
||||
|
||||
#define IOV_LIST_MAX_LEN 5
|
||||
|
||||
#ifdef DHD_DEBUG
|
||||
typedef struct {
|
||||
dll_t list;
|
||||
uint32 id; /* wasted chunk id */
|
||||
uint32 handle; /* wasted chunk handle */
|
||||
uint32 size; /* wasted chunk size */
|
||||
} dhd_dbg_mwli_t;
|
||||
#endif /* DHD_DEBUG */
|
||||
|
||||
#define DHD_OW_BI_RAW_EVENT_LOG_FMT 0xFFFF
|
||||
|
||||
/* LSB 2 bits of format number to identify the type of event log */
|
||||
#define DHD_EVENT_LOG_HDR_MASK 0x3
|
||||
|
||||
#define DHD_EVENT_LOG_FMT_NUM_OFFSET 2
|
||||
#define DHD_EVENT_LOG_FMT_NUM_MASK 0x3FFF
|
||||
/**
|
||||
* OW:- one word
|
||||
* TW:- two word
|
||||
* NB:- non binary
|
||||
* BI:- binary
|
||||
*/
|
||||
#define DHD_OW_NB_EVENT_LOG_HDR 0
|
||||
#define DHD_TW_NB_EVENT_LOG_HDR 1
|
||||
#define DHD_BI_EVENT_LOG_HDR 3
|
||||
#define DHD_INVALID_EVENT_LOG_HDR 2
|
||||
|
||||
#define DHD_TW_VALID_TAG_BITS_MASK 0xF
|
||||
#define DHD_OW_BI_EVENT_FMT_NUM 0x3FFF
|
||||
#define DHD_TW_BI_EVENT_FMT_NUM 0x3FFE
|
||||
|
||||
#define DHD_TW_EVENT_LOG_TAG_OFFSET 8
|
||||
|
||||
#define EVENT_TAG_TIMESTAMP_OFFSET 1
|
||||
#define EVENT_TAG_TIMESTAMP_EXT_OFFSET 2
|
||||
|
||||
typedef struct prcd_event_log_hdr {
|
||||
uint32 tag; /* Event_log entry tag */
|
||||
uint32 count; /* Count of 4-byte entries */
|
||||
uint32 fmt_num_raw; /* Format number */
|
||||
uint32 fmt_num; /* Format number >> 2 */
|
||||
uint32 armcycle; /* global ARM CYCLE for TAG */
|
||||
uint32 *log_ptr; /* start of payload */
|
||||
uint32 payload_len;
|
||||
/* Extended event log header info
|
||||
* 0 - legacy, 1 - extended event log header present
|
||||
*/
|
||||
bool ext_event_log_hdr;
|
||||
bool binary_payload; /* 0 - non binary payload, 1 - binary payload */
|
||||
} prcd_event_log_hdr_t; /* Processed event log header */
|
||||
|
||||
/* dhd_dbg functions */
|
||||
extern void dhd_dbg_trace_evnt_handler(dhd_pub_t *dhdp, void *event_data,
|
||||
void *raw_event_ptr, uint datalen);
|
||||
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);
|
||||
|
||||
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);
|
||||
extern int dhd_dbg_start(dhd_pub_t *dhdp, bool start);
|
||||
extern int dhd_dbg_set_configuration(dhd_pub_t *dhdp, int ring_id,
|
||||
int log_level, int flags, uint32 threshold);
|
||||
extern int dhd_dbg_find_ring_id(dhd_pub_t *dhdp, char *ring_name);
|
||||
extern dhd_dbg_ring_t *dhd_dbg_get_ring_from_ring_id(dhd_pub_t *dhdp, int ring_id);
|
||||
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_single_from_ring(dhd_pub_t *dhdp, int ring_id, void *data, uint32 buf_len,
|
||||
bool strip_header);
|
||||
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);
|
||||
int dhd_dbg_get_ring_status(dhd_pub_t *dhdp, int ring_id,
|
||||
dhd_dbg_ring_status_t *dbg_ring_status);
|
||||
#ifdef SHOW_LOGTRACE
|
||||
void dhd_dbg_read_ring_into_trace_buf(dhd_dbg_ring_t *ring, trace_buf_info_t *trace_buf_info);
|
||||
#endif /* SHOW_LOGTRACE */
|
||||
|
||||
#ifdef DBG_PKT_MON
|
||||
extern int dhd_dbg_attach_pkt_monitor(dhd_pub_t *dhdp,
|
||||
dbg_mon_tx_pkts_t tx_pkt_mon,
|
||||
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_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_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);
|
||||
extern int dhd_dbg_monitor_get_rx_pkts(dhd_pub_t *dhdp, void __user *user_buf,
|
||||
uint16 req_count, uint16 *resp_count);
|
||||
extern int dhd_dbg_detach_pkt_monitor(dhd_pub_t *dhdp);
|
||||
#endif /* DBG_PKT_MON */
|
||||
|
||||
extern bool dhd_dbg_process_tx_status(dhd_pub_t *dhdp, void *pkt,
|
||||
uint32 pktid, uint16 status);
|
||||
|
||||
/* os wrapper function */
|
||||
extern int dhd_os_dbg_attach(dhd_pub_t *dhdp);
|
||||
extern void dhd_os_dbg_detach(dhd_pub_t *dhdp);
|
||||
extern int dhd_os_dbg_register_callback(int ring_id,
|
||||
void (*dbg_ring_sub_cb)(void *ctx, const int ring_id, const void *data,
|
||||
const uint32 len, const dhd_dbg_ring_status_t dbg_ring_status));
|
||||
extern int dhd_os_dbg_register_urgent_notifier(dhd_pub_t *dhdp,
|
||||
void (*urgent_noti)(void *ctx, const void *data, const uint32 len, const uint32 fw_len));
|
||||
|
||||
extern int dhd_os_start_logging(dhd_pub_t *dhdp, char *ring_name, int log_level,
|
||||
int flags, int time_intval, int threshold);
|
||||
extern int dhd_os_reset_logging(dhd_pub_t *dhdp);
|
||||
extern int dhd_os_suppress_logging(dhd_pub_t *dhdp, bool suppress);
|
||||
|
||||
extern int dhd_os_get_ring_status(dhd_pub_t *dhdp, int ring_id,
|
||||
dhd_dbg_ring_status_t *dbg_ring_status);
|
||||
extern int dhd_os_trigger_get_ring_data(dhd_pub_t *dhdp, char *ring_name);
|
||||
extern int dhd_os_push_push_ring_data(dhd_pub_t *dhdp, int ring_id, void *data, int32 data_len);
|
||||
extern int dhd_os_dbg_get_feature(dhd_pub_t *dhdp, int32 *features);
|
||||
|
||||
#ifdef DBG_PKT_MON
|
||||
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);
|
||||
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_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);
|
||||
extern int dhd_os_dbg_monitor_get_rx_pkts(dhd_pub_t *dhdp,
|
||||
void __user *user_buf, uint16 req_count, uint16 *resp_count);
|
||||
extern int dhd_os_dbg_detach_pkt_monitor(dhd_pub_t *dhdp);
|
||||
#endif /* DBG_PKT_MON */
|
||||
|
||||
#ifdef DUMP_IOCTL_IOV_LIST
|
||||
extern void dhd_iov_li_append(dhd_pub_t *dhd, dll_t *list_head, dll_t *node);
|
||||
extern void dhd_iov_li_print(dll_t *list_head);
|
||||
extern void dhd_iov_li_delete(dhd_pub_t *dhd, dll_t *list_head);
|
||||
#endif /* DUMP_IOCTL_IOV_LIST */
|
||||
|
||||
#ifdef DHD_DEBUG
|
||||
extern void dhd_mw_list_delete(dhd_pub_t *dhd, dll_t *list_head);
|
||||
#endif /* DHD_DEBUG */
|
||||
#endif /* _dhd_debug_h_ */
|
||||
@@ -0,0 +1,512 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* DHD debugability Linux os layer
|
||||
*
|
||||
* <<Broadcom-WL-IPTag/Open:>>
|
||||
*
|
||||
* Copyright (C) 1999-2019, 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.
|
||||
*
|
||||
* 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_debug_linux.c 769272 2018-06-25 09:23:27Z $
|
||||
*/
|
||||
|
||||
#include <typedefs.h>
|
||||
#include <osl.h>
|
||||
#include <bcmutils.h>
|
||||
#include <bcmendian.h>
|
||||
#include <dngl_stats.h>
|
||||
#include <dhd.h>
|
||||
#include <dhd_dbg.h>
|
||||
#include <dhd_debug.h>
|
||||
|
||||
#include <net/cfg80211.h>
|
||||
#include <wl_cfgvendor.h>
|
||||
|
||||
typedef void (*dbg_ring_send_sub_t)(void *ctx, const int ring_id, const void *data,
|
||||
const uint32 len, const dhd_dbg_ring_status_t ring_status);
|
||||
typedef void (*dbg_urgent_noti_sub_t)(void *ctx, const void *data,
|
||||
const uint32 len, const uint32 fw_len);
|
||||
|
||||
static dbg_ring_send_sub_t ring_send_sub_cb[DEBUG_RING_ID_MAX];
|
||||
static dbg_urgent_noti_sub_t urgent_noti_sub_cb;
|
||||
typedef struct dhd_dbg_os_ring_info {
|
||||
dhd_pub_t *dhdp;
|
||||
int ring_id;
|
||||
int log_level;
|
||||
unsigned long interval;
|
||||
struct delayed_work work;
|
||||
uint64 tsoffset;
|
||||
} linux_dbgring_info_t;
|
||||
|
||||
struct log_level_table dhd_event_map[] = {
|
||||
{1, WIFI_EVENT_DRIVER_EAPOL_FRAME_TRANSMIT_REQUESTED, "DRIVER EAPOL TX REQ"},
|
||||
{1, WIFI_EVENT_DRIVER_EAPOL_FRAME_RECEIVED, "DRIVER EAPOL RX"},
|
||||
{2, WIFI_EVENT_DRIVER_SCAN_REQUESTED, "SCAN_REQUESTED"},
|
||||
{2, WIFI_EVENT_DRIVER_SCAN_COMPLETE, "SCAN COMPELETE"},
|
||||
{3, WIFI_EVENT_DRIVER_SCAN_RESULT_FOUND, "SCAN RESULT FOUND"},
|
||||
{2, WIFI_EVENT_DRIVER_PNO_ADD, "PNO ADD"},
|
||||
{2, WIFI_EVENT_DRIVER_PNO_REMOVE, "PNO REMOVE"},
|
||||
{2, WIFI_EVENT_DRIVER_PNO_NETWORK_FOUND, "PNO NETWORK FOUND"},
|
||||
{2, WIFI_EVENT_DRIVER_PNO_SCAN_REQUESTED, "PNO SCAN_REQUESTED"},
|
||||
{1, WIFI_EVENT_DRIVER_PNO_SCAN_RESULT_FOUND, "PNO SCAN RESULT FOUND"},
|
||||
{1, WIFI_EVENT_DRIVER_PNO_SCAN_COMPLETE, "PNO SCAN COMPELETE"}
|
||||
};
|
||||
|
||||
static void
|
||||
debug_data_send(dhd_pub_t *dhdp, int ring_id, const void *data, const uint32 len,
|
||||
const dhd_dbg_ring_status_t ring_status)
|
||||
{
|
||||
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))
|
||||
return;
|
||||
if (ring_send_sub_cb[ring_id]) {
|
||||
ring_sub_send = ring_send_sub_cb[ring_id];
|
||||
ring_sub_send(ndev, ring_id, data, len, ring_status);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
dhd_os_dbg_urgent_notifier(dhd_pub_t *dhdp, const void *data, const uint32 len)
|
||||
{
|
||||
struct net_device *ndev;
|
||||
ndev = dhd_linux_get_primary_netdev(dhdp);
|
||||
if (!ndev)
|
||||
return;
|
||||
if (urgent_noti_sub_cb) {
|
||||
urgent_noti_sub_cb(ndev, data, len, dhdp->soc_ram_length);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
dbg_ring_poll_worker(struct work_struct *work)
|
||||
{
|
||||
struct delayed_work *d_work = to_delayed_work(work);
|
||||
bool sched = TRUE;
|
||||
dhd_dbg_ring_t *ring;
|
||||
#if defined(STRICT_GCC_WARNINGS) && defined(__GNUC__)
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wcast-qual"
|
||||
#endif // endif
|
||||
linux_dbgring_info_t *ring_info =
|
||||
container_of(d_work, linux_dbgring_info_t, work);
|
||||
#if defined(STRICT_GCC_WARNINGS) && defined(__GNUC__)
|
||||
#pragma GCC diagnostic pop
|
||||
#endif // endif
|
||||
dhd_pub_t *dhdp = ring_info->dhdp;
|
||||
int ringid = ring_info->ring_id;
|
||||
dhd_dbg_ring_status_t ring_status;
|
||||
void *buf;
|
||||
dhd_dbg_ring_entry_t *hdr;
|
||||
uint32 buflen, rlen;
|
||||
unsigned long flags;
|
||||
|
||||
ring = &dhdp->dbg->dbg_rings[ringid];
|
||||
DHD_DBG_RING_LOCK(ring->lock, flags);
|
||||
dhd_dbg_get_ring_status(dhdp, ringid, &ring_status);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
if (buflen > ring->ring_size) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
buf = MALLOCZ(dhdp->osh, buflen);
|
||||
if (!buf) {
|
||||
DHD_ERROR(("%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);
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
DHD_DBG_RING_UNLOCK(ring->lock, flags);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
int
|
||||
dhd_os_dbg_register_callback(int ring_id, dbg_ring_send_sub_t callback)
|
||||
{
|
||||
if (!VALID_RING(ring_id))
|
||||
return BCME_RANGE;
|
||||
|
||||
ring_send_sub_cb[ring_id] = callback;
|
||||
return BCME_OK;
|
||||
}
|
||||
|
||||
int
|
||||
dhd_os_dbg_register_urgent_notifier(dhd_pub_t *dhdp, dbg_urgent_noti_sub_t urgent_noti_sub)
|
||||
{
|
||||
if (!dhdp || !urgent_noti_sub)
|
||||
return BCME_BADARG;
|
||||
urgent_noti_sub_cb = urgent_noti_sub;
|
||||
|
||||
return BCME_OK;
|
||||
}
|
||||
|
||||
int
|
||||
dhd_os_start_logging(dhd_pub_t *dhdp, char *ring_name, int log_level,
|
||||
int flags, int time_intval, int threshold)
|
||||
{
|
||||
int ret = BCME_OK;
|
||||
int ring_id;
|
||||
linux_dbgring_info_t *os_priv, *ring_info;
|
||||
|
||||
ring_id = dhd_dbg_find_ring_id(dhdp, ring_name);
|
||||
if (!VALID_RING(ring_id))
|
||||
return BCME_UNSUPPORTED;
|
||||
|
||||
DHD_DBGIF(("%s , log_level : %d, time_intval : %d, threshod %d Bytes\n",
|
||||
__FUNCTION__, log_level, time_intval, threshold));
|
||||
|
||||
/* change the configuration */
|
||||
ret = dhd_dbg_set_configuration(dhdp, ring_id, log_level, flags, threshold);
|
||||
if (ret) {
|
||||
DHD_ERROR(("dhd_set_configuration is failed : %d\n", ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
os_priv = dhd_dbg_get_priv(dhdp);
|
||||
if (!os_priv)
|
||||
return BCME_ERROR;
|
||||
ring_info = &os_priv[ring_id];
|
||||
ring_info->log_level = log_level;
|
||||
|
||||
if (time_intval == 0 || log_level == 0) {
|
||||
ring_info->interval = 0;
|
||||
cancel_delayed_work_sync(&ring_info->work);
|
||||
} else {
|
||||
ring_info->interval = msecs_to_jiffies(time_intval * MSEC_PER_SEC);
|
||||
cancel_delayed_work_sync(&ring_info->work);
|
||||
schedule_delayed_work(&ring_info->work, ring_info->interval);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
dhd_os_reset_logging(dhd_pub_t *dhdp)
|
||||
{
|
||||
int ret = BCME_OK;
|
||||
int ring_id;
|
||||
linux_dbgring_info_t *os_priv, *ring_info;
|
||||
|
||||
os_priv = dhd_dbg_get_priv(dhdp);
|
||||
if (!os_priv)
|
||||
return BCME_ERROR;
|
||||
|
||||
/* Stop all rings */
|
||||
for (ring_id = DEBUG_RING_ID_INVALID + 1; ring_id < DEBUG_RING_ID_MAX; ring_id++) {
|
||||
DHD_DBGIF(("%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;
|
||||
/* change the configuration */
|
||||
ret = dhd_dbg_set_configuration(dhdp, ring_id, 0, 0, 0);
|
||||
if (ret) {
|
||||
DHD_ERROR(("dhd_set_configuration is failed : %d\n", ret));
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
#define SUPPRESS_LOG_LEVEL 1
|
||||
int
|
||||
dhd_os_suppress_logging(dhd_pub_t *dhdp, bool suppress)
|
||||
{
|
||||
int ret = BCME_OK;
|
||||
int max_log_level;
|
||||
int enable = (suppress) ? 0 : 1;
|
||||
linux_dbgring_info_t *os_priv;
|
||||
|
||||
os_priv = dhd_dbg_get_priv(dhdp);
|
||||
if (!os_priv)
|
||||
return BCME_ERROR;
|
||||
|
||||
max_log_level = os_priv[FW_VERBOSE_RING_ID].log_level;
|
||||
|
||||
if (max_log_level == SUPPRESS_LOG_LEVEL) {
|
||||
/* suppress the logging in FW not to wake up host while device in suspend mode */
|
||||
ret = dhd_iovar(dhdp, 0, "logtrace", (char *)&enable, sizeof(enable), NULL, 0,
|
||||
TRUE);
|
||||
if (ret < 0 && (ret != BCME_UNSUPPORTED)) {
|
||||
DHD_ERROR(("logtrace is failed : %d\n", ret));
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
dhd_os_get_ring_status(dhd_pub_t *dhdp, int ring_id, dhd_dbg_ring_status_t *dbg_ring_status)
|
||||
{
|
||||
return dhd_dbg_get_ring_status(dhdp, ring_id, dbg_ring_status);
|
||||
}
|
||||
|
||||
int
|
||||
dhd_os_trigger_get_ring_data(dhd_pub_t *dhdp, char *ring_name)
|
||||
{
|
||||
int ret = BCME_OK;
|
||||
int ring_id;
|
||||
linux_dbgring_info_t *os_priv, *ring_info;
|
||||
ring_id = dhd_dbg_find_ring_id(dhdp, ring_name);
|
||||
if (!VALID_RING(ring_id))
|
||||
return BCME_UNSUPPORTED;
|
||||
os_priv = dhd_dbg_get_priv(dhdp);
|
||||
if (os_priv) {
|
||||
ring_info = &os_priv[ring_id];
|
||||
if (ring_info->interval) {
|
||||
cancel_delayed_work_sync(&ring_info->work);
|
||||
}
|
||||
schedule_delayed_work(&ring_info->work, 0);
|
||||
} else {
|
||||
DHD_ERROR(("%s : os_priv is NULL\n", __FUNCTION__));
|
||||
ret = BCME_ERROR;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
dhd_os_push_push_ring_data(dhd_pub_t *dhdp, int ring_id, void *data, int32 data_len)
|
||||
{
|
||||
int ret = BCME_OK, i;
|
||||
dhd_dbg_ring_entry_t msg_hdr;
|
||||
log_conn_event_t *event_data = (log_conn_event_t *)data;
|
||||
linux_dbgring_info_t *os_priv, *ring_info = NULL;
|
||||
|
||||
if (!VALID_RING(ring_id))
|
||||
return BCME_UNSUPPORTED;
|
||||
os_priv = dhd_dbg_get_priv(dhdp);
|
||||
|
||||
if (os_priv) {
|
||||
ring_info = &os_priv[ring_id];
|
||||
} else
|
||||
return BCME_NORESOURCE;
|
||||
|
||||
memset(&msg_hdr, 0, sizeof(dhd_dbg_ring_entry_t));
|
||||
|
||||
if (ring_id == DHD_EVENT_RING_ID) {
|
||||
msg_hdr.type = DBG_RING_ENTRY_EVENT_TYPE;
|
||||
msg_hdr.flags |= DBG_RING_ENTRY_FLAGS_HAS_TIMESTAMP;
|
||||
msg_hdr.flags |= DBG_RING_ENTRY_FLAGS_HAS_BINARY;
|
||||
msg_hdr.timestamp = local_clock();
|
||||
/* convert to ms */
|
||||
msg_hdr.timestamp = DIV_U64_BY_U32(msg_hdr.timestamp, NSEC_PER_MSEC);
|
||||
msg_hdr.len = data_len;
|
||||
/* filter the event for higher log level with current log level */
|
||||
for (i = 0; i < ARRAYSIZE(dhd_event_map); i++) {
|
||||
if ((dhd_event_map[i].tag == event_data->event) &&
|
||||
dhd_event_map[i].log_level > ring_info->log_level) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
ret = dhd_dbg_push_to_ring(dhdp, ring_id, &msg_hdr, event_data);
|
||||
if (ret) {
|
||||
DHD_ERROR(("%s : failed to push data into the ring (%d) with ret(%d)\n",
|
||||
__FUNCTION__, ring_id, ret));
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef DBG_PKT_MON
|
||||
int
|
||||
dhd_os_dbg_attach_pkt_monitor(dhd_pub_t *dhdp)
|
||||
{
|
||||
return dhd_dbg_attach_pkt_monitor(dhdp, dhd_os_dbg_monitor_tx_pkts,
|
||||
dhd_os_dbg_monitor_tx_status, dhd_os_dbg_monitor_rx_pkts);
|
||||
}
|
||||
|
||||
int
|
||||
dhd_os_dbg_start_pkt_monitor(dhd_pub_t *dhdp)
|
||||
{
|
||||
return dhd_dbg_start_pkt_monitor(dhdp);
|
||||
}
|
||||
|
||||
int
|
||||
dhd_os_dbg_monitor_tx_pkts(dhd_pub_t *dhdp, void *pkt, uint32 pktid)
|
||||
{
|
||||
return dhd_dbg_monitor_tx_pkts(dhdp, pkt, pktid);
|
||||
}
|
||||
|
||||
int
|
||||
dhd_os_dbg_monitor_tx_status(dhd_pub_t *dhdp, void *pkt, uint32 pktid,
|
||||
uint16 status)
|
||||
{
|
||||
return dhd_dbg_monitor_tx_status(dhdp, pkt, pktid, status);
|
||||
}
|
||||
|
||||
int
|
||||
dhd_os_dbg_monitor_rx_pkts(dhd_pub_t *dhdp, void *pkt)
|
||||
{
|
||||
return dhd_dbg_monitor_rx_pkts(dhdp, pkt);
|
||||
}
|
||||
|
||||
int
|
||||
dhd_os_dbg_stop_pkt_monitor(dhd_pub_t *dhdp)
|
||||
{
|
||||
return dhd_dbg_stop_pkt_monitor(dhdp);
|
||||
}
|
||||
|
||||
int
|
||||
dhd_os_dbg_monitor_get_tx_pkts(dhd_pub_t *dhdp, void __user *user_buf,
|
||||
uint16 req_count, uint16 *resp_count)
|
||||
{
|
||||
return dhd_dbg_monitor_get_tx_pkts(dhdp, user_buf, req_count, resp_count);
|
||||
}
|
||||
|
||||
int
|
||||
dhd_os_dbg_monitor_get_rx_pkts(dhd_pub_t *dhdp, void __user *user_buf,
|
||||
uint16 req_count, uint16 *resp_count)
|
||||
{
|
||||
return dhd_dbg_monitor_get_rx_pkts(dhdp, user_buf, req_count, resp_count);
|
||||
}
|
||||
|
||||
int
|
||||
dhd_os_dbg_detach_pkt_monitor(dhd_pub_t *dhdp)
|
||||
{
|
||||
return dhd_dbg_detach_pkt_monitor(dhdp);
|
||||
}
|
||||
#endif /* DBG_PKT_MON */
|
||||
|
||||
int
|
||||
dhd_os_dbg_get_feature(dhd_pub_t *dhdp, int32 *features)
|
||||
{
|
||||
int ret = BCME_OK;
|
||||
*features = 0;
|
||||
#ifdef DEBUGABILITY
|
||||
*features |= DBG_MEMORY_DUMP_SUPPORTED;
|
||||
if (FW_SUPPORTED(dhdp, logtrace)) {
|
||||
*features |= DBG_CONNECT_EVENT_SUPPORTED;
|
||||
*features |= DBG_VERBOSE_LOG_SUPPORTED;
|
||||
}
|
||||
if (FW_SUPPORTED(dhdp, hchk)) {
|
||||
*features |= DBG_HEALTH_CHECK_SUPPORTED;
|
||||
}
|
||||
#ifdef DBG_PKT_MON
|
||||
if (FW_SUPPORTED(dhdp, d11status)) {
|
||||
*features |= DBG_PACKET_FATE_SUPPORTED;
|
||||
}
|
||||
#endif /* DBG_PKT_MON */
|
||||
#endif /* DEBUGABILITY */
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
dhd_os_dbg_pullreq(void *os_priv, int ring_id)
|
||||
{
|
||||
linux_dbgring_info_t *ring_info;
|
||||
|
||||
ring_info = &((linux_dbgring_info_t *)os_priv)[ring_id];
|
||||
cancel_delayed_work(&ring_info->work);
|
||||
schedule_delayed_work(&ring_info->work, 0);
|
||||
}
|
||||
|
||||
int
|
||||
dhd_os_dbg_attach(dhd_pub_t *dhdp)
|
||||
{
|
||||
int ret = BCME_OK;
|
||||
linux_dbgring_info_t *os_priv, *ring_info;
|
||||
int ring_id;
|
||||
|
||||
/* os_dbg data */
|
||||
os_priv = MALLOCZ(dhdp->osh, sizeof(*os_priv) * DEBUG_RING_ID_MAX);
|
||||
if (!os_priv)
|
||||
return BCME_NOMEM;
|
||||
|
||||
for (ring_id = DEBUG_RING_ID_INVALID + 1; ring_id < DEBUG_RING_ID_MAX;
|
||||
ring_id++) {
|
||||
ring_info = &os_priv[ring_id];
|
||||
INIT_DELAYED_WORK(&ring_info->work, dbg_ring_poll_worker);
|
||||
ring_info->dhdp = dhdp;
|
||||
ring_info->ring_id = ring_id;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
dhd_os_dbg_detach(dhd_pub_t *dhdp)
|
||||
{
|
||||
linux_dbgring_info_t *os_priv, *ring_info;
|
||||
int ring_id;
|
||||
/* free os_dbg data */
|
||||
os_priv = dhd_dbg_get_priv(dhdp);
|
||||
if (!os_priv)
|
||||
return;
|
||||
/* abort pending any job */
|
||||
for (ring_id = DEBUG_RING_ID_INVALID + 1; ring_id < DEBUG_RING_ID_MAX; ring_id++) {
|
||||
ring_info = &os_priv[ring_id];
|
||||
if (ring_info->interval) {
|
||||
ring_info->interval = 0;
|
||||
cancel_delayed_work_sync(&ring_info->work);
|
||||
}
|
||||
}
|
||||
MFREE(dhdp->osh, os_priv, sizeof(*os_priv) * DEBUG_RING_ID_MAX);
|
||||
|
||||
return dhd_dbg_detach(dhdp);
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,289 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* @file Header file describing the flow rings DHD interfaces.
|
||||
*
|
||||
* Flow rings are transmit traffic (=propagating towards antenna) related entities.
|
||||
*
|
||||
* Provides type definitions and function prototypes used to create, delete and manage flow rings at
|
||||
* high level.
|
||||
*
|
||||
* Copyright (C) 1999-2019, 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.
|
||||
*
|
||||
* Notwithstanding the above, under no circumstances may you combine this
|
||||
* software in any way with any other Broadcom software provided under a license
|
||||
* other than the GPL, without Broadcom's express prior written consent.
|
||||
*
|
||||
*
|
||||
* <<Broadcom-WL-IPTag/Open:>>
|
||||
*
|
||||
* $Id: dhd_flowring.h 786596 2018-10-26 22:54:51Z $
|
||||
*/
|
||||
|
||||
/****************
|
||||
* Common types *
|
||||
*/
|
||||
|
||||
#ifndef _dhd_flowrings_h_
|
||||
#define _dhd_flowrings_h_
|
||||
|
||||
/* Max pkts held in a flow ring's backup queue */
|
||||
#define FLOW_RING_QUEUE_THRESHOLD (2048)
|
||||
|
||||
/* Number of H2D common rings */
|
||||
#define FLOW_RING_COMMON BCMPCIE_H2D_COMMON_MSGRINGS
|
||||
|
||||
#define FLOWID_INVALID (ID16_INVALID)
|
||||
#define FLOWID_RESERVED (FLOW_RING_COMMON)
|
||||
|
||||
#define FLOW_RING_STATUS_OPEN 0
|
||||
#define FLOW_RING_STATUS_CREATE_PENDING 1
|
||||
#define FLOW_RING_STATUS_CLOSED 2
|
||||
#define FLOW_RING_STATUS_DELETE_PENDING 3
|
||||
#define FLOW_RING_STATUS_FLUSH_PENDING 4
|
||||
|
||||
#ifdef IDLE_TX_FLOW_MGMT
|
||||
#define FLOW_RING_STATUS_SUSPENDED 5
|
||||
#define FLOW_RING_STATUS_RESUME_PENDING 6
|
||||
#endif /* IDLE_TX_FLOW_MGMT */
|
||||
#define FLOW_RING_STATUS_STA_FREEING 7
|
||||
|
||||
#define DHD_FLOWRING_RX_BUFPOST_PKTSZ 2048
|
||||
#define DHD_FLOWRING_RX_BUFPOST_PKTSZ_MAX 4096
|
||||
|
||||
#define DHD_FLOW_PRIO_AC_MAP 0
|
||||
#define DHD_FLOW_PRIO_TID_MAP 1
|
||||
/* Flow ring prority map for lossless roaming */
|
||||
#define DHD_FLOW_PRIO_LLR_MAP 2
|
||||
|
||||
/* Hashing a MacAddress for lkup into a per interface flow hash table */
|
||||
#define DHD_FLOWRING_HASH_SIZE 256
|
||||
#define DHD_FLOWRING_HASHINDEX(ea, prio) \
|
||||
((((uint8 *)(ea))[3] ^ ((uint8 *)(ea))[4] ^ ((uint8 *)(ea))[5] ^ ((uint8)(prio))) \
|
||||
% DHD_FLOWRING_HASH_SIZE)
|
||||
|
||||
#define DHD_IF_ROLE(pub, idx) (((if_flow_lkup_t *)(pub)->if_flow_lkup)[idx].role)
|
||||
#define DHD_IF_ROLE_AP(pub, idx) (DHD_IF_ROLE(pub, idx) == WLC_E_IF_ROLE_AP)
|
||||
#define DHD_IF_ROLE_STA(pub, idx) (DHD_IF_ROLE(pub, idx) == WLC_E_IF_ROLE_STA)
|
||||
#define DHD_IF_ROLE_P2PGC(pub, idx) (DHD_IF_ROLE(pub, idx) == WLC_E_IF_ROLE_P2P_CLIENT)
|
||||
#define DHD_IF_ROLE_P2PGO(pub, idx) (DHD_IF_ROLE(pub, idx) == WLC_E_IF_ROLE_P2P_GO)
|
||||
#define DHD_IF_ROLE_WDS(pub, idx) (DHD_IF_ROLE(pub, idx) == WLC_E_IF_ROLE_WDS)
|
||||
#define DHD_IF_ROLE_IBSS(pub, idx) (DHD_IF_ROLE(pub, idx) == WLC_E_IF_ROLE_IBSS)
|
||||
#ifdef WL_NAN
|
||||
#define DHD_IF_ROLE_NAN(pub, idx) (DHD_IF_ROLE(pub, idx) == WLC_E_IF_ROLE_NAN)
|
||||
#else
|
||||
#define DHD_IF_ROLE_NAN(pub, idx) (FALSE)
|
||||
#endif /* WL_NAN */
|
||||
#define DHD_IF_ROLE_AWDL(pub, idx) (FALSE)
|
||||
|
||||
#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))
|
||||
|
||||
#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))
|
||||
|
||||
#define DHD_FLOW_RING(dhdp, flowid) \
|
||||
(flow_ring_node_t *)&(((flow_ring_node_t *)((dhdp)->flow_ring_table))[flowid])
|
||||
|
||||
struct flow_queue;
|
||||
|
||||
/* Flow Ring Queue Enqueue overflow callback */
|
||||
typedef int (*flow_queue_cb_t)(struct flow_queue * queue, void * pkt);
|
||||
|
||||
/**
|
||||
* Each flow ring has an associated (tx flow controlled) queue. 802.3 packets are transferred
|
||||
* between queue and ring. A packet from the host stack is first added to the queue, and in a later
|
||||
* stage transferred to the flow ring. Packets in the queue are dhd owned, whereas packets in the
|
||||
* flow ring are device owned.
|
||||
*/
|
||||
typedef struct flow_queue {
|
||||
dll_t list; /* manage a flowring queue in a double linked list */
|
||||
void * head; /* first packet in the queue */
|
||||
void * tail; /* last packet in the queue */
|
||||
uint16 len; /* number of packets in the queue */
|
||||
uint16 max; /* maximum or min budget (used in cumm) */
|
||||
uint32 threshold; /* parent's cummulative length threshold */
|
||||
void * clen_ptr; /* parent's cummulative length counter */
|
||||
uint32 failures; /* enqueue failures due to queue overflow */
|
||||
flow_queue_cb_t cb; /* callback invoked on threshold crossing */
|
||||
uint32 l2threshold; /* grandparent's (level 2) cummulative length threshold */
|
||||
void * l2clen_ptr; /* grandparent's (level 2) cummulative length counter */
|
||||
} flow_queue_t;
|
||||
|
||||
#define DHD_FLOW_QUEUE_LEN(queue) ((int)(queue)->len)
|
||||
#define DHD_FLOW_QUEUE_MAX(queue) ((int)(queue)->max)
|
||||
#define DHD_FLOW_QUEUE_THRESHOLD(queue) ((int)(queue)->threshold)
|
||||
#define DHD_FLOW_QUEUE_L2THRESHOLD(queue) ((int)(queue)->l2threshold)
|
||||
#define DHD_FLOW_QUEUE_EMPTY(queue) ((queue)->len == 0)
|
||||
#define DHD_FLOW_QUEUE_FAILURES(queue) ((queue)->failures)
|
||||
|
||||
#define DHD_FLOW_QUEUE_AVAIL(queue) ((int)((queue)->max - (queue)->len))
|
||||
#define DHD_FLOW_QUEUE_FULL(queue) ((queue)->len >= (queue)->max)
|
||||
|
||||
#define DHD_FLOW_QUEUE_OVFL(queue, budget) \
|
||||
(((queue)->len) > budget)
|
||||
|
||||
#define DHD_FLOW_QUEUE_SET_MAX(queue, budget) \
|
||||
((queue)->max) = ((budget) - 1)
|
||||
|
||||
/* Queue's cummulative threshold. */
|
||||
#define DHD_FLOW_QUEUE_SET_THRESHOLD(queue, cumm_threshold) \
|
||||
((queue)->threshold) = ((cumm_threshold) - 1)
|
||||
|
||||
/* Queue's cummulative length object accessor. */
|
||||
#define DHD_FLOW_QUEUE_CLEN_PTR(queue) ((queue)->clen_ptr)
|
||||
|
||||
/* Set a queue's cumm_len point to a parent's cumm_ctr_t cummulative length */
|
||||
#define DHD_FLOW_QUEUE_SET_CLEN(queue, parent_clen_ptr) \
|
||||
((queue)->clen_ptr) = (void *)(parent_clen_ptr)
|
||||
|
||||
/* Queue's level 2 cummulative threshold. */
|
||||
#define DHD_FLOW_QUEUE_SET_L2THRESHOLD(queue, l2cumm_threshold) \
|
||||
((queue)->l2threshold) = ((l2cumm_threshold) - 1)
|
||||
|
||||
/* Queue's level 2 cummulative length object accessor. */
|
||||
#define DHD_FLOW_QUEUE_L2CLEN_PTR(queue) ((queue)->l2clen_ptr)
|
||||
|
||||
/* Set a queue's level 2 cumm_len point to a grandparent's cumm_ctr_t cummulative length */
|
||||
#define DHD_FLOW_QUEUE_SET_L2CLEN(queue, grandparent_clen_ptr) \
|
||||
((queue)->l2clen_ptr) = (void *)(grandparent_clen_ptr)
|
||||
|
||||
#define DHD_FLOWRING_TXSTATUS_CNT_UPDATE(bus, flowid, txstatus)
|
||||
|
||||
/* Pkttag not compatible with PROP_TXSTATUS or WLFC */
|
||||
typedef struct dhd_pkttag_fr {
|
||||
uint16 flowid;
|
||||
uint16 ifid;
|
||||
#ifdef DHD_LB_TXC
|
||||
int dataoff;
|
||||
dmaaddr_t physaddr;
|
||||
uint32 pa_len;
|
||||
#endif /* DHD_LB_TXC */
|
||||
} dhd_pkttag_fr_t;
|
||||
|
||||
#define DHD_PKTTAG_SET_IFID(tag, idx) ((tag)->ifid = (uint16)(idx))
|
||||
#define DHD_PKTTAG_SET_PA(tag, pa) ((tag)->physaddr = (pa))
|
||||
#define DHD_PKTTAG_SET_PA_LEN(tag, palen) ((tag)->pa_len = (palen))
|
||||
#define DHD_PKTTAG_IFID(tag) ((tag)->ifid)
|
||||
#define DHD_PKTTAG_PA(tag) ((tag)->physaddr)
|
||||
#define DHD_PKTTAG_PA_LEN(tag) ((tag)->pa_len)
|
||||
|
||||
/** each flow ring is dedicated to a tid/sa/da combination */
|
||||
typedef struct flow_info {
|
||||
uint8 tid;
|
||||
uint8 ifindex;
|
||||
uchar sa[ETHER_ADDR_LEN];
|
||||
uchar da[ETHER_ADDR_LEN];
|
||||
#ifdef TX_STATUS_LATENCY_STATS
|
||||
/* total number of tx_status received on this flowid */
|
||||
uint64 num_tx_status;
|
||||
/* cumulative tx_status latency for this flowid */
|
||||
uint64 cum_tx_status_latency;
|
||||
/* num tx packets sent on this flowring */
|
||||
uint64 num_tx_pkts;
|
||||
#endif /* TX_STATUS_LATENCY_STATS */
|
||||
} flow_info_t;
|
||||
|
||||
/** a flow ring is used for outbound (towards antenna) 802.3 packets */
|
||||
typedef struct flow_ring_node {
|
||||
dll_t list; /* manage a constructed flowring in a dll, must be at first place */
|
||||
flow_queue_t queue; /* queues packets before they enter the flow ring, flow control */
|
||||
bool active;
|
||||
uint8 status;
|
||||
/*
|
||||
* flowid: unique ID of a flow ring, which can either be unicast or broadcast/multicast. For
|
||||
* unicast flow rings, the flow id accelerates ARM 802.3->802.11 header translation.
|
||||
*/
|
||||
uint16 flowid;
|
||||
flow_info_t flow_info;
|
||||
void *prot_info;
|
||||
void *lock; /* lock for flowring access protection */
|
||||
|
||||
#ifdef IDLE_TX_FLOW_MGMT
|
||||
uint64 last_active_ts; /* contains last active timestamp */
|
||||
#endif /* IDLE_TX_FLOW_MGMT */
|
||||
#ifdef DHD_HP2P
|
||||
bool hp2p_ring;
|
||||
#endif /* DHD_HP2P */
|
||||
} flow_ring_node_t;
|
||||
|
||||
typedef flow_ring_node_t flow_ring_table_t;
|
||||
|
||||
typedef struct flow_hash_info {
|
||||
uint16 flowid;
|
||||
flow_info_t flow_info;
|
||||
struct flow_hash_info *next;
|
||||
} flow_hash_info_t;
|
||||
|
||||
typedef struct if_flow_lkup {
|
||||
bool status;
|
||||
uint8 role; /* Interface role: STA/AP */
|
||||
flow_hash_info_t *fl_hash[DHD_FLOWRING_HASH_SIZE]; /* Lkup Hash table */
|
||||
} if_flow_lkup_t;
|
||||
|
||||
static INLINE flow_ring_node_t *
|
||||
dhd_constlist_to_flowring(dll_t *item)
|
||||
{
|
||||
return ((flow_ring_node_t *)item);
|
||||
}
|
||||
|
||||
/* Exported API */
|
||||
|
||||
/* Flow ring's queue management functions */
|
||||
extern flow_ring_node_t * dhd_flow_ring_node(dhd_pub_t *dhdp, uint16 flowid);
|
||||
extern flow_queue_t * dhd_flow_queue(dhd_pub_t *dhdp, uint16 flowid);
|
||||
|
||||
extern void dhd_flow_queue_init(dhd_pub_t *dhdp, flow_queue_t *queue, int max);
|
||||
extern void dhd_flow_queue_reinit(dhd_pub_t *dhdp, flow_queue_t *queue, int max);
|
||||
extern void dhd_flow_queue_register(flow_queue_t *queue, flow_queue_cb_t cb);
|
||||
extern int dhd_flow_queue_enqueue(dhd_pub_t *dhdp, flow_queue_t *queue, void *pkt);
|
||||
extern void * dhd_flow_queue_dequeue(dhd_pub_t *dhdp, flow_queue_t *queue);
|
||||
extern void dhd_flow_queue_reinsert(dhd_pub_t *dhdp, flow_queue_t *queue, void *pkt);
|
||||
|
||||
extern void dhd_flow_ring_config_thresholds(dhd_pub_t *dhdp, uint16 flowid,
|
||||
int queue_budget, int cumm_threshold, void *cumm_ctr,
|
||||
int l2cumm_threshold, void *l2cumm_ctr);
|
||||
extern int dhd_flow_rings_init(dhd_pub_t *dhdp, uint32 num_flow_rings);
|
||||
|
||||
extern void dhd_flow_rings_deinit(dhd_pub_t *dhdp);
|
||||
|
||||
extern int dhd_flowid_update(dhd_pub_t *dhdp, uint8 ifindex, uint8 prio,
|
||||
void *pktbuf);
|
||||
extern int dhd_flowid_debug_create(dhd_pub_t *dhdp, uint8 ifindex,
|
||||
uint8 prio, char *sa, char *da, uint16 *flowid);
|
||||
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_flow_rings_flush(dhd_pub_t *dhdp, uint8 ifindex);
|
||||
|
||||
extern void dhd_flow_rings_delete_for_peer(dhd_pub_t *dhdp, uint8 ifindex,
|
||||
char *addr);
|
||||
|
||||
/* Handle Interface ADD, DEL operations */
|
||||
extern void dhd_update_interface_flow_info(dhd_pub_t *dhdp, uint8 ifindex,
|
||||
uint8 op, uint8 role);
|
||||
|
||||
/* Handle a STA interface link status update */
|
||||
extern int dhd_update_interface_link_status(dhd_pub_t *dhdp, uint8 ifindex,
|
||||
uint8 status);
|
||||
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 uint8 dhd_flow_rings_ifindex2role(dhd_pub_t *dhdp, uint8 ifindex);
|
||||
#endif /* _dhd_flowrings_h_ */
|
||||
@@ -0,0 +1,350 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#include <osl.h>
|
||||
#include <dhd_linux.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/rfkill-wlan.h>
|
||||
|
||||
#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
|
||||
extern void *dhd_wlan_mem_prealloc(int section, unsigned long size);
|
||||
#endif /* CONFIG_DHD_USE_STATIC_BUF */
|
||||
|
||||
static int gpio_wl_reg_on = -1; // WL_REG_ON is input pin of WLAN module
|
||||
#ifdef CUSTOMER_OOB
|
||||
static int gpio_wl_host_wake = -1; // WL_HOST_WAKE is output pin of WLAN module
|
||||
#endif
|
||||
|
||||
static int
|
||||
dhd_wlan_set_power(int on
|
||||
#ifdef BUS_POWER_RESTORE
|
||||
, wifi_adapter_info_t *adapter
|
||||
#endif /* BUS_POWER_RESTORE */
|
||||
)
|
||||
{
|
||||
int err = 0;
|
||||
|
||||
if (on) {
|
||||
printf("======== PULL WL_REG_ON(%d) HIGH! ========\n", gpio_wl_reg_on);
|
||||
if (gpio_wl_reg_on >= 0) {
|
||||
err = gpio_direction_output(gpio_wl_reg_on, 1);
|
||||
if (err) {
|
||||
printf("%s: WL_REG_ON didn't output high\n", __FUNCTION__);
|
||||
return -EIO;
|
||||
}
|
||||
}
|
||||
rockchip_wifi_power(1);
|
||||
#if defined(BUS_POWER_RESTORE)
|
||||
#if defined(BCMSDIO) && (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);
|
||||
}
|
||||
#elif defined(BCMPCIE)
|
||||
if (adapter->pci_dev) {
|
||||
mdelay(100);
|
||||
printf("======== pci_set_power_state PCI_D0! ========\n");
|
||||
pci_set_power_state(adapter->pci_dev, PCI_D0);
|
||||
if (adapter->pci_saved_state)
|
||||
pci_load_and_free_saved_state(adapter->pci_dev, &adapter->pci_saved_state);
|
||||
pci_restore_state(adapter->pci_dev);
|
||||
err = pci_enable_device(adapter->pci_dev);
|
||||
if (err < 0)
|
||||
printf("%s: PCI enable device failed", __FUNCTION__);
|
||||
pci_set_master(adapter->pci_dev);
|
||||
}
|
||||
#endif /* BCMPCIE */
|
||||
#endif /* BUS_POWER_RESTORE */
|
||||
/* Lets customer power to get stable */
|
||||
mdelay(100);
|
||||
} else {
|
||||
#if defined(BUS_POWER_RESTORE)
|
||||
#if defined(BCMSDIO) && (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);
|
||||
}
|
||||
#elif defined(BCMPCIE)
|
||||
if (adapter->pci_dev) {
|
||||
printf("======== pci_set_power_state PCI_D3hot! ========\n");
|
||||
pci_save_state(adapter->pci_dev);
|
||||
adapter->pci_saved_state = pci_store_saved_state(adapter->pci_dev);
|
||||
if (pci_is_enabled(adapter->pci_dev))
|
||||
pci_disable_device(adapter->pci_dev);
|
||||
pci_set_power_state(adapter->pci_dev, PCI_D3hot);
|
||||
}
|
||||
#endif /* BCMPCIE */
|
||||
#endif /* BUS_POWER_RESTORE */
|
||||
printf("======== PULL WL_REG_ON(%d) LOW! ========\n", gpio_wl_reg_on);
|
||||
if (gpio_wl_reg_on >= 0) {
|
||||
err = gpio_direction_output(gpio_wl_reg_on, 0);
|
||||
if (err) {
|
||||
printf("%s: WL_REG_ON didn't output low\n", __FUNCTION__);
|
||||
return -EIO;
|
||||
}
|
||||
}
|
||||
rockchip_wifi_power(0);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int dhd_wlan_set_reset(int onoff)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
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");
|
||||
#ifdef CUSTOMER_HW_PLATFORM
|
||||
err = sdhci_force_presence_change(&sdmmc_channel, 1);
|
||||
#endif /* CUSTOMER_HW_PLATFORM */
|
||||
rockchip_wifi_set_carddetect(1);
|
||||
#elif defined(BCMPCIE)
|
||||
printf("======== Card detection to detect PCIE card! ========\n");
|
||||
#endif
|
||||
} else {
|
||||
#if defined(BCMSDIO)
|
||||
printf("======== Card detection to remove SDIO card! ========\n");
|
||||
#ifdef CUSTOMER_HW_PLATFORM
|
||||
err = sdhci_force_presence_change(&sdmmc_channel, 0);
|
||||
#endif /* CUSTOMER_HW_PLATFORM */
|
||||
rockchip_wifi_set_carddetect(0);
|
||||
#elif defined(BCMPCIE)
|
||||
printf("======== Card detection to remove PCIE card! ========\n");
|
||||
#endif
|
||||
}
|
||||
#endif /* BUS_POWER_RESTORE */
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int dhd_wlan_get_mac_addr(unsigned char *buf
|
||||
#ifdef CUSTOM_MULTI_MAC
|
||||
, char *name
|
||||
#endif
|
||||
)
|
||||
{
|
||||
int err = 0;
|
||||
|
||||
#ifdef CUSTOM_MULTI_MAC
|
||||
if (!strcmp("wlan1", name)) {
|
||||
#ifdef EXAMPLE_GET_MAC
|
||||
struct ether_addr ea_example = {{0x00, 0x11, 0x22, 0x33, 0x44, 0xFF}};
|
||||
bcopy((char *)&ea_example, buf, sizeof(struct ether_addr));
|
||||
#endif /* EXAMPLE_GET_MAC */
|
||||
} else
|
||||
#endif /* CUSTOM_MULTI_MAC */
|
||||
{
|
||||
#ifdef EXAMPLE_GET_MAC
|
||||
struct ether_addr ea_example = {{0x02, 0x11, 0x22, 0x33, 0x44, 0x55}};
|
||||
bcopy((char *)&ea_example, buf, sizeof(struct ether_addr));
|
||||
#endif /* EXAMPLE_GET_MAC */
|
||||
}
|
||||
|
||||
#ifdef EXAMPLE_GET_MAC_VER2
|
||||
/* EXAMPLE code */
|
||||
{
|
||||
char macpad[56]= {
|
||||
0x00,0xaa,0x9c,0x84,0xc7,0xbc,0x9b,0xf6,
|
||||
0x02,0x33,0xa9,0x4d,0x5c,0xb4,0x0a,0x5d,
|
||||
0xa8,0xef,0xb0,0xcf,0x8e,0xbf,0x24,0x8a,
|
||||
0x87,0x0f,0x6f,0x0d,0xeb,0x83,0x6a,0x70,
|
||||
0x4a,0xeb,0xf6,0xe6,0x3c,0xe7,0x5f,0xfc,
|
||||
0x0e,0xa7,0xb3,0x0f,0x00,0xe4,0x4a,0xaf,
|
||||
0x87,0x08,0x16,0x6d,0x3a,0xe3,0xc7,0x80};
|
||||
bcopy(macpad, buf+6, sizeof(macpad));
|
||||
}
|
||||
#endif /* EXAMPLE_GET_MAC_VER2 */
|
||||
|
||||
printf("======== %s err=%d ========\n", __FUNCTION__, err);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static struct cntry_locales_custom brcm_wlan_translate_custom_table[] = {
|
||||
/* Table should be filled out based on custom platform regulatory requirement */
|
||||
#ifdef EXAMPLE_TABLE
|
||||
{"", "XT", 49}, /* Universal if Country code is unknown or empty */
|
||||
{"US", "US", 0},
|
||||
#endif /* EXMAPLE_TABLE */
|
||||
};
|
||||
|
||||
#ifdef CUSTOM_FORCE_NODFS_FLAG
|
||||
struct cntry_locales_custom brcm_wlan_translate_nodfs_table[] = {
|
||||
#ifdef EXAMPLE_TABLE
|
||||
{"", "XT", 50}, /* Universal if Country code is unknown or empty */
|
||||
{"US", "US", 0},
|
||||
#endif /* EXMAPLE_TABLE */
|
||||
};
|
||||
#endif
|
||||
|
||||
static void *dhd_wlan_get_country_code(char *ccode
|
||||
#ifdef CUSTOM_FORCE_NODFS_FLAG
|
||||
, u32 flags
|
||||
#endif
|
||||
)
|
||||
{
|
||||
struct cntry_locales_custom *locales;
|
||||
int size;
|
||||
int i;
|
||||
|
||||
if (!ccode)
|
||||
return NULL;
|
||||
|
||||
#ifdef CUSTOM_FORCE_NODFS_FLAG
|
||||
if (flags & WLAN_PLAT_NODFS_FLAG) {
|
||||
locales = brcm_wlan_translate_nodfs_table;
|
||||
size = ARRAY_SIZE(brcm_wlan_translate_nodfs_table);
|
||||
} else {
|
||||
#endif
|
||||
locales = brcm_wlan_translate_custom_table;
|
||||
size = ARRAY_SIZE(brcm_wlan_translate_custom_table);
|
||||
#ifdef CUSTOM_FORCE_NODFS_FLAG
|
||||
}
|
||||
#endif
|
||||
|
||||
for (i = 0; i < size; i++)
|
||||
if (strcmp(ccode, locales[i].iso_abbrev) == 0)
|
||||
return &locales[i];
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct resource dhd_wlan_resources[] = {
|
||||
[0] = {
|
||||
.name = "bcmdhd_wlan_irq",
|
||||
.start = 0, /* Dummy */
|
||||
.end = 0, /* Dummy */
|
||||
.flags = IORESOURCE_IRQ | IORESOURCE_IRQ_SHAREABLE
|
||||
| IORESOURCE_IRQ_HIGHLEVEL, /* Dummy */
|
||||
},
|
||||
};
|
||||
|
||||
struct wifi_platform_data dhd_wlan_control = {
|
||||
.set_power = dhd_wlan_set_power,
|
||||
.set_reset = dhd_wlan_set_reset,
|
||||
.set_carddetect = dhd_wlan_set_carddetect,
|
||||
.get_mac_addr = dhd_wlan_get_mac_addr,
|
||||
#ifdef CONFIG_DHD_USE_STATIC_BUF
|
||||
.mem_prealloc = dhd_wlan_mem_prealloc,
|
||||
#endif /* CONFIG_DHD_USE_STATIC_BUF */
|
||||
.get_country_code = dhd_wlan_get_country_code,
|
||||
};
|
||||
|
||||
int dhd_wlan_init_gpio(void)
|
||||
{
|
||||
int err = 0;
|
||||
#ifdef CUSTOMER_OOB
|
||||
int host_oob_irq = -1;
|
||||
uint host_oob_irq_flags = 0;
|
||||
int irq_flags = -1;
|
||||
#endif
|
||||
|
||||
/* Please check your schematic and fill right GPIO number which connected to
|
||||
* WL_REG_ON and WL_HOST_WAKE.
|
||||
*/
|
||||
gpio_wl_reg_on = -1;
|
||||
#ifdef CUSTOMER_OOB
|
||||
gpio_wl_host_wake = -1;
|
||||
#endif
|
||||
|
||||
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);
|
||||
gpio_wl_reg_on = -1;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef CUSTOMER_OOB
|
||||
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);
|
||||
return -1;
|
||||
}
|
||||
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);
|
||||
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);
|
||||
gpio_free(gpio_wl_host_wake);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
host_oob_irq = rockchip_wifi_get_oob_irq();
|
||||
|
||||
#ifdef HW_OOB
|
||||
host_oob_irq_flags = IORESOURCE_IRQ | IORESOURCE_IRQ_SHAREABLE;
|
||||
irq_flags = rockchip_wifi_get_oob_irq_flag();
|
||||
if (irq_flags == 1)
|
||||
host_oob_irq_flags |= IORESOURCE_IRQ_HIGHLEVEL;
|
||||
else if (irq_flags == 0)
|
||||
host_oob_irq_flags |= IORESOURCE_IRQ_LOWLEVEL;
|
||||
else
|
||||
pr_warn("%s: unknown oob irqflags !\n", __func__);
|
||||
#else
|
||||
host_oob_irq_flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE | IORESOURCE_IRQ_SHAREABLE;
|
||||
#endif
|
||||
|
||||
dhd_wlan_resources[0].start = dhd_wlan_resources[0].end = host_oob_irq;
|
||||
dhd_wlan_resources[0].flags = host_oob_irq_flags;
|
||||
printf("%s: WL_HOST_WAKE=%d, oob_irq=%d, oob_irq_flags=0x%x\n", __FUNCTION__,
|
||||
gpio_wl_host_wake, host_oob_irq, host_oob_irq_flags);
|
||||
#endif /* CUSTOMER_OOB */
|
||||
printf("%s: WL_REG_ON=%d\n", __FUNCTION__, gpio_wl_reg_on);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void dhd_wlan_deinit_gpio(void)
|
||||
{
|
||||
if (gpio_wl_reg_on >= 0) {
|
||||
printf("%s: gpio_free(WL_REG_ON %d)\n", __FUNCTION__, gpio_wl_reg_on);
|
||||
gpio_free(gpio_wl_reg_on);
|
||||
gpio_wl_reg_on = -1;
|
||||
}
|
||||
#ifdef CUSTOMER_OOB
|
||||
if (gpio_wl_host_wake >= 0) {
|
||||
printf("%s: gpio_free(WL_HOST_WAKE %d)\n", __FUNCTION__, gpio_wl_host_wake);
|
||||
gpio_free(gpio_wl_host_wake);
|
||||
gpio_wl_host_wake = -1;
|
||||
}
|
||||
#endif /* CUSTOMER_OOB */
|
||||
}
|
||||
|
||||
int dhd_wlan_init_plat_data(void)
|
||||
{
|
||||
int err = 0;
|
||||
|
||||
printf("======== %s ========\n", __FUNCTION__);
|
||||
err = dhd_wlan_init_gpio();
|
||||
return err;
|
||||
}
|
||||
|
||||
void dhd_wlan_deinit_plat_data(wifi_adapter_info_t *adapter)
|
||||
{
|
||||
printf("======== %s ========\n", __FUNCTION__);
|
||||
dhd_wlan_deinit_gpio();
|
||||
}
|
||||
|
||||
1428
drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd_wifi6/dhd_ip.c
Normal file
1428
drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd_wifi6/dhd_ip.c
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,97 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Header file describing the common ip parser function.
|
||||
*
|
||||
* Provides type definitions and function prototypes used to parse ip packet.
|
||||
*
|
||||
* Copyright (C) 1999-2019, 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.
|
||||
*
|
||||
* Notwithstanding the above, under no circumstances may you combine this
|
||||
* software in any way with any other Broadcom software provided under a license
|
||||
* other than the GPL, without Broadcom's express prior written consent.
|
||||
*
|
||||
*
|
||||
* <<Broadcom-WL-IPTag/Open:>>
|
||||
*
|
||||
* $Id: dhd_ip.h 790572 2018-11-26 11:03:46Z $
|
||||
*/
|
||||
|
||||
#ifndef _dhd_ip_h_
|
||||
#define _dhd_ip_h_
|
||||
|
||||
#if defined(DHDTCPACK_SUPPRESS) || defined(DHDTCPSYNC_FLOOD_BLK)
|
||||
#include <dngl_stats.h>
|
||||
#include <bcmutils.h>
|
||||
#include <dhd.h>
|
||||
#endif /* DHDTCPACK_SUPPRESS || DHDTCPSYNC_FLOOD_BLK */
|
||||
|
||||
typedef enum pkt_frag
|
||||
{
|
||||
DHD_PKT_FRAG_NONE = 0,
|
||||
DHD_PKT_FRAG_FIRST,
|
||||
DHD_PKT_FRAG_CONT,
|
||||
DHD_PKT_FRAG_LAST
|
||||
} pkt_frag_t;
|
||||
|
||||
extern pkt_frag_t pkt_frag_info(osl_t *osh, void *p);
|
||||
|
||||
#ifdef DHDTCPSYNC_FLOOD_BLK
|
||||
typedef enum tcp_hdr_flags {
|
||||
FLAG_SYNC,
|
||||
FLAG_SYNCACK,
|
||||
FLAG_RST,
|
||||
FLAG_OTHERS
|
||||
} tcp_hdr_flag_t;
|
||||
|
||||
extern tcp_hdr_flag_t dhd_tcpdata_get_flag(dhd_pub_t *dhdp, void *pkt);
|
||||
#endif /* DHDTCPSYNC_FLOOD_BLK */
|
||||
|
||||
#ifdef DHDTCPACK_SUPPRESS
|
||||
#define TCPACKSZMIN (ETHER_HDR_LEN + IPV4_MIN_HEADER_LEN + TCP_MIN_HEADER_LEN)
|
||||
/* Size of MAX possible TCP ACK packet. Extra bytes for IP/TCP option fields */
|
||||
#define TCPACKSZMAX (TCPACKSZMIN + 100)
|
||||
|
||||
/* Max number of TCP streams that have own src/dst IP addrs and TCP ports */
|
||||
#define TCPACK_INFO_MAXNUM 4
|
||||
#define TCPDATA_INFO_MAXNUM 4
|
||||
#define TCPDATA_PSH_INFO_MAXNUM (8 * TCPDATA_INFO_MAXNUM)
|
||||
|
||||
#define TCPDATA_INFO_TIMEOUT 5000 /* Remove tcpdata_info if inactive for this time (in ms) */
|
||||
|
||||
#define DEFAULT_TCPACK_SUPP_RATIO 3
|
||||
#ifndef CUSTOM_TCPACK_SUPP_RATIO
|
||||
#define CUSTOM_TCPACK_SUPP_RATIO DEFAULT_TCPACK_SUPP_RATIO
|
||||
#endif /* CUSTOM_TCPACK_SUPP_RATIO */
|
||||
|
||||
#define DEFAULT_TCPACK_DELAY_TIME 10 /* ms */
|
||||
#ifndef CUSTOM_TCPACK_DELAY_TIME
|
||||
#define CUSTOM_TCPACK_DELAY_TIME DEFAULT_TCPACK_DELAY_TIME
|
||||
#endif /* CUSTOM_TCPACK_DELAY_TIME */
|
||||
|
||||
extern int dhd_tcpack_suppress_set(dhd_pub_t *dhdp, uint8 on);
|
||||
extern void dhd_tcpack_info_tbl_clean(dhd_pub_t *dhdp);
|
||||
extern int dhd_tcpack_check_xmit(dhd_pub_t *dhdp, void *pkt);
|
||||
extern bool dhd_tcpack_suppress(dhd_pub_t *dhdp, void *pkt);
|
||||
extern bool dhd_tcpdata_info_get(dhd_pub_t *dhdp, void *pkt);
|
||||
extern bool dhd_tcpack_hold(dhd_pub_t *dhdp, void *pkt, int ifidx);
|
||||
/* #define DHDTCPACK_SUP_DBG */
|
||||
#if defined(DEBUG_COUNTER) && defined(DHDTCPACK_SUP_DBG)
|
||||
extern counter_tbl_t tack_tbl;
|
||||
#endif /* DEBUG_COUNTER && DHDTCPACK_SUP_DBG */
|
||||
#endif /* DHDTCPACK_SUPPRESS */
|
||||
|
||||
#endif /* _dhd_ip_h_ */
|
||||
22038
drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd_wifi6/dhd_linux.c
Normal file
22038
drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd_wifi6/dhd_linux.c
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,450 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* DHD Linux header file (dhd_linux exports for cfg80211 and other components)
|
||||
*
|
||||
* Copyright (C) 1999-2019, 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.
|
||||
*
|
||||
* Notwithstanding the above, under no circumstances may you combine this
|
||||
* software in any way with any other Broadcom software provided under a license
|
||||
* other than the GPL, without Broadcom's express prior written consent.
|
||||
*
|
||||
*
|
||||
* <<Broadcom-WL-IPTag/Open:>>
|
||||
*
|
||||
* $Id: dhd_linux.h 816392 2019-04-24 14:39:02Z $
|
||||
*/
|
||||
|
||||
/* wifi platform functions for power, interrupt and pre-alloc, either
|
||||
* from Android-like platform device data, or Broadcom wifi platform
|
||||
* device data.
|
||||
*
|
||||
*/
|
||||
#ifndef __DHD_LINUX_H__
|
||||
#define __DHD_LINUX_H__
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/fs.h>
|
||||
#include <dngl_stats.h>
|
||||
#include <dhd.h>
|
||||
/* Linux wireless extension support */
|
||||
#if defined(WL_WIRELESS_EXT)
|
||||
#include <wl_iw.h>
|
||||
#endif /* defined(WL_WIRELESS_EXT) */
|
||||
#if defined(CONFIG_HAS_EARLYSUSPEND) && defined(DHD_USE_EARLYSUSPEND)
|
||||
#include <linux/earlysuspend.h>
|
||||
#endif /* defined(CONFIG_HAS_EARLYSUSPEND) && defined(DHD_USE_EARLYSUSPEND) */
|
||||
#ifdef PCIE_FULL_DONGLE
|
||||
#include <etd.h>
|
||||
#endif /* PCIE_FULL_DONGLE */
|
||||
#ifdef WL_MONITOR
|
||||
#include <bcmmsgbuf.h>
|
||||
#define MAX_RADIOTAP_SIZE 256 /* Maximum size to hold HE Radiotap header format */
|
||||
#define MAX_MON_PKT_SIZE (4096 + MAX_RADIOTAP_SIZE)
|
||||
#endif /* WL_MONITOR */
|
||||
|
||||
#define FILE_DUMP_MAX_WAIT_TIME 4000
|
||||
|
||||
#define htod32(i) (i)
|
||||
#define htod16(i) (i)
|
||||
#define dtoh32(i) (i)
|
||||
#define dtoh16(i) (i)
|
||||
#define htodchanspec(i) (i)
|
||||
#define dtohchanspec(i) (i)
|
||||
|
||||
#ifdef BLOCK_IPV6_PACKET
|
||||
#define HEX_PREF_STR "0x"
|
||||
#define UNI_FILTER_STR "010000000000"
|
||||
#define ZERO_ADDR_STR "000000000000"
|
||||
#define ETHER_TYPE_STR "0000"
|
||||
#define IPV6_FILTER_STR "20"
|
||||
#define ZERO_TYPE_STR "00"
|
||||
#endif /* BLOCK_IPV6_PACKET */
|
||||
|
||||
typedef struct dhd_if_event {
|
||||
struct list_head list;
|
||||
wl_event_data_if_t event;
|
||||
char name[IFNAMSIZ+1];
|
||||
uint8 mac[ETHER_ADDR_LEN];
|
||||
} dhd_if_event_t;
|
||||
|
||||
/* Interface control information */
|
||||
typedef struct dhd_if {
|
||||
struct dhd_info *info; /* back pointer to dhd_info */
|
||||
/* OS/stack specifics */
|
||||
struct net_device *net;
|
||||
int idx; /* iface idx in dongle */
|
||||
uint subunit; /* subunit */
|
||||
uint8 mac_addr[ETHER_ADDR_LEN]; /* assigned MAC address */
|
||||
bool set_macaddress;
|
||||
bool set_multicast;
|
||||
uint8 bssidx; /* bsscfg index for the interface */
|
||||
bool attached; /* Delayed attachment when unset */
|
||||
bool txflowcontrol; /* Per interface flow control indicator */
|
||||
char name[IFNAMSIZ+1]; /* linux interface name */
|
||||
char dngl_name[IFNAMSIZ+1]; /* corresponding dongle interface name */
|
||||
struct net_device_stats stats;
|
||||
#ifdef PCIE_FULL_DONGLE
|
||||
struct list_head sta_list; /* sll of associated stations */
|
||||
spinlock_t sta_list_lock; /* lock for manipulating sll */
|
||||
#endif /* PCIE_FULL_DONGLE */
|
||||
uint32 ap_isolate; /* ap-isolation settings */
|
||||
#ifdef DHD_L2_FILTER
|
||||
bool parp_enable;
|
||||
bool parp_discard;
|
||||
bool parp_allnode;
|
||||
arp_table_t *phnd_arp_table;
|
||||
/* for Per BSS modification */
|
||||
bool dhcp_unicast;
|
||||
bool block_ping;
|
||||
bool grat_arp;
|
||||
bool block_tdls;
|
||||
#endif /* DHD_L2_FILTER */
|
||||
#ifdef DHD_MCAST_REGEN
|
||||
bool mcast_regen_bss_enable;
|
||||
#endif // endif
|
||||
bool rx_pkt_chainable; /* set all rx packet to chainable config by default */
|
||||
cumm_ctr_t cumm_ctr; /* cummulative queue length of child flowrings */
|
||||
uint8 tx_paths_active;
|
||||
bool del_in_progress;
|
||||
bool static_if; /* used to avoid some operations on static_if */
|
||||
#ifdef DHD_4WAYM4_FAIL_DISCONNECT
|
||||
struct delayed_work m4state_work;
|
||||
atomic_t m4state;
|
||||
#endif /* DHD_4WAYM4_FAIL_DISCONNECT */
|
||||
#ifdef DHD_POST_EAPOL_M1_AFTER_ROAM_EVT
|
||||
bool recv_reassoc_evt;
|
||||
bool post_roam_evt;
|
||||
#endif /* DHD_POST_EAPOL_M1_AFTER_ROAM_EVT */
|
||||
#ifdef DHDTCPSYNC_FLOOD_BLK
|
||||
uint32 tsync_rcvd;
|
||||
uint32 tsyncack_txed;
|
||||
u64 last_sync;
|
||||
struct work_struct blk_tsfl_work;
|
||||
#endif /* DHDTCPSYNC_FLOOD_BLK */
|
||||
} dhd_if_t;
|
||||
|
||||
struct ipv6_work_info_t {
|
||||
uint8 if_idx;
|
||||
char ipv6_addr[IPV6_ADDR_LEN];
|
||||
unsigned long event;
|
||||
};
|
||||
|
||||
typedef struct dhd_dump {
|
||||
uint8 *buf;
|
||||
int bufsize;
|
||||
uint8 *hscb_buf;
|
||||
int hscb_bufsize;
|
||||
} dhd_dump_t;
|
||||
#ifdef DNGL_AXI_ERROR_LOGGING
|
||||
typedef struct dhd_axi_error_dump {
|
||||
ulong fault_address;
|
||||
uint32 axid;
|
||||
struct hnd_ext_trap_axi_error_v1 etd_axi_error_v1;
|
||||
} dhd_axi_error_dump_t;
|
||||
#endif /* DNGL_AXI_ERROR_LOGGING */
|
||||
|
||||
#ifdef DHD_PCIE_NATIVE_RUNTIMEPM
|
||||
struct dhd_rx_tx_work {
|
||||
struct work_struct work;
|
||||
struct sk_buff *skb;
|
||||
struct net_device *net;
|
||||
struct dhd_pub *pub;
|
||||
};
|
||||
#endif /* DHD_PCIE_NATIVE_RUNTIMEPM */
|
||||
|
||||
#if defined(DHD_LB)
|
||||
#if !defined(PCIE_FULL_DONGLE)
|
||||
#error "DHD Loadbalancing only supported on PCIE_FULL_DONGLE"
|
||||
#endif /* !PCIE_FULL_DONGLE */
|
||||
#endif /* DHD_LB */
|
||||
|
||||
#if defined(DHD_LB_RXP) || defined(DHD_LB_RXC) || defined(DHD_LB_TXC) || \
|
||||
defined(DHD_LB_STATS)
|
||||
#if !defined(DHD_LB)
|
||||
#error "DHD loadbalance derivatives are supported only if DHD_LB is defined"
|
||||
#endif /* !DHD_LB */
|
||||
#endif /* DHD_LB_RXP || DHD_LB_RXC || DHD_LB_TXC || DHD_LB_STATS */
|
||||
|
||||
#if defined(DHD_LB)
|
||||
/* Dynamic CPU selection for load balancing */
|
||||
#include <linux/cpu.h>
|
||||
#include <linux/cpumask.h>
|
||||
#include <linux/notifier.h>
|
||||
#include <linux/workqueue.h>
|
||||
#include <asm/atomic.h>
|
||||
|
||||
#if !defined(DHD_LB_PRIMARY_CPUS)
|
||||
#define DHD_LB_PRIMARY_CPUS 0x0 /* Big CPU coreids mask */
|
||||
#endif // endif
|
||||
#if !defined(DHD_LB_SECONDARY_CPUS)
|
||||
#define DHD_LB_SECONDARY_CPUS 0xFE /* Little CPU coreids mask */
|
||||
#endif // endif
|
||||
|
||||
#define HIST_BIN_SIZE 9
|
||||
|
||||
#if defined(DHD_LB_TXP)
|
||||
/* Pkttag not compatible with PROP_TXSTATUS or WLFC */
|
||||
typedef struct dhd_tx_lb_pkttag_fr {
|
||||
struct net_device *net;
|
||||
int ifidx;
|
||||
} dhd_tx_lb_pkttag_fr_t;
|
||||
|
||||
#define DHD_LB_TX_PKTTAG_SET_NETDEV(tag, netdevp) ((tag)->net = netdevp)
|
||||
#define DHD_LB_TX_PKTTAG_NETDEV(tag) ((tag)->net)
|
||||
|
||||
#define DHD_LB_TX_PKTTAG_SET_IFIDX(tag, ifidx) ((tag)->ifidx = ifidx)
|
||||
#define DHD_LB_TX_PKTTAG_IFIDX(tag) ((tag)->ifidx)
|
||||
#endif /* DHD_LB_TXP */
|
||||
|
||||
#endif /* DHD_LB */
|
||||
|
||||
#ifdef FILTER_IE
|
||||
#define FILTER_IE_PATH "/etc/wifi/filter_ie"
|
||||
#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)
|
||||
|
||||
/* dongle status */
|
||||
enum wifi_adapter_status {
|
||||
WIFI_STATUS_POWER_ON = 0,
|
||||
WIFI_STATUS_ATTACH,
|
||||
WIFI_STATUS_FW_READY,
|
||||
WIFI_STATUS_DETTACH
|
||||
};
|
||||
#define wifi_chk_adapter_status(adapter, stat) (test_bit(stat, &(adapter)->status))
|
||||
#define wifi_get_adapter_status(adapter, stat) (test_bit(stat, &(adapter)->status))
|
||||
#define wifi_set_adapter_status(adapter, stat) (set_bit(stat, &(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))
|
||||
|
||||
#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 */
|
||||
|
||||
typedef struct wifi_adapter_info {
|
||||
const char *name;
|
||||
uint irq_num;
|
||||
uint intr_flags;
|
||||
const char *fw_path;
|
||||
const char *nv_path;
|
||||
const char *clm_path;
|
||||
const char *conf_path;
|
||||
void *wifi_plat_data; /* wifi ctrl func, for backward compatibility */
|
||||
uint bus_type;
|
||||
uint bus_num;
|
||||
uint slot_num;
|
||||
wait_queue_head_t status_event;
|
||||
unsigned long status;
|
||||
#if defined(BT_OVER_SDIO)
|
||||
const char *btfw_path;
|
||||
#endif /* defined (BT_OVER_SDIO) */
|
||||
#ifdef BUS_POWER_RESTORE
|
||||
#if defined(BCMSDIO)
|
||||
struct sdio_func *sdio_func;
|
||||
#endif /* BCMSDIO */
|
||||
#if defined(BCMPCIE)
|
||||
struct pci_dev *pci_dev;
|
||||
struct pci_saved_state *pci_saved_state;
|
||||
#endif /* BCMPCIE */
|
||||
#endif
|
||||
} wifi_adapter_info_t;
|
||||
|
||||
#define WLAN_PLAT_NODFS_FLAG 0x01
|
||||
#define WLAN_PLAT_AP_FLAG 0x02
|
||||
#if !defined(CONFIG_WIFI_CONTROL_FUNC)
|
||||
struct wifi_platform_data {
|
||||
#ifdef BUS_POWER_RESTORE
|
||||
int (*set_power)(int val, wifi_adapter_info_t *adapter);
|
||||
#else
|
||||
int (*set_power)(int val);
|
||||
#endif
|
||||
int (*set_reset)(int val);
|
||||
int (*set_carddetect)(int val);
|
||||
void *(*mem_prealloc)(int section, unsigned long size);
|
||||
#ifdef CUSTOM_MULTI_MAC
|
||||
int (*get_mac_addr)(unsigned char *buf, char *name);
|
||||
#else
|
||||
int (*get_mac_addr)(unsigned char *buf);
|
||||
#endif
|
||||
#ifdef BCMSDIO
|
||||
int (*get_wake_irq)(void);
|
||||
#endif // endif
|
||||
#ifdef CUSTOM_FORCE_NODFS_FLAG
|
||||
void *(*get_country_code)(char *ccode, u32 flags);
|
||||
#else /* defined (CUSTOM_FORCE_NODFS_FLAG) */
|
||||
void *(*get_country_code)(char *ccode);
|
||||
#endif
|
||||
};
|
||||
#endif
|
||||
|
||||
typedef struct bcmdhd_wifi_platdata {
|
||||
uint num_adapters;
|
||||
wifi_adapter_info_t *adapters;
|
||||
} bcmdhd_wifi_platdata_t;
|
||||
|
||||
/** Per STA params. A list of dhd_sta objects are managed in dhd_if */
|
||||
typedef struct dhd_sta {
|
||||
cumm_ctr_t cumm_ctr; /* cummulative queue length of child flowrings */
|
||||
uint16 flowid[NUMPRIO]; /* allocated flow ring ids (by priority) */
|
||||
void * ifp; /* associated dhd_if */
|
||||
struct ether_addr ea; /* stations ethernet mac address */
|
||||
struct list_head list; /* link into dhd_if::sta_list */
|
||||
int idx; /* index of self in dhd_pub::sta_pool[] */
|
||||
int ifidx; /* index of interface in dhd */
|
||||
} dhd_sta_t;
|
||||
typedef dhd_sta_t dhd_sta_pool_t;
|
||||
|
||||
#ifdef DHD_4WAYM4_FAIL_DISCONNECT
|
||||
typedef enum {
|
||||
M3_RXED,
|
||||
M4_TXFAILED
|
||||
} msg_4way_state_t;
|
||||
#define MAX_4WAY_TIMEOUT_MS 2000
|
||||
#endif /* DHD_4WAYM4_FAIL_DISCONNECT */
|
||||
|
||||
#ifdef DHD_SEND_HANG_PRIVCMD_ERRORS
|
||||
extern uint32 report_hang_privcmd_err;
|
||||
#endif /* DHD_SEND_HANG_PRIVCMD_ERRORS */
|
||||
|
||||
#if defined(ARGOS_NOTIFY_CB)
|
||||
int argos_register_notifier_init(struct net_device *net);
|
||||
int argos_register_notifier_deinit(void);
|
||||
|
||||
extern int sec_argos_register_notifier(struct notifier_block *n, char *label);
|
||||
extern int sec_argos_unregister_notifier(struct notifier_block *n, char *label);
|
||||
|
||||
typedef struct {
|
||||
struct net_device *wlan_primary_netdev;
|
||||
int argos_rps_cpus_enabled;
|
||||
} argos_rps_ctrl;
|
||||
|
||||
#define RPS_TPUT_THRESHOLD 300
|
||||
#define DELAY_TO_CLEAR_RPS_CPUS 300
|
||||
#endif // endif
|
||||
|
||||
#if defined(BT_OVER_SDIO)
|
||||
extern void wl_android_set_wifi_on_flag(bool enable);
|
||||
#endif /* BT_OVER_SDIO */
|
||||
|
||||
#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
|
||||
*/
|
||||
#define LOG_DUMP_GENERAL_MAX_BUFSIZE (256 * 1024 * CUSTOM_LOG_DUMP_BUFSIZE_MB)
|
||||
#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_FILTER_MAX_BUFSIZE)
|
||||
#error "LOG_DUMP_TOTAL_BUFSIZE is lesser than sum of all rings"
|
||||
#endif // 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;
|
||||
|
||||
typedef struct {
|
||||
int attr;
|
||||
char *hdr_str;
|
||||
log_dump_section_type_t sec_type;
|
||||
int log_type;
|
||||
} dld_log_hdr_t;
|
||||
|
||||
#define DHD_PRINT_BUF_NAME_LEN 30
|
||||
#endif /* DHD_LOG_DUMP */
|
||||
|
||||
int dhd_wifi_platform_register_drv(void);
|
||||
void dhd_wifi_platform_unregister_drv(void);
|
||||
wifi_adapter_info_t* dhd_wifi_platform_attach_adapter(uint32 bus_type,
|
||||
uint32 bus_num, uint32 slot_num, unsigned long status);
|
||||
wifi_adapter_info_t* dhd_wifi_platform_get_adapter(uint32 bus_type, uint32 bus_num,
|
||||
uint32 slot_num);
|
||||
int wifi_platform_set_power(wifi_adapter_info_t *adapter, bool on, unsigned long msec);
|
||||
int wifi_platform_bus_enumerate(wifi_adapter_info_t *adapter, bool device_present);
|
||||
int wifi_platform_get_irq_number(wifi_adapter_info_t *adapter, unsigned long *irq_flags_ptr);
|
||||
int wifi_platform_get_mac_addr(wifi_adapter_info_t *adapter, unsigned char *buf, char *name);
|
||||
#ifdef CUSTOM_COUNTRY_CODE
|
||||
void *wifi_platform_get_country_code(wifi_adapter_info_t *adapter, char *ccode,
|
||||
u32 flags);
|
||||
#else
|
||||
void *wifi_platform_get_country_code(wifi_adapter_info_t *adapter, char *ccode);
|
||||
#endif /* CUSTOM_COUNTRY_CODE */
|
||||
void* wifi_platform_prealloc(wifi_adapter_info_t *adapter, int section, unsigned long size);
|
||||
void* wifi_platform_get_prealloc_func_ptr(wifi_adapter_info_t *adapter);
|
||||
|
||||
int dhd_get_fw_mode(struct dhd_info *dhdinfo);
|
||||
bool dhd_update_fw_nv_path(struct dhd_info *dhdinfo);
|
||||
|
||||
#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)
|
||||
#define ADPS_ENABLE 1
|
||||
#define ADPS_DISABLE 0
|
||||
|
||||
int dhd_enable_adps(dhd_pub_t *dhd, uint8 on);
|
||||
#endif // 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 */
|
||||
|
||||
int compat_kernel_read(struct file *file, loff_t offset, char *addr, unsigned long count);
|
||||
int compat_vfs_write(struct file *file, char *addr, int count, loff_t *offset);
|
||||
|
||||
#endif /* __DHD_LINUX_H__ */
|
||||
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
@@ -0,0 +1,125 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Header file for the Packet dump helper functions
|
||||
*
|
||||
* Copyright (C) 1999-2019, 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.
|
||||
*
|
||||
* Notwithstanding the above, under no circumstances may you combine this
|
||||
* software in any way with any other Broadcom software provided under a license
|
||||
* other than the GPL, without Broadcom's express prior written consent.
|
||||
*
|
||||
*
|
||||
* <<Broadcom-WL-IPTag/Open:>>
|
||||
*
|
||||
* $Id: dhd_linux_pktdump.h 820929 2019-05-21 14:09:11Z $
|
||||
*/
|
||||
|
||||
#ifndef __DHD_LINUX_PKTDUMP_H_
|
||||
#define __DHD_LINUX_PKTDUMP_H_
|
||||
|
||||
#include <typedefs.h>
|
||||
#include <dhd.h>
|
||||
|
||||
typedef enum {
|
||||
EAPOL_OTHER = 0,
|
||||
EAPOL_4WAY_M1,
|
||||
EAPOL_4WAY_M2,
|
||||
EAPOL_4WAY_M3,
|
||||
EAPOL_4WAY_M4,
|
||||
EAPOL_GROUPKEY_M1,
|
||||
EAPOL_GROUPKEY_M2
|
||||
} msg_eapol_t;
|
||||
|
||||
typedef enum pkt_cnt_rsn {
|
||||
PKT_CNT_RSN_INVALID = 0,
|
||||
PKT_CNT_RSN_ROAM = 1,
|
||||
PKT_CNT_RSN_GRPKEY_UP = 2,
|
||||
PKT_CNT_RSN_CONNECT = 3,
|
||||
PKT_CNT_RSN_MAX = 4
|
||||
} pkt_cnt_rsn_t;
|
||||
|
||||
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);
|
||||
|
||||
#ifdef DHD_PKTDUMP_ROAM
|
||||
extern void dhd_dump_mod_pkt_timer(dhd_pub_t *dhdp, uint16 rsn);
|
||||
extern void dhd_dump_pkt_init(dhd_pub_t *dhdp);
|
||||
extern void dhd_dump_pkt_deinit(dhd_pub_t *dhdp);
|
||||
extern void dhd_dump_pkt_clear(dhd_pub_t *dhdp);
|
||||
#else
|
||||
static INLINE void dhd_dump_mod_pkt_timer(dhd_pub_t *dhdp, uint16 rsn) { }
|
||||
static INLINE void dhd_dump_pkt_init(dhd_pub_t *dhdp) { }
|
||||
static INLINE void dhd_dump_pkt_deinit(dhd_pub_t *dhdp) { }
|
||||
static INLINE void dhd_dump_pkt_clear(dhd_pub_t *dhdp) { }
|
||||
#endif /* DHD_PKTDUMP_ROAM */
|
||||
|
||||
/* Rx packet dump */
|
||||
#ifdef DHD_TRX_DUMP
|
||||
extern void dhd_trx_pkt_dump(dhd_pub_t *dhdp, int ifidx,
|
||||
uint8 *pktdata, uint32 pktlen, bool tx);
|
||||
#else
|
||||
static INLINE void dhd_trx_pkt_dump(dhd_pub_t *dhdp, int ifidx,
|
||||
uint8 *pktdata, uint32 pktlen, bool tx) { }
|
||||
#endif /* DHD_TRX_DUMP */
|
||||
|
||||
/* DHCP packet dump */
|
||||
#ifdef DHD_DHCP_DUMP
|
||||
extern void dhd_dhcp_dump(dhd_pub_t *dhdp, int ifidx, uint8 *pktdata, bool tx,
|
||||
uint32 *pkthash, uint16 *pktfate);
|
||||
#else
|
||||
static INLINE void dhd_dhcp_dump(dhd_pub_t *dhdp, int ifidx,
|
||||
uint8 *pktdata, bool tx, uint32 *pkthash, uint16 *pktfate) { }
|
||||
#endif /* DHD_DHCP_DUMP */
|
||||
|
||||
/* DNS packet dump */
|
||||
#ifdef DHD_DNS_DUMP
|
||||
extern void dhd_dns_dump(dhd_pub_t *dhdp, int ifidx, uint8 *pktdata, bool tx,
|
||||
uint32 *pkthash, uint16 *pktfate);
|
||||
#else
|
||||
static INLINE void dhd_dns_dump(dhd_pub_t *dhdp, int ifidx,
|
||||
uint8 *pktdata, bool tx, uint32 *pkthash, uint16 *pktfate) { }
|
||||
#endif /* DHD_DNS_DUMP */
|
||||
|
||||
/* ICMP packet dump */
|
||||
#ifdef DHD_ICMP_DUMP
|
||||
extern void dhd_icmp_dump(dhd_pub_t *dhdp, int ifidx, uint8 *pktdata, bool tx,
|
||||
uint32 *pkthash, uint16 *pktfate);
|
||||
#else
|
||||
static INLINE void dhd_icmp_dump(dhd_pub_t *dhdp, int ifidx,
|
||||
uint8 *pktdata, bool tx, uint32 *pkthash, uint16 *pktfate) { }
|
||||
#endif /* DHD_ICMP_DUMP */
|
||||
|
||||
/* ARP packet dump */
|
||||
#ifdef DHD_ARP_DUMP
|
||||
extern void dhd_arp_dump(dhd_pub_t *dhdp, int ifidx, uint8 *pktdata, bool tx,
|
||||
uint32 *pkthash, uint16 *pktfate);
|
||||
#else
|
||||
static INLINE void dhd_arp_dump(dhd_pub_t *dhdp, int ifidx,
|
||||
uint8 *pktdata, bool tx, uint32 *pkthash, uint16 *pktfate) { }
|
||||
#endif /* DHD_ARP_DUMP */
|
||||
|
||||
/* 802.1X packet dump */
|
||||
#ifdef DHD_8021X_DUMP
|
||||
extern void dhd_dump_eapol_message(dhd_pub_t *dhd, int ifidx,
|
||||
uint8 *pktdata, uint32 pktlen, bool tx, uint32 *pkthash, uint16 *pktfate);
|
||||
#else
|
||||
static INLINE void dhd_dump_eapol_message(dhd_pub_t *dhd, int ifidx,
|
||||
uint8 *pktdata, uint32 pktlen, bool tx, uint32 *pkthash, uint16 *pktfate) { }
|
||||
#endif /* DHD_8021X_DUMP */
|
||||
|
||||
#endif /* __DHD_LINUX_PKTDUMP_H_ */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,432 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* DHD Linux header file - contains private structure definition of the Linux specific layer
|
||||
*
|
||||
* Copyright (C) 1999-2019, 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.
|
||||
*
|
||||
* Notwithstanding the above, under no circumstances may you combine this
|
||||
* software in any way with any other Broadcom software provided under a license
|
||||
* other than the GPL, without Broadcom's express prior written consent.
|
||||
*
|
||||
*
|
||||
* <<Broadcom-WL-IPTag/Open:>>
|
||||
*
|
||||
* $Id: dhd_linux_priv.h 815919 2019-04-22 09:06:50Z $
|
||||
*/
|
||||
|
||||
#ifndef __DHD_LINUX_PRIV_H__
|
||||
#define __DHD_LINUX_PRIV_H__
|
||||
|
||||
#include <osl.h>
|
||||
|
||||
#ifdef SHOW_LOGTRACE
|
||||
#include <linux/syscalls.h>
|
||||
#include <event_log.h>
|
||||
#endif /* SHOW_LOGTRACE */
|
||||
#include <linux/skbuff.h>
|
||||
#include <linux/spinlock.h>
|
||||
#ifdef CONFIG_COMPAT
|
||||
#include <linux/compat.h>
|
||||
#endif /* CONFIG COMPAT */
|
||||
#include <dngl_stats.h>
|
||||
#include <dhd.h>
|
||||
#include <dhd_dbg.h>
|
||||
#include <dhd_debug.h>
|
||||
#include <dhd_linux.h>
|
||||
#include <dhd_bus.h>
|
||||
|
||||
#ifdef PCIE_FULL_DONGLE
|
||||
#include <bcmmsgbuf.h>
|
||||
#include <dhd_flowring.h>
|
||||
#endif /* PCIE_FULL_DONGLE */
|
||||
|
||||
/*
|
||||
* Do not include this header except for the dhd_linux.c dhd_linux_sysfs.c
|
||||
* Local private structure (extension of pub)
|
||||
*/
|
||||
typedef struct dhd_info {
|
||||
#if defined(WL_WIRELESS_EXT)
|
||||
wl_iw_t iw; /* wireless extensions state (must be first) */
|
||||
#endif /* defined(WL_WIRELESS_EXT) */
|
||||
dhd_pub_t pub;
|
||||
/* for supporting multiple interfaces.
|
||||
* static_ifs hold the net ifaces without valid FW IF
|
||||
*/
|
||||
dhd_if_t *iflist[DHD_MAX_IFS + DHD_MAX_STATIC_IFS];
|
||||
|
||||
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 conf_path[PATH_MAX]; /* path to config vars file */
|
||||
#ifdef DHD_UCODE_DOWNLOAD
|
||||
char uc_path[PATH_MAX]; /* path to ucode image */
|
||||
#endif /* DHD_UCODE_DOWNLOAD */
|
||||
|
||||
/* serialize dhd iovars */
|
||||
struct mutex dhd_iovar_mutex;
|
||||
|
||||
struct semaphore proto_sem;
|
||||
#ifdef PROP_TXSTATUS
|
||||
spinlock_t wlfc_spinlock;
|
||||
|
||||
#ifdef BCMDBUS
|
||||
ulong wlfc_lock_flags;
|
||||
ulong wlfc_pub_lock_flags;
|
||||
#endif /* BCMDBUS */
|
||||
#endif /* PROP_TXSTATUS */
|
||||
wait_queue_head_t ioctl_resp_wait;
|
||||
wait_queue_head_t d3ack_wait;
|
||||
wait_queue_head_t dhd_bus_busy_state_wait;
|
||||
wait_queue_head_t dmaxfer_wait;
|
||||
uint32 default_wd_interval;
|
||||
|
||||
timer_list_compat_t timer;
|
||||
bool wd_timer_valid;
|
||||
struct tasklet_struct tasklet;
|
||||
spinlock_t sdlock;
|
||||
spinlock_t txqlock;
|
||||
spinlock_t dhd_lock;
|
||||
#ifdef BCMDBUS
|
||||
ulong txqlock_flags;
|
||||
#else
|
||||
|
||||
struct semaphore sdsem;
|
||||
tsk_ctl_t thr_dpc_ctl;
|
||||
tsk_ctl_t thr_wdt_ctl;
|
||||
#endif /* BCMDBUS */
|
||||
|
||||
tsk_ctl_t thr_rxf_ctl;
|
||||
spinlock_t rxf_lock;
|
||||
bool rxthread_enabled;
|
||||
|
||||
/* Wakelocks */
|
||||
#if defined(CONFIG_HAS_WAKELOCK)
|
||||
struct wake_lock wl_wifi; /* Wifi wakelock */
|
||||
struct wake_lock wl_rxwake; /* Wifi rx wakelock */
|
||||
struct wake_lock wl_ctrlwake; /* Wifi ctrl wakelock */
|
||||
struct wake_lock wl_wdwake; /* Wifi wd wakelock */
|
||||
struct wake_lock wl_evtwake; /* Wifi event wakelock */
|
||||
struct wake_lock wl_pmwake; /* Wifi pm handler wakelock */
|
||||
struct wake_lock wl_txflwake; /* Wifi tx flow wakelock */
|
||||
#ifdef BCMPCIE_OOB_HOST_WAKE
|
||||
struct wake_lock wl_intrwake; /* Host wakeup wakelock */
|
||||
#endif /* BCMPCIE_OOB_HOST_WAKE */
|
||||
#ifdef DHD_USE_SCAN_WAKELOCK
|
||||
struct wake_lock wl_scanwake; /* Wifi scan wakelock */
|
||||
#endif /* DHD_USE_SCAN_WAKELOCK */
|
||||
#endif /* CONFIG_HAS_WAKELOCK */
|
||||
|
||||
/* 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)
|
||||
struct mutex dhd_apf_mutex;
|
||||
#endif /* PKT_FILTER_SUPPORT && APF */
|
||||
spinlock_t wakelock_spinlock;
|
||||
spinlock_t wakelock_evt_spinlock;
|
||||
uint32 wakelock_counter;
|
||||
int wakelock_wd_counter;
|
||||
int wakelock_rx_timeout_enable;
|
||||
int wakelock_ctrl_timeout_enable;
|
||||
bool waive_wakelock;
|
||||
uint32 wakelock_before_waive;
|
||||
|
||||
/* Thread to issue ioctl for multicast */
|
||||
wait_queue_head_t ctrl_wait;
|
||||
atomic_t pend_8021x_cnt;
|
||||
dhd_attach_states_t dhd_state;
|
||||
#ifdef SHOW_LOGTRACE
|
||||
dhd_event_log_t event_data;
|
||||
#endif /* SHOW_LOGTRACE */
|
||||
|
||||
#if defined(CONFIG_HAS_EARLYSUSPEND) && defined(DHD_USE_EARLYSUSPEND)
|
||||
struct early_suspend early_suspend;
|
||||
#endif /* CONFIG_HAS_EARLYSUSPEND && DHD_USE_EARLYSUSPEND */
|
||||
|
||||
#ifdef ARP_OFFLOAD_SUPPORT
|
||||
u32 pend_ipaddr;
|
||||
#endif /* ARP_OFFLOAD_SUPPORT */
|
||||
#ifdef DHDTCPACK_SUPPRESS
|
||||
spinlock_t tcpack_lock;
|
||||
#endif /* DHDTCPACK_SUPPRESS */
|
||||
#ifdef FIX_CPU_MIN_CLOCK
|
||||
bool cpufreq_fix_status;
|
||||
struct mutex cpufreq_fix;
|
||||
struct pm_qos_request dhd_cpu_qos;
|
||||
#ifdef FIX_BUS_MIN_CLOCK
|
||||
struct pm_qos_request dhd_bus_qos;
|
||||
#endif /* FIX_BUS_MIN_CLOCK */
|
||||
#endif /* FIX_CPU_MIN_CLOCK */
|
||||
void *dhd_deferred_wq;
|
||||
#ifdef DEBUG_CPU_FREQ
|
||||
struct notifier_block freq_trans;
|
||||
int __percpu *new_freq;
|
||||
#endif // endif
|
||||
unsigned int unit;
|
||||
struct notifier_block pm_notifier;
|
||||
#ifdef DHD_PSTA
|
||||
uint32 psta_mode; /* PSTA or PSR */
|
||||
#endif /* DHD_PSTA */
|
||||
#ifdef DHD_WET
|
||||
uint32 wet_mode;
|
||||
#endif /* DHD_WET */
|
||||
#ifdef DHD_DEBUG
|
||||
dhd_dump_t *dump;
|
||||
struct timer_list join_timer;
|
||||
u32 join_timeout_val;
|
||||
bool join_timer_active;
|
||||
uint scan_time_count;
|
||||
struct timer_list scan_timer;
|
||||
bool scan_timer_active;
|
||||
#endif // endif
|
||||
#if defined(DHD_LB)
|
||||
/* CPU Load Balance dynamic CPU selection */
|
||||
|
||||
/* Variable that tracks the currect CPUs available for candidacy */
|
||||
cpumask_var_t cpumask_curr_avail;
|
||||
|
||||
/* Primary and secondary CPU mask */
|
||||
cpumask_var_t cpumask_primary, cpumask_secondary; /* configuration */
|
||||
cpumask_var_t cpumask_primary_new, cpumask_secondary_new; /* temp */
|
||||
|
||||
struct notifier_block cpu_notifier;
|
||||
|
||||
/* Tasklet to handle Tx Completion packet freeing */
|
||||
struct tasklet_struct tx_compl_tasklet;
|
||||
atomic_t tx_compl_cpu;
|
||||
|
||||
/* Tasklet to handle RxBuf Post during Rx completion */
|
||||
struct tasklet_struct rx_compl_tasklet;
|
||||
atomic_t rx_compl_cpu;
|
||||
|
||||
/* Napi struct for handling rx packet sendup. Packets are removed from
|
||||
* H2D RxCompl ring and placed into rx_pend_queue. rx_pend_queue is then
|
||||
* appended to rx_napi_queue (w/ lock) and the rx_napi_struct is scheduled
|
||||
* to run to rx_napi_cpu.
|
||||
*/
|
||||
struct sk_buff_head rx_pend_queue ____cacheline_aligned;
|
||||
struct sk_buff_head rx_napi_queue ____cacheline_aligned;
|
||||
struct napi_struct rx_napi_struct ____cacheline_aligned;
|
||||
atomic_t rx_napi_cpu; /* cpu on which the napi is dispatched */
|
||||
struct net_device *rx_napi_netdev; /* netdev of primary interface */
|
||||
|
||||
struct work_struct rx_napi_dispatcher_work;
|
||||
struct work_struct tx_compl_dispatcher_work;
|
||||
struct work_struct tx_dispatcher_work;
|
||||
struct work_struct rx_compl_dispatcher_work;
|
||||
|
||||
/* Number of times DPC Tasklet ran */
|
||||
uint32 dhd_dpc_cnt;
|
||||
/* Number of times NAPI processing got scheduled */
|
||||
uint32 napi_sched_cnt;
|
||||
/* Number of times NAPI processing ran on each available core */
|
||||
uint32 *napi_percpu_run_cnt;
|
||||
/* Number of times RX Completions got scheduled */
|
||||
uint32 rxc_sched_cnt;
|
||||
/* Number of times RX Completion ran on each available core */
|
||||
uint32 *rxc_percpu_run_cnt;
|
||||
/* Number of times TX Completions got scheduled */
|
||||
uint32 txc_sched_cnt;
|
||||
/* Number of times TX Completions ran on each available core */
|
||||
uint32 *txc_percpu_run_cnt;
|
||||
/* CPU status */
|
||||
/* Number of times each CPU came online */
|
||||
uint32 *cpu_online_cnt;
|
||||
/* Number of times each CPU went offline */
|
||||
uint32 *cpu_offline_cnt;
|
||||
|
||||
/* Number of times TX processing run on each core */
|
||||
uint32 *txp_percpu_run_cnt;
|
||||
/* Number of times TX start run on each core */
|
||||
uint32 *tx_start_percpu_run_cnt;
|
||||
|
||||
/* Tx load balancing */
|
||||
|
||||
/* TODO: Need to see if batch processing is really required in case of TX
|
||||
* processing. In case of RX the Dongle can send a bunch of rx completions,
|
||||
* hence we took a 3 queue approach
|
||||
* enque - adds the skbs to rx_pend_queue
|
||||
* dispatch - uses a lock and adds the list of skbs from pend queue to
|
||||
* napi queue
|
||||
* napi processing - copies the pend_queue into a local queue and works
|
||||
* on it.
|
||||
* But for TX its going to be 1 skb at a time, so we are just thinking
|
||||
* of using only one queue and use the lock supported skb queue functions
|
||||
* to add and process it. If its in-efficient we'll re-visit the queue
|
||||
* design.
|
||||
*/
|
||||
|
||||
/* When the NET_TX tries to send a TX packet put it into tx_pend_queue */
|
||||
/* struct sk_buff_head tx_pend_queue ____cacheline_aligned; */
|
||||
/*
|
||||
* From the Tasklet that actually sends out data
|
||||
* copy the list tx_pend_queue into tx_active_queue. There by we need
|
||||
* to spinlock to only perform the copy the rest of the code ie to
|
||||
* construct the tx_pend_queue and the code to process tx_active_queue
|
||||
* can be lockless. The concept is borrowed as is from RX processing
|
||||
*/
|
||||
/* struct sk_buff_head tx_active_queue ____cacheline_aligned; */
|
||||
|
||||
/* Control TXP in runtime, enable by default */
|
||||
atomic_t lb_txp_active;
|
||||
|
||||
/* Control RXP in runtime, enable by default */
|
||||
atomic_t lb_rxp_active;
|
||||
|
||||
/*
|
||||
* When the NET_TX tries to send a TX packet put it into tx_pend_queue
|
||||
* For now, the processing tasklet will also direcly operate on this
|
||||
* queue
|
||||
*/
|
||||
struct sk_buff_head tx_pend_queue ____cacheline_aligned;
|
||||
|
||||
/* Control RXP in runtime, enable by default */
|
||||
/* cpu on which the DHD Tx is happenning */
|
||||
atomic_t tx_cpu;
|
||||
|
||||
/* CPU on which the Network stack is calling the DHD's xmit function */
|
||||
atomic_t net_tx_cpu;
|
||||
|
||||
/* Tasklet context from which the DHD's TX processing happens */
|
||||
struct tasklet_struct tx_tasklet;
|
||||
|
||||
/*
|
||||
* Consumer Histogram - NAPI RX Packet processing
|
||||
* -----------------------------------------------
|
||||
* On Each CPU, when the NAPI RX Packet processing call back was invoked
|
||||
* how many packets were processed is captured in this data structure.
|
||||
* Now its difficult to capture the "exact" number of packets processed.
|
||||
* So considering the packet counter to be a 32 bit one, we have a
|
||||
* bucket with 8 bins (2^1, 2^2 ... 2^8). The "number" of packets
|
||||
* processed is rounded off to the next power of 2 and put in the
|
||||
* approriate "bin" the value in the bin gets incremented.
|
||||
* For example, assume that in CPU 1 if NAPI Rx runs 3 times
|
||||
* and the packet count processed is as follows (assume the bin counters are 0)
|
||||
* iteration 1 - 10 (the bin counter 2^4 increments to 1)
|
||||
* iteration 2 - 30 (the bin counter 2^5 increments to 1)
|
||||
* iteration 3 - 15 (the bin counter 2^4 increments by 1 to become 2)
|
||||
*/
|
||||
uint32 *napi_rx_hist[HIST_BIN_SIZE];
|
||||
uint32 *txc_hist[HIST_BIN_SIZE];
|
||||
uint32 *rxc_hist[HIST_BIN_SIZE];
|
||||
#endif /* DHD_LB */
|
||||
#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 */
|
||||
#ifdef SHOW_LOGTRACE
|
||||
#ifdef DHD_USE_KTHREAD_FOR_LOGTRACE
|
||||
tsk_ctl_t thr_logtrace_ctl;
|
||||
#else
|
||||
struct delayed_work event_log_dispatcher_work;
|
||||
#endif /* DHD_USE_KTHREAD_FOR_LOGTRACE */
|
||||
#endif /* SHOW_LOGTRACE */
|
||||
|
||||
#if defined(BCM_DNGL_EMBEDIMAGE) || defined(BCM_REQUEST_FW)
|
||||
#endif /* defined(BCM_DNGL_EMBEDIMAGE) || defined(BCM_REQUEST_FW) */
|
||||
struct kobject dhd_kobj;
|
||||
struct kobject dhd_conf_file_kobj;
|
||||
struct timer_list timesync_timer;
|
||||
#if defined(BT_OVER_SDIO)
|
||||
char btfw_path[PATH_MAX];
|
||||
#endif /* defined (BT_OVER_SDIO) */
|
||||
#ifdef WL_MONITOR
|
||||
struct net_device *monitor_dev; /* monitor pseudo device */
|
||||
struct sk_buff *monitor_skb;
|
||||
uint monitor_len;
|
||||
uint monitor_type; /* monitor pseudo device */
|
||||
#endif /* WL_MONITOR */
|
||||
#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 */
|
||||
#ifdef SHOW_LOGTRACE
|
||||
struct sk_buff_head evt_trace_queue ____cacheline_aligned;
|
||||
#endif // endif
|
||||
#ifdef DHD_PCIE_NATIVE_RUNTIMEPM
|
||||
struct workqueue_struct *tx_wq;
|
||||
struct workqueue_struct *rx_wq;
|
||||
#endif /* DHD_PCIE_NATIVE_RUNTIMEPM */
|
||||
#ifdef DHD_DEBUG_UART
|
||||
bool duart_execute;
|
||||
#endif /* DHD_DEBUG_UART */
|
||||
struct mutex logdump_lock;
|
||||
/* indicates mem_dump was scheduled as work queue or called directly */
|
||||
bool scheduled_memdump;
|
||||
struct work_struct dhd_hang_process_work;
|
||||
#ifdef DHD_HP2P
|
||||
spinlock_t hp2p_lock;
|
||||
#endif /* DHD_HP2P */
|
||||
} dhd_info_t;
|
||||
|
||||
extern int dhd_sysfs_init(dhd_info_t *dhd);
|
||||
extern void dhd_sysfs_exit(dhd_info_t *dhd);
|
||||
extern void dhd_dbg_ring_proc_create(dhd_pub_t *dhdp);
|
||||
extern void dhd_dbg_ring_proc_destroy(dhd_pub_t *dhdp);
|
||||
|
||||
int __dhd_sendpkt(dhd_pub_t *dhdp, int ifidx, void *pktbuf);
|
||||
|
||||
#if defined(DHD_LB)
|
||||
#if defined(DHD_LB_TXP)
|
||||
int dhd_lb_sendpkt(dhd_info_t *dhd, struct net_device *net, int ifidx, void *skb);
|
||||
void dhd_tx_dispatcher_work(struct work_struct * work);
|
||||
void dhd_tx_dispatcher_fn(dhd_pub_t *dhdp);
|
||||
void dhd_lb_tx_dispatch(dhd_pub_t *dhdp);
|
||||
void dhd_lb_tx_handler(unsigned long data);
|
||||
#endif /* DHD_LB_TXP */
|
||||
|
||||
#if defined(DHD_LB_RXP)
|
||||
int dhd_napi_poll(struct napi_struct *napi, int budget);
|
||||
void dhd_rx_napi_dispatcher_fn(struct work_struct * work);
|
||||
void dhd_lb_rx_napi_dispatch(dhd_pub_t *dhdp);
|
||||
void dhd_lb_rx_pkt_enqueue(dhd_pub_t *dhdp, void *pkt, int ifidx);
|
||||
#endif /* DHD_LB_RXP */
|
||||
|
||||
void dhd_lb_set_default_cpus(dhd_info_t *dhd);
|
||||
void dhd_cpumasks_deinit(dhd_info_t *dhd);
|
||||
int dhd_cpumasks_init(dhd_info_t *dhd);
|
||||
|
||||
void dhd_select_cpu_candidacy(dhd_info_t *dhd);
|
||||
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0))
|
||||
int dhd_cpu_startup_callback(unsigned int cpu);
|
||||
int dhd_cpu_teardown_callback(unsigned int cpu);
|
||||
#else
|
||||
int dhd_cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu);
|
||||
#endif /* LINUX_VERSION_CODE < 4.10.0 */
|
||||
|
||||
int dhd_register_cpuhp_callback(dhd_info_t *dhd);
|
||||
int dhd_unregister_cpuhp_callback(dhd_info_t *dhd);
|
||||
|
||||
#if defined(DHD_LB_TXC)
|
||||
void dhd_lb_tx_compl_dispatch(dhd_pub_t *dhdp);
|
||||
#endif /* DHD_LB_TXC */
|
||||
|
||||
#if defined(DHD_LB_RXC)
|
||||
void dhd_lb_rx_compl_dispatch(dhd_pub_t *dhdp);
|
||||
void dhd_rx_compl_dispatcher_fn(struct work_struct * work);
|
||||
#endif /* DHD_LB_RXC */
|
||||
|
||||
#endif /* DHD_LB */
|
||||
|
||||
#if defined(DHD_LB_IRQSET) || defined(DHD_CONTROL_PCIE_CPUCORE_WIFI_TURNON)
|
||||
void dhd_irq_set_affinity(dhd_pub_t *dhdp, const struct cpumask *cpumask);
|
||||
#endif /* DHD_LB_IRQSET || DHD_CONTROL_PCIE_CPUCORE_WIFI_TURNON */
|
||||
|
||||
#endif /* __DHD_LINUX_PRIV_H__ */
|
||||
@@ -0,0 +1,48 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Expose some of the kernel scheduler routines
|
||||
*
|
||||
* Copyright (C) 1999-2019, 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.
|
||||
*
|
||||
* Notwithstanding the above, under no circumstances may you combine this
|
||||
* software in any way with any other Broadcom software provided under a license
|
||||
* other than the GPL, without Broadcom's express prior written consent.
|
||||
*
|
||||
*
|
||||
* <<Broadcom-WL-IPTag/Open:>>
|
||||
*
|
||||
* $Id: dhd_linux_sched.c 815919 2019-04-22 09:06:50Z $
|
||||
*/
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/sched.h>
|
||||
#include <typedefs.h>
|
||||
#include <linuxver.h>
|
||||
|
||||
int setScheduler(struct task_struct *p, int policy, struct sched_param *param)
|
||||
{
|
||||
int rc = 0;
|
||||
rc = sched_setscheduler(p, policy, param);
|
||||
return rc;
|
||||
}
|
||||
|
||||
int get_scheduler_policy(struct task_struct *p)
|
||||
{
|
||||
int rc = SCHED_NORMAL;
|
||||
rc = p->policy;
|
||||
return rc;
|
||||
}
|
||||
@@ -0,0 +1,397 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Broadcom Dongle Host Driver (DHD), Generic work queue framework
|
||||
* Generic interface to handle dhd deferred work events
|
||||
*
|
||||
* Copyright (C) 1999-2019, 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.
|
||||
*
|
||||
* Notwithstanding the above, under no circumstances may you combine this
|
||||
* software in any way with any other Broadcom software provided under a license
|
||||
* other than the GPL, without Broadcom's express prior written consent.
|
||||
*
|
||||
*
|
||||
* <<Broadcom-WL-IPTag/Open:>>
|
||||
*
|
||||
* $Id: dhd_linux_wq.c 815919 2019-04-22 09:06:50Z $
|
||||
*/
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/fcntl.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/ip.h>
|
||||
#include <linux/kfifo.h>
|
||||
|
||||
#include <linuxver.h>
|
||||
#include <osl.h>
|
||||
#include <bcmutils.h>
|
||||
#include <bcmendian.h>
|
||||
#include <bcmdevs.h>
|
||||
#include <dngl_stats.h>
|
||||
#include <dhd.h>
|
||||
#include <dhd_dbg.h>
|
||||
#include <dhd_linux_wq.h>
|
||||
|
||||
typedef struct dhd_deferred_event {
|
||||
u8 event; /* holds the event */
|
||||
void *event_data; /* holds event specific data */
|
||||
event_handler_t event_handler;
|
||||
unsigned long pad; /* for memory alignment to power of 2 */
|
||||
} dhd_deferred_event_t;
|
||||
|
||||
#define DEFRD_EVT_SIZE (sizeof(dhd_deferred_event_t))
|
||||
|
||||
/*
|
||||
* work events may occur simultaneously.
|
||||
* can hold upto 64 low priority events and 16 high priority events
|
||||
*/
|
||||
#define DHD_PRIO_WORK_FIFO_SIZE (16 * DEFRD_EVT_SIZE)
|
||||
#define DHD_WORK_FIFO_SIZE (64 * DEFRD_EVT_SIZE)
|
||||
|
||||
#define DHD_FIFO_HAS_FREE_SPACE(fifo) \
|
||||
((fifo) && (kfifo_avail(fifo) >= DEFRD_EVT_SIZE))
|
||||
#define DHD_FIFO_HAS_ENOUGH_DATA(fifo) \
|
||||
((fifo) && (kfifo_len(fifo) >= DEFRD_EVT_SIZE))
|
||||
|
||||
struct dhd_deferred_wq {
|
||||
struct work_struct deferred_work; /* should be the first member */
|
||||
|
||||
struct kfifo *prio_fifo;
|
||||
struct kfifo *work_fifo;
|
||||
u8 *prio_fifo_buf;
|
||||
u8 *work_fifo_buf;
|
||||
spinlock_t work_lock;
|
||||
void *dhd_info; /* review: does it require */
|
||||
u32 event_skip_mask;
|
||||
};
|
||||
|
||||
static inline struct kfifo*
|
||||
dhd_kfifo_init(u8 *buf, int size, spinlock_t *lock)
|
||||
{
|
||||
struct kfifo *fifo;
|
||||
gfp_t flags = CAN_SLEEP()? GFP_KERNEL : GFP_ATOMIC;
|
||||
|
||||
fifo = (struct kfifo *)kzalloc(sizeof(struct kfifo), flags);
|
||||
if (!fifo) {
|
||||
return NULL;
|
||||
}
|
||||
kfifo_init(fifo, buf, size);
|
||||
return fifo;
|
||||
}
|
||||
|
||||
static inline void
|
||||
dhd_kfifo_free(struct kfifo *fifo)
|
||||
{
|
||||
kfifo_free(fifo);
|
||||
}
|
||||
|
||||
/* deferred work functions */
|
||||
static void dhd_deferred_work_handler(struct work_struct *data);
|
||||
|
||||
void*
|
||||
dhd_deferred_work_init(void *dhd_info)
|
||||
{
|
||||
struct dhd_deferred_wq *work = NULL;
|
||||
u8* buf;
|
||||
unsigned long fifo_size = 0;
|
||||
gfp_t flags = CAN_SLEEP()? GFP_KERNEL : GFP_ATOMIC;
|
||||
|
||||
if (!dhd_info) {
|
||||
DHD_ERROR(("%s: dhd info not initialized\n", __FUNCTION__));
|
||||
goto return_null;
|
||||
}
|
||||
|
||||
work = (struct dhd_deferred_wq *)kzalloc(sizeof(struct dhd_deferred_wq),
|
||||
flags);
|
||||
if (!work) {
|
||||
DHD_ERROR(("%s: work queue creation failed\n", __FUNCTION__));
|
||||
goto return_null;
|
||||
}
|
||||
|
||||
INIT_WORK((struct work_struct *)work, dhd_deferred_work_handler);
|
||||
|
||||
/* initialize event fifo */
|
||||
spin_lock_init(&work->work_lock);
|
||||
|
||||
/* allocate buffer to hold prio events */
|
||||
fifo_size = DHD_PRIO_WORK_FIFO_SIZE;
|
||||
fifo_size = is_power_of_2(fifo_size) ? fifo_size :
|
||||
roundup_pow_of_two(fifo_size);
|
||||
buf = (u8*)kzalloc(fifo_size, flags);
|
||||
if (!buf) {
|
||||
DHD_ERROR(("%s: prio work fifo allocation failed\n",
|
||||
__FUNCTION__));
|
||||
goto return_null;
|
||||
}
|
||||
|
||||
/* Initialize prio event fifo */
|
||||
work->prio_fifo = dhd_kfifo_init(buf, fifo_size, &work->work_lock);
|
||||
if (!work->prio_fifo) {
|
||||
kfree(buf);
|
||||
goto return_null;
|
||||
}
|
||||
|
||||
/* allocate buffer to hold work events */
|
||||
fifo_size = DHD_WORK_FIFO_SIZE;
|
||||
fifo_size = is_power_of_2(fifo_size) ? fifo_size :
|
||||
roundup_pow_of_two(fifo_size);
|
||||
buf = (u8*)kzalloc(fifo_size, flags);
|
||||
if (!buf) {
|
||||
DHD_ERROR(("%s: work fifo allocation failed\n", __FUNCTION__));
|
||||
goto return_null;
|
||||
}
|
||||
|
||||
/* Initialize event fifo */
|
||||
work->work_fifo = dhd_kfifo_init(buf, fifo_size, &work->work_lock);
|
||||
if (!work->work_fifo) {
|
||||
kfree(buf);
|
||||
goto return_null;
|
||||
}
|
||||
|
||||
work->dhd_info = dhd_info;
|
||||
work->event_skip_mask = 0;
|
||||
DHD_ERROR(("%s: work queue initialized\n", __FUNCTION__));
|
||||
return work;
|
||||
|
||||
return_null:
|
||||
if (work) {
|
||||
dhd_deferred_work_deinit(work);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
dhd_deferred_work_deinit(void *work)
|
||||
{
|
||||
struct dhd_deferred_wq *deferred_work = work;
|
||||
|
||||
if (!deferred_work) {
|
||||
DHD_ERROR(("%s: deferred work has been freed already\n",
|
||||
__FUNCTION__));
|
||||
return;
|
||||
}
|
||||
|
||||
/* cancel the deferred work handling */
|
||||
cancel_work_sync((struct work_struct *)deferred_work);
|
||||
|
||||
/*
|
||||
* free work event fifo.
|
||||
* kfifo_free frees locally allocated fifo buffer
|
||||
*/
|
||||
if (deferred_work->prio_fifo) {
|
||||
dhd_kfifo_free(deferred_work->prio_fifo);
|
||||
}
|
||||
|
||||
if (deferred_work->work_fifo) {
|
||||
dhd_kfifo_free(deferred_work->work_fifo);
|
||||
}
|
||||
|
||||
kfree(deferred_work);
|
||||
}
|
||||
|
||||
/* select kfifo according to priority */
|
||||
static inline struct kfifo *
|
||||
dhd_deferred_work_select_kfifo(struct dhd_deferred_wq *deferred_wq,
|
||||
u8 priority)
|
||||
{
|
||||
if (priority == DHD_WQ_WORK_PRIORITY_HIGH) {
|
||||
return deferred_wq->prio_fifo;
|
||||
} else if (priority == DHD_WQ_WORK_PRIORITY_LOW) {
|
||||
return deferred_wq->work_fifo;
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Prepares event to be queued
|
||||
* Schedules the event
|
||||
*/
|
||||
int
|
||||
dhd_deferred_schedule_work(void *workq, void *event_data, u8 event,
|
||||
event_handler_t event_handler, u8 priority)
|
||||
{
|
||||
struct dhd_deferred_wq *deferred_wq = (struct dhd_deferred_wq *)workq;
|
||||
struct kfifo *fifo;
|
||||
dhd_deferred_event_t deferred_event;
|
||||
int bytes_copied = 0;
|
||||
|
||||
if (!deferred_wq) {
|
||||
DHD_ERROR(("%s: work queue not initialized\n", __FUNCTION__));
|
||||
ASSERT(0);
|
||||
return DHD_WQ_STS_UNINITIALIZED;
|
||||
}
|
||||
|
||||
if (!event || (event >= DHD_MAX_WQ_EVENTS)) {
|
||||
DHD_ERROR(("%s: unknown event, event=%d\n", __FUNCTION__,
|
||||
event));
|
||||
return DHD_WQ_STS_UNKNOWN_EVENT;
|
||||
}
|
||||
|
||||
if (!priority || (priority >= DHD_WQ_MAX_PRIORITY)) {
|
||||
DHD_ERROR(("%s: unknown priority, priority=%d\n",
|
||||
__FUNCTION__, priority));
|
||||
return DHD_WQ_STS_UNKNOWN_PRIORITY;
|
||||
}
|
||||
|
||||
if ((deferred_wq->event_skip_mask & (1 << event))) {
|
||||
DHD_ERROR(("%s: Skip event requested. Mask = 0x%x\n",
|
||||
__FUNCTION__, deferred_wq->event_skip_mask));
|
||||
return DHD_WQ_STS_EVENT_SKIPPED;
|
||||
}
|
||||
|
||||
/*
|
||||
* default element size is 1, which can be changed
|
||||
* using kfifo_esize(). Older kernel(FC11) doesn't support
|
||||
* changing element size. For compatibility changing
|
||||
* element size is not prefered
|
||||
*/
|
||||
ASSERT(kfifo_esize(deferred_wq->prio_fifo) == 1);
|
||||
ASSERT(kfifo_esize(deferred_wq->work_fifo) == 1);
|
||||
|
||||
deferred_event.event = event;
|
||||
deferred_event.event_data = event_data;
|
||||
deferred_event.event_handler = event_handler;
|
||||
|
||||
fifo = dhd_deferred_work_select_kfifo(deferred_wq, priority);
|
||||
if (DHD_FIFO_HAS_FREE_SPACE(fifo)) {
|
||||
bytes_copied = kfifo_in_spinlocked(fifo, &deferred_event,
|
||||
DEFRD_EVT_SIZE, &deferred_wq->work_lock);
|
||||
}
|
||||
if (bytes_copied != DEFRD_EVT_SIZE) {
|
||||
DHD_ERROR(("%s: failed to schedule deferred work, "
|
||||
"priority=%d, bytes_copied=%d\n", __FUNCTION__,
|
||||
priority, bytes_copied));
|
||||
return DHD_WQ_STS_SCHED_FAILED;
|
||||
}
|
||||
schedule_work((struct work_struct *)deferred_wq);
|
||||
return DHD_WQ_STS_OK;
|
||||
}
|
||||
|
||||
static bool
|
||||
dhd_get_scheduled_work(struct dhd_deferred_wq *deferred_wq,
|
||||
dhd_deferred_event_t *event)
|
||||
{
|
||||
int bytes_copied = 0;
|
||||
|
||||
if (!deferred_wq) {
|
||||
DHD_ERROR(("%s: work queue not initialized\n", __FUNCTION__));
|
||||
return DHD_WQ_STS_UNINITIALIZED;
|
||||
}
|
||||
|
||||
/*
|
||||
* default element size is 1 byte, which can be changed
|
||||
* using kfifo_esize(). Older kernel(FC11) doesn't support
|
||||
* changing element size. For compatibility changing
|
||||
* element size is not prefered
|
||||
*/
|
||||
ASSERT(kfifo_esize(deferred_wq->prio_fifo) == 1);
|
||||
ASSERT(kfifo_esize(deferred_wq->work_fifo) == 1);
|
||||
|
||||
/* handle priority work */
|
||||
if (DHD_FIFO_HAS_ENOUGH_DATA(deferred_wq->prio_fifo)) {
|
||||
bytes_copied = kfifo_out_spinlocked(deferred_wq->prio_fifo,
|
||||
event, DEFRD_EVT_SIZE, &deferred_wq->work_lock);
|
||||
}
|
||||
|
||||
/* handle normal work if priority work doesn't have enough data */
|
||||
if ((bytes_copied != DEFRD_EVT_SIZE) &&
|
||||
DHD_FIFO_HAS_ENOUGH_DATA(deferred_wq->work_fifo)) {
|
||||
bytes_copied = kfifo_out_spinlocked(deferred_wq->work_fifo,
|
||||
event, DEFRD_EVT_SIZE, &deferred_wq->work_lock);
|
||||
}
|
||||
|
||||
return (bytes_copied == DEFRD_EVT_SIZE);
|
||||
}
|
||||
|
||||
static inline void
|
||||
dhd_deferred_dump_work_event(dhd_deferred_event_t *work_event)
|
||||
{
|
||||
if (!work_event) {
|
||||
DHD_ERROR(("%s: work_event is null\n", __FUNCTION__));
|
||||
return;
|
||||
}
|
||||
|
||||
DHD_ERROR(("%s: work_event->event = %d\n", __FUNCTION__,
|
||||
work_event->event));
|
||||
DHD_ERROR(("%s: work_event->event_data = %p\n", __FUNCTION__,
|
||||
work_event->event_data));
|
||||
DHD_ERROR(("%s: work_event->event_handler = %p\n", __FUNCTION__,
|
||||
work_event->event_handler));
|
||||
}
|
||||
|
||||
/*
|
||||
* Called when work is scheduled
|
||||
*/
|
||||
static void
|
||||
dhd_deferred_work_handler(struct work_struct *work)
|
||||
{
|
||||
struct dhd_deferred_wq *deferred_work = (struct dhd_deferred_wq *)work;
|
||||
dhd_deferred_event_t work_event;
|
||||
|
||||
if (!deferred_work) {
|
||||
DHD_ERROR(("%s: work queue not initialized\n", __FUNCTION__));
|
||||
return;
|
||||
}
|
||||
|
||||
do {
|
||||
if (!dhd_get_scheduled_work(deferred_work, &work_event)) {
|
||||
DHD_TRACE(("%s: no event to handle\n", __FUNCTION__));
|
||||
break;
|
||||
}
|
||||
|
||||
if (work_event.event >= DHD_MAX_WQ_EVENTS) {
|
||||
DHD_ERROR(("%s: unknown event\n", __FUNCTION__));
|
||||
dhd_deferred_dump_work_event(&work_event);
|
||||
ASSERT(work_event.event < DHD_MAX_WQ_EVENTS);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (work_event.event_handler) {
|
||||
work_event.event_handler(deferred_work->dhd_info,
|
||||
work_event.event_data, work_event.event);
|
||||
} else {
|
||||
DHD_ERROR(("%s: event handler is null\n",
|
||||
__FUNCTION__));
|
||||
dhd_deferred_dump_work_event(&work_event);
|
||||
ASSERT(work_event.event_handler != NULL);
|
||||
}
|
||||
} while (1);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
dhd_deferred_work_set_skip(void *work, u8 event, bool set)
|
||||
{
|
||||
struct dhd_deferred_wq *deferred_wq = (struct dhd_deferred_wq *)work;
|
||||
|
||||
if (!deferred_wq || !event || (event >= DHD_MAX_WQ_EVENTS)) {
|
||||
DHD_ERROR(("%s: Invalid!!\n", __FUNCTION__));
|
||||
return;
|
||||
}
|
||||
|
||||
if (set) {
|
||||
/* Set */
|
||||
deferred_wq->event_skip_mask |= (1 << event);
|
||||
} else {
|
||||
/* Clear */
|
||||
deferred_wq->event_skip_mask &= ~(1 << event);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Broadcom Dongle Host Driver (DHD), Generic work queue framework
|
||||
* Generic interface to handle dhd deferred work events
|
||||
*
|
||||
* Copyright (C) 1999-2019, 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.
|
||||
*
|
||||
* Notwithstanding the above, under no circumstances may you combine this
|
||||
* software in any way with any other Broadcom software provided under a license
|
||||
* other than the GPL, without Broadcom's express prior written consent.
|
||||
*
|
||||
*
|
||||
* <<Broadcom-WL-IPTag/Open:>>
|
||||
*
|
||||
* $Id: dhd_linux_wq.h 814378 2019-04-11 02:21:31Z $
|
||||
*/
|
||||
#ifndef _dhd_linux_wq_h_
|
||||
#define _dhd_linux_wq_h_
|
||||
/*
|
||||
* Work event definitions
|
||||
*/
|
||||
enum _wq_event {
|
||||
DHD_WQ_WORK_IF_ADD = 1,
|
||||
DHD_WQ_WORK_IF_DEL,
|
||||
DHD_WQ_WORK_SET_MAC,
|
||||
DHD_WQ_WORK_SET_MCAST_LIST,
|
||||
DHD_WQ_WORK_IPV6_NDO,
|
||||
DHD_WQ_WORK_HANG_MSG,
|
||||
DHD_WQ_WORK_DHD_LOG_DUMP,
|
||||
DHD_WQ_WORK_PKTLOG_DUMP,
|
||||
DHD_WQ_WORK_INFORM_DHD_MON,
|
||||
DHD_WQ_WORK_EVENT_LOGTRACE,
|
||||
DHD_WQ_WORK_DMA_LB_MEM_REL,
|
||||
DHD_WQ_WORK_NATOE_EVENT,
|
||||
DHD_WQ_WORK_NATOE_IOCTL,
|
||||
DHD_WQ_WORK_MACDBG,
|
||||
DHD_WQ_WORK_DEBUG_UART_DUMP,
|
||||
DHD_WQ_WORK_GET_BIGDATA_AP,
|
||||
DHD_WQ_WORK_SOC_RAM_DUMP,
|
||||
#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_MAX_WQ_EVENTS
|
||||
};
|
||||
|
||||
/*
|
||||
* Work event priority
|
||||
*/
|
||||
enum wq_priority {
|
||||
DHD_WQ_WORK_PRIORITY_LOW = 1,
|
||||
DHD_WQ_WORK_PRIORITY_HIGH,
|
||||
DHD_WQ_MAX_PRIORITY
|
||||
};
|
||||
|
||||
/*
|
||||
* Error definitions
|
||||
*/
|
||||
#define DHD_WQ_STS_OK 0
|
||||
#define DHD_WQ_STS_FAILED -1 /* General failure */
|
||||
#define DHD_WQ_STS_UNINITIALIZED -2
|
||||
#define DHD_WQ_STS_SCHED_FAILED -3
|
||||
#define DHD_WQ_STS_UNKNOWN_EVENT -4
|
||||
#define DHD_WQ_STS_UNKNOWN_PRIORITY -5
|
||||
#define DHD_WQ_STS_EVENT_SKIPPED -6
|
||||
|
||||
typedef void (*event_handler_t)(void *handle, void *event_data, u8 event);
|
||||
|
||||
void *dhd_deferred_work_init(void *dhd);
|
||||
void dhd_deferred_work_deinit(void *workq);
|
||||
int dhd_deferred_schedule_work(void *workq, void *event_data, u8 event,
|
||||
event_handler_t evt_handler, u8 priority);
|
||||
void dhd_deferred_work_set_skip(void *work, u8 event, bool set);
|
||||
#endif /* _dhd_linux_wq_h_ */
|
||||
@@ -0,0 +1,789 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* DHD debugability support
|
||||
*
|
||||
* <<Broadcom-WL-IPTag/Open:>>
|
||||
*
|
||||
* Copyright (C) 1999-2019, 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.
|
||||
*
|
||||
* 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_mschdbg.c 639872 2016-05-25 05:39:30Z $
|
||||
*/
|
||||
#ifdef SHOW_LOGTRACE
|
||||
#include <typedefs.h>
|
||||
#include <osl.h>
|
||||
#include <bcmutils.h>
|
||||
#include <bcmendian.h>
|
||||
#include <dngl_stats.h>
|
||||
#include <dhd.h>
|
||||
#include <dhd_dbg.h>
|
||||
#include <dhd_debug.h>
|
||||
#include <dhd_mschdbg.h>
|
||||
|
||||
#include <event_log.h>
|
||||
#include <event_trace.h>
|
||||
#include <msgtrace.h>
|
||||
|
||||
static const char *head_log = "";
|
||||
#define MSCH_EVENT_HEAD(space) \
|
||||
do { \
|
||||
MSCH_EVENT(("%s_E: ", head_log)); \
|
||||
if (space > 0) { \
|
||||
int ii; \
|
||||
for (ii = 0; ii < space; ii += 4) MSCH_EVENT((" ")); \
|
||||
} \
|
||||
} while (0)
|
||||
#define MSCH_EVENT(args) do {if (dhd_msg_level & DHD_EVENT_VAL) printf args;} while (0)
|
||||
|
||||
static uint64 solt_start_time[4], req_start_time[4], profiler_start_time[4];
|
||||
static uint32 solt_chanspec[4] = {0, }, req_start[4] = {0, };
|
||||
static bool lastMessages = FALSE;
|
||||
|
||||
#define US_PRE_SEC 1000000
|
||||
#define DATA_UNIT_FOR_LOG_CNT 4
|
||||
|
||||
static void dhd_mschdbg_us_to_sec(uint32 time_h, uint32 time_l, uint32 *sec, uint32 *remain)
|
||||
{
|
||||
uint64 cur_time = ((uint64)(ntoh32(time_h)) << 32) | ntoh32(time_l);
|
||||
uint64 r, u = 0;
|
||||
|
||||
r = cur_time;
|
||||
while (time_h != 0) {
|
||||
u += (uint64)((0xffffffff / US_PRE_SEC)) * time_h;
|
||||
r = cur_time - u * US_PRE_SEC;
|
||||
time_h = (uint32)(r >> 32);
|
||||
}
|
||||
|
||||
*sec = (uint32)(u + ((uint32)(r) / US_PRE_SEC));
|
||||
*remain = (uint32)(r) % US_PRE_SEC;
|
||||
}
|
||||
|
||||
static char *dhd_mschdbg_display_time(uint32 time_h, uint32 time_l)
|
||||
{
|
||||
static char display_time[32];
|
||||
uint32 s, ss;
|
||||
|
||||
if (time_h == 0xffffffff && time_l == 0xffffffff) {
|
||||
snprintf(display_time, 31, "-1");
|
||||
} else {
|
||||
dhd_mschdbg_us_to_sec(time_h, time_l, &s, &ss);
|
||||
snprintf(display_time, 31, "%d.%06d", s, ss);
|
||||
}
|
||||
return display_time;
|
||||
}
|
||||
|
||||
static void
|
||||
dhd_mschdbg_chanspec_list(int sp, char *data, uint16 ptr, uint16 chanspec_cnt)
|
||||
{
|
||||
int i, cnt = (int)ntoh16(chanspec_cnt);
|
||||
uint16 *chanspec_list = (uint16 *)(data + ntoh16(ptr));
|
||||
char buf[CHANSPEC_STR_LEN];
|
||||
chanspec_t c;
|
||||
|
||||
MSCH_EVENT_HEAD(sp);
|
||||
MSCH_EVENT(("<chanspec_list>:"));
|
||||
for (i = 0; i < cnt; i++) {
|
||||
c = (chanspec_t)ntoh16(chanspec_list[i]);
|
||||
MSCH_EVENT((" %s", wf_chspec_ntoa(c, buf)));
|
||||
}
|
||||
MSCH_EVENT(("\n"));
|
||||
}
|
||||
|
||||
static void
|
||||
dhd_mschdbg_elem_list(int sp, char *title, char *data, uint16 ptr, uint16 list_cnt)
|
||||
{
|
||||
int i, cnt = (int)ntoh16(list_cnt);
|
||||
uint32 *list = (uint32 *)(data + ntoh16(ptr));
|
||||
|
||||
MSCH_EVENT_HEAD(sp);
|
||||
MSCH_EVENT(("%s_list: ", title));
|
||||
for (i = 0; i < cnt; i++) {
|
||||
MSCH_EVENT(("0x%08x->", ntoh32(list[i])));
|
||||
}
|
||||
MSCH_EVENT(("null\n"));
|
||||
}
|
||||
|
||||
static void
|
||||
dhd_mschdbg_req_param_profiler_event_data(int sp, int ver, char *data, uint16 ptr)
|
||||
{
|
||||
int sn = sp + 4;
|
||||
msch_req_param_profiler_event_data_t *p =
|
||||
(msch_req_param_profiler_event_data_t *)(data + ntoh16(ptr));
|
||||
uint32 type, flags;
|
||||
|
||||
MSCH_EVENT_HEAD(sp);
|
||||
MSCH_EVENT(("<request parameters>\n"));
|
||||
MSCH_EVENT_HEAD(sn);
|
||||
MSCH_EVENT(("req_type: "));
|
||||
|
||||
type = p->req_type;
|
||||
if (type < 4) {
|
||||
char *req_type[] = {"fixed", "start-flexible", "duration-flexible",
|
||||
"both-flexible"};
|
||||
MSCH_EVENT(("%s", req_type[type]));
|
||||
}
|
||||
else
|
||||
MSCH_EVENT(("unknown(%d)", type));
|
||||
|
||||
flags = ntoh16(p->flags);
|
||||
if (flags & WL_MSCH_REQ_FLAGS_CHAN_CONTIGUOUS)
|
||||
MSCH_EVENT((", CHAN_CONTIGUOUS"));
|
||||
if (flags & WL_MSCH_REQ_FLAGS_MERGE_CONT_SLOTS)
|
||||
MSCH_EVENT((", MERGE_CONT_SLOTS"));
|
||||
if (flags & WL_MSCH_REQ_FLAGS_PREMTABLE)
|
||||
MSCH_EVENT((", PREMTABLE"));
|
||||
if (flags & WL_MSCH_REQ_FLAGS_PREMT_CURTS)
|
||||
MSCH_EVENT((", PREMT_CURTS"));
|
||||
if (flags & WL_MSCH_REQ_FLAGS_PREMT_IMMEDIATE)
|
||||
MSCH_EVENT((", PREMT_IMMEDIATE"));
|
||||
MSCH_EVENT((", priority: %d\n", p->priority));
|
||||
|
||||
MSCH_EVENT_HEAD(sn);
|
||||
MSCH_EVENT(("start-time: %s, duration: %d(us), interval: %d(us)\n",
|
||||
dhd_mschdbg_display_time(p->start_time_h, p->start_time_l),
|
||||
ntoh32(p->duration), ntoh32(p->interval)));
|
||||
|
||||
if (type == WL_MSCH_RT_DUR_FLEX) {
|
||||
MSCH_EVENT_HEAD(sn);
|
||||
MSCH_EVENT(("dur_flex: %d(us)\n", ntoh32(p->flex.dur_flex)));
|
||||
} else if (type == WL_MSCH_RT_BOTH_FLEX) {
|
||||
MSCH_EVENT_HEAD(sn);
|
||||
MSCH_EVENT(("min_dur: %d(us), max_away_dur: %d(us)\n",
|
||||
ntoh32(p->flex.bf.min_dur), ntoh32(p->flex.bf.max_away_dur)));
|
||||
|
||||
MSCH_EVENT_HEAD(sn);
|
||||
MSCH_EVENT(("hi_prio_time: %s, hi_prio_interval: %d(us)\n",
|
||||
dhd_mschdbg_display_time(p->flex.bf.hi_prio_time_h,
|
||||
p->flex.bf.hi_prio_time_l),
|
||||
ntoh32(p->flex.bf.hi_prio_interval)));
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
dhd_mschdbg_timeslot_profiler_event_data(int sp, int ver, char *title, char *data,
|
||||
uint16 ptr, bool empty)
|
||||
{
|
||||
int s, sn = sp + 4;
|
||||
msch_timeslot_profiler_event_data_t *p =
|
||||
(msch_timeslot_profiler_event_data_t *)(data + ntoh16(ptr));
|
||||
char *state[] = {"NONE", "CHN_SW", "ONCHAN_FIRE", "OFF_CHN_PREP",
|
||||
"OFF_CHN_DONE", "TS_COMPLETE"};
|
||||
|
||||
MSCH_EVENT_HEAD(sp);
|
||||
MSCH_EVENT(("<%s timeslot>: ", title));
|
||||
if (empty) {
|
||||
MSCH_EVENT((" null\n"));
|
||||
return;
|
||||
}
|
||||
else
|
||||
MSCH_EVENT(("0x%08x\n", ntoh32(p->p_timeslot)));
|
||||
|
||||
s = (int)(ntoh32(p->state));
|
||||
if (s > 5) s = 0;
|
||||
|
||||
MSCH_EVENT_HEAD(sn);
|
||||
MSCH_EVENT(("id: %d, state[%d]: %s, chan_ctxt: [0x%08x]\n",
|
||||
ntoh32(p->timeslot_id), ntoh32(p->state), state[s], ntoh32(p->p_chan_ctxt)));
|
||||
|
||||
MSCH_EVENT_HEAD(sn);
|
||||
MSCH_EVENT(("fire_time: %s",
|
||||
dhd_mschdbg_display_time(p->fire_time_h, p->fire_time_l)));
|
||||
|
||||
MSCH_EVENT((", pre_start_time: %s",
|
||||
dhd_mschdbg_display_time(p->pre_start_time_h, p->pre_start_time_l)));
|
||||
|
||||
MSCH_EVENT((", end_time: %s",
|
||||
dhd_mschdbg_display_time(p->end_time_h, p->end_time_l)));
|
||||
|
||||
MSCH_EVENT((", sch_dur: %s\n",
|
||||
dhd_mschdbg_display_time(p->sch_dur_h, p->sch_dur_l)));
|
||||
}
|
||||
|
||||
static void
|
||||
dhd_mschdbg_req_timing_profiler_event_data(int sp, int ver, char *title, char *data,
|
||||
uint16 ptr, bool empty)
|
||||
{
|
||||
int sn = sp + 4;
|
||||
msch_req_timing_profiler_event_data_t *p =
|
||||
(msch_req_timing_profiler_event_data_t *)(data + ntoh16(ptr));
|
||||
uint32 type;
|
||||
|
||||
MSCH_EVENT_HEAD(sp);
|
||||
MSCH_EVENT(("<%s req_timing>: ", title));
|
||||
if (empty) {
|
||||
MSCH_EVENT((" null\n"));
|
||||
return;
|
||||
}
|
||||
else
|
||||
MSCH_EVENT(("0x%08x (prev 0x%08x, next 0x%08x)\n",
|
||||
ntoh32(p->p_req_timing), ntoh32(p->p_prev), ntoh32(p->p_next)));
|
||||
|
||||
MSCH_EVENT_HEAD(sn);
|
||||
MSCH_EVENT(("flags:"));
|
||||
type = ntoh16(p->flags);
|
||||
if ((type & 0x7f) == 0)
|
||||
MSCH_EVENT((" NONE"));
|
||||
else {
|
||||
if (type & WL_MSCH_RC_FLAGS_ONCHAN_FIRE)
|
||||
MSCH_EVENT((" ONCHAN_FIRE"));
|
||||
if (type & WL_MSCH_RC_FLAGS_START_FIRE_DONE)
|
||||
MSCH_EVENT((" START_FIRE"));
|
||||
if (type & WL_MSCH_RC_FLAGS_END_FIRE_DONE)
|
||||
MSCH_EVENT((" END_FIRE"));
|
||||
if (type & WL_MSCH_RC_FLAGS_ONFIRE_DONE)
|
||||
MSCH_EVENT((" ONFIRE_DONE"));
|
||||
if (type & WL_MSCH_RC_FLAGS_SPLIT_SLOT_START)
|
||||
MSCH_EVENT((" SPLIT_SLOT_START"));
|
||||
if (type & WL_MSCH_RC_FLAGS_SPLIT_SLOT_END)
|
||||
MSCH_EVENT((" SPLIT_SLOT_END"));
|
||||
if (type & WL_MSCH_RC_FLAGS_PRE_ONFIRE_DONE)
|
||||
MSCH_EVENT((" PRE_ONFIRE_DONE"));
|
||||
}
|
||||
MSCH_EVENT(("\n"));
|
||||
|
||||
MSCH_EVENT_HEAD(sn);
|
||||
MSCH_EVENT(("pre_start_time: %s",
|
||||
dhd_mschdbg_display_time(p->pre_start_time_h, p->pre_start_time_l)));
|
||||
|
||||
MSCH_EVENT((", start_time: %s",
|
||||
dhd_mschdbg_display_time(p->start_time_h, p->start_time_l)));
|
||||
|
||||
MSCH_EVENT((", end_time: %s\n",
|
||||
dhd_mschdbg_display_time(p->end_time_h, p->end_time_l)));
|
||||
|
||||
if (p->p_timeslot && (p->timeslot_ptr == 0)) {
|
||||
MSCH_EVENT_HEAD(sn);
|
||||
MSCH_EVENT(("<%s timeslot>: 0x%08x\n", title, ntoh32(p->p_timeslot)));
|
||||
} else
|
||||
dhd_mschdbg_timeslot_profiler_event_data(sn, ver, title, data, p->timeslot_ptr,
|
||||
(p->timeslot_ptr == 0));
|
||||
}
|
||||
|
||||
static void
|
||||
dhd_mschdbg_chan_ctxt_profiler_event_data(int sp, int ver, char *data, uint16 ptr, bool empty)
|
||||
{
|
||||
int sn = sp + 4;
|
||||
msch_chan_ctxt_profiler_event_data_t *p =
|
||||
(msch_chan_ctxt_profiler_event_data_t *)(data + ntoh16(ptr));
|
||||
chanspec_t c;
|
||||
char buf[CHANSPEC_STR_LEN];
|
||||
|
||||
MSCH_EVENT_HEAD(sp);
|
||||
MSCH_EVENT(("<chan_ctxt>: "));
|
||||
if (empty) {
|
||||
MSCH_EVENT((" null\n"));
|
||||
return;
|
||||
}
|
||||
else
|
||||
MSCH_EVENT(("0x%08x (prev 0x%08x, next 0x%08x)\n",
|
||||
ntoh32(p->p_chan_ctxt), ntoh32(p->p_prev), ntoh32(p->p_next)));
|
||||
|
||||
c = (chanspec_t)ntoh16(p->chanspec);
|
||||
|
||||
MSCH_EVENT_HEAD(sn);
|
||||
MSCH_EVENT(("channel: %s, bf_sch_pending: %s, bf_skipped: %d\n",
|
||||
wf_chspec_ntoa(c, buf), p->bf_sch_pending? "TRUE" : "FALSE",
|
||||
ntoh32(p->bf_skipped_count)));
|
||||
|
||||
MSCH_EVENT_HEAD(sn);
|
||||
MSCH_EVENT(("bf_link: prev 0x%08x, next 0x%08x\n",
|
||||
ntoh32(p->bf_link_prev), ntoh32(p->bf_link_next)));
|
||||
|
||||
MSCH_EVENT_HEAD(sn);
|
||||
MSCH_EVENT(("onchan_time: %s",
|
||||
dhd_mschdbg_display_time(p->onchan_time_h, p->onchan_time_l)));
|
||||
MSCH_EVENT((", actual_onchan_dur: %s",
|
||||
dhd_mschdbg_display_time(p->actual_onchan_dur_h, p->actual_onchan_dur_l)));
|
||||
MSCH_EVENT((", pend_onchan_dur: %s\n",
|
||||
dhd_mschdbg_display_time(p->pend_onchan_dur_h, p->pend_onchan_dur_l)));
|
||||
|
||||
dhd_mschdbg_elem_list(sn, "req_entity", data, p->req_entity_list_ptr,
|
||||
p->req_entity_list_cnt);
|
||||
dhd_mschdbg_elem_list(sn, "bf_entity", data, p->bf_entity_list_ptr,
|
||||
p->bf_entity_list_cnt);
|
||||
}
|
||||
|
||||
static void
|
||||
dhd_mschdbg_req_entity_profiler_event_data(int sp, int ver, char *data, uint16 ptr, bool empty)
|
||||
{
|
||||
int sn = sp + 4;
|
||||
msch_req_entity_profiler_event_data_t *p =
|
||||
(msch_req_entity_profiler_event_data_t *)(data + ntoh16(ptr));
|
||||
char buf[CHANSPEC_STR_LEN];
|
||||
chanspec_t c;
|
||||
uint32 flags;
|
||||
|
||||
MSCH_EVENT_HEAD(sp);
|
||||
MSCH_EVENT(("<req_entity>: "));
|
||||
if (empty) {
|
||||
MSCH_EVENT((" null\n"));
|
||||
return;
|
||||
}
|
||||
else
|
||||
MSCH_EVENT(("0x%08x (prev 0x%08x, next 0x%08x)\n",
|
||||
ntoh32(p->p_req_entity), ntoh32(p->req_hdl_link_prev),
|
||||
ntoh32(p->req_hdl_link_next)));
|
||||
|
||||
MSCH_EVENT_HEAD(sn);
|
||||
MSCH_EVENT(("req_hdl: [0x%08x]\n", ntoh32(p->p_req_hdl)));
|
||||
|
||||
MSCH_EVENT_HEAD(sn);
|
||||
MSCH_EVENT(("chan_ctxt_link: prev 0x%08x, next 0x%08x\n",
|
||||
ntoh32(p->chan_ctxt_link_prev), ntoh32(p->chan_ctxt_link_next)));
|
||||
MSCH_EVENT_HEAD(sn);
|
||||
MSCH_EVENT(("rt_specific_link: prev 0x%08x, next 0x%08x\n",
|
||||
ntoh32(p->rt_specific_link_prev), ntoh32(p->rt_specific_link_next)));
|
||||
MSCH_EVENT_HEAD(sn);
|
||||
MSCH_EVENT(("start_fixed_link: prev 0x%08x, next 0x%08x\n",
|
||||
ntoh32(p->start_fixed_link_prev), ntoh32(p->start_fixed_link_next)));
|
||||
MSCH_EVENT_HEAD(sn);
|
||||
MSCH_EVENT(("both_flex_list: prev 0x%08x, next 0x%08x\n",
|
||||
ntoh32(p->both_flex_list_prev), ntoh32(p->both_flex_list_next)));
|
||||
|
||||
c = (chanspec_t)ntoh16(p->chanspec);
|
||||
MSCH_EVENT_HEAD(sn);
|
||||
if (ver >= 2) {
|
||||
MSCH_EVENT(("channel: %s, onchan Id %d, current chan Id %d, priority %d",
|
||||
wf_chspec_ntoa(c, buf), ntoh16(p->onchan_chn_idx), ntoh16(p->cur_chn_idx),
|
||||
ntoh16(p->priority)));
|
||||
flags = ntoh32(p->flags);
|
||||
if (flags & WL_MSCH_ENTITY_FLAG_MULTI_INSTANCE)
|
||||
MSCH_EVENT((" : MULTI_INSTANCE\n"));
|
||||
else
|
||||
MSCH_EVENT(("\n"));
|
||||
MSCH_EVENT_HEAD(sn);
|
||||
MSCH_EVENT(("actual_start_time: %s, ",
|
||||
dhd_mschdbg_display_time(p->actual_start_time_h, p->actual_start_time_l)));
|
||||
MSCH_EVENT(("curts_fire_time: %s, ",
|
||||
dhd_mschdbg_display_time(p->curts_fire_time_h, p->curts_fire_time_l)));
|
||||
} else {
|
||||
MSCH_EVENT(("channel: %s, priority %d, ", wf_chspec_ntoa(c, buf),
|
||||
ntoh16(p->priority)));
|
||||
}
|
||||
MSCH_EVENT(("bf_last_serv_time: %s\n",
|
||||
dhd_mschdbg_display_time(p->bf_last_serv_time_h, p->bf_last_serv_time_l)));
|
||||
|
||||
dhd_mschdbg_req_timing_profiler_event_data(sn, ver, "current", data, p->cur_slot_ptr,
|
||||
(p->cur_slot_ptr == 0));
|
||||
dhd_mschdbg_req_timing_profiler_event_data(sn, ver, "pending", data, p->pend_slot_ptr,
|
||||
(p->pend_slot_ptr == 0));
|
||||
|
||||
if (p->p_chan_ctxt && (p->chan_ctxt_ptr == 0)) {
|
||||
MSCH_EVENT_HEAD(sn);
|
||||
MSCH_EVENT(("<chan_ctxt>: 0x%08x\n", ntoh32(p->p_chan_ctxt)));
|
||||
}
|
||||
else
|
||||
dhd_mschdbg_chan_ctxt_profiler_event_data(sn, ver, data, p->chan_ctxt_ptr,
|
||||
(p->chan_ctxt_ptr == 0));
|
||||
}
|
||||
|
||||
static void
|
||||
dhd_mschdbg_req_handle_profiler_event_data(int sp, int ver, char *data, uint16 ptr, bool empty)
|
||||
{
|
||||
int sn = sp + 4;
|
||||
msch_req_handle_profiler_event_data_t *p =
|
||||
(msch_req_handle_profiler_event_data_t *)(data + ntoh16(ptr));
|
||||
uint32 flags;
|
||||
|
||||
MSCH_EVENT_HEAD(sp);
|
||||
MSCH_EVENT(("<req_handle>: "));
|
||||
if (empty) {
|
||||
MSCH_EVENT((" null\n"));
|
||||
return;
|
||||
}
|
||||
else
|
||||
MSCH_EVENT(("0x%08x (prev 0x%08x, next 0x%08x)\n",
|
||||
ntoh32(p->p_req_handle), ntoh32(p->p_prev), ntoh32(p->p_next)));
|
||||
|
||||
dhd_mschdbg_elem_list(sn, "req_entity", data, p->req_entity_list_ptr,
|
||||
p->req_entity_list_cnt);
|
||||
MSCH_EVENT_HEAD(sn);
|
||||
MSCH_EVENT(("cb_func: [0x%08x], cb_func: [0x%08x]",
|
||||
ntoh32(p->cb_func), ntoh32(p->cb_ctxt)));
|
||||
if (ver < 2) {
|
||||
MSCH_EVENT((", chan_cnt: %d", ntoh16(p->chan_cnt)));
|
||||
}
|
||||
flags = ntoh32(p->flags);
|
||||
if (flags & WL_MSCH_REQ_HDL_FLAGS_NEW_REQ)
|
||||
MSCH_EVENT((", NEW_REQ"));
|
||||
MSCH_EVENT(("\n"));
|
||||
|
||||
dhd_mschdbg_req_param_profiler_event_data(sn, ver, data, p->req_param_ptr);
|
||||
|
||||
if (ver >= 2) {
|
||||
MSCH_EVENT_HEAD(sn);
|
||||
MSCH_EVENT(("req_time: %s\n",
|
||||
dhd_mschdbg_display_time(p->req_time_h, p->req_time_l)));
|
||||
MSCH_EVENT_HEAD(sn);
|
||||
MSCH_EVENT(("chan_cnt: %d, chan idx %d, last chan idx %d\n",
|
||||
ntoh16(p->chan_cnt), ntoh16(p->chan_idx), ntoh16(p->last_chan_idx)));
|
||||
if (p->chanspec_list && p->chanspec_cnt) {
|
||||
dhd_mschdbg_chanspec_list(sn, data, p->chanspec_list, p->chanspec_cnt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
dhd_mschdbg_profiler_profiler_event_data(int sp, int ver, char *data, uint16 ptr)
|
||||
{
|
||||
msch_profiler_profiler_event_data_t *p =
|
||||
(msch_profiler_profiler_event_data_t *)(data + ntoh16(ptr));
|
||||
uint32 flags;
|
||||
|
||||
MSCH_EVENT_HEAD(sp);
|
||||
MSCH_EVENT(("free list: req_hdl 0x%08x, req_entity 0x%08x,"
|
||||
" chan_ctxt 0x%08x, chanspec 0x%08x\n",
|
||||
ntoh32(p->free_req_hdl_list), ntoh32(p->free_req_entity_list),
|
||||
ntoh32(p->free_chan_ctxt_list), ntoh32(p->free_chanspec_list)));
|
||||
|
||||
MSCH_EVENT_HEAD(sp);
|
||||
MSCH_EVENT(("alloc count: chanspec %d, req_entity %d, req_hdl %d, "
|
||||
"chan_ctxt %d, timeslot %d\n",
|
||||
ntoh16(p->msch_chanspec_alloc_cnt), ntoh16(p->msch_req_entity_alloc_cnt),
|
||||
ntoh16(p->msch_req_hdl_alloc_cnt), ntoh16(p->msch_chan_ctxt_alloc_cnt),
|
||||
ntoh16(p->msch_timeslot_alloc_cnt)));
|
||||
|
||||
dhd_mschdbg_elem_list(sp, "req_hdl", data, p->msch_req_hdl_list_ptr,
|
||||
p->msch_req_hdl_list_cnt);
|
||||
dhd_mschdbg_elem_list(sp, "chan_ctxt", data, p->msch_chan_ctxt_list_ptr,
|
||||
p->msch_chan_ctxt_list_cnt);
|
||||
dhd_mschdbg_elem_list(sp, "req_timing", data, p->msch_req_timing_list_ptr,
|
||||
p->msch_req_timing_list_cnt);
|
||||
dhd_mschdbg_elem_list(sp, "start_fixed", data, p->msch_start_fixed_list_ptr,
|
||||
p->msch_start_fixed_list_cnt);
|
||||
dhd_mschdbg_elem_list(sp, "both_flex_req_entity", data,
|
||||
p->msch_both_flex_req_entity_list_ptr,
|
||||
p->msch_both_flex_req_entity_list_cnt);
|
||||
dhd_mschdbg_elem_list(sp, "start_flex", data, p->msch_start_flex_list_ptr,
|
||||
p->msch_start_flex_list_cnt);
|
||||
dhd_mschdbg_elem_list(sp, "both_flex", data, p->msch_both_flex_list_ptr,
|
||||
p->msch_both_flex_list_cnt);
|
||||
|
||||
if (p->p_cur_msch_timeslot && (p->cur_msch_timeslot_ptr == 0)) {
|
||||
MSCH_EVENT_HEAD(sp);
|
||||
MSCH_EVENT(("<cur_msch timeslot>: 0x%08x\n",
|
||||
ntoh32(p->p_cur_msch_timeslot)));
|
||||
} else
|
||||
dhd_mschdbg_timeslot_profiler_event_data(sp, ver, "cur_msch", data,
|
||||
p->cur_msch_timeslot_ptr, (p->cur_msch_timeslot_ptr == 0));
|
||||
|
||||
if (p->p_next_timeslot && (p->next_timeslot_ptr == 0)) {
|
||||
MSCH_EVENT_HEAD(sp);
|
||||
MSCH_EVENT(("<next timeslot>: 0x%08x\n",
|
||||
ntoh32(p->p_next_timeslot)));
|
||||
} else
|
||||
dhd_mschdbg_timeslot_profiler_event_data(sp, ver, "next", data,
|
||||
p->next_timeslot_ptr, (p->next_timeslot_ptr == 0));
|
||||
|
||||
MSCH_EVENT_HEAD(sp);
|
||||
MSCH_EVENT(("ts_id: %d, ", ntoh32(p->ts_id)));
|
||||
flags = ntoh32(p->flags);
|
||||
if (flags & WL_MSCH_STATE_IN_TIEMR_CTXT)
|
||||
MSCH_EVENT(("IN_TIEMR_CTXT, "));
|
||||
if (flags & WL_MSCH_STATE_SCHD_PENDING)
|
||||
MSCH_EVENT(("SCHD_PENDING, "));
|
||||
MSCH_EVENT(("slotskip_flags: %d, cur_armed_timeslot: 0x%08x\n",
|
||||
(ver >= 2)? ntoh32(p->slotskip_flag) : 0, ntoh32(p->cur_armed_timeslot)));
|
||||
MSCH_EVENT_HEAD(sp);
|
||||
MSCH_EVENT(("flex_list_cnt: %d, service_interval: %d, "
|
||||
"max_lo_prio_interval: %d\n",
|
||||
ntoh16(p->flex_list_cnt), ntoh32(p->service_interval),
|
||||
ntoh32(p->max_lo_prio_interval)));
|
||||
}
|
||||
|
||||
static void dhd_mschdbg_dump_data(dhd_pub_t *dhdp, void *raw_event_ptr, int type,
|
||||
char *data, int len)
|
||||
{
|
||||
uint64 t = 0, tt = 0;
|
||||
uint32 s = 0, ss = 0;
|
||||
int wlc_index, ver;
|
||||
|
||||
ver = (type & WL_MSCH_PROFILER_VER_MASK) >> WL_MSCH_PROFILER_VER_SHIFT;
|
||||
wlc_index = (type & WL_MSCH_PROFILER_WLINDEX_MASK) >> WL_MSCH_PROFILER_WLINDEX_SHIFT;
|
||||
if (wlc_index >= 4)
|
||||
return;
|
||||
|
||||
type &= WL_MSCH_PROFILER_TYPE_MASK;
|
||||
if (type <= WL_MSCH_PROFILER_PROFILE_END) {
|
||||
msch_profiler_event_data_t *pevent = (msch_profiler_event_data_t *)data;
|
||||
tt = ((uint64)(ntoh32(pevent->time_hi)) << 32) | ntoh32(pevent->time_lo);
|
||||
dhd_mschdbg_us_to_sec(pevent->time_hi, pevent->time_lo, &s, &ss);
|
||||
}
|
||||
|
||||
if (lastMessages && (type != WL_MSCH_PROFILER_MESSAGE) &&
|
||||
(type != WL_MSCH_PROFILER_EVENT_LOG)) {
|
||||
MSCH_EVENT_HEAD(0);
|
||||
MSCH_EVENT(("\n"));
|
||||
lastMessages = FALSE;
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case WL_MSCH_PROFILER_START:
|
||||
MSCH_EVENT_HEAD(0);
|
||||
MSCH_EVENT(("%06d.%06d START\n", s, ss));
|
||||
break;
|
||||
|
||||
case WL_MSCH_PROFILER_EXIT:
|
||||
MSCH_EVENT_HEAD(0);
|
||||
MSCH_EVENT(("%06d.%06d EXIT\n", s, ss));
|
||||
break;
|
||||
|
||||
case WL_MSCH_PROFILER_REQ:
|
||||
{
|
||||
msch_req_profiler_event_data_t *p = (msch_req_profiler_event_data_t *)data;
|
||||
MSCH_EVENT_HEAD(0);
|
||||
MSCH_EVENT(("\n"));
|
||||
MSCH_EVENT_HEAD(0);
|
||||
MSCH_EVENT(("===============================\n"));
|
||||
MSCH_EVENT_HEAD(0);
|
||||
MSCH_EVENT(("%06d.%06d [wl%d] REGISTER:\n", s, ss, wlc_index));
|
||||
dhd_mschdbg_req_param_profiler_event_data(4, ver, data, p->req_param_ptr);
|
||||
dhd_mschdbg_chanspec_list(4, data, p->chanspec_ptr, p->chanspec_cnt);
|
||||
MSCH_EVENT_HEAD(0);
|
||||
MSCH_EVENT(("===============================\n"));
|
||||
MSCH_EVENT_HEAD(0);
|
||||
MSCH_EVENT(("\n"));
|
||||
}
|
||||
break;
|
||||
|
||||
case WL_MSCH_PROFILER_CALLBACK:
|
||||
{
|
||||
msch_callback_profiler_event_data_t *p =
|
||||
(msch_callback_profiler_event_data_t *)data;
|
||||
char buf[CHANSPEC_STR_LEN];
|
||||
chanspec_t chanspec;
|
||||
uint16 cbtype;
|
||||
|
||||
MSCH_EVENT_HEAD(0);
|
||||
MSCH_EVENT(("%06d.%06d [wl%d] CALLBACK: ", s, ss, wlc_index));
|
||||
chanspec = (chanspec_t)ntoh16(p->chanspec);
|
||||
MSCH_EVENT(("req_hdl[0x%08x], channel %s --",
|
||||
ntoh32(p->p_req_hdl), wf_chspec_ntoa(chanspec, buf)));
|
||||
|
||||
cbtype = ntoh16(p->type);
|
||||
if (cbtype & WL_MSCH_CT_ON_CHAN)
|
||||
MSCH_EVENT((" ON_CHAN"));
|
||||
if (cbtype & WL_MSCH_CT_OFF_CHAN)
|
||||
MSCH_EVENT((" OFF_CHAN"));
|
||||
if (cbtype & WL_MSCH_CT_REQ_START)
|
||||
MSCH_EVENT((" REQ_START"));
|
||||
if (cbtype & WL_MSCH_CT_REQ_END)
|
||||
MSCH_EVENT((" REQ_END"));
|
||||
if (cbtype & WL_MSCH_CT_SLOT_START)
|
||||
MSCH_EVENT((" SLOT_START"));
|
||||
if (cbtype & WL_MSCH_CT_SLOT_SKIP)
|
||||
MSCH_EVENT((" SLOT_SKIP"));
|
||||
if (cbtype & WL_MSCH_CT_SLOT_END)
|
||||
MSCH_EVENT((" SLOT_END"));
|
||||
if (cbtype & WL_MSCH_CT_OFF_CHAN_DONE)
|
||||
MSCH_EVENT((" OFF_CHAN_DONE"));
|
||||
if (cbtype & WL_MSCH_CT_PARTIAL)
|
||||
MSCH_EVENT((" PARTIAL"));
|
||||
if (cbtype & WL_MSCH_CT_PRE_ONCHAN)
|
||||
MSCH_EVENT((" PRE_ONCHAN"));
|
||||
if (cbtype & WL_MSCH_CT_PRE_REQ_START)
|
||||
MSCH_EVENT((" PRE_REQ_START"));
|
||||
|
||||
if (cbtype & WL_MSCH_CT_REQ_START) {
|
||||
req_start[wlc_index] = 1;
|
||||
req_start_time[wlc_index] = tt;
|
||||
} else if (cbtype & WL_MSCH_CT_REQ_END) {
|
||||
if (req_start[wlc_index]) {
|
||||
MSCH_EVENT((" : REQ duration %d",
|
||||
(uint32)(tt - req_start_time[wlc_index])));
|
||||
req_start[wlc_index] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (cbtype & WL_MSCH_CT_SLOT_START) {
|
||||
solt_chanspec[wlc_index] = p->chanspec;
|
||||
solt_start_time[wlc_index] = tt;
|
||||
} else if (cbtype & WL_MSCH_CT_SLOT_END) {
|
||||
if (p->chanspec == solt_chanspec[wlc_index]) {
|
||||
MSCH_EVENT((" : SLOT duration %d",
|
||||
(uint32)(tt - solt_start_time[wlc_index])));
|
||||
solt_chanspec[wlc_index] = 0;
|
||||
}
|
||||
}
|
||||
MSCH_EVENT(("\n"));
|
||||
|
||||
if (cbtype & (WL_MSCH_CT_ON_CHAN | WL_MSCH_CT_SLOT_SKIP)) {
|
||||
MSCH_EVENT_HEAD(4);
|
||||
if (cbtype & WL_MSCH_CT_ON_CHAN) {
|
||||
MSCH_EVENT(("ID %d onchan idx %d cur_chan_seq_start %s ",
|
||||
ntoh32(p->timeslot_id), ntoh32(p->onchan_idx),
|
||||
dhd_mschdbg_display_time(p->cur_chan_seq_start_time_h,
|
||||
p->cur_chan_seq_start_time_l)));
|
||||
}
|
||||
t = ((uint64)(ntoh32(p->start_time_h)) << 32) |
|
||||
ntoh32(p->start_time_l);
|
||||
MSCH_EVENT(("start %s ",
|
||||
dhd_mschdbg_display_time(p->start_time_h,
|
||||
p->start_time_l)));
|
||||
tt = ((uint64)(ntoh32(p->end_time_h)) << 32) | ntoh32(p->end_time_l);
|
||||
MSCH_EVENT(("end %s duration %d\n",
|
||||
dhd_mschdbg_display_time(p->end_time_h, p->end_time_l),
|
||||
(p->end_time_h == 0xffffffff && p->end_time_l == 0xffffffff)?
|
||||
-1 : (int)(tt - t)));
|
||||
}
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
case WL_MSCH_PROFILER_EVENT_LOG:
|
||||
{
|
||||
while (len >= (int)WL_MSCH_EVENT_LOG_HEAD_SIZE) {
|
||||
msch_event_log_profiler_event_data_t *p =
|
||||
(msch_event_log_profiler_event_data_t *)data;
|
||||
/* TODO: How to parse MSCH if extended event tag is present ??? */
|
||||
prcd_event_log_hdr_t hdr;
|
||||
int size = WL_MSCH_EVENT_LOG_HEAD_SIZE + p->hdr.count * sizeof(uint32);
|
||||
if (len < size || size > sizeof(msch_event_log_profiler_event_data_t)) {
|
||||
break;
|
||||
}
|
||||
data += size;
|
||||
len -= size;
|
||||
dhd_mschdbg_us_to_sec(p->time_hi, p->time_lo, &s, &ss);
|
||||
MSCH_EVENT_HEAD(0);
|
||||
MSCH_EVENT(("%06d.%06d [wl%d]: ", s, ss, p->hdr.tag));
|
||||
bzero(&hdr, sizeof(hdr));
|
||||
hdr.tag = EVENT_LOG_TAG_MSCHPROFILE;
|
||||
hdr.count = p->hdr.count + 1;
|
||||
/* exclude LSB 2 bits which indicate binary/non-binary data */
|
||||
hdr.fmt_num = ntoh16(p->hdr.fmt_num) >> 2;
|
||||
hdr.fmt_num_raw = ntoh16(p->hdr.fmt_num);
|
||||
if (ntoh16(p->hdr.fmt_num) == DHD_OW_BI_RAW_EVENT_LOG_FMT) {
|
||||
hdr.binary_payload = TRUE;
|
||||
}
|
||||
dhd_dbg_verboselog_printf(dhdp, &hdr, raw_event_ptr, p->data, 0, 0);
|
||||
}
|
||||
lastMessages = TRUE;
|
||||
break;
|
||||
}
|
||||
|
||||
case WL_MSCH_PROFILER_MESSAGE:
|
||||
{
|
||||
msch_message_profiler_event_data_t *p = (msch_message_profiler_event_data_t *)data;
|
||||
MSCH_EVENT_HEAD(0);
|
||||
MSCH_EVENT(("%06d.%06d [wl%d]: %s", s, ss, wlc_index, p->message));
|
||||
lastMessages = TRUE;
|
||||
break;
|
||||
}
|
||||
|
||||
case WL_MSCH_PROFILER_PROFILE_START:
|
||||
profiler_start_time[wlc_index] = tt;
|
||||
MSCH_EVENT_HEAD(0);
|
||||
MSCH_EVENT(("-------------------------------\n"));
|
||||
MSCH_EVENT_HEAD(0);
|
||||
MSCH_EVENT(("%06d.%06d [wl%d] PROFILE DATA:\n", s, ss, wlc_index));
|
||||
dhd_mschdbg_profiler_profiler_event_data(4, ver, data, 0);
|
||||
break;
|
||||
|
||||
case WL_MSCH_PROFILER_PROFILE_END:
|
||||
MSCH_EVENT_HEAD(0);
|
||||
MSCH_EVENT(("%06d.%06d [wl%d] PROFILE END: take time %d\n", s, ss,
|
||||
wlc_index, (uint32)(tt - profiler_start_time[wlc_index])));
|
||||
MSCH_EVENT_HEAD(0);
|
||||
MSCH_EVENT(("-------------------------------\n"));
|
||||
MSCH_EVENT_HEAD(0);
|
||||
MSCH_EVENT(("\n"));
|
||||
break;
|
||||
|
||||
case WL_MSCH_PROFILER_REQ_HANDLE:
|
||||
dhd_mschdbg_req_handle_profiler_event_data(4, ver, data, 0, FALSE);
|
||||
break;
|
||||
|
||||
case WL_MSCH_PROFILER_REQ_ENTITY:
|
||||
dhd_mschdbg_req_entity_profiler_event_data(4, ver, data, 0, FALSE);
|
||||
break;
|
||||
|
||||
case WL_MSCH_PROFILER_CHAN_CTXT:
|
||||
dhd_mschdbg_chan_ctxt_profiler_event_data(4, ver, data, 0, FALSE);
|
||||
break;
|
||||
|
||||
case WL_MSCH_PROFILER_REQ_TIMING:
|
||||
dhd_mschdbg_req_timing_profiler_event_data(4, ver, "msch", data, 0, FALSE);
|
||||
break;
|
||||
|
||||
default:
|
||||
MSCH_EVENT_HEAD(0);
|
||||
MSCH_EVENT(("[wl%d] ERROR: unsupported EVENT reason code:%d; ",
|
||||
wlc_index, type));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
wl_mschdbg_event_handler(dhd_pub_t *dhdp, void *raw_event_ptr, int type, void *data, int len)
|
||||
{
|
||||
head_log = "MSCH";
|
||||
dhd_mschdbg_dump_data(dhdp, raw_event_ptr, type, (char *)data, len);
|
||||
}
|
||||
|
||||
void
|
||||
wl_mschdbg_verboselog_handler(dhd_pub_t *dhdp, void *raw_event_ptr, prcd_event_log_hdr_t *plog_hdr,
|
||||
uint32 *log_ptr)
|
||||
{
|
||||
uint32 log_pyld_len;
|
||||
head_log = "CONSOLE";
|
||||
|
||||
if (plog_hdr->count == 0) {
|
||||
return;
|
||||
}
|
||||
log_pyld_len = (plog_hdr->count - 1) * DATA_UNIT_FOR_LOG_CNT;
|
||||
|
||||
if (plog_hdr->tag == EVENT_LOG_TAG_MSCHPROFILE) {
|
||||
msch_event_log_profiler_event_data_t *p =
|
||||
(msch_event_log_profiler_event_data_t *)log_ptr;
|
||||
/* TODO: How to parse MSCH if extended event tag is present ??? */
|
||||
prcd_event_log_hdr_t hdr;
|
||||
uint32 s, ss;
|
||||
|
||||
if (log_pyld_len < OFFSETOF(msch_event_log_profiler_event_data_t, data) ||
|
||||
log_pyld_len > sizeof(msch_event_log_profiler_event_data_t)) {
|
||||
return;
|
||||
}
|
||||
|
||||
dhd_mschdbg_us_to_sec(p->time_hi, p->time_lo, &s, &ss);
|
||||
MSCH_EVENT_HEAD(0);
|
||||
MSCH_EVENT(("%06d.%06d [wl%d]: ", s, ss, p->hdr.tag));
|
||||
bzero(&hdr, sizeof(hdr));
|
||||
hdr.tag = EVENT_LOG_TAG_MSCHPROFILE;
|
||||
hdr.count = p->hdr.count + 1;
|
||||
/* exclude LSB 2 bits which indicate binary/non-binary data */
|
||||
hdr.fmt_num = ntoh16(p->hdr.fmt_num) >> 2;
|
||||
hdr.fmt_num_raw = ntoh16(p->hdr.fmt_num);
|
||||
if (ntoh16(p->hdr.fmt_num) == DHD_OW_BI_RAW_EVENT_LOG_FMT) {
|
||||
hdr.binary_payload = TRUE;
|
||||
}
|
||||
dhd_dbg_verboselog_printf(dhdp, &hdr, raw_event_ptr, p->data, 0, 0);
|
||||
} else {
|
||||
msch_collect_tlv_t *p = (msch_collect_tlv_t *)log_ptr;
|
||||
int type = ntoh16(p->type);
|
||||
int len = ntoh16(p->size);
|
||||
|
||||
if (log_pyld_len < OFFSETOF(msch_collect_tlv_t, value) + len) {
|
||||
return;
|
||||
}
|
||||
|
||||
dhd_mschdbg_dump_data(dhdp, raw_event_ptr, type, p->value, len);
|
||||
}
|
||||
}
|
||||
#endif /* SHOW_LOGTRACE */
|
||||
@@ -0,0 +1,40 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* DHD debugability header file
|
||||
*
|
||||
* <<Broadcom-WL-IPTag/Open:>>
|
||||
*
|
||||
* Copyright (C) 1999-2019, 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.
|
||||
*
|
||||
* 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_mschdbg.h 571265 2015-07-14 20:50:18Z $
|
||||
*/
|
||||
|
||||
#ifndef _dhd_mschdbg_h_
|
||||
#define _dhd_mschdbg_h_
|
||||
|
||||
#ifdef SHOW_LOGTRACE
|
||||
extern void wl_mschdbg_event_handler(dhd_pub_t *dhdp, void *raw_event_ptr, int type,
|
||||
void *data, int len);
|
||||
extern void wl_mschdbg_verboselog_handler(dhd_pub_t *dhdp, void *raw_event_ptr,
|
||||
prcd_event_log_hdr_t *plog_hdr, uint32 *log_ptr);
|
||||
#endif /* SHOW_LOGTRACE */
|
||||
|
||||
#endif /* _dhd_mschdbg_h_ */
|
||||
11155
drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd_wifi6/dhd_msgbuf.c
Normal file
11155
drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd_wifi6/dhd_msgbuf.c
Normal file
File diff suppressed because it is too large
Load Diff
11604
drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd_wifi6/dhd_pcie.c
Normal file
11604
drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd_wifi6/dhd_pcie.c
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,602 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Linux DHD Bus Module for PCIE
|
||||
*
|
||||
* Copyright (C) 1999-2019, 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.
|
||||
*
|
||||
* Notwithstanding the above, under no circumstances may you combine this
|
||||
* software in any way with any other Broadcom software provided under a license
|
||||
* other than the GPL, without Broadcom's express prior written consent.
|
||||
*
|
||||
*
|
||||
* <<Broadcom-WL-IPTag/Open:>>
|
||||
*
|
||||
* $Id: dhd_pcie.h 816392 2019-04-24 14:39:02Z $
|
||||
*/
|
||||
|
||||
#ifndef dhd_pcie_h
|
||||
#define dhd_pcie_h
|
||||
|
||||
#include <bcmpcie.h>
|
||||
#include <hnd_cons.h>
|
||||
|
||||
/* defines */
|
||||
#define PCIE_SHARED_VERSION PCIE_SHARED_VERSION_7
|
||||
|
||||
#define PCMSGBUF_HDRLEN 0
|
||||
#define DONGLE_REG_MAP_SIZE (32 * 1024)
|
||||
#define DONGLE_TCM_MAP_SIZE (4096 * 1024)
|
||||
#define DONGLE_MIN_MEMSIZE (128 *1024)
|
||||
#ifdef DHD_DEBUG
|
||||
#define DHD_PCIE_SUCCESS 0
|
||||
#define DHD_PCIE_FAILURE 1
|
||||
#endif /* DHD_DEBUG */
|
||||
#define REMAP_ENAB(bus) ((bus)->remap)
|
||||
#define REMAP_ISADDR(bus, a) (((a) >= ((bus)->orig_ramsize)) && ((a) < ((bus)->ramsize)))
|
||||
|
||||
#define MAX_DHD_TX_FLOWS 320
|
||||
|
||||
/* user defined data structures */
|
||||
/* Device console log buffer state */
|
||||
#define CONSOLE_LINE_MAX 192u
|
||||
#define CONSOLE_BUFFER_MAX (8 * 1024)
|
||||
|
||||
#ifdef IDLE_TX_FLOW_MGMT
|
||||
#define IDLE_FLOW_LIST_TIMEOUT 5000
|
||||
#define IDLE_FLOW_RING_TIMEOUT 5000
|
||||
#endif /* IDLE_TX_FLOW_MGMT */
|
||||
|
||||
/* HWA enabled and inited */
|
||||
#define HWA_ACTIVE(dhd) (((dhd)->hwa_enable) && ((dhd)->hwa_inited))
|
||||
|
||||
/* implicit DMA for h2d wr and d2h rd indice from Host memory to TCM */
|
||||
#define IDMA_ENAB(dhd) ((dhd)->idma_enable)
|
||||
#define IDMA_ACTIVE(dhd) (((dhd)->idma_enable) && ((dhd)->idma_inited))
|
||||
|
||||
#define IDMA_CAPABLE(bus) (((bus)->sih->buscorerev == 19) || ((bus)->sih->buscorerev >= 23))
|
||||
|
||||
/* IFRM (Implicit Flow Ring Manager enable and inited */
|
||||
#define IFRM_ENAB(dhd) ((dhd)->ifrm_enable)
|
||||
#define IFRM_ACTIVE(dhd) (((dhd)->ifrm_enable) && ((dhd)->ifrm_inited))
|
||||
|
||||
/* DAR registers use for h2d doorbell */
|
||||
#define DAR_ENAB(dhd) ((dhd)->dar_enable)
|
||||
#define DAR_ACTIVE(dhd) (((dhd)->dar_enable) && ((dhd)->dar_inited))
|
||||
|
||||
/* DAR WAR for revs < 64 */
|
||||
#define DAR_PWRREQ(bus) (((bus)->_dar_war) && DAR_ACTIVE((bus)->dhd))
|
||||
|
||||
/* PCIE CTO Prevention and Recovery */
|
||||
#define PCIECTO_ENAB(bus) ((bus)->cto_enable)
|
||||
|
||||
/* Implicit DMA index usage :
|
||||
* Index 0 for h2d write index transfer
|
||||
* Index 1 for d2h read index transfer
|
||||
*/
|
||||
#define IDMA_IDX0 0
|
||||
#define IDMA_IDX1 1
|
||||
#define IDMA_IDX2 2
|
||||
#define IDMA_IDX3 3
|
||||
#define DMA_TYPE_SHIFT 4
|
||||
#define DMA_TYPE_IDMA 1
|
||||
|
||||
#define DHDPCIE_CONFIG_HDR_SIZE 16
|
||||
#define DHDPCIE_CONFIG_CHECK_DELAY_MS 10 /* 10ms */
|
||||
#define DHDPCIE_CONFIG_CHECK_RETRY_COUNT 20
|
||||
#define DHDPCIE_DONGLE_PWR_TOGGLE_DELAY 1000 /* 1ms in units of us */
|
||||
#define DHDPCIE_PM_D3_DELAY 200000 /* 200ms in units of us */
|
||||
#define DHDPCIE_PM_D2_DELAY 200 /* 200us */
|
||||
|
||||
typedef struct dhd_console {
|
||||
uint count; /* Poll interval msec counter */
|
||||
uint log_addr; /* Log struct address (fixed) */
|
||||
hnd_log_t log; /* Log struct (host copy) */
|
||||
uint bufsize; /* Size of log buffer */
|
||||
uint8 *buf; /* Log buffer (host copy) */
|
||||
uint last; /* Last buffer read index */
|
||||
} dhd_console_t;
|
||||
|
||||
typedef struct ring_sh_info {
|
||||
uint32 ring_mem_addr;
|
||||
uint32 ring_state_w;
|
||||
uint32 ring_state_r;
|
||||
} ring_sh_info_t;
|
||||
|
||||
#define DEVICE_WAKE_NONE 0
|
||||
#define DEVICE_WAKE_OOB 1
|
||||
#define DEVICE_WAKE_INB 2
|
||||
|
||||
#define INBAND_DW_ENAB(bus) ((bus)->dw_option == DEVICE_WAKE_INB)
|
||||
#define OOB_DW_ENAB(bus) ((bus)->dw_option == DEVICE_WAKE_OOB)
|
||||
#define NO_DW_ENAB(bus) ((bus)->dw_option == DEVICE_WAKE_NONE)
|
||||
|
||||
#define PCIE_RELOAD_WAR_ENAB(buscorerev) \
|
||||
((buscorerev == 66) || (buscorerev == 67) || (buscorerev == 68) || (buscorerev == 70))
|
||||
|
||||
/*
|
||||
* HW JIRA - CRWLPCIEGEN2-672
|
||||
* Producer Index Feature which is used by F1 gets reset on F0 FLR
|
||||
* fixed in REV68
|
||||
*/
|
||||
#define PCIE_ENUM_RESET_WAR_ENAB(buscorerev) \
|
||||
((buscorerev == 66) || (buscorerev == 67))
|
||||
|
||||
struct dhd_bus;
|
||||
|
||||
struct dhd_pcie_rev {
|
||||
uint8 fw_rev;
|
||||
void (*handle_mb_data)(struct dhd_bus *);
|
||||
};
|
||||
|
||||
typedef struct dhdpcie_config_save
|
||||
{
|
||||
uint32 header[DHDPCIE_CONFIG_HDR_SIZE];
|
||||
/* pmcsr save */
|
||||
uint32 pmcsr;
|
||||
/* express save */
|
||||
uint32 exp_dev_ctrl_stat;
|
||||
uint32 exp_link_ctrl_stat;
|
||||
uint32 exp_dev_ctrl_stat2;
|
||||
uint32 exp_link_ctrl_stat2;
|
||||
/* msi save */
|
||||
uint32 msi_cap;
|
||||
uint32 msi_addr0;
|
||||
uint32 msi_addr1;
|
||||
uint32 msi_data;
|
||||
/* l1pm save */
|
||||
uint32 l1pm0;
|
||||
uint32 l1pm1;
|
||||
/* ltr save */
|
||||
uint32 ltr;
|
||||
/* aer save */
|
||||
uint32 aer_caps_ctrl; /* 0x18 */
|
||||
uint32 aer_severity; /* 0x0C */
|
||||
uint32 aer_umask; /* 0x08 */
|
||||
uint32 aer_cmask; /* 0x14 */
|
||||
uint32 aer_root_cmd; /* 0x2c */
|
||||
/* BAR0 and BAR1 windows */
|
||||
uint32 bar0_win;
|
||||
uint32 bar1_win;
|
||||
} dhdpcie_config_save_t;
|
||||
|
||||
/* The level of bus communication with the dongle */
|
||||
enum dhd_bus_low_power_state {
|
||||
DHD_BUS_NO_LOW_POWER_STATE, /* Not in low power state */
|
||||
DHD_BUS_D3_INFORM_SENT, /* D3 INFORM sent */
|
||||
DHD_BUS_D3_ACK_RECIEVED, /* D3 ACK recieved */
|
||||
};
|
||||
|
||||
/** 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 */
|
||||
struct pci_dev *rc_dev; /* pci RC device handle */
|
||||
struct pci_dev *dev; /* pci device handle */
|
||||
|
||||
dll_t flowring_active_list; /* constructed list of tx flowring queues */
|
||||
#ifdef IDLE_TX_FLOW_MGMT
|
||||
uint64 active_list_last_process_ts;
|
||||
/* stores the timestamp of active list processing */
|
||||
#endif /* IDLE_TX_FLOW_MGMT */
|
||||
|
||||
si_t *sih; /* Handle for SI calls */
|
||||
char *vars; /* Variables (from CIS and/or other) */
|
||||
uint varsz; /* Size of variables buffer */
|
||||
uint32 sbaddr; /* Current SB window pointer (-1, invalid) */
|
||||
sbpcieregs_t *reg; /* Registers for PCIE core */
|
||||
|
||||
uint armrev; /* CPU core revision */
|
||||
uint coreid; /* CPU core id */
|
||||
uint ramrev; /* SOCRAM core revision */
|
||||
uint32 ramsize; /* Size of RAM in SOCRAM (bytes) */
|
||||
uint32 orig_ramsize; /* Size of RAM in SOCRAM (bytes) */
|
||||
bool ramsize_adjusted; /* flag to note adjustment, so that
|
||||
* adjustment routine and file io
|
||||
* are avoided on D3 cold -> D0
|
||||
*/
|
||||
uint32 srmemsize; /* Size of SRMEM */
|
||||
|
||||
uint32 bus; /* gSPI or SDIO bus */
|
||||
uint32 intstatus; /* Intstatus bits (events) pending */
|
||||
bool dpc_sched; /* Indicates DPC schedule (intrpt rcvd) */
|
||||
bool fcstate; /* State of dongle flow-control */
|
||||
|
||||
uint16 cl_devid; /* cached devid for dhdsdio_probe_attach() */
|
||||
char *fw_path; /* module_param: path to firmware image */
|
||||
char *nv_path; /* module_param: path to nvram vars file */
|
||||
|
||||
struct pktq txq; /* Queue length used for flow-control */
|
||||
|
||||
bool intr; /* Use interrupts */
|
||||
bool poll; /* Use polling */
|
||||
bool ipend; /* Device interrupt is pending */
|
||||
bool intdis; /* Interrupts disabled by isr */
|
||||
uint intrcount; /* Count of device interrupt callbacks */
|
||||
uint lastintrs; /* Count as of last watchdog timer */
|
||||
|
||||
dhd_console_t console; /* Console output polling support */
|
||||
uint console_addr; /* Console address from shared struct */
|
||||
|
||||
bool alp_only; /* Don't use HT clock (ALP only) */
|
||||
|
||||
bool remap; /* Contiguous 1MB RAM: 512K socram + 512K devram
|
||||
* Available with socram rev 16
|
||||
* Remap region not DMA-able
|
||||
*/
|
||||
uint32 resetinstr;
|
||||
uint32 dongle_ram_base;
|
||||
|
||||
ulong shared_addr;
|
||||
pciedev_shared_t *pcie_sh;
|
||||
uint32 dma_rxoffset;
|
||||
volatile char *regs; /* pci device memory va */
|
||||
volatile char *tcm; /* pci device memory va */
|
||||
osl_t *osh;
|
||||
uint32 nvram_csm; /* Nvram checksum */
|
||||
uint16 pollrate;
|
||||
uint16 polltick;
|
||||
|
||||
volatile uint32 *pcie_mb_intr_addr;
|
||||
volatile uint32 *pcie_mb_intr_2_addr;
|
||||
void *pcie_mb_intr_osh;
|
||||
bool sleep_allowed;
|
||||
|
||||
wake_counts_t wake_counts;
|
||||
|
||||
/* version 3 shared struct related info start */
|
||||
ring_sh_info_t ring_sh[BCMPCIE_COMMON_MSGRINGS + MAX_DHD_TX_FLOWS];
|
||||
|
||||
uint8 h2d_ring_count;
|
||||
uint8 d2h_ring_count;
|
||||
uint32 ringmem_ptr;
|
||||
uint32 ring_state_ptr;
|
||||
|
||||
uint32 d2h_dma_scratch_buffer_mem_addr;
|
||||
|
||||
uint32 h2d_mb_data_ptr_addr;
|
||||
uint32 d2h_mb_data_ptr_addr;
|
||||
/* version 3 shared struct related info end */
|
||||
|
||||
uint32 def_intmask;
|
||||
uint32 d2h_mb_mask;
|
||||
uint32 pcie_mailbox_mask;
|
||||
uint32 pcie_mailbox_int;
|
||||
bool ltrsleep_on_unload;
|
||||
uint wait_for_d3_ack;
|
||||
uint16 max_tx_flowrings;
|
||||
uint16 max_submission_rings;
|
||||
uint16 max_completion_rings;
|
||||
uint16 max_cmn_rings;
|
||||
uint32 rw_index_sz;
|
||||
bool db1_for_mb;
|
||||
|
||||
dhd_timeout_t doorbell_timer;
|
||||
bool device_wake_state;
|
||||
bool irq_registered;
|
||||
bool d2h_intr_method;
|
||||
int32 idletime; /* Control for activity timeout */
|
||||
uint32 d3_inform_cnt;
|
||||
uint32 d0_inform_cnt;
|
||||
uint32 d0_inform_in_use_cnt;
|
||||
uint8 force_suspend;
|
||||
uint8 is_linkdown;
|
||||
uint8 no_bus_init;
|
||||
#ifdef IDLE_TX_FLOW_MGMT
|
||||
bool enable_idle_flowring_mgmt;
|
||||
#endif /* IDLE_TX_FLOW_MGMT */
|
||||
struct dhd_pcie_rev api;
|
||||
bool use_mailbox;
|
||||
bool use_d0_inform;
|
||||
void *bus_lock;
|
||||
void *backplane_access_lock;
|
||||
enum dhd_bus_low_power_state bus_low_power_state;
|
||||
uint32 hostready_count; /* Number of hostready issued */
|
||||
#if defined(BCMPCIE_OOB_HOST_WAKE)
|
||||
bool oob_presuspend;
|
||||
#endif // endif
|
||||
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 dpc_return_busdown_count;
|
||||
ulong non_ours_irq_count;
|
||||
#ifdef BCMPCIE_OOB_HOST_WAKE
|
||||
ulong oob_intr_count;
|
||||
ulong oob_intr_enable_count;
|
||||
ulong oob_intr_disable_count;
|
||||
uint64 last_oob_irq_time;
|
||||
uint64 last_oob_irq_enable_time;
|
||||
uint64 last_oob_irq_disable_time;
|
||||
#endif /* BCMPCIE_OOB_HOST_WAKE */
|
||||
uint64 isr_entry_time;
|
||||
uint64 isr_exit_time;
|
||||
uint64 dpc_sched_time;
|
||||
uint64 dpc_entry_time;
|
||||
uint64 dpc_exit_time;
|
||||
uint64 resched_dpc_time;
|
||||
uint64 last_d3_inform_time;
|
||||
uint64 last_process_ctrlbuf_time;
|
||||
uint64 last_process_flowring_time;
|
||||
uint64 last_process_txcpl_time;
|
||||
uint64 last_process_rxcpl_time;
|
||||
uint64 last_process_infocpl_time;
|
||||
uint64 last_process_edl_time;
|
||||
uint64 last_suspend_start_time;
|
||||
uint64 last_suspend_end_time;
|
||||
uint64 last_resume_start_time;
|
||||
uint64 last_resume_end_time;
|
||||
uint64 last_non_ours_irq_time;
|
||||
uint8 hwa_enab_bmap;
|
||||
bool idma_enabled;
|
||||
bool ifrm_enabled;
|
||||
bool dar_enabled;
|
||||
uint32 dmaxfer_complete;
|
||||
uint8 dw_option;
|
||||
bool _dar_war;
|
||||
uint8 dma_chan;
|
||||
bool cto_enable; /* enable PCIE CTO Prevention and recovery */
|
||||
uint32 cto_threshold; /* PCIE CTO timeout threshold */
|
||||
bool cto_triggered; /* CTO is triggered */
|
||||
int pwr_req_ref;
|
||||
bool flr_force_fail; /* user intends to simulate flr force fail */
|
||||
bool intr_enabled; /* ready to receive interrupts from dongle */
|
||||
bool force_bt_quiesce; /* send bt_quiesce command to BT driver. */
|
||||
#if defined(DHD_H2D_LOG_TIME_SYNC)
|
||||
ulong dhd_rte_time_sync_count; /* OSL_SYSUPTIME_US() */
|
||||
#endif /* DHD_H2D_LOG_TIME_SYNC */
|
||||
bool rc_ep_aspm_cap; /* RC and EP ASPM capable */
|
||||
bool rc_ep_l1ss_cap; /* EC and EP L1SS capable */
|
||||
uint16 hp2p_txcpl_max_items;
|
||||
uint16 hp2p_rxcpl_max_items;
|
||||
/* PCIE coherent status */
|
||||
uint32 coherent_state;
|
||||
} dhd_bus_t;
|
||||
|
||||
#ifdef DHD_MSI_SUPPORT
|
||||
extern uint enable_msi;
|
||||
#endif /* DHD_MSI_SUPPORT */
|
||||
|
||||
enum {
|
||||
PCIE_INTX = 0,
|
||||
PCIE_MSI = 1
|
||||
};
|
||||
|
||||
/* function declarations */
|
||||
|
||||
extern uint32* dhdpcie_bus_reg_map(osl_t *osh, ulong addr, int size);
|
||||
extern int dhdpcie_bus_register(void);
|
||||
extern void dhdpcie_bus_unregister(void);
|
||||
extern bool dhdpcie_chipmatch(uint16 vendor, uint16 device);
|
||||
|
||||
extern int dhdpcie_bus_attach(osl_t *osh, dhd_bus_t **bus_ptr,
|
||||
volatile char *regs, volatile char *tcm, void *pci_dev);
|
||||
extern uint32 dhdpcie_bus_cfg_read_dword(struct dhd_bus *bus, uint32 addr, uint32 size);
|
||||
extern void dhdpcie_bus_cfg_write_dword(struct dhd_bus *bus, uint32 addr, uint32 size, uint32 data);
|
||||
extern void dhdpcie_bus_intr_enable(struct dhd_bus *bus);
|
||||
extern void dhdpcie_bus_intr_disable(struct dhd_bus *bus);
|
||||
extern int dhpcie_bus_mask_interrupt(dhd_bus_t *bus);
|
||||
extern void dhdpcie_bus_release(struct dhd_bus *bus);
|
||||
extern int32 dhdpcie_bus_isr(struct dhd_bus *bus);
|
||||
extern void dhdpcie_free_irq(dhd_bus_t *bus);
|
||||
extern void dhdpcie_bus_ringbell_fast(struct dhd_bus *bus, uint32 value);
|
||||
extern void dhdpcie_bus_ringbell_2_fast(struct dhd_bus *bus, uint32 value, bool devwake);
|
||||
extern void dhdpcie_dongle_reset(dhd_bus_t *bus);
|
||||
#ifdef DHD_PCIE_NATIVE_RUNTIMEPM
|
||||
extern int dhdpcie_bus_suspend(struct dhd_bus *bus, bool state, bool byint);
|
||||
#else
|
||||
extern int dhdpcie_bus_suspend(struct dhd_bus *bus, bool state);
|
||||
#endif /* DHD_PCIE_NATIVE_RUNTIMEPM */
|
||||
extern int dhdpcie_pci_suspend_resume(struct dhd_bus *bus, bool state);
|
||||
extern uint32 dhdpcie_force_alp(struct dhd_bus *bus, bool enable);
|
||||
extern uint32 dhdpcie_set_l1_entry_time(struct dhd_bus *bus, int force_l1_entry_time);
|
||||
extern bool dhdpcie_tcm_valid(dhd_bus_t *bus);
|
||||
extern void dhdpcie_pme_active(osl_t *osh, bool enable);
|
||||
extern bool dhdpcie_pme_cap(osl_t *osh);
|
||||
extern uint32 dhdpcie_lcreg(osl_t *osh, uint32 mask, uint32 val);
|
||||
extern void dhdpcie_set_pmu_min_res_mask(struct dhd_bus *bus, uint min_res_mask);
|
||||
extern uint8 dhdpcie_clkreq(osl_t *osh, uint32 mask, uint32 val);
|
||||
extern int dhdpcie_disable_irq(dhd_bus_t *bus);
|
||||
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 uint32 dhdpcie_rc_config_read(dhd_bus_t *bus, uint offset);
|
||||
extern uint32 dhdpcie_rc_access_cap(dhd_bus_t *bus, int cap, uint offset, bool is_ext,
|
||||
bool is_write, uint32 writeval);
|
||||
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 int dhdpcie_start_host_pcieclock(dhd_bus_t *bus);
|
||||
extern int dhdpcie_stop_host_pcieclock(dhd_bus_t *bus);
|
||||
extern int dhdpcie_disable_device(dhd_bus_t *bus);
|
||||
extern int dhdpcie_alloc_resource(dhd_bus_t *bus);
|
||||
extern void dhdpcie_free_resource(dhd_bus_t *bus);
|
||||
extern void dhdpcie_dump_resource(dhd_bus_t *bus);
|
||||
extern int dhdpcie_bus_request_irq(struct dhd_bus *bus);
|
||||
void dhdpcie_os_setbar1win(dhd_bus_t *bus, uint32 addr);
|
||||
void dhdpcie_os_wtcm8(dhd_bus_t *bus, ulong offset, uint8 data);
|
||||
uint8 dhdpcie_os_rtcm8(dhd_bus_t *bus, ulong offset);
|
||||
void dhdpcie_os_wtcm16(dhd_bus_t *bus, ulong offset, uint16 data);
|
||||
uint16 dhdpcie_os_rtcm16(dhd_bus_t *bus, ulong offset);
|
||||
void dhdpcie_os_wtcm32(dhd_bus_t *bus, ulong offset, uint32 data);
|
||||
uint32 dhdpcie_os_rtcm32(dhd_bus_t *bus, ulong offset);
|
||||
#ifdef DHD_SUPPORT_64BIT
|
||||
void dhdpcie_os_wtcm64(dhd_bus_t *bus, ulong offset, uint64 data);
|
||||
uint64 dhdpcie_os_rtcm64(dhd_bus_t *bus, ulong offset);
|
||||
#endif // endif
|
||||
|
||||
extern int dhdpcie_enable_device(dhd_bus_t *bus);
|
||||
|
||||
#ifdef BCMPCIE_OOB_HOST_WAKE
|
||||
extern int dhdpcie_oob_intr_register(dhd_bus_t *bus);
|
||||
extern void dhdpcie_oob_intr_unregister(dhd_bus_t *bus);
|
||||
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);
|
||||
#endif /* BCMPCIE_OOB_HOST_WAKE */
|
||||
|
||||
#if defined(CONFIG_ARCH_EXYNOS)
|
||||
#define SAMSUNG_PCIE_VENDOR_ID 0x144d
|
||||
#if defined(CONFIG_MACH_UNIVERSAL7420) || defined(CONFIG_SOC_EXYNOS7420)
|
||||
#define SAMSUNG_PCIE_DEVICE_ID 0xa575
|
||||
#define SAMSUNG_PCIE_CH_NUM 1
|
||||
#elif defined(CONFIG_SOC_EXYNOS8890)
|
||||
#define SAMSUNG_PCIE_DEVICE_ID 0xa544
|
||||
#define SAMSUNG_PCIE_CH_NUM 0
|
||||
#elif defined(CONFIG_SOC_EXYNOS8895) || defined(CONFIG_SOC_EXYNOS9810) || \
|
||||
defined(CONFIG_SOC_EXYNOS9820)
|
||||
#define SAMSUNG_PCIE_DEVICE_ID 0xecec
|
||||
#define SAMSUNG_PCIE_CH_NUM 0
|
||||
#else
|
||||
#error "Not supported platform"
|
||||
#endif /* CONFIG_SOC_EXYNOSXXXX & CONFIG_MACH_UNIVERSALXXXX */
|
||||
#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)
|
||||
#define MSM_PCIE_DEVICE_ID 0x0106
|
||||
#else
|
||||
#error "Not supported platform"
|
||||
#endif // 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 */
|
||||
|
||||
#define HIKEY_PCIE_VENDOR_ID 0x19e5
|
||||
#define HIKEY_PCIE_DEVICE_ID 0x3660
|
||||
|
||||
#define DUMMY_PCIE_VENDOR_ID 0xffff
|
||||
#define DUMMY_PCIE_DEVICE_ID 0xffff
|
||||
|
||||
#if defined(CONFIG_ARCH_EXYNOS)
|
||||
#define PCIE_RC_VENDOR_ID SAMSUNG_PCIE_VENDOR_ID
|
||||
#define PCIE_RC_DEVICE_ID SAMSUNG_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
|
||||
#else
|
||||
#define PCIE_RC_VENDOR_ID HIKEY_PCIE_VENDOR_ID
|
||||
#define PCIE_RC_DEVICE_ID HIKEY_PCIE_DEVICE_ID
|
||||
#endif /* CONFIG_ARCH_EXYNOS */
|
||||
|
||||
#define DHD_REGULAR_RING 0
|
||||
#define DHD_HP2P_RING 1
|
||||
|
||||
#ifdef USE_EXYNOS_PCIE_RC_PMPATCH
|
||||
extern int exynos_pcie_pm_suspend(int ch_num);
|
||||
extern int exynos_pcie_pm_resume(int ch_num);
|
||||
#endif /* USE_EXYNOS_PCIE_RC_PMPATCH */
|
||||
|
||||
#ifdef CONFIG_ARCH_TEGRA
|
||||
extern int tegra_pcie_pm_suspend(void);
|
||||
extern int tegra_pcie_pm_resume(void);
|
||||
#endif /* CONFIG_ARCH_TEGRA */
|
||||
|
||||
extern int dhd_buzzz_dump_dngl(dhd_bus_t *bus);
|
||||
#ifdef IDLE_TX_FLOW_MGMT
|
||||
extern int dhd_bus_flow_ring_resume_request(struct dhd_bus *bus, void *arg);
|
||||
extern void dhd_bus_flow_ring_resume_response(struct dhd_bus *bus, uint16 flowid, int32 status);
|
||||
extern int dhd_bus_flow_ring_suspend_request(struct dhd_bus *bus, void *arg);
|
||||
extern void dhd_bus_flow_ring_suspend_response(struct dhd_bus *bus, uint16 flowid, uint32 status);
|
||||
extern void dhd_flow_ring_move_to_active_list_head(struct dhd_bus *bus,
|
||||
flow_ring_node_t *flow_ring_node);
|
||||
extern void dhd_flow_ring_add_to_active_list(struct dhd_bus *bus,
|
||||
flow_ring_node_t *flow_ring_node);
|
||||
extern void dhd_flow_ring_delete_from_active_list(struct dhd_bus *bus,
|
||||
flow_ring_node_t *flow_ring_node);
|
||||
extern void __dhd_flow_ring_delete_from_active_list(struct dhd_bus *bus,
|
||||
flow_ring_node_t *flow_ring_node);
|
||||
#endif /* IDLE_TX_FLOW_MGMT */
|
||||
|
||||
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);
|
||||
#endif /* DHD_WAKE_STATUS */
|
||||
extern bool dhdpcie_bus_get_pcie_hostready_supported(dhd_bus_t *bus);
|
||||
extern void dhd_bus_hostready(struct dhd_bus *bus);
|
||||
extern void dhdpcie_bus_enab_pcie_dw(dhd_bus_t *bus, uint8 dw_option);
|
||||
extern int dhdpcie_irq_disabled(struct dhd_bus *bus);
|
||||
|
||||
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; }
|
||||
|
||||
int dhdpcie_config_check(dhd_bus_t *bus);
|
||||
int dhdpcie_config_restore(dhd_bus_t *bus, bool restore_pmcsr);
|
||||
int dhdpcie_config_save(dhd_bus_t *bus);
|
||||
int dhdpcie_set_pwr_state(dhd_bus_t *bus, uint state);
|
||||
|
||||
extern bool dhdpcie_bus_get_pcie_hwa_supported(dhd_bus_t *bus);
|
||||
extern bool dhdpcie_bus_get_pcie_idma_supported(dhd_bus_t *bus);
|
||||
extern bool dhdpcie_bus_get_pcie_ifrm_supported(dhd_bus_t *bus);
|
||||
extern bool dhdpcie_bus_get_pcie_dar_supported(dhd_bus_t *bus);
|
||||
|
||||
static INLINE uint32
|
||||
dhd_pcie_config_read(osl_t *osh, uint offset, uint size)
|
||||
{
|
||||
OSL_DELAY(100);
|
||||
return OSL_PCI_READ_CONFIG(osh, offset, size);
|
||||
}
|
||||
|
||||
static INLINE uint32
|
||||
dhd_pcie_corereg_read(si_t *sih, uint val)
|
||||
{
|
||||
OSL_DELAY(100);
|
||||
si_corereg(sih, sih->buscoreidx, OFFSETOF(sbpcieregs_t, configaddr), ~0, val);
|
||||
return si_corereg(sih, sih->buscoreidx, OFFSETOF(sbpcieregs_t, configdata), 0, 0);
|
||||
}
|
||||
|
||||
extern int dhdpcie_get_fwpath_otp(dhd_bus_t *bus, char *fw_path, char *nv_path,
|
||||
char *clm_path, char *txcap_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 // endif
|
||||
|
||||
#endif /* dhd_pcie_h */
|
||||
File diff suppressed because it is too large
Load Diff
4435
drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd_wifi6/dhd_pno.c
Normal file
4435
drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd_wifi6/dhd_pno.c
Normal file
File diff suppressed because it is too large
Load Diff
585
drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd_wifi6/dhd_pno.h
Normal file
585
drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd_wifi6/dhd_pno.h
Normal file
@@ -0,0 +1,585 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Header file of Broadcom Dongle Host Driver (DHD)
|
||||
* Prefered Network Offload code and Wi-Fi Location Service(WLS) code.
|
||||
*
|
||||
* Copyright (C) 1999-2019, 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.
|
||||
*
|
||||
* Notwithstanding the above, under no circumstances may you combine this
|
||||
* software in any way with any other Broadcom software provided under a license
|
||||
* other than the GPL, without Broadcom's express prior written consent.
|
||||
*
|
||||
*
|
||||
* <<Broadcom-WL-IPTag/Open:>>
|
||||
*
|
||||
* $Id: dhd_pno.h 805174 2019-02-15 17:26:01Z $
|
||||
*/
|
||||
|
||||
#ifndef __DHD_PNO_H__
|
||||
#define __DHD_PNO_H__
|
||||
|
||||
#if defined(PNO_SUPPORT)
|
||||
#define PNO_TLV_PREFIX 'S'
|
||||
#define PNO_TLV_VERSION '1'
|
||||
#define PNO_TLV_SUBTYPE_LEGACY_PNO '2'
|
||||
#define PNO_TLV_RESERVED '0'
|
||||
|
||||
#define PNO_BATCHING_SET "SET"
|
||||
#define PNO_BATCHING_GET "GET"
|
||||
#define PNO_BATCHING_STOP "STOP"
|
||||
|
||||
#define PNO_PARAMS_DELIMETER " "
|
||||
#define PNO_PARAM_CHANNEL_DELIMETER ","
|
||||
#define PNO_PARAM_VALUE_DELLIMETER '='
|
||||
#define PNO_PARAM_SCANFREQ "SCANFREQ"
|
||||
#define PNO_PARAM_BESTN "BESTN"
|
||||
#define PNO_PARAM_MSCAN "MSCAN"
|
||||
#define PNO_PARAM_CHANNEL "CHANNEL"
|
||||
#define PNO_PARAM_RTT "RTT"
|
||||
|
||||
#define PNO_TLV_TYPE_SSID_IE 'S'
|
||||
#define PNO_TLV_TYPE_TIME 'T'
|
||||
#define PNO_TLV_FREQ_REPEAT 'R'
|
||||
#define PNO_TLV_FREQ_EXPO_MAX 'M'
|
||||
|
||||
#define MAXNUM_SSID_PER_ADD 16
|
||||
#define MAXNUM_PNO_PARAMS 2
|
||||
#define PNO_TLV_COMMON_LENGTH 1
|
||||
#define DEFAULT_BATCH_MSCAN 16
|
||||
|
||||
#define RESULTS_END_MARKER "----\n"
|
||||
#define SCAN_END_MARKER "####\n"
|
||||
#define AP_END_MARKER "====\n"
|
||||
#define PNO_RSSI_MARGIN_DBM 30
|
||||
|
||||
#define CSCAN_COMMAND "CSCAN "
|
||||
#define CSCAN_TLV_PREFIX 'S'
|
||||
#define CSCAN_TLV_VERSION 1
|
||||
#define CSCAN_TLV_SUBVERSION 0
|
||||
#define CSCAN_TLV_TYPE_SSID_IE 'S'
|
||||
#define CSCAN_TLV_TYPE_CHANNEL_IE 'C'
|
||||
#define CSCAN_TLV_TYPE_NPROBE_IE 'N'
|
||||
#define CSCAN_TLV_TYPE_ACTIVE_IE 'A'
|
||||
#define CSCAN_TLV_TYPE_PASSIVE_IE 'P'
|
||||
#define CSCAN_TLV_TYPE_HOME_IE 'H'
|
||||
#define CSCAN_TLV_TYPE_STYPE_IE 'T'
|
||||
|
||||
#define WL_SCAN_PARAMS_SSID_MAX 10
|
||||
#define GET_SSID "SSID="
|
||||
#define GET_CHANNEL "CH="
|
||||
#define GET_NPROBE "NPROBE="
|
||||
#define GET_ACTIVE_ASSOC_DWELL "ACTIVE="
|
||||
#define GET_PASSIVE_ASSOC_DWELL "PASSIVE="
|
||||
#define GET_HOME_DWELL "HOME="
|
||||
#define GET_SCAN_TYPE "TYPE="
|
||||
|
||||
#if defined(GSCAN_SUPPORT) || defined(DHD_GET_VALID_CHANNELS)
|
||||
#define GSCAN_MAX_CH_BUCKETS 8
|
||||
#define GSCAN_MAX_CHANNELS_IN_BUCKET 32
|
||||
#define GSCAN_MAX_AP_CACHE_PER_SCAN 32
|
||||
#define GSCAN_MAX_AP_CACHE 320
|
||||
#define GSCAN_BG_BAND_MASK (1 << 0)
|
||||
#define GSCAN_A_BAND_MASK (1 << 1)
|
||||
#define GSCAN_DFS_MASK (1 << 2)
|
||||
#define GSCAN_ABG_BAND_MASK (GSCAN_A_BAND_MASK | GSCAN_BG_BAND_MASK)
|
||||
#define GSCAN_BAND_MASK (GSCAN_ABG_BAND_MASK | GSCAN_DFS_MASK)
|
||||
|
||||
#define GSCAN_FLUSH_HOTLIST_CFG (1 << 0)
|
||||
#define GSCAN_FLUSH_SIGNIFICANT_CFG (1 << 1)
|
||||
#define GSCAN_FLUSH_SCAN_CFG (1 << 2)
|
||||
#define GSCAN_FLUSH_EPNO_CFG (1 << 3)
|
||||
#define GSCAN_FLUSH_ALL_CFG (GSCAN_FLUSH_SCAN_CFG | \
|
||||
GSCAN_FLUSH_SIGNIFICANT_CFG | \
|
||||
GSCAN_FLUSH_HOTLIST_CFG | \
|
||||
GSCAN_FLUSH_EPNO_CFG)
|
||||
#define DHD_EPNO_HIDDEN_SSID (1 << 0)
|
||||
#define DHD_EPNO_A_BAND_TRIG (1 << 1)
|
||||
#define DHD_EPNO_BG_BAND_TRIG (1 << 2)
|
||||
#define DHD_EPNO_STRICT_MATCH (1 << 3)
|
||||
#define DHD_EPNO_SAME_NETWORK (1 << 4)
|
||||
#define DHD_PNO_USE_SSID (DHD_EPNO_HIDDEN_SSID | DHD_EPNO_STRICT_MATCH)
|
||||
|
||||
/* Do not change GSCAN_BATCH_RETRIEVAL_COMPLETE */
|
||||
#define GSCAN_BATCH_RETRIEVAL_COMPLETE 0
|
||||
#define GSCAN_BATCH_RETRIEVAL_IN_PROGRESS 1
|
||||
#define GSCAN_BATCH_NO_THR_SET 101
|
||||
#define GSCAN_LOST_AP_WINDOW_DEFAULT 4
|
||||
#define GSCAN_MIN_BSSID_TIMEOUT 90
|
||||
#define GSCAN_BATCH_GET_MAX_WAIT 500
|
||||
#define CHANNEL_BUCKET_EMPTY_INDEX 0xFFFF
|
||||
#define GSCAN_RETRY_THRESHOLD 3
|
||||
|
||||
#define MAX_EPNO_SSID_NUM 64
|
||||
#endif /* GSCAN_SUPPORT || DHD_GET_VALID_CHANNELS */
|
||||
|
||||
enum scan_status {
|
||||
/* SCAN ABORT by other scan */
|
||||
PNO_STATUS_ABORT,
|
||||
/* RTT is presence or not */
|
||||
PNO_STATUS_RTT_PRESENCE,
|
||||
/* Disable PNO by Driver */
|
||||
PNO_STATUS_DISABLE,
|
||||
/* NORMAL BATCHING GET */
|
||||
PNO_STATUS_NORMAL,
|
||||
/* WLC_E_PFN_BEST_BATCHING */
|
||||
PNO_STATUS_EVENT,
|
||||
PNO_STATUS_MAX
|
||||
};
|
||||
#define PNO_STATUS_ABORT_MASK 0x0001
|
||||
#define PNO_STATUS_RTT_MASK 0x0002
|
||||
#define PNO_STATUS_DISABLE_MASK 0x0004
|
||||
#define PNO_STATUS_OOM_MASK 0x0010
|
||||
|
||||
enum index_mode {
|
||||
INDEX_OF_LEGACY_PARAMS,
|
||||
INDEX_OF_BATCH_PARAMS,
|
||||
INDEX_OF_HOTLIST_PARAMS,
|
||||
/* GSCAN includes hotlist scan and they do not run
|
||||
* independent of each other
|
||||
*/
|
||||
INDEX_OF_GSCAN_PARAMS = INDEX_OF_HOTLIST_PARAMS,
|
||||
INDEX_MODE_MAX
|
||||
};
|
||||
enum dhd_pno_status {
|
||||
DHD_PNO_DISABLED,
|
||||
DHD_PNO_ENABLED,
|
||||
DHD_PNO_SUSPEND
|
||||
};
|
||||
typedef struct cmd_tlv {
|
||||
char prefix;
|
||||
char version;
|
||||
char subtype;
|
||||
char reserved;
|
||||
} cmd_tlv_t;
|
||||
#if defined(GSCAN_SUPPORT) || defined(DHD_GET_VALID_CHANNELS)
|
||||
typedef enum {
|
||||
WIFI_BAND_UNSPECIFIED,
|
||||
WIFI_BAND_BG = 1, /* 2.4 GHz */
|
||||
WIFI_BAND_A = 2, /* 5 GHz without DFS */
|
||||
WIFI_BAND_A_DFS = 4, /* 5 GHz DFS only */
|
||||
WIFI_BAND_A_WITH_DFS = 6, /* 5 GHz with DFS */
|
||||
WIFI_BAND_ABG = 3, /* 2.4 GHz + 5 GHz; no DFS */
|
||||
WIFI_BAND_ABG_WITH_DFS = 7, /* 2.4 GHz + 5 GHz with DFS */
|
||||
} gscan_wifi_band_t;
|
||||
|
||||
typedef enum {
|
||||
HOTLIST_LOST,
|
||||
HOTLIST_FOUND
|
||||
} hotlist_type_t;
|
||||
|
||||
typedef enum dhd_pno_gscan_cmd_cfg {
|
||||
DHD_PNO_BATCH_SCAN_CFG_ID = 0,
|
||||
DHD_PNO_GEOFENCE_SCAN_CFG_ID,
|
||||
DHD_PNO_SIGNIFICANT_SCAN_CFG_ID,
|
||||
DHD_PNO_SCAN_CFG_ID,
|
||||
DHD_PNO_GET_CAPABILITIES,
|
||||
DHD_PNO_GET_BATCH_RESULTS,
|
||||
DHD_PNO_GET_CHANNEL_LIST,
|
||||
DHD_PNO_GET_NEW_EPNO_SSID_ELEM,
|
||||
DHD_PNO_EPNO_CFG_ID,
|
||||
DHD_PNO_GET_AUTOJOIN_CAPABILITIES,
|
||||
DHD_PNO_EPNO_PARAMS_ID
|
||||
} dhd_pno_gscan_cmd_cfg_t;
|
||||
|
||||
typedef enum dhd_pno_mode {
|
||||
/* Wi-Fi Legacy PNO Mode */
|
||||
DHD_PNO_NONE_MODE = 0,
|
||||
DHD_PNO_LEGACY_MODE = (1 << (0)),
|
||||
/* Wi-Fi Android BATCH SCAN Mode */
|
||||
DHD_PNO_BATCH_MODE = (1 << (1)),
|
||||
/* Wi-Fi Android Hotlist SCAN Mode */
|
||||
DHD_PNO_HOTLIST_MODE = (1 << (2)),
|
||||
/* Wi-Fi Google Android SCAN Mode */
|
||||
DHD_PNO_GSCAN_MODE = (1 << (3))
|
||||
} dhd_pno_mode_t;
|
||||
#else
|
||||
typedef enum dhd_pno_mode {
|
||||
/* Wi-Fi Legacy PNO Mode */
|
||||
DHD_PNO_NONE_MODE = 0,
|
||||
DHD_PNO_LEGACY_MODE = (1 << (0)),
|
||||
/* Wi-Fi Android BATCH SCAN Mode */
|
||||
DHD_PNO_BATCH_MODE = (1 << (1)),
|
||||
/* Wi-Fi Android Hotlist SCAN Mode */
|
||||
DHD_PNO_HOTLIST_MODE = (1 << (2))
|
||||
} dhd_pno_mode_t;
|
||||
#endif /* GSCAN_SUPPORT || DHD_GET_VALID_CHANNELS */
|
||||
|
||||
typedef struct dhd_pno_ssid {
|
||||
bool hidden;
|
||||
int8 rssi_thresh;
|
||||
uint8 dummy;
|
||||
uint16 SSID_len;
|
||||
uint32 flags;
|
||||
int32 wpa_auth;
|
||||
uchar SSID[DOT11_MAX_SSID_LEN];
|
||||
struct list_head list;
|
||||
} dhd_pno_ssid_t;
|
||||
|
||||
struct dhd_pno_bssid {
|
||||
struct ether_addr macaddr;
|
||||
/* Bit4: suppress_lost, Bit3: suppress_found */
|
||||
uint16 flags;
|
||||
struct list_head list;
|
||||
};
|
||||
|
||||
typedef struct dhd_pno_bestnet_entry {
|
||||
struct ether_addr BSSID;
|
||||
uint8 SSID_len;
|
||||
uint8 SSID[DOT11_MAX_SSID_LEN];
|
||||
int8 RSSI;
|
||||
uint8 channel;
|
||||
uint32 timestamp;
|
||||
uint16 rtt0; /* distance_cm based on RTT */
|
||||
uint16 rtt1; /* distance_cm based on sample standard deviation */
|
||||
unsigned long recorded_time;
|
||||
struct list_head list;
|
||||
} dhd_pno_bestnet_entry_t;
|
||||
#define BESTNET_ENTRY_SIZE (sizeof(dhd_pno_bestnet_entry_t))
|
||||
|
||||
typedef struct dhd_pno_bestnet_header {
|
||||
struct dhd_pno_bestnet_header *next;
|
||||
uint8 reason;
|
||||
uint32 tot_cnt;
|
||||
uint32 tot_size;
|
||||
struct list_head entry_list;
|
||||
} dhd_pno_best_header_t;
|
||||
#define BEST_HEADER_SIZE (sizeof(dhd_pno_best_header_t))
|
||||
|
||||
typedef struct dhd_pno_scan_results {
|
||||
dhd_pno_best_header_t *bestnetheader;
|
||||
uint8 cnt_header;
|
||||
struct list_head list;
|
||||
} dhd_pno_scan_results_t;
|
||||
#define SCAN_RESULTS_SIZE (sizeof(dhd_pno_scan_results_t))
|
||||
|
||||
struct dhd_pno_get_batch_info {
|
||||
/* info related to get batch */
|
||||
char *buf;
|
||||
bool batch_started;
|
||||
uint32 tot_scan_cnt;
|
||||
uint32 expired_tot_scan_cnt;
|
||||
uint32 top_node_cnt;
|
||||
uint32 bufsize;
|
||||
uint32 bytes_written;
|
||||
int reason;
|
||||
struct list_head scan_results_list;
|
||||
struct list_head expired_scan_results_list;
|
||||
};
|
||||
struct dhd_pno_legacy_params {
|
||||
uint16 scan_fr;
|
||||
uint16 chan_list[WL_NUMCHANNELS];
|
||||
uint16 nchan;
|
||||
int pno_repeat;
|
||||
int pno_freq_expo_max;
|
||||
int nssid;
|
||||
struct list_head ssid_list;
|
||||
};
|
||||
struct dhd_pno_batch_params {
|
||||
int32 scan_fr;
|
||||
uint8 bestn;
|
||||
uint8 mscan;
|
||||
uint8 band;
|
||||
uint16 chan_list[WL_NUMCHANNELS];
|
||||
uint16 nchan;
|
||||
uint16 rtt;
|
||||
struct dhd_pno_get_batch_info get_batch;
|
||||
};
|
||||
struct dhd_pno_hotlist_params {
|
||||
uint8 band;
|
||||
int32 scan_fr;
|
||||
uint16 chan_list[WL_NUMCHANNELS];
|
||||
uint16 nchan;
|
||||
uint16 nbssid;
|
||||
struct list_head bssid_list;
|
||||
};
|
||||
#if defined(GSCAN_SUPPORT) || defined(DHD_GET_VALID_CHANNELS)
|
||||
#define DHD_PNO_REPORT_NO_BATCH (1 << 2)
|
||||
|
||||
typedef struct dhd_pno_gscan_channel_bucket {
|
||||
uint16 bucket_freq_multiple;
|
||||
/* band = 1 All bg band channels,
|
||||
* band = 2 All a band channels,
|
||||
* band = 0 chan_list channels
|
||||
*/
|
||||
uint16 band;
|
||||
uint8 report_flag;
|
||||
uint8 num_channels;
|
||||
uint16 repeat;
|
||||
uint16 bucket_max_multiple;
|
||||
uint16 chan_list[GSCAN_MAX_CHANNELS_IN_BUCKET];
|
||||
} dhd_pno_gscan_channel_bucket_t;
|
||||
|
||||
#define DHD_PNO_AUTH_CODE_OPEN 1 /* Open */
|
||||
#define DHD_PNO_AUTH_CODE_PSK 2 /* WPA_PSK or WPA2PSK */
|
||||
#define DHD_PNO_AUTH_CODE_EAPOL 4 /* any EAPOL */
|
||||
|
||||
#define DHD_EPNO_DEFAULT_INDEX 0xFFFFFFFF
|
||||
|
||||
typedef struct dhd_epno_params {
|
||||
uint8 ssid[DOT11_MAX_SSID_LEN];
|
||||
uint8 ssid_len;
|
||||
int8 rssi_thresh;
|
||||
uint8 flags;
|
||||
uint8 auth;
|
||||
/* index required only for visble ssid */
|
||||
uint32 index;
|
||||
struct list_head list;
|
||||
} dhd_epno_params_t;
|
||||
|
||||
typedef struct dhd_epno_results {
|
||||
uint8 ssid[DOT11_MAX_SSID_LEN];
|
||||
uint8 ssid_len;
|
||||
int8 rssi;
|
||||
uint16 channel;
|
||||
uint16 flags;
|
||||
struct ether_addr bssid;
|
||||
} dhd_epno_results_t;
|
||||
|
||||
typedef struct dhd_pno_swc_evt_param {
|
||||
uint16 results_rxed_so_far;
|
||||
wl_pfn_significant_net_t *change_array;
|
||||
} dhd_pno_swc_evt_param_t;
|
||||
|
||||
typedef struct wifi_gscan_result {
|
||||
uint64 ts; /* Time of discovery */
|
||||
char ssid[DOT11_MAX_SSID_LEN+1]; /* null terminated */
|
||||
struct ether_addr macaddr; /* BSSID */
|
||||
uint32 channel; /* channel frequency in MHz */
|
||||
int32 rssi; /* in db */
|
||||
uint64 rtt; /* in nanoseconds */
|
||||
uint64 rtt_sd; /* standard deviation in rtt */
|
||||
uint16 beacon_period; /* units are Kusec */
|
||||
uint16 capability; /* Capability information */
|
||||
uint32 pad;
|
||||
} wifi_gscan_result_t;
|
||||
|
||||
typedef struct wifi_gscan_full_result {
|
||||
wifi_gscan_result_t fixed;
|
||||
uint32 scan_ch_bucket;
|
||||
uint32 ie_length; /* byte length of Information Elements */
|
||||
char ie_data[1]; /* IE data to follow */
|
||||
} wifi_gscan_full_result_t;
|
||||
|
||||
typedef struct gscan_results_cache {
|
||||
struct gscan_results_cache *next;
|
||||
uint8 scan_id;
|
||||
uint8 flag;
|
||||
uint8 tot_count;
|
||||
uint8 tot_consumed;
|
||||
uint32 scan_ch_bucket;
|
||||
wifi_gscan_result_t results[1];
|
||||
} gscan_results_cache_t;
|
||||
|
||||
typedef struct dhd_pno_gscan_capabilities {
|
||||
int max_scan_cache_size;
|
||||
int max_scan_buckets;
|
||||
int max_ap_cache_per_scan;
|
||||
int max_rssi_sample_size;
|
||||
int max_scan_reporting_threshold;
|
||||
int max_hotlist_bssids;
|
||||
int max_hotlist_ssids;
|
||||
int max_significant_wifi_change_aps;
|
||||
int max_bssid_history_entries;
|
||||
int max_epno_ssid_crc32;
|
||||
int max_epno_hidden_ssid;
|
||||
int max_white_list_ssid;
|
||||
} dhd_pno_gscan_capabilities_t;
|
||||
|
||||
typedef struct dhd_epno_ssid_cfg {
|
||||
wl_ssid_ext_params_t params;
|
||||
uint32 num_epno_ssid;
|
||||
struct list_head epno_ssid_list;
|
||||
} dhd_epno_ssid_cfg_t;
|
||||
|
||||
struct dhd_pno_gscan_params {
|
||||
int32 scan_fr;
|
||||
uint8 bestn;
|
||||
uint8 mscan;
|
||||
uint8 buffer_threshold;
|
||||
uint8 swc_nbssid_threshold;
|
||||
uint8 swc_rssi_window_size;
|
||||
uint8 lost_ap_window;
|
||||
uint8 nchannel_buckets;
|
||||
uint8 reason;
|
||||
uint8 get_batch_flag;
|
||||
uint8 send_all_results_flag;
|
||||
uint16 max_ch_bucket_freq;
|
||||
gscan_results_cache_t *gscan_batch_cache;
|
||||
gscan_results_cache_t *gscan_hotlist_found;
|
||||
gscan_results_cache_t*gscan_hotlist_lost;
|
||||
uint16 nbssid_significant_change;
|
||||
uint16 nbssid_hotlist;
|
||||
struct dhd_pno_swc_evt_param param_significant;
|
||||
struct dhd_pno_gscan_channel_bucket channel_bucket[GSCAN_MAX_CH_BUCKETS];
|
||||
struct list_head hotlist_bssid_list;
|
||||
struct list_head significant_bssid_list;
|
||||
dhd_epno_ssid_cfg_t epno_cfg;
|
||||
uint32 scan_id;
|
||||
};
|
||||
|
||||
typedef struct gscan_scan_params {
|
||||
int32 scan_fr;
|
||||
uint16 nchannel_buckets;
|
||||
struct dhd_pno_gscan_channel_bucket channel_bucket[GSCAN_MAX_CH_BUCKETS];
|
||||
} gscan_scan_params_t;
|
||||
|
||||
typedef struct gscan_batch_params {
|
||||
uint8 bestn;
|
||||
uint8 mscan;
|
||||
uint8 buffer_threshold;
|
||||
} gscan_batch_params_t;
|
||||
|
||||
struct bssid_t {
|
||||
struct ether_addr macaddr;
|
||||
int16 rssi_reporting_threshold; /* 0 -> no reporting threshold */
|
||||
};
|
||||
|
||||
typedef struct gscan_hotlist_scan_params {
|
||||
uint16 lost_ap_window; /* number of scans to declare LOST */
|
||||
uint16 nbssid; /* number of bssids */
|
||||
struct bssid_t bssid[1]; /* n bssids to follow */
|
||||
} gscan_hotlist_scan_params_t;
|
||||
|
||||
#endif /* GSCAN_SUPPORT || DHD_GET_VALID_CHANNELS */
|
||||
|
||||
typedef union dhd_pno_params {
|
||||
struct dhd_pno_legacy_params params_legacy;
|
||||
struct dhd_pno_batch_params params_batch;
|
||||
struct dhd_pno_hotlist_params params_hotlist;
|
||||
#if defined(GSCAN_SUPPORT) || defined(DHD_GET_VALID_CHANNELS)
|
||||
struct dhd_pno_gscan_params params_gscan;
|
||||
#endif /* GSCAN_SUPPORT || DHD_GET_VALID_CHANNELS */
|
||||
} dhd_pno_params_t;
|
||||
|
||||
typedef struct dhd_pno_status_info {
|
||||
dhd_pub_t *dhd;
|
||||
struct work_struct work;
|
||||
struct mutex pno_mutex;
|
||||
#ifdef GSCAN_SUPPORT
|
||||
wait_queue_head_t batch_get_wait;
|
||||
#endif /* GSCAN_SUPPORT */
|
||||
struct completion get_batch_done;
|
||||
bool wls_supported; /* wifi location service supported or not */
|
||||
enum dhd_pno_status pno_status;
|
||||
enum dhd_pno_mode pno_mode;
|
||||
dhd_pno_params_t pno_params_arr[INDEX_MODE_MAX];
|
||||
struct list_head head_list;
|
||||
} dhd_pno_status_info_t;
|
||||
|
||||
/* wrapper functions */
|
||||
extern int
|
||||
dhd_dev_pno_enable(struct net_device *dev, int enable);
|
||||
|
||||
extern int
|
||||
dhd_dev_pno_stop_for_ssid(struct net_device *dev);
|
||||
|
||||
extern int
|
||||
dhd_dev_pno_set_for_ssid(struct net_device *dev, wlc_ssid_ext_t* ssids_local, int nssid,
|
||||
uint16 scan_fr, int pno_repeat, int pno_freq_expo_max, uint16 *channel_list, int nchan);
|
||||
|
||||
extern int
|
||||
dhd_dev_pno_set_for_batch(struct net_device *dev,
|
||||
struct dhd_pno_batch_params *batch_params);
|
||||
|
||||
extern int
|
||||
dhd_dev_pno_get_for_batch(struct net_device *dev, char *buf, int bufsize);
|
||||
|
||||
extern int
|
||||
dhd_dev_pno_stop_for_batch(struct net_device *dev);
|
||||
|
||||
extern int
|
||||
dhd_dev_pno_set_for_hotlist(struct net_device *dev, wl_pfn_bssid_t *p_pfn_bssid,
|
||||
struct dhd_pno_hotlist_params *hotlist_params);
|
||||
extern bool dhd_dev_is_legacy_pno_enabled(struct net_device *dev);
|
||||
#if defined(GSCAN_SUPPORT) || defined(DHD_GET_VALID_CHANNELS)
|
||||
extern void *
|
||||
dhd_dev_pno_get_gscan(struct net_device *dev, dhd_pno_gscan_cmd_cfg_t type, void *info,
|
||||
uint32 *len);
|
||||
#endif /* GSCAN_SUPPORT || DHD_GET_VALID_CHANNELS */
|
||||
#ifdef GSCAN_SUPPORT
|
||||
extern int
|
||||
dhd_dev_pno_set_cfg_gscan(struct net_device *dev, dhd_pno_gscan_cmd_cfg_t type,
|
||||
void *buf, bool flush);
|
||||
int dhd_dev_pno_lock_access_batch_results(struct net_device *dev);
|
||||
void dhd_dev_pno_unlock_access_batch_results(struct net_device *dev);
|
||||
extern int dhd_dev_pno_run_gscan(struct net_device *dev, bool run, bool flush);
|
||||
extern int dhd_dev_pno_enable_full_scan_result(struct net_device *dev, bool real_time);
|
||||
int dhd_retreive_batch_scan_results(dhd_pub_t *dhd);
|
||||
extern void * dhd_dev_hotlist_scan_event(struct net_device *dev,
|
||||
const void *data, int *send_evt_bytes, hotlist_type_t type, u32 *buf_len);
|
||||
void * dhd_dev_process_full_gscan_result(struct net_device *dev,
|
||||
const void *data, uint32 len, int *send_evt_bytes);
|
||||
extern int dhd_dev_gscan_batch_cache_cleanup(struct net_device *dev);
|
||||
extern void dhd_dev_gscan_hotlist_cache_cleanup(struct net_device *dev, hotlist_type_t type);
|
||||
extern int dhd_dev_wait_batch_results_complete(struct net_device *dev);
|
||||
extern void * dhd_dev_process_epno_result(struct net_device *dev,
|
||||
const void *data, uint32 event, int *send_evt_bytes);
|
||||
extern int dhd_dev_set_epno(struct net_device *dev);
|
||||
extern int dhd_dev_flush_fw_epno(struct net_device *dev);
|
||||
#endif /* GSCAN_SUPPORT */
|
||||
/* dhd pno fuctions */
|
||||
extern int dhd_pno_stop_for_ssid(dhd_pub_t *dhd);
|
||||
extern int dhd_pno_enable(dhd_pub_t *dhd, int enable);
|
||||
extern int dhd_pno_set_for_ssid(dhd_pub_t *dhd, wlc_ssid_ext_t* ssid_list, int nssid,
|
||||
uint16 scan_fr, int pno_repeat, int pno_freq_expo_max, uint16 *channel_list, int nchan);
|
||||
|
||||
extern int dhd_pno_set_for_batch(dhd_pub_t *dhd, struct dhd_pno_batch_params *batch_params);
|
||||
|
||||
extern int dhd_pno_get_for_batch(dhd_pub_t *dhd, char *buf, int bufsize, int reason);
|
||||
|
||||
extern int dhd_pno_stop_for_batch(dhd_pub_t *dhd);
|
||||
|
||||
extern int dhd_pno_set_for_hotlist(dhd_pub_t *dhd, wl_pfn_bssid_t *p_pfn_bssid,
|
||||
struct dhd_pno_hotlist_params *hotlist_params);
|
||||
|
||||
extern int dhd_pno_stop_for_hotlist(dhd_pub_t *dhd);
|
||||
|
||||
extern int dhd_pno_event_handler(dhd_pub_t *dhd, wl_event_msg_t *event, void *event_data);
|
||||
extern int dhd_pno_init(dhd_pub_t *dhd);
|
||||
extern int dhd_pno_deinit(dhd_pub_t *dhd);
|
||||
extern bool dhd_is_pno_supported(dhd_pub_t *dhd);
|
||||
extern bool dhd_is_legacy_pno_enabled(dhd_pub_t *dhd);
|
||||
#if defined(GSCAN_SUPPORT) || defined(DHD_GET_VALID_CHANNELS)
|
||||
extern void * dhd_pno_get_gscan(dhd_pub_t *dhd, dhd_pno_gscan_cmd_cfg_t type, void *info,
|
||||
uint32 *len);
|
||||
#endif /* GSCAN_SUPPORT || DHD_GET_VALID_CHANNELS */
|
||||
#ifdef GSCAN_SUPPORT
|
||||
extern int dhd_pno_set_cfg_gscan(dhd_pub_t *dhd, dhd_pno_gscan_cmd_cfg_t type,
|
||||
void *buf, bool flush);
|
||||
extern int dhd_pno_lock_batch_results(dhd_pub_t *dhd);
|
||||
extern void dhd_pno_unlock_batch_results(dhd_pub_t *dhd);
|
||||
extern int dhd_pno_initiate_gscan_request(dhd_pub_t *dhd, bool run, bool flush);
|
||||
extern int dhd_pno_enable_full_scan_result(dhd_pub_t *dhd, bool real_time_flag);
|
||||
extern int dhd_pno_cfg_gscan(dhd_pub_t *dhd, dhd_pno_gscan_cmd_cfg_t type, void *buf);
|
||||
extern int dhd_dev_retrieve_batch_scan(struct net_device *dev);
|
||||
extern void *dhd_handle_hotlist_scan_evt(dhd_pub_t *dhd, const void *event_data,
|
||||
int *send_evt_bytes, hotlist_type_t type, u32 *buf_len);
|
||||
extern void *dhd_process_full_gscan_result(dhd_pub_t *dhd, const void *event_data,
|
||||
uint32 len, int *send_evt_bytes);
|
||||
extern int dhd_gscan_batch_cache_cleanup(dhd_pub_t *dhd);
|
||||
extern void dhd_gscan_hotlist_cache_cleanup(dhd_pub_t *dhd, hotlist_type_t type);
|
||||
extern int dhd_wait_batch_results_complete(dhd_pub_t *dhd);
|
||||
extern void * dhd_pno_process_epno_result(dhd_pub_t *dhd, const void *data,
|
||||
uint32 event, int *size);
|
||||
extern void dhd_pno_translate_epno_fw_flags(uint32 *flags);
|
||||
extern int dhd_pno_set_epno(dhd_pub_t *dhd);
|
||||
extern int dhd_pno_flush_fw_epno(dhd_pub_t *dhd);
|
||||
extern void dhd_pno_set_epno_auth_flag(uint32 *wpa_auth);
|
||||
#endif /* GSCAN_SUPPORT */
|
||||
#endif // endif
|
||||
|
||||
#endif /* __DHD_PNO_H__ */
|
||||
@@ -0,0 +1,243 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Header file describing the internal (inter-module) DHD interfaces.
|
||||
*
|
||||
* Provides type definitions and function prototypes used to link the
|
||||
* DHD OS, bus, and protocol modules.
|
||||
*
|
||||
* Copyright (C) 1999-2019, 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.
|
||||
*
|
||||
* Notwithstanding the above, under no circumstances may you combine this
|
||||
* software in any way with any other Broadcom software provided under a license
|
||||
* other than the GPL, without Broadcom's express prior written consent.
|
||||
*
|
||||
*
|
||||
* <<Broadcom-WL-IPTag/Open:>>
|
||||
*
|
||||
* $Id: dhd_proto.h 814912 2019-04-15 10:38:59Z $
|
||||
*/
|
||||
|
||||
#ifndef _dhd_proto_h_
|
||||
#define _dhd_proto_h_
|
||||
|
||||
#include <dhdioctl.h>
|
||||
#include <wlioctl.h>
|
||||
#ifdef BCMPCIE
|
||||
#include <dhd_flowring.h>
|
||||
#endif // endif
|
||||
|
||||
#define DEFAULT_IOCTL_RESP_TIMEOUT 5000
|
||||
#ifndef IOCTL_RESP_TIMEOUT
|
||||
/* In milli second default value for Production FW */
|
||||
#define IOCTL_RESP_TIMEOUT DEFAULT_IOCTL_RESP_TIMEOUT
|
||||
#endif /* IOCTL_RESP_TIMEOUT */
|
||||
|
||||
/* In milli second default value for Production FW */
|
||||
#define IOCTL_DMAXFER_TIMEOUT 10000
|
||||
|
||||
#ifndef MFG_IOCTL_RESP_TIMEOUT
|
||||
#define MFG_IOCTL_RESP_TIMEOUT 20000 /* In milli second default value for MFG FW */
|
||||
#endif /* MFG_IOCTL_RESP_TIMEOUT */
|
||||
|
||||
#define DEFAULT_D3_ACK_RESP_TIMEOUT 2000
|
||||
#ifndef D3_ACK_RESP_TIMEOUT
|
||||
#define D3_ACK_RESP_TIMEOUT DEFAULT_D3_ACK_RESP_TIMEOUT
|
||||
#endif /* D3_ACK_RESP_TIMEOUT */
|
||||
|
||||
#define DEFAULT_DHD_BUS_BUSY_TIMEOUT (IOCTL_RESP_TIMEOUT + 1000)
|
||||
#ifndef DHD_BUS_BUSY_TIMEOUT
|
||||
#define DHD_BUS_BUSY_TIMEOUT DEFAULT_DHD_BUS_BUSY_TIMEOUT
|
||||
#endif /* DEFAULT_DHD_BUS_BUSY_TIMEOUT */
|
||||
|
||||
#define DS_EXIT_TIMEOUT 1000 /* In ms */
|
||||
#define DS_ENTER_TIMEOUT 1000 /* In ms */
|
||||
|
||||
#define IOCTL_DISABLE_TIMEOUT 0
|
||||
|
||||
/*
|
||||
* Exported from the dhd protocol module (dhd_cdc, dhd_rndis)
|
||||
*/
|
||||
|
||||
/* Linkage, sets prot link and updates hdrlen in pub */
|
||||
extern int dhd_prot_attach(dhd_pub_t *dhdp);
|
||||
|
||||
/* Initilizes the index block for dma'ing indices */
|
||||
extern int dhd_prot_dma_indx_init(dhd_pub_t *dhdp, uint32 rw_index_sz,
|
||||
uint8 type, uint32 length);
|
||||
|
||||
/* Unlink, frees allocated protocol memory (including dhd_prot) */
|
||||
extern void dhd_prot_detach(dhd_pub_t *dhdp);
|
||||
|
||||
/* Initialize protocol: sync w/dongle state.
|
||||
* Sets dongle media info (iswl, drv_version, mac address).
|
||||
*/
|
||||
extern int dhd_sync_with_dongle(dhd_pub_t *dhdp);
|
||||
|
||||
/* Protocol initialization needed for IOCTL/IOVAR path */
|
||||
extern int dhd_prot_init(dhd_pub_t *dhd);
|
||||
|
||||
/* Stop protocol: sync w/dongle state. */
|
||||
extern void dhd_prot_stop(dhd_pub_t *dhdp);
|
||||
|
||||
/* Add any protocol-specific data header.
|
||||
* Caller must reserve prot_hdrlen prepend space.
|
||||
*/
|
||||
extern void dhd_prot_hdrpush(dhd_pub_t *, int ifidx, void *txp);
|
||||
extern uint dhd_prot_hdrlen(dhd_pub_t *, void *txp);
|
||||
|
||||
/* Remove any protocol-specific data header. */
|
||||
extern int dhd_prot_hdrpull(dhd_pub_t *, int *ifidx, void *rxp, uchar *buf, uint *len);
|
||||
|
||||
/* Use protocol to issue ioctl to dongle */
|
||||
extern int dhd_prot_ioctl(dhd_pub_t *dhd, int ifidx, wl_ioctl_t * ioc, void * buf, int len);
|
||||
|
||||
/* Handles a protocol control response asynchronously */
|
||||
extern int dhd_prot_ctl_complete(dhd_pub_t *dhd);
|
||||
|
||||
/* Check for and handle local prot-specific iovar commands */
|
||||
extern int dhd_prot_iovar_op(dhd_pub_t *dhdp, const char *name,
|
||||
void *params, int plen, void *arg, int len, bool set);
|
||||
|
||||
/* Add prot dump output to a buffer */
|
||||
extern void dhd_prot_dump(dhd_pub_t *dhdp, struct bcmstrbuf *strbuf);
|
||||
|
||||
/* Dump extended trap data */
|
||||
extern int dhd_prot_dump_extended_trap(dhd_pub_t *dhdp, struct bcmstrbuf *b, bool raw);
|
||||
|
||||
/* Update local copy of dongle statistics */
|
||||
extern void dhd_prot_dstats(dhd_pub_t *dhdp);
|
||||
|
||||
extern int dhd_ioctl(dhd_pub_t * dhd_pub, dhd_ioctl_t *ioc, void * buf, uint buflen);
|
||||
|
||||
extern int dhd_preinit_ioctls(dhd_pub_t *dhd);
|
||||
|
||||
extern int dhd_process_pkt_reorder_info(dhd_pub_t *dhd, uchar *reorder_info_buf,
|
||||
uint reorder_info_len, void **pkt, uint32 *free_buf_count);
|
||||
|
||||
#ifdef BCMPCIE
|
||||
extern bool dhd_prot_process_msgbuf_txcpl(dhd_pub_t *dhd, uint bound, int ringtype);
|
||||
extern bool dhd_prot_process_msgbuf_rxcpl(dhd_pub_t *dhd, uint bound, int ringtype);
|
||||
extern bool dhd_prot_process_msgbuf_infocpl(dhd_pub_t *dhd, uint bound);
|
||||
extern int dhd_prot_process_ctrlbuf(dhd_pub_t * dhd);
|
||||
extern int dhd_prot_process_trapbuf(dhd_pub_t * dhd);
|
||||
extern bool dhd_prot_dtohsplit(dhd_pub_t * dhd);
|
||||
extern int dhd_post_dummy_msg(dhd_pub_t *dhd);
|
||||
extern int dhdmsgbuf_lpbk_req(dhd_pub_t *dhd, uint len);
|
||||
extern void dhd_prot_rx_dataoffset(dhd_pub_t *dhd, uint32 offset);
|
||||
extern int dhd_prot_txdata(dhd_pub_t *dhd, void *p, uint8 ifidx);
|
||||
extern int dhdmsgbuf_dmaxfer_req(dhd_pub_t *dhd,
|
||||
uint len, uint srcdelay, uint destdelay, uint d11_lpbk, uint core_num);
|
||||
extern int dhdmsgbuf_dmaxfer_status(dhd_pub_t *dhd, dma_xfer_info_t *result);
|
||||
|
||||
extern void dhd_dma_buf_init(dhd_pub_t *dhd, void *dma_buf,
|
||||
void *va, uint32 len, dmaaddr_t pa, void *dmah, void *secdma);
|
||||
extern void dhd_prot_flowrings_pool_release(dhd_pub_t *dhd,
|
||||
uint16 flowid, void *msgbuf_ring);
|
||||
extern int dhd_prot_flow_ring_create(dhd_pub_t *dhd, flow_ring_node_t *flow_ring_node);
|
||||
extern int dhd_post_tx_ring_item(dhd_pub_t *dhd, void *PKTBUF, uint8 ifindex);
|
||||
extern int dhd_prot_flow_ring_delete(dhd_pub_t *dhd, flow_ring_node_t *flow_ring_node);
|
||||
extern int dhd_prot_flow_ring_flush(dhd_pub_t *dhd, flow_ring_node_t *flow_ring_node);
|
||||
extern int dhd_prot_ringupd_dump(dhd_pub_t *dhd, struct bcmstrbuf *b);
|
||||
extern uint32 dhd_prot_metadata_dbg_set(dhd_pub_t *dhd, bool val);
|
||||
extern uint32 dhd_prot_metadata_dbg_get(dhd_pub_t *dhd);
|
||||
extern uint32 dhd_prot_metadatalen_set(dhd_pub_t *dhd, uint32 val, bool rx);
|
||||
extern uint32 dhd_prot_metadatalen_get(dhd_pub_t *dhd, bool rx);
|
||||
extern void dhd_prot_print_flow_ring(dhd_pub_t *dhd, void *msgbuf_flow_info,
|
||||
struct bcmstrbuf *strbuf, const char * fmt);
|
||||
extern void dhd_prot_print_info(dhd_pub_t *dhd, struct bcmstrbuf *strbuf);
|
||||
extern void dhd_prot_update_txflowring(dhd_pub_t *dhdp, uint16 flow_id, void *msgring_info);
|
||||
extern void dhd_prot_txdata_write_flush(dhd_pub_t *dhd, uint16 flow_id);
|
||||
extern uint32 dhd_prot_txp_threshold(dhd_pub_t *dhd, bool set, uint32 val);
|
||||
extern void dhd_prot_reset(dhd_pub_t *dhd);
|
||||
extern uint16 dhd_get_max_flow_rings(dhd_pub_t *dhd);
|
||||
|
||||
#ifdef IDLE_TX_FLOW_MGMT
|
||||
extern int dhd_prot_flow_ring_batch_suspend_request(dhd_pub_t *dhd, uint16 *ringid, uint16 count);
|
||||
extern int dhd_prot_flow_ring_resume(dhd_pub_t *dhd, flow_ring_node_t *flow_ring_node);
|
||||
#endif /* IDLE_TX_FLOW_MGMT */
|
||||
extern int dhd_prot_init_info_rings(dhd_pub_t *dhd);
|
||||
#ifdef DHD_HP2P
|
||||
extern int dhd_prot_init_hp2p_rings(dhd_pub_t *dhd);
|
||||
#endif /* DHD_HP2P */
|
||||
|
||||
extern int dhd_prot_check_tx_resource(dhd_pub_t *dhd);
|
||||
|
||||
extern void dhd_prot_update_pktid_txq_stop_cnt(dhd_pub_t *dhd);
|
||||
extern void dhd_prot_update_pktid_txq_start_cnt(dhd_pub_t *dhd);
|
||||
#else
|
||||
static INLINE void dhd_prot_update_pktid_txq_stop_cnt(dhd_pub_t *dhd) { return; }
|
||||
static INLINE void dhd_prot_update_pktid_txq_start_cnt(dhd_pub_t *dhd) { return; }
|
||||
#endif /* BCMPCIE */
|
||||
|
||||
#ifdef DHD_LB
|
||||
extern void dhd_lb_tx_compl_handler(unsigned long data);
|
||||
extern void dhd_lb_rx_compl_handler(unsigned long data);
|
||||
extern void dhd_lb_rx_process_handler(unsigned long data);
|
||||
#endif /* DHD_LB */
|
||||
extern int dhd_prot_h2d_mbdata_send_ctrlmsg(dhd_pub_t *dhd, uint32 mb_data);
|
||||
|
||||
#ifdef BCMPCIE
|
||||
extern int dhd_prot_send_host_timestamp(dhd_pub_t *dhdp, uchar *tlv, uint16 tlv_len,
|
||||
uint16 seq, uint16 xt_id);
|
||||
extern bool dhd_prot_data_path_tx_timestamp_logging(dhd_pub_t *dhd, bool enable, bool set);
|
||||
extern bool dhd_prot_data_path_rx_timestamp_logging(dhd_pub_t *dhd, bool enable, bool set);
|
||||
extern bool dhd_prot_pkt_noretry(dhd_pub_t *dhd, bool enable, bool set);
|
||||
extern bool dhd_prot_pkt_noaggr(dhd_pub_t *dhd, bool enable, bool set);
|
||||
extern bool dhd_prot_pkt_fixed_rate(dhd_pub_t *dhd, bool enable, bool set);
|
||||
#else /* BCMPCIE */
|
||||
#define dhd_prot_send_host_timestamp(a, b, c, d, e) 0
|
||||
#define dhd_prot_data_path_tx_timestamp_logging(a, b, c) 0
|
||||
#define dhd_prot_data_path_rx_timestamp_logging(a, b, c) 0
|
||||
#endif /* BCMPCIE */
|
||||
|
||||
extern void dhd_prot_dma_indx_free(dhd_pub_t *dhd);
|
||||
|
||||
#ifdef EWP_EDL
|
||||
int dhd_prot_init_edl_rings(dhd_pub_t *dhd);
|
||||
bool dhd_prot_process_msgbuf_edl(dhd_pub_t *dhd);
|
||||
int dhd_prot_process_edl_complete(dhd_pub_t *dhd, void *evt_decode_data);
|
||||
#endif /* EWP_EDL */
|
||||
|
||||
/* APIs for managing a DMA-able buffer */
|
||||
int dhd_dma_buf_alloc(dhd_pub_t *dhd, dhd_dma_buf_t *dma_buf, uint32 buf_len);
|
||||
void dhd_dma_buf_free(dhd_pub_t *dhd, dhd_dma_buf_t *dma_buf);
|
||||
|
||||
/********************************
|
||||
* For version-string expansion *
|
||||
*/
|
||||
#if defined(BDC)
|
||||
#define DHD_PROTOCOL "bdc"
|
||||
#elif defined(CDC)
|
||||
#define DHD_PROTOCOL "cdc"
|
||||
#else
|
||||
#define DHD_PROTOCOL "unknown"
|
||||
#endif /* proto */
|
||||
|
||||
int dhd_get_hscb_info(dhd_pub_t *dhd, void ** va, uint32 *len);
|
||||
int dhd_get_hscb_buff(dhd_pub_t *dhd, uint32 offset, uint32 length, void * buff);
|
||||
|
||||
#ifdef DHD_HP2P
|
||||
extern uint8 dhd_prot_hp2p_enable(dhd_pub_t *dhd, bool set, int enable);
|
||||
extern uint32 dhd_prot_pkt_threshold(dhd_pub_t *dhd, bool set, uint32 val);
|
||||
extern uint32 dhd_prot_time_threshold(dhd_pub_t *dhd, bool set, uint32 val);
|
||||
extern uint32 dhd_prot_pkt_expiry(dhd_pub_t *dhd, bool set, uint32 val);
|
||||
#endif // endif
|
||||
|
||||
#ifdef DHD_MAP_LOGGING
|
||||
extern void dhd_prot_smmu_fault_dump(dhd_pub_t *dhdp);
|
||||
#endif /* DHD_MAP_LOGGING */
|
||||
#endif /* _dhd_proto_h_ */
|
||||
4103
drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd_wifi6/dhd_rtt.c
Normal file
4103
drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd_wifi6/dhd_rtt.c
Normal file
File diff suppressed because it is too large
Load Diff
537
drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd_wifi6/dhd_rtt.h
Normal file
537
drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd_wifi6/dhd_rtt.h
Normal file
@@ -0,0 +1,537 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Broadcom Dongle Host Driver (DHD), RTT
|
||||
*
|
||||
* Copyright (C) 1999-2019, 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.
|
||||
*
|
||||
* 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$
|
||||
*/
|
||||
#ifndef __DHD_RTT_H__
|
||||
#define __DHD_RTT_H__
|
||||
|
||||
#include "dngl_stats.h"
|
||||
|
||||
#define RTT_MAX_TARGET_CNT 50
|
||||
#define RTT_MAX_FRAME_CNT 25
|
||||
#define RTT_MAX_RETRY_CNT 10
|
||||
#define DEFAULT_FTM_CNT 6
|
||||
#define DEFAULT_RETRY_CNT 6
|
||||
#define DEFAULT_FTM_FREQ 5180
|
||||
#define DEFAULT_FTM_CNTR_FREQ0 5210
|
||||
#define RTT_MAX_GEOFENCE_TARGET_CNT 8
|
||||
|
||||
#define TARGET_INFO_SIZE(count) (sizeof(rtt_target_info_t) * count)
|
||||
|
||||
#define TARGET_TYPE(target) (target->type)
|
||||
|
||||
#define RTT_IS_ENABLED(rtt_status) (rtt_status->status == RTT_ENABLED)
|
||||
#define RTT_IS_STOPPED(rtt_status) (rtt_status->status == RTT_STOPPED)
|
||||
|
||||
#define GEOFENCE_RTT_LOCK(rtt_status) mutex_lock(&(rtt_status)->geofence_mutex)
|
||||
#define GEOFENCE_RTT_UNLOCK(rtt_status) mutex_unlock(&(rtt_status)->geofence_mutex)
|
||||
|
||||
#ifndef BIT
|
||||
#define BIT(x) (1 << (x))
|
||||
#endif // endif
|
||||
|
||||
/* DSSS, CCK and 802.11n rates in [500kbps] units */
|
||||
#define WL_MAXRATE 108 /* in 500kbps units */
|
||||
#define WL_RATE_1M 2 /* in 500kbps units */
|
||||
#define WL_RATE_2M 4 /* in 500kbps units */
|
||||
#define WL_RATE_5M5 11 /* in 500kbps units */
|
||||
#define WL_RATE_11M 22 /* in 500kbps units */
|
||||
#define WL_RATE_6M 12 /* in 500kbps units */
|
||||
#define WL_RATE_9M 18 /* in 500kbps units */
|
||||
#define WL_RATE_12M 24 /* in 500kbps units */
|
||||
#define WL_RATE_18M 36 /* in 500kbps units */
|
||||
#define WL_RATE_24M 48 /* in 500kbps units */
|
||||
#define WL_RATE_36M 72 /* in 500kbps units */
|
||||
#define WL_RATE_48M 96 /* in 500kbps units */
|
||||
#define WL_RATE_54M 108 /* in 500kbps units */
|
||||
#define GET_RTTSTATE(dhd) ((rtt_status_info_t *)dhd->rtt_state)
|
||||
|
||||
#ifdef WL_NAN
|
||||
/* RTT Retry Timer Interval */
|
||||
#define DHD_RTT_RETRY_TIMER_INTERVAL_MS 3000u
|
||||
#endif /* WL_NAN */
|
||||
|
||||
#define DHD_RTT_INVALID_TARGET_INDEX -1
|
||||
|
||||
enum rtt_role {
|
||||
RTT_INITIATOR = 0,
|
||||
RTT_TARGET = 1
|
||||
};
|
||||
enum rtt_status {
|
||||
RTT_STOPPED = 0,
|
||||
RTT_STARTED = 1,
|
||||
RTT_ENABLED = 2
|
||||
};
|
||||
typedef int64_t wifi_timestamp; /* In microseconds (us) */
|
||||
typedef int64_t wifi_timespan;
|
||||
typedef int32 wifi_rssi_rtt;
|
||||
|
||||
typedef enum {
|
||||
RTT_INVALID,
|
||||
RTT_ONE_WAY,
|
||||
RTT_TWO_WAY,
|
||||
RTT_AUTO
|
||||
} rtt_type_t;
|
||||
|
||||
/* RTT peer type */
|
||||
typedef enum {
|
||||
RTT_PEER_AP = 0x1,
|
||||
RTT_PEER_STA = 0x2,
|
||||
RTT_PEER_P2P_GO = 0x3,
|
||||
RTT_PEER_P2P_CLIENT = 0x4,
|
||||
RTT_PEER_NAN = 0x5,
|
||||
RTT_PEER_INVALID = 0x6
|
||||
} rtt_peer_type_t;
|
||||
|
||||
/* Ranging status */
|
||||
typedef enum rtt_reason {
|
||||
RTT_STATUS_SUCCESS = 0,
|
||||
RTT_STATUS_FAILURE = 1, // general failure status
|
||||
RTT_STATUS_FAIL_NO_RSP = 2, // target STA does not respond to request
|
||||
RTT_STATUS_FAIL_REJECTED = 3, // request rejected. Applies to 2-sided RTT only
|
||||
RTT_STATUS_FAIL_NOT_SCHEDULED_YET = 4,
|
||||
RTT_STATUS_FAIL_TM_TIMEOUT = 5, // timing measurement times out
|
||||
RTT_STATUS_FAIL_AP_ON_DIFF_CHANNEL = 6, // Target on different channel, cannot range
|
||||
RTT_STATUS_FAIL_NO_CAPABILITY = 7, // ranging not supported
|
||||
RTT_STATUS_ABORTED = 8, // request aborted for unknown reason
|
||||
RTT_STATUS_FAIL_INVALID_TS = 9, // Invalid T1-T4 timestamp
|
||||
RTT_STATUS_FAIL_PROTOCOL = 10, // 11mc protocol failed
|
||||
RTT_STATUS_FAIL_SCHEDULE = 11, // request could not be scheduled
|
||||
RTT_STATUS_FAIL_BUSY_TRY_LATER = 12, // responder cannot collaborate at time of request
|
||||
RTT_STATUS_INVALID_REQ = 13, // bad request args
|
||||
RTT_STATUS_NO_WIFI = 14, // WiFi not enabled Responder overrides param info
|
||||
// cannot range with new params
|
||||
RTT_STATUS_FAIL_FTM_PARAM_OVERRIDE = 15
|
||||
} rtt_reason_t;
|
||||
|
||||
enum {
|
||||
RTT_CAP_ONE_WAY = BIT(0),
|
||||
/* IEEE802.11mc */
|
||||
RTT_CAP_FTM_WAY = BIT(1)
|
||||
};
|
||||
|
||||
enum {
|
||||
RTT_FEATURE_LCI = BIT(0),
|
||||
RTT_FEATURE_LCR = BIT(1),
|
||||
RTT_FEATURE_PREAMBLE = BIT(2),
|
||||
RTT_FEATURE_BW = BIT(3)
|
||||
};
|
||||
|
||||
enum {
|
||||
RTT_PREAMBLE_LEGACY = BIT(0),
|
||||
RTT_PREAMBLE_HT = BIT(1),
|
||||
RTT_PREAMBLE_VHT = BIT(2)
|
||||
};
|
||||
|
||||
enum {
|
||||
RTT_BW_5 = BIT(0),
|
||||
RTT_BW_10 = BIT(1),
|
||||
RTT_BW_20 = BIT(2),
|
||||
RTT_BW_40 = BIT(3),
|
||||
RTT_BW_80 = BIT(4),
|
||||
RTT_BW_160 = BIT(5)
|
||||
};
|
||||
|
||||
enum rtt_rate_bw {
|
||||
RTT_RATE_20M,
|
||||
RTT_RATE_40M,
|
||||
RTT_RATE_80M,
|
||||
RTT_RATE_160M
|
||||
};
|
||||
|
||||
typedef enum ranging_type {
|
||||
RTT_TYPE_INVALID = 0,
|
||||
RTT_TYPE_LEGACY = 1,
|
||||
RTT_TYPE_NAN_DIRECTED = 2,
|
||||
RTT_TYPE_NAN_GEOFENCE = 3
|
||||
} ranging_type_t;
|
||||
|
||||
#define FTM_MAX_NUM_BURST_EXP 14
|
||||
#define HAS_11MC_CAP(cap) (cap & RTT_CAP_FTM_WAY)
|
||||
#define HAS_ONEWAY_CAP(cap) (cap & RTT_CAP_ONE_WAY)
|
||||
#define HAS_RTT_CAP(cap) (HAS_ONEWAY_CAP(cap) || HAS_11MC_CAP(cap))
|
||||
|
||||
typedef struct wifi_channel_info {
|
||||
wifi_channel_width_t width;
|
||||
wifi_channel center_freq; /* primary 20 MHz channel */
|
||||
wifi_channel center_freq0; /* center freq (MHz) first segment */
|
||||
wifi_channel center_freq1; /* center freq (MHz) second segment valid for 80 + 80 */
|
||||
} wifi_channel_info_t;
|
||||
|
||||
typedef struct wifi_rate {
|
||||
uint32 preamble :3; /* 0: OFDM, 1: CCK, 2 : HT, 3: VHT, 4..7 reserved */
|
||||
uint32 nss :2; /* 1 : 1x1, 2: 2x2, 3: 3x3, 4: 4x4 */
|
||||
uint32 bw :3; /* 0: 20Mhz, 1: 40Mhz, 2: 80Mhz, 3: 160Mhz */
|
||||
/* OFDM/CCK rate code would be as per IEEE std in the unit of 0.5 mb
|
||||
* HT/VHT it would be mcs index
|
||||
*/
|
||||
uint32 rateMcsIdx :8;
|
||||
uint32 reserved :16; /* reserved */
|
||||
uint32 bitrate; /* unit of 100 Kbps */
|
||||
} wifi_rate_t;
|
||||
|
||||
typedef struct rtt_target_info {
|
||||
struct ether_addr addr;
|
||||
struct ether_addr local_addr;
|
||||
rtt_type_t type; /* rtt_type */
|
||||
rtt_peer_type_t peer; /* peer type */
|
||||
wifi_channel_info_t channel; /* channel information */
|
||||
chanspec_t chanspec; /* chanspec for channel */
|
||||
bool disable; /* disable for RTT measurement */
|
||||
/*
|
||||
* Time interval between bursts (units: 100 ms).
|
||||
* Applies to 1-sided and 2-sided RTT multi-burst requests.
|
||||
* Range: 0-31, 0: no preference by initiator (2-sided RTT)
|
||||
*/
|
||||
uint32 burst_period;
|
||||
/*
|
||||
* Total number of RTT bursts to be executed. It will be
|
||||
* specified in the same way as the parameter "Number of
|
||||
* Burst Exponent" found in the FTM frame format. It
|
||||
* applies to both: 1-sided RTT and 2-sided RTT. Valid
|
||||
* values are 0 to 15 as defined in 802.11mc std.
|
||||
* 0 means single shot
|
||||
* The implication of this parameter on the maximum
|
||||
* number of RTT results is the following:
|
||||
* for 1-sided RTT: max num of RTT results = (2^num_burst)*(num_frames_per_burst)
|
||||
* for 2-sided RTT: max num of RTT results = (2^num_burst)*(num_frames_per_burst - 1)
|
||||
*/
|
||||
uint16 num_burst;
|
||||
/*
|
||||
* num of frames per burst.
|
||||
* Minimum value = 1, Maximum value = 31
|
||||
* For 2-sided this equals the number of FTM frames
|
||||
* to be attempted in a single burst. This also
|
||||
* equals the number of FTM frames that the
|
||||
* initiator will request that the responder send
|
||||
* in a single frame
|
||||
*/
|
||||
uint32 num_frames_per_burst;
|
||||
/*
|
||||
* num of frames in each RTT burst
|
||||
* for single side, measurement result num = frame number
|
||||
* for 2 side RTT, measurement result num = frame number - 1
|
||||
*/
|
||||
uint32 num_retries_per_ftm; /* retry time for RTT measurment frame */
|
||||
/* following fields are only valid for 2 side RTT */
|
||||
uint32 num_retries_per_ftmr;
|
||||
uint8 LCI_request;
|
||||
uint8 LCR_request;
|
||||
/*
|
||||
* Applies to 1-sided and 2-sided RTT. Valid values will
|
||||
* be 2-11 and 15 as specified by the 802.11mc std for
|
||||
* the FTM parameter burst duration. In a multi-burst
|
||||
* request, if responder overrides with larger value,
|
||||
* the initiator will return failure. In a single-burst
|
||||
* request if responder overrides with larger value,
|
||||
* the initiator will sent TMR_STOP to terminate RTT
|
||||
* at the end of the burst_duration it requested.
|
||||
*/
|
||||
uint32 burst_duration;
|
||||
uint32 burst_timeout;
|
||||
uint8 preamble; /* 1 - Legacy, 2 - HT, 4 - VHT */
|
||||
uint8 bw; /* 5, 10, 20, 40, 80, 160 */
|
||||
} rtt_target_info_t;
|
||||
|
||||
typedef struct rtt_goefence_target_info {
|
||||
bool valid;
|
||||
struct ether_addr peer_addr;
|
||||
} rtt_geofence_target_info_t;
|
||||
|
||||
typedef struct rtt_config_params {
|
||||
int8 rtt_target_cnt;
|
||||
rtt_target_info_t *target_info;
|
||||
} rtt_config_params_t;
|
||||
|
||||
typedef struct rtt_geofence_cfg {
|
||||
int8 geofence_target_cnt;
|
||||
bool rtt_in_progress;
|
||||
bool role_concurr_state;
|
||||
int8 cur_target_idx;
|
||||
rtt_geofence_target_info_t geofence_target_info[RTT_MAX_GEOFENCE_TARGET_CNT];
|
||||
int geofence_rtt_interval;
|
||||
#ifdef RTT_GEOFENCE_CONT
|
||||
bool geofence_cont;
|
||||
#endif /* RTT_GEOFENCE_CONT */
|
||||
} rtt_geofence_cfg_t;
|
||||
|
||||
/*
|
||||
* Keep Adding more reasons
|
||||
* going forward if needed
|
||||
*/
|
||||
enum rtt_schedule_reason {
|
||||
RTT_SCHED_HOST_TRIGGER = 1, /* On host command for directed RTT */
|
||||
RTT_SCHED_SUB_MATCH = 2, /* on Sub Match for svc with range req */
|
||||
RTT_SCHED_DIR_TRIGGER_FAIL = 3, /* On failure of Directed RTT Trigger */
|
||||
RTT_SCHED_DP_END = 4, /* ON NDP End event from fw */
|
||||
RTT_SCHED_DP_REJECTED = 5, /* On receving reject dp event from fw */
|
||||
RTT_SCHED_RNG_RPT_DIRECTED = 6, /* On Ranging report for directed RTT */
|
||||
RTT_SCHED_RNG_TERM = 7, /* On Range Term Indicator */
|
||||
RTT_SHCED_HOST_DIRECTED_TERM = 8, /* On host terminating directed RTT sessions */
|
||||
RTT_SCHED_RNG_RPT_GEOFENCE = 9, /* On Ranging report for geofence RTT */
|
||||
RTT_SCHED_RTT_RETRY_GEOFENCE = 10, /* On Geofence Retry */
|
||||
RTT_SCHED_RNG_TERM_PEND_ROLE_CHANGE = 11 /* On Rng Term, while pending role change */
|
||||
};
|
||||
|
||||
/*
|
||||
* Keep Adding more invalid RTT states
|
||||
* going forward if needed
|
||||
*/
|
||||
enum rtt_invalid_state {
|
||||
RTT_STATE_VALID = 0, /* RTT state is valid */
|
||||
RTT_STATE_INV_REASON_NDP_EXIST = 1 /* RTT state invalid as ndp exists */
|
||||
};
|
||||
|
||||
typedef struct rtt_status_info {
|
||||
dhd_pub_t *dhd;
|
||||
int8 status; /* current status for the current entry */
|
||||
int8 txchain; /* current device tx chain */
|
||||
int pm; /* to save current value of pm */
|
||||
int8 pm_restore; /* flag to reset the old value of pm */
|
||||
int8 cur_idx; /* current entry to do RTT */
|
||||
bool all_cancel; /* cancel all request once we got the cancel requet */
|
||||
uint32 flags; /* indicate whether device is configured as initiator or target */
|
||||
struct capability {
|
||||
int32 proto :8;
|
||||
int32 feature :8;
|
||||
int32 preamble :8;
|
||||
int32 bw :8;
|
||||
} rtt_capa; /* rtt capability */
|
||||
struct mutex rtt_mutex;
|
||||
struct mutex rtt_work_mutex;
|
||||
struct mutex geofence_mutex;
|
||||
rtt_config_params_t rtt_config;
|
||||
rtt_geofence_cfg_t geofence_cfg;
|
||||
struct work_struct work;
|
||||
struct list_head noti_fn_list;
|
||||
struct list_head rtt_results_cache; /* store results for RTT */
|
||||
int rtt_sched_reason; /* rtt_schedule_reason: what scheduled RTT */
|
||||
struct delayed_work proxd_timeout; /* Proxd Timeout work */
|
||||
struct delayed_work rtt_retry_timer; /* Timer for retry RTT after all targets done */
|
||||
} rtt_status_info_t;
|
||||
|
||||
typedef struct rtt_report {
|
||||
struct ether_addr addr;
|
||||
unsigned int burst_num; /* # of burst inside a multi-burst request */
|
||||
unsigned int ftm_num; /* total RTT measurement frames attempted */
|
||||
unsigned int success_num; /* total successful RTT measurement frames */
|
||||
uint8 num_per_burst_peer; /* max number of FTM number per burst the peer support */
|
||||
rtt_reason_t status; /* raging status */
|
||||
/* in s, 11mc only, only for RTT_REASON_FAIL_BUSY_TRY_LATER, 1- 31s */
|
||||
uint8 retry_after_duration;
|
||||
rtt_type_t type; /* rtt type */
|
||||
wifi_rssi_rtt rssi; /* average rssi in 0.5 dB steps e.g. 143 implies -71.5 dB */
|
||||
wifi_rssi_rtt rssi_spread; /* rssi spread in 0.5 db steps e.g. 5 implies 2.5 spread */
|
||||
/*
|
||||
* 1-sided RTT: TX rate of RTT frame.
|
||||
* 2-sided RTT: TX rate of initiator's Ack in response to FTM frame.
|
||||
*/
|
||||
wifi_rate_t tx_rate;
|
||||
/*
|
||||
* 1-sided RTT: TX rate of Ack from other side.
|
||||
* 2-sided RTT: TX rate of FTM frame coming from responder.
|
||||
*/
|
||||
wifi_rate_t rx_rate;
|
||||
wifi_timespan rtt; /* round trip time in 0.1 nanoseconds */
|
||||
wifi_timespan rtt_sd; /* rtt standard deviation in 0.1 nanoseconds */
|
||||
wifi_timespan rtt_spread; /* difference between max and min rtt times recorded */
|
||||
int distance; /* distance in cm (optional) */
|
||||
int distance_sd; /* standard deviation in cm (optional) */
|
||||
int distance_spread; /* difference between max and min distance recorded (optional) */
|
||||
wifi_timestamp ts; /* time of the measurement (in microseconds since boot) */
|
||||
int burst_duration; /* in ms, how long the FW time is to fininish one burst measurement */
|
||||
int negotiated_burst_num; /* Number of bursts allowed by the responder */
|
||||
bcm_tlv_t *LCI; /* LCI Report */
|
||||
bcm_tlv_t *LCR; /* Location Civic Report */
|
||||
} rtt_report_t;
|
||||
#define RTT_REPORT_SIZE (sizeof(rtt_report_t))
|
||||
|
||||
/* rtt_results_header to maintain rtt result list per mac address */
|
||||
typedef struct rtt_results_header {
|
||||
struct ether_addr peer_mac;
|
||||
uint32 result_cnt;
|
||||
uint32 result_tot_len; /* sum of report_len of rtt_result */
|
||||
struct list_head list;
|
||||
struct list_head result_list;
|
||||
} rtt_results_header_t;
|
||||
struct rtt_result_detail {
|
||||
uint8 num_ota_meas;
|
||||
uint32 result_flags;
|
||||
};
|
||||
/* rtt_result to link all of rtt_report */
|
||||
typedef struct rtt_result {
|
||||
struct list_head list;
|
||||
struct rtt_report report;
|
||||
int32 report_len; /* total length of rtt_report */
|
||||
struct rtt_result_detail rtt_detail;
|
||||
int32 detail_len;
|
||||
} rtt_result_t;
|
||||
|
||||
/* RTT Capabilities */
|
||||
typedef struct rtt_capabilities {
|
||||
uint8 rtt_one_sided_supported; /* if 1-sided rtt data collection is supported */
|
||||
uint8 rtt_ftm_supported; /* if ftm rtt data collection is supported */
|
||||
uint8 lci_support; /* location configuration information */
|
||||
uint8 lcr_support; /* Civic Location */
|
||||
uint8 preamble_support; /* bit mask indicate what preamble is supported */
|
||||
uint8 bw_support; /* bit mask indicate what BW is supported */
|
||||
} rtt_capabilities_t;
|
||||
|
||||
/* RTT responder information */
|
||||
typedef struct wifi_rtt_responder {
|
||||
wifi_channel_info channel; /* channel of responder */
|
||||
uint8 preamble; /* preamble supported by responder */
|
||||
} wifi_rtt_responder_t;
|
||||
|
||||
typedef void (*dhd_rtt_compl_noti_fn)(void *ctx, void *rtt_data);
|
||||
/* Linux wrapper to call common dhd_rtt_set_cfg */
|
||||
int
|
||||
dhd_dev_rtt_set_cfg(struct net_device *dev, void *buf);
|
||||
|
||||
int
|
||||
dhd_dev_rtt_cancel_cfg(struct net_device *dev, struct ether_addr *mac_list, int mac_cnt);
|
||||
|
||||
int
|
||||
dhd_dev_rtt_register_noti_callback(struct net_device *dev, void *ctx,
|
||||
dhd_rtt_compl_noti_fn noti_fn);
|
||||
|
||||
int
|
||||
dhd_dev_rtt_unregister_noti_callback(struct net_device *dev, dhd_rtt_compl_noti_fn noti_fn);
|
||||
|
||||
int
|
||||
dhd_dev_rtt_capability(struct net_device *dev, rtt_capabilities_t *capa);
|
||||
|
||||
int
|
||||
dhd_dev_rtt_avail_channel(struct net_device *dev, wifi_channel_info *channel_info);
|
||||
|
||||
int
|
||||
dhd_dev_rtt_enable_responder(struct net_device *dev, wifi_channel_info *channel_info);
|
||||
|
||||
int
|
||||
dhd_dev_rtt_cancel_responder(struct net_device *dev);
|
||||
/* export to upper layer */
|
||||
chanspec_t
|
||||
dhd_rtt_convert_to_chspec(wifi_channel_info_t channel);
|
||||
|
||||
int
|
||||
dhd_rtt_idx_to_burst_duration(uint idx);
|
||||
|
||||
int
|
||||
dhd_rtt_set_cfg(dhd_pub_t *dhd, rtt_config_params_t *params);
|
||||
|
||||
#ifdef WL_NAN
|
||||
void dhd_rtt_initialize_geofence_cfg(dhd_pub_t *dhd);
|
||||
#ifdef RTT_GEOFENCE_CONT
|
||||
void dhd_rtt_set_geofence_cont_ind(dhd_pub_t *dhd, bool geofence_cont);
|
||||
|
||||
void dhd_rtt_get_geofence_cont_ind(dhd_pub_t *dhd, bool* geofence_cont);
|
||||
#endif /* RTT_GEOFENCE_CONT */
|
||||
|
||||
#ifdef RTT_GEOFENCE_INTERVAL
|
||||
void dhd_rtt_set_geofence_rtt_interval(dhd_pub_t *dhd, int interval);
|
||||
#endif /* RTT_GEOFENCE_INTERVAL */
|
||||
|
||||
void dhd_rtt_set_role_concurrency_state(dhd_pub_t *dhd, bool state);
|
||||
|
||||
bool dhd_rtt_get_role_concurrency_state(dhd_pub_t *dhd);
|
||||
|
||||
int8 dhd_rtt_get_geofence_target_cnt(dhd_pub_t *dhd);
|
||||
|
||||
void dhd_rtt_set_geofence_rtt_state(dhd_pub_t *dhd, bool state);
|
||||
|
||||
bool dhd_rtt_get_geofence_rtt_state(dhd_pub_t *dhd);
|
||||
|
||||
rtt_geofence_target_info_t*
|
||||
dhd_rtt_get_geofence_target_head(dhd_pub_t *dhd);
|
||||
|
||||
rtt_geofence_target_info_t*
|
||||
dhd_rtt_get_geofence_current_target(dhd_pub_t *dhd);
|
||||
|
||||
rtt_geofence_target_info_t*
|
||||
dhd_rtt_get_geofence_target(dhd_pub_t *dhd, struct ether_addr* peer_addr,
|
||||
int8 *index);
|
||||
|
||||
int
|
||||
dhd_rtt_add_geofence_target(dhd_pub_t *dhd, rtt_geofence_target_info_t *target);
|
||||
|
||||
int
|
||||
dhd_rtt_remove_geofence_target(dhd_pub_t *dhd, struct ether_addr *peer_addr);
|
||||
|
||||
int
|
||||
dhd_rtt_delete_geofence_target_list(dhd_pub_t *dhd);
|
||||
|
||||
int
|
||||
dhd_rtt_delete_nan_session(dhd_pub_t *dhd);
|
||||
#endif /* WL_NAN */
|
||||
|
||||
uint8
|
||||
dhd_rtt_invalid_states(struct net_device *ndev, struct ether_addr *peer_addr);
|
||||
|
||||
void
|
||||
dhd_rtt_schedule_rtt_work_thread(dhd_pub_t *dhd, int sched_reason);
|
||||
|
||||
int
|
||||
dhd_rtt_stop(dhd_pub_t *dhd, struct ether_addr *mac_list, int mac_cnt);
|
||||
|
||||
int
|
||||
dhd_rtt_register_noti_callback(dhd_pub_t *dhd, void *ctx, dhd_rtt_compl_noti_fn noti_fn);
|
||||
|
||||
int
|
||||
dhd_rtt_unregister_noti_callback(dhd_pub_t *dhd, dhd_rtt_compl_noti_fn noti_fn);
|
||||
|
||||
int
|
||||
dhd_rtt_event_handler(dhd_pub_t *dhd, wl_event_msg_t *event, void *event_data);
|
||||
|
||||
int
|
||||
dhd_rtt_capability(dhd_pub_t *dhd, rtt_capabilities_t *capa);
|
||||
|
||||
int
|
||||
dhd_rtt_avail_channel(dhd_pub_t *dhd, wifi_channel_info *channel_info);
|
||||
|
||||
int
|
||||
dhd_rtt_enable_responder(dhd_pub_t *dhd, wifi_channel_info *channel_info);
|
||||
|
||||
int
|
||||
dhd_rtt_cancel_responder(dhd_pub_t *dhd);
|
||||
|
||||
int
|
||||
dhd_rtt_init(dhd_pub_t *dhd);
|
||||
|
||||
int
|
||||
dhd_rtt_deinit(dhd_pub_t *dhd);
|
||||
|
||||
#ifdef WL_CFG80211
|
||||
int dhd_rtt_handle_nan_rtt_session_end(dhd_pub_t *dhd,
|
||||
struct ether_addr *peer);
|
||||
|
||||
void dhd_rtt_move_geofence_cur_target_idx_to_next(dhd_pub_t *dhd);
|
||||
|
||||
int8 dhd_rtt_get_geofence_cur_target_idx(dhd_pub_t *dhd);
|
||||
#endif /* WL_CFG80211 */
|
||||
|
||||
#endif /* __DHD_RTT_H__ */
|
||||
10597
drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd_wifi6/dhd_sdio.c
Normal file
10597
drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd_wifi6/dhd_sdio.c
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,586 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/skbuff.h>
|
||||
|
||||
#define DHD_STATIC_VERSION_STR "100.10.545.7 (r826445-20200110-2)"
|
||||
|
||||
#define BCMDHD_SDIO
|
||||
#define BCMDHD_PCIE
|
||||
|
||||
enum dhd_prealloc_index {
|
||||
DHD_PREALLOC_PROT = 0,
|
||||
#if defined(BCMDHD_SDIO)
|
||||
DHD_PREALLOC_RXBUF = 1,
|
||||
DHD_PREALLOC_DATABUF = 2,
|
||||
#endif
|
||||
DHD_PREALLOC_OSL_BUF = 3,
|
||||
DHD_PREALLOC_SKB_BUF = 4,
|
||||
DHD_PREALLOC_WIPHY_ESCAN0 = 5,
|
||||
DHD_PREALLOC_WIPHY_ESCAN1 = 6,
|
||||
DHD_PREALLOC_DHD_INFO = 7,
|
||||
DHD_PREALLOC_DHD_WLFC_INFO = 8,
|
||||
#ifdef BCMDHD_PCIE
|
||||
DHD_PREALLOC_IF_FLOW_LKUP = 9,
|
||||
#endif
|
||||
DHD_PREALLOC_MEMDUMP_BUF = 10,
|
||||
DHD_PREALLOC_MEMDUMP_RAM = 11,
|
||||
DHD_PREALLOC_DHD_WLFC_HANGER = 12,
|
||||
DHD_PREALLOC_PKTID_MAP = 13,
|
||||
DHD_PREALLOC_PKTID_MAP_IOCTL = 14,
|
||||
DHD_PREALLOC_DHD_LOG_DUMP_BUF = 15,
|
||||
DHD_PREALLOC_DHD_LOG_DUMP_BUF_EX = 16,
|
||||
DHD_PREALLOC_DHD_PKTLOG_DUMP_BUF = 17,
|
||||
DHD_PREALLOC_STAT_REPORT_BUF = 18,
|
||||
DHD_PREALLOC_WL_ESCAN = 19,
|
||||
DHD_PREALLOC_FW_VERBOSE_RING = 20,
|
||||
DHD_PREALLOC_FW_EVENT_RING = 21,
|
||||
DHD_PREALLOC_DHD_EVENT_RING = 22,
|
||||
DHD_PREALLOC_NAN_EVENT_RING = 23,
|
||||
DHD_PREALLOC_MAX
|
||||
};
|
||||
|
||||
#define STATIC_BUF_MAX_NUM 20
|
||||
#define STATIC_BUF_SIZE (PAGE_SIZE*2)
|
||||
|
||||
#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 DHD_PREALLOC_PROT_SIZE (16 * 1024)
|
||||
#define DHD_PREALLOC_RXBUF_SIZE (24 * 1024)
|
||||
#define DHD_PREALLOC_DATABUF_SIZE (64 * 1024)
|
||||
#define DHD_PREALLOC_OSL_BUF_SIZE (STATIC_BUF_MAX_NUM * STATIC_BUF_SIZE)
|
||||
#define DHD_PREALLOC_WIPHY_ESCAN0_SIZE (64 * 1024)
|
||||
#define DHD_PREALLOC_DHD_INFO_SIZE (32 * 1024)
|
||||
#define DHD_PREALLOC_MEMDUMP_RAM_SIZE (1290 * 1024)
|
||||
#define DHD_PREALLOC_DHD_WLFC_HANGER_SIZE (73 * 1024)
|
||||
#define DHD_PREALLOC_DHD_LOG_DUMP_BUF_SIZE (1024 * 1024 * CUSTOM_LOG_DUMP_BUFSIZE_MB)
|
||||
#define DHD_PREALLOC_DHD_LOG_DUMP_BUF_EX_SIZE (8 * 1024)
|
||||
#define DHD_PREALLOC_WL_ESCAN_SIZE (70 * 1024)
|
||||
#ifdef CONFIG_64BIT
|
||||
#define DHD_PREALLOC_IF_FLOW_LKUP_SIZE (20 * 1024 * 2)
|
||||
#else
|
||||
#define DHD_PREALLOC_IF_FLOW_LKUP_SIZE (20 * 1024)
|
||||
#endif
|
||||
#define FW_VERBOSE_RING_SIZE (256 * 1024)
|
||||
#define FW_EVENT_RING_SIZE (64 * 1024)
|
||||
#define DHD_EVENT_RING_SIZE (64 * 1024)
|
||||
#define NAN_EVENT_RING_SIZE (64 * 1024)
|
||||
|
||||
#if defined(CONFIG_64BIT)
|
||||
#define WLAN_DHD_INFO_BUF_SIZE (24 * 1024)
|
||||
#define WLAN_DHD_WLFC_BUF_SIZE (64 * 1024)
|
||||
#define WLAN_DHD_IF_FLOW_LKUP_SIZE (64 * 1024)
|
||||
#else
|
||||
#define WLAN_DHD_INFO_BUF_SIZE (16 * 1024)
|
||||
#define WLAN_DHD_WLFC_BUF_SIZE (64 * 1024)
|
||||
#define WLAN_DHD_IF_FLOW_LKUP_SIZE (20 * 1024)
|
||||
#endif /* CONFIG_64BIT */
|
||||
#define WLAN_DHD_MEMDUMP_SIZE (800 * 1024)
|
||||
|
||||
#define DHD_SKB_1PAGE_BUFSIZE (PAGE_SIZE*1)
|
||||
#define DHD_SKB_2PAGE_BUFSIZE (PAGE_SIZE*2)
|
||||
#define DHD_SKB_4PAGE_BUFSIZE (PAGE_SIZE*4)
|
||||
|
||||
#define DHD_SKB_1PAGE_BUF_NUM 8
|
||||
#ifdef BCMDHD_PCIE
|
||||
#define DHD_SKB_2PAGE_BUF_NUM 64
|
||||
#elif defined(BCMDHD_SDIO)
|
||||
#define DHD_SKB_2PAGE_BUF_NUM 8
|
||||
#endif
|
||||
#define DHD_SKB_4PAGE_BUF_NUM 1
|
||||
|
||||
/* The number is defined in linux_osl.c
|
||||
* WLAN_SKB_1_2PAGE_BUF_NUM => STATIC_PKT_1_2PAGE_NUM
|
||||
* WLAN_SKB_BUF_NUM => STATIC_PKT_MAX_NUM
|
||||
*/
|
||||
#define WLAN_SKB_1_2PAGE_BUF_NUM ((DHD_SKB_1PAGE_BUF_NUM) + \
|
||||
(DHD_SKB_2PAGE_BUF_NUM))
|
||||
#define WLAN_SKB_BUF_NUM ((WLAN_SKB_1_2PAGE_BUF_NUM) + (DHD_SKB_4PAGE_BUF_NUM))
|
||||
|
||||
void *wlan_static_prot = NULL;
|
||||
void *wlan_static_rxbuf = NULL;
|
||||
void *wlan_static_databuf = NULL;
|
||||
void *wlan_static_osl_buf = NULL;
|
||||
void *wlan_static_scan_buf0 = NULL;
|
||||
void *wlan_static_scan_buf1 = NULL;
|
||||
void *wlan_static_dhd_info_buf = NULL;
|
||||
void *wlan_static_dhd_wlfc_info_buf = NULL;
|
||||
void *wlan_static_if_flow_lkup = NULL;
|
||||
void *wlan_static_dhd_memdump_ram_buf = NULL;
|
||||
void *wlan_static_dhd_wlfc_hanger_buf = NULL;
|
||||
void *wlan_static_dhd_log_dump_buf = NULL;
|
||||
void *wlan_static_dhd_log_dump_buf_ex = NULL;
|
||||
void *wlan_static_wl_escan_info_buf = NULL;
|
||||
void *wlan_static_fw_verbose_ring_buf = NULL;
|
||||
void *wlan_static_fw_event_ring_buf = NULL;
|
||||
void *wlan_static_dhd_event_ring_buf = NULL;
|
||||
void *wlan_static_nan_event_ring_buf = NULL;
|
||||
|
||||
static struct sk_buff *wlan_static_skb[WLAN_SKB_BUF_NUM];
|
||||
|
||||
void *dhd_wlan_mem_prealloc(int section, unsigned long size)
|
||||
{
|
||||
pr_err("%s: sectoin %d, %ld\n", __func__, section, size);
|
||||
if (section == DHD_PREALLOC_PROT)
|
||||
return wlan_static_prot;
|
||||
|
||||
#if defined(BCMDHD_SDIO)
|
||||
if (section == DHD_PREALLOC_RXBUF)
|
||||
return wlan_static_rxbuf;
|
||||
|
||||
if (section == DHD_PREALLOC_DATABUF)
|
||||
return wlan_static_databuf;
|
||||
#endif /* BCMDHD_SDIO */
|
||||
|
||||
if (section == DHD_PREALLOC_SKB_BUF)
|
||||
return wlan_static_skb;
|
||||
|
||||
if (section == DHD_PREALLOC_WIPHY_ESCAN0)
|
||||
return wlan_static_scan_buf0;
|
||||
|
||||
if (section == DHD_PREALLOC_WIPHY_ESCAN1)
|
||||
return wlan_static_scan_buf1;
|
||||
|
||||
if (section == DHD_PREALLOC_OSL_BUF) {
|
||||
if (size > DHD_PREALLOC_OSL_BUF_SIZE) {
|
||||
pr_err("request OSL_BUF(%lu) > %ld\n",
|
||||
size, DHD_PREALLOC_OSL_BUF_SIZE);
|
||||
return NULL;
|
||||
}
|
||||
return wlan_static_osl_buf;
|
||||
}
|
||||
|
||||
if (section == DHD_PREALLOC_DHD_INFO) {
|
||||
if (size > DHD_PREALLOC_DHD_INFO_SIZE) {
|
||||
pr_err("request DHD_INFO size(%lu) > %d\n",
|
||||
size, DHD_PREALLOC_DHD_INFO_SIZE);
|
||||
return NULL;
|
||||
}
|
||||
return wlan_static_dhd_info_buf;
|
||||
}
|
||||
if (section == DHD_PREALLOC_DHD_WLFC_INFO) {
|
||||
if (size > WLAN_DHD_WLFC_BUF_SIZE) {
|
||||
pr_err("request DHD_WLFC_INFO size(%lu) > %d\n",
|
||||
size, WLAN_DHD_WLFC_BUF_SIZE);
|
||||
return NULL;
|
||||
}
|
||||
return wlan_static_dhd_wlfc_info_buf;
|
||||
}
|
||||
#ifdef BCMDHD_PCIE
|
||||
if (section == DHD_PREALLOC_IF_FLOW_LKUP) {
|
||||
if (size > DHD_PREALLOC_IF_FLOW_LKUP_SIZE) {
|
||||
pr_err("request DHD_IF_FLOW_LKUP size(%lu) > %d\n",
|
||||
size, DHD_PREALLOC_IF_FLOW_LKUP_SIZE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return wlan_static_if_flow_lkup;
|
||||
}
|
||||
#endif /* BCMDHD_PCIE */
|
||||
if (section == DHD_PREALLOC_MEMDUMP_RAM) {
|
||||
if (size > DHD_PREALLOC_MEMDUMP_RAM_SIZE) {
|
||||
pr_err("request DHD_PREALLOC_MEMDUMP_RAM_SIZE(%lu) > %d\n",
|
||||
size, DHD_PREALLOC_MEMDUMP_RAM_SIZE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return wlan_static_dhd_memdump_ram_buf;
|
||||
}
|
||||
if (section == DHD_PREALLOC_DHD_WLFC_HANGER) {
|
||||
if (size > DHD_PREALLOC_DHD_WLFC_HANGER_SIZE) {
|
||||
pr_err("request DHD_WLFC_HANGER size(%lu) > %d\n",
|
||||
size, DHD_PREALLOC_DHD_WLFC_HANGER_SIZE);
|
||||
return NULL;
|
||||
}
|
||||
return wlan_static_dhd_wlfc_hanger_buf;
|
||||
}
|
||||
if (section == DHD_PREALLOC_DHD_LOG_DUMP_BUF) {
|
||||
if (size > DHD_PREALLOC_DHD_LOG_DUMP_BUF_SIZE) {
|
||||
pr_err("request DHD_PREALLOC_DHD_LOG_DUMP_BUF_SIZE(%lu) > %d\n",
|
||||
size, DHD_PREALLOC_DHD_LOG_DUMP_BUF_SIZE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return wlan_static_dhd_log_dump_buf;
|
||||
}
|
||||
if (section == DHD_PREALLOC_DHD_LOG_DUMP_BUF_EX) {
|
||||
if (size > DHD_PREALLOC_DHD_LOG_DUMP_BUF_EX_SIZE) {
|
||||
pr_err("request DHD_PREALLOC_DHD_LOG_DUMP_BUF_EX_SIZE(%lu) > %d\n",
|
||||
size, DHD_PREALLOC_DHD_LOG_DUMP_BUF_EX_SIZE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return wlan_static_dhd_log_dump_buf_ex;
|
||||
}
|
||||
if (section == DHD_PREALLOC_WL_ESCAN) {
|
||||
if (size > DHD_PREALLOC_WL_ESCAN_SIZE) {
|
||||
pr_err("request DHD_PREALLOC_WL_ESCAN_SIZE(%lu) > %d\n",
|
||||
size, DHD_PREALLOC_WL_ESCAN_SIZE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return wlan_static_wl_escan_info_buf;
|
||||
}
|
||||
if (section == DHD_PREALLOC_FW_VERBOSE_RING) {
|
||||
if (size > FW_VERBOSE_RING_SIZE) {
|
||||
pr_err("request DHD_PREALLOC_FW_VERBOSE_RING(%lu) > %d\n",
|
||||
size, FW_VERBOSE_RING_SIZE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return wlan_static_fw_verbose_ring_buf;
|
||||
}
|
||||
if (section == DHD_PREALLOC_FW_EVENT_RING) {
|
||||
if (size > FW_EVENT_RING_SIZE) {
|
||||
pr_err("request DHD_PREALLOC_FW_EVENT_RING(%lu) > %d\n",
|
||||
size, FW_EVENT_RING_SIZE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return wlan_static_fw_event_ring_buf;
|
||||
}
|
||||
if (section == DHD_PREALLOC_DHD_EVENT_RING) {
|
||||
if (size > DHD_EVENT_RING_SIZE) {
|
||||
pr_err("request DHD_PREALLOC_DHD_EVENT_RING(%lu) > %d\n",
|
||||
size, DHD_EVENT_RING_SIZE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return wlan_static_dhd_event_ring_buf;
|
||||
}
|
||||
if (section == DHD_PREALLOC_NAN_EVENT_RING) {
|
||||
if (size > NAN_EVENT_RING_SIZE) {
|
||||
pr_err("request DHD_PREALLOC_NAN_EVENT_RING(%lu) > %d\n",
|
||||
size, NAN_EVENT_RING_SIZE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return wlan_static_nan_event_ring_buf;
|
||||
}
|
||||
if ((section < 0) || (section > DHD_PREALLOC_MAX))
|
||||
pr_err("request section id(%d) is out of max index %d\n",
|
||||
section, DHD_PREALLOC_MAX);
|
||||
|
||||
pr_err("%s: failed to alloc section %d, size=%ld\n",
|
||||
__func__, section, size);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
EXPORT_SYMBOL(dhd_wlan_mem_prealloc);
|
||||
|
||||
static int dhd_init_wlan_mem(void)
|
||||
{
|
||||
int i;
|
||||
int j;
|
||||
printk(KERN_ERR "%s(): %s\n", __func__, DHD_STATIC_VERSION_STR);
|
||||
|
||||
for (i = 0; i < DHD_SKB_1PAGE_BUF_NUM; i++) {
|
||||
wlan_static_skb[i] = dev_alloc_skb(DHD_SKB_1PAGE_BUFSIZE);
|
||||
if (!wlan_static_skb[i]) {
|
||||
goto err_skb_alloc;
|
||||
}
|
||||
pr_err("%s: sectoin %d skb[%d], size=%ld\n", __func__,
|
||||
DHD_PREALLOC_SKB_BUF, i, DHD_SKB_1PAGE_BUFSIZE);
|
||||
}
|
||||
|
||||
for (i = DHD_SKB_1PAGE_BUF_NUM; i < WLAN_SKB_1_2PAGE_BUF_NUM; i++) {
|
||||
wlan_static_skb[i] = dev_alloc_skb(DHD_SKB_2PAGE_BUFSIZE);
|
||||
if (!wlan_static_skb[i]) {
|
||||
goto err_skb_alloc;
|
||||
}
|
||||
pr_err("%s: sectoin %d skb[%d], size=%ld\n", __func__,
|
||||
DHD_PREALLOC_SKB_BUF, i, DHD_SKB_2PAGE_BUFSIZE);
|
||||
}
|
||||
|
||||
#if defined(BCMDHD_SDIO)
|
||||
wlan_static_skb[i] = dev_alloc_skb(DHD_SKB_4PAGE_BUFSIZE);
|
||||
if (!wlan_static_skb[i])
|
||||
goto err_skb_alloc;
|
||||
pr_err("%s: sectoin %d skb[%d], size=%ld\n", __func__,
|
||||
DHD_PREALLOC_SKB_BUF, i, DHD_SKB_4PAGE_BUFSIZE);
|
||||
#endif /* BCMDHD_SDIO */
|
||||
|
||||
wlan_static_prot = kmalloc(DHD_PREALLOC_PROT_SIZE, GFP_KERNEL);
|
||||
if (!wlan_static_prot)
|
||||
goto err_mem_alloc;
|
||||
pr_err("%s: sectoin %d, size=%d\n", __func__,
|
||||
DHD_PREALLOC_PROT, DHD_PREALLOC_PROT_SIZE);
|
||||
|
||||
#if defined(BCMDHD_SDIO)
|
||||
wlan_static_rxbuf = kmalloc(DHD_PREALLOC_RXBUF_SIZE, GFP_KERNEL);
|
||||
if (!wlan_static_rxbuf)
|
||||
goto err_mem_alloc;
|
||||
pr_err("%s: sectoin %d, size=%d\n", __func__,
|
||||
DHD_PREALLOC_RXBUF, DHD_PREALLOC_RXBUF_SIZE);
|
||||
|
||||
wlan_static_databuf = kmalloc(DHD_PREALLOC_DATABUF_SIZE, GFP_KERNEL);
|
||||
if (!wlan_static_databuf)
|
||||
goto err_mem_alloc;
|
||||
pr_err("%s: sectoin %d, size=%d\n", __func__,
|
||||
DHD_PREALLOC_DATABUF, DHD_PREALLOC_DATABUF_SIZE);
|
||||
#endif /* BCMDHD_SDIO */
|
||||
|
||||
wlan_static_osl_buf = kmalloc(DHD_PREALLOC_OSL_BUF_SIZE, GFP_KERNEL);
|
||||
if (!wlan_static_osl_buf)
|
||||
goto err_mem_alloc;
|
||||
pr_err("%s: sectoin %d, size=%ld\n", __func__,
|
||||
DHD_PREALLOC_OSL_BUF, DHD_PREALLOC_OSL_BUF_SIZE);
|
||||
|
||||
wlan_static_scan_buf0 = kmalloc(DHD_PREALLOC_WIPHY_ESCAN0_SIZE, GFP_KERNEL);
|
||||
if (!wlan_static_scan_buf0)
|
||||
goto err_mem_alloc;
|
||||
pr_err("%s: sectoin %d, size=%d\n", __func__,
|
||||
DHD_PREALLOC_WIPHY_ESCAN0, DHD_PREALLOC_WIPHY_ESCAN0_SIZE);
|
||||
|
||||
wlan_static_dhd_info_buf = kmalloc(DHD_PREALLOC_DHD_INFO_SIZE, GFP_KERNEL);
|
||||
if (!wlan_static_dhd_info_buf)
|
||||
goto err_mem_alloc;
|
||||
pr_err("%s: sectoin %d, size=%d\n", __func__,
|
||||
DHD_PREALLOC_DHD_INFO, DHD_PREALLOC_DHD_INFO_SIZE);
|
||||
|
||||
wlan_static_dhd_wlfc_info_buf = kmalloc(WLAN_DHD_WLFC_BUF_SIZE, GFP_KERNEL);
|
||||
if (!wlan_static_dhd_wlfc_info_buf)
|
||||
goto err_mem_alloc;
|
||||
pr_err("%s: sectoin %d, size=%d\n", __func__,
|
||||
DHD_PREALLOC_DHD_WLFC_INFO, WLAN_DHD_WLFC_BUF_SIZE);
|
||||
|
||||
#ifdef BCMDHD_PCIE
|
||||
wlan_static_if_flow_lkup = kmalloc(DHD_PREALLOC_IF_FLOW_LKUP_SIZE, GFP_KERNEL);
|
||||
if (!wlan_static_if_flow_lkup)
|
||||
goto err_mem_alloc;
|
||||
pr_err("%s: sectoin %d, size=%d\n", __func__,
|
||||
DHD_PREALLOC_IF_FLOW_LKUP, DHD_PREALLOC_IF_FLOW_LKUP_SIZE);
|
||||
#endif /* BCMDHD_PCIE */
|
||||
|
||||
wlan_static_dhd_memdump_ram_buf = kmalloc(DHD_PREALLOC_MEMDUMP_RAM_SIZE, GFP_KERNEL);
|
||||
if (!wlan_static_dhd_memdump_ram_buf)
|
||||
goto err_mem_alloc;
|
||||
pr_err("%s: sectoin %d, size=%d\n", __func__,
|
||||
DHD_PREALLOC_MEMDUMP_RAM, DHD_PREALLOC_MEMDUMP_RAM_SIZE);
|
||||
|
||||
wlan_static_dhd_wlfc_hanger_buf = kmalloc(DHD_PREALLOC_DHD_WLFC_HANGER_SIZE, GFP_KERNEL);
|
||||
if (!wlan_static_dhd_wlfc_hanger_buf)
|
||||
goto err_mem_alloc;
|
||||
pr_err("%s: sectoin %d, size=%d\n", __func__,
|
||||
DHD_PREALLOC_DHD_WLFC_HANGER, DHD_PREALLOC_DHD_WLFC_HANGER_SIZE);
|
||||
|
||||
wlan_static_dhd_log_dump_buf = kmalloc(DHD_PREALLOC_DHD_LOG_DUMP_BUF_SIZE, GFP_KERNEL);
|
||||
if (!wlan_static_dhd_log_dump_buf)
|
||||
goto err_mem_alloc;
|
||||
pr_err("%s: sectoin %d, size=%d\n", __func__,
|
||||
DHD_PREALLOC_DHD_LOG_DUMP_BUF, DHD_PREALLOC_DHD_LOG_DUMP_BUF_SIZE);
|
||||
|
||||
wlan_static_dhd_log_dump_buf_ex = kmalloc(DHD_PREALLOC_DHD_LOG_DUMP_BUF_EX_SIZE, GFP_KERNEL);
|
||||
if (!wlan_static_dhd_log_dump_buf_ex)
|
||||
goto err_mem_alloc;
|
||||
pr_err("%s: sectoin %d, size=%d\n", __func__,
|
||||
DHD_PREALLOC_DHD_LOG_DUMP_BUF_EX, DHD_PREALLOC_DHD_LOG_DUMP_BUF_EX_SIZE);
|
||||
|
||||
wlan_static_wl_escan_info_buf = kmalloc(DHD_PREALLOC_WL_ESCAN_SIZE, GFP_KERNEL);
|
||||
if (!wlan_static_wl_escan_info_buf)
|
||||
goto err_mem_alloc;
|
||||
pr_err("%s: sectoin %d, size=%d\n", __func__,
|
||||
DHD_PREALLOC_WL_ESCAN, DHD_PREALLOC_WL_ESCAN_SIZE);
|
||||
|
||||
wlan_static_fw_verbose_ring_buf = kmalloc(FW_VERBOSE_RING_SIZE, GFP_KERNEL);
|
||||
if (!wlan_static_fw_verbose_ring_buf)
|
||||
goto err_mem_alloc;
|
||||
pr_err("%s: sectoin %d, size=%d\n", __func__,
|
||||
DHD_PREALLOC_FW_VERBOSE_RING, FW_VERBOSE_RING_SIZE);
|
||||
|
||||
wlan_static_fw_event_ring_buf = kmalloc(FW_EVENT_RING_SIZE, GFP_KERNEL);
|
||||
if (!wlan_static_fw_event_ring_buf)
|
||||
goto err_mem_alloc;
|
||||
pr_err("%s: sectoin %d, size=%d\n", __func__,
|
||||
DHD_PREALLOC_FW_EVENT_RING, FW_EVENT_RING_SIZE);
|
||||
|
||||
wlan_static_dhd_event_ring_buf = kmalloc(DHD_EVENT_RING_SIZE, GFP_KERNEL);
|
||||
if (!wlan_static_dhd_event_ring_buf)
|
||||
goto err_mem_alloc;
|
||||
pr_err("%s: sectoin %d, size=%d\n", __func__,
|
||||
DHD_PREALLOC_DHD_EVENT_RING, DHD_EVENT_RING_SIZE);
|
||||
|
||||
wlan_static_nan_event_ring_buf = kmalloc(NAN_EVENT_RING_SIZE, GFP_KERNEL);
|
||||
if (!wlan_static_nan_event_ring_buf)
|
||||
goto err_mem_alloc;
|
||||
pr_err("%s: sectoin %d, size=%d\n", __func__,
|
||||
DHD_PREALLOC_NAN_EVENT_RING, NAN_EVENT_RING_SIZE);
|
||||
|
||||
return 0;
|
||||
|
||||
err_mem_alloc:
|
||||
|
||||
if (wlan_static_prot)
|
||||
kfree(wlan_static_prot);
|
||||
|
||||
#if defined(BCMDHD_SDIO)
|
||||
if (wlan_static_rxbuf)
|
||||
kfree(wlan_static_rxbuf);
|
||||
|
||||
if (wlan_static_databuf)
|
||||
kfree(wlan_static_databuf);
|
||||
#endif /* BCMDHD_SDIO */
|
||||
|
||||
if (wlan_static_osl_buf)
|
||||
kfree(wlan_static_osl_buf);
|
||||
|
||||
if (wlan_static_scan_buf0)
|
||||
kfree(wlan_static_scan_buf0);
|
||||
|
||||
if (wlan_static_scan_buf1)
|
||||
kfree(wlan_static_scan_buf1);
|
||||
|
||||
if (wlan_static_dhd_info_buf)
|
||||
kfree(wlan_static_dhd_info_buf);
|
||||
|
||||
if (wlan_static_dhd_wlfc_info_buf)
|
||||
kfree(wlan_static_dhd_wlfc_info_buf);
|
||||
|
||||
#ifdef BCMDHD_PCIE
|
||||
if (wlan_static_if_flow_lkup)
|
||||
kfree(wlan_static_if_flow_lkup);
|
||||
#endif /* BCMDHD_PCIE */
|
||||
|
||||
if (wlan_static_dhd_memdump_ram_buf)
|
||||
kfree(wlan_static_dhd_memdump_ram_buf);
|
||||
|
||||
if (wlan_static_dhd_wlfc_hanger_buf)
|
||||
kfree(wlan_static_dhd_wlfc_hanger_buf);
|
||||
|
||||
if (wlan_static_dhd_log_dump_buf)
|
||||
kfree(wlan_static_dhd_log_dump_buf);
|
||||
|
||||
if (wlan_static_dhd_log_dump_buf_ex)
|
||||
kfree(wlan_static_dhd_log_dump_buf_ex);
|
||||
|
||||
if (wlan_static_wl_escan_info_buf)
|
||||
kfree(wlan_static_wl_escan_info_buf);
|
||||
|
||||
#ifdef BCMDHD_PCIE
|
||||
if (wlan_static_fw_verbose_ring_buf)
|
||||
kfree(wlan_static_fw_verbose_ring_buf);
|
||||
|
||||
if (wlan_static_fw_event_ring_buf)
|
||||
kfree(wlan_static_fw_event_ring_buf);
|
||||
|
||||
if (wlan_static_dhd_event_ring_buf)
|
||||
kfree(wlan_static_dhd_event_ring_buf);
|
||||
|
||||
if (wlan_static_nan_event_ring_buf)
|
||||
kfree(wlan_static_nan_event_ring_buf);
|
||||
#endif /* BCMDHD_PCIE */
|
||||
|
||||
pr_err("%s: Failed to mem_alloc for WLAN\n", __func__);
|
||||
|
||||
i = WLAN_SKB_BUF_NUM;
|
||||
|
||||
err_skb_alloc:
|
||||
pr_err("%s: Failed to skb_alloc for WLAN\n", __func__);
|
||||
for (j = 0; j < i; j++)
|
||||
dev_kfree_skb(wlan_static_skb[j]);
|
||||
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
static int __init
|
||||
dhd_static_buf_init(void)
|
||||
{
|
||||
dhd_init_wlan_mem();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __exit
|
||||
dhd_static_buf_exit(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
pr_err("%s()\n", __FUNCTION__);
|
||||
|
||||
for (i = 0; i < DHD_SKB_1PAGE_BUF_NUM; i++) {
|
||||
if (wlan_static_skb[i])
|
||||
dev_kfree_skb(wlan_static_skb[i]);
|
||||
}
|
||||
|
||||
for (i = DHD_SKB_1PAGE_BUF_NUM; i < WLAN_SKB_1_2PAGE_BUF_NUM; i++) {
|
||||
if (wlan_static_skb[i])
|
||||
dev_kfree_skb(wlan_static_skb[i]);
|
||||
}
|
||||
|
||||
#if defined(BCMDHD_SDIO)
|
||||
if (wlan_static_skb[i])
|
||||
dev_kfree_skb(wlan_static_skb[i]);
|
||||
#endif /* BCMDHD_SDIO */
|
||||
|
||||
if (wlan_static_prot)
|
||||
kfree(wlan_static_prot);
|
||||
|
||||
#if defined(BCMDHD_SDIO)
|
||||
if (wlan_static_rxbuf)
|
||||
kfree(wlan_static_rxbuf);
|
||||
|
||||
if (wlan_static_databuf)
|
||||
kfree(wlan_static_databuf);
|
||||
#endif /* BCMDHD_SDIO */
|
||||
|
||||
if (wlan_static_osl_buf)
|
||||
kfree(wlan_static_osl_buf);
|
||||
|
||||
if (wlan_static_scan_buf0)
|
||||
kfree(wlan_static_scan_buf0);
|
||||
|
||||
if (wlan_static_scan_buf1)
|
||||
kfree(wlan_static_scan_buf1);
|
||||
|
||||
if (wlan_static_dhd_info_buf)
|
||||
kfree(wlan_static_dhd_info_buf);
|
||||
|
||||
if (wlan_static_dhd_wlfc_info_buf)
|
||||
kfree(wlan_static_dhd_wlfc_info_buf);
|
||||
|
||||
#ifdef BCMDHD_PCIE
|
||||
if (wlan_static_if_flow_lkup)
|
||||
kfree(wlan_static_if_flow_lkup);
|
||||
#endif /* BCMDHD_PCIE */
|
||||
|
||||
if (wlan_static_dhd_memdump_ram_buf)
|
||||
kfree(wlan_static_dhd_memdump_ram_buf);
|
||||
|
||||
if (wlan_static_dhd_wlfc_hanger_buf)
|
||||
kfree(wlan_static_dhd_wlfc_hanger_buf);
|
||||
|
||||
if (wlan_static_dhd_log_dump_buf)
|
||||
kfree(wlan_static_dhd_log_dump_buf);
|
||||
|
||||
if (wlan_static_dhd_log_dump_buf_ex)
|
||||
kfree(wlan_static_dhd_log_dump_buf_ex);
|
||||
|
||||
if (wlan_static_wl_escan_info_buf)
|
||||
kfree(wlan_static_wl_escan_info_buf);
|
||||
|
||||
#ifdef BCMDHD_PCIE
|
||||
if (wlan_static_fw_verbose_ring_buf)
|
||||
kfree(wlan_static_fw_verbose_ring_buf);
|
||||
|
||||
if (wlan_static_fw_event_ring_buf)
|
||||
kfree(wlan_static_fw_event_ring_buf);
|
||||
|
||||
if (wlan_static_dhd_event_ring_buf)
|
||||
kfree(wlan_static_dhd_event_ring_buf);
|
||||
|
||||
if (wlan_static_nan_event_ring_buf)
|
||||
kfree(wlan_static_nan_event_ring_buf);
|
||||
#endif
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
module_init(dhd_static_buf_init);
|
||||
|
||||
module_exit(dhd_static_buf_exit);
|
||||
4577
drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd_wifi6/dhd_wlfc.c
Normal file
4577
drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd_wifi6/dhd_wlfc.c
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,563 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Copyright (C) 1999-2019, 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.
|
||||
*
|
||||
* Notwithstanding the above, under no circumstances may you combine this
|
||||
* software in any way with any other Broadcom software provided under a license
|
||||
* other than the GPL, without Broadcom's express prior written consent.
|
||||
*
|
||||
*
|
||||
* <<Broadcom-WL-IPTag/Open:>>
|
||||
*
|
||||
* $Id: dhd_wlfc.h 690477 2017-03-16 10:17:17Z $
|
||||
*
|
||||
*/
|
||||
#ifndef __wlfc_host_driver_definitions_h__
|
||||
#define __wlfc_host_driver_definitions_h__
|
||||
|
||||
/* #define OOO_DEBUG */
|
||||
|
||||
#define KERNEL_THREAD_RETURN_TYPE int
|
||||
|
||||
typedef int (*f_commitpkt_t)(void* ctx, void* p);
|
||||
typedef bool (*f_processpkt_t)(void* p, void* arg);
|
||||
|
||||
#define WLFC_UNSUPPORTED -9999
|
||||
|
||||
#define WLFC_NO_TRAFFIC -1
|
||||
#define WLFC_MULTI_TRAFFIC 0
|
||||
|
||||
#define BUS_RETRIES 1 /* # of retries before aborting a bus tx operation */
|
||||
|
||||
/** 16 bits will provide an absolute max of 65536 slots */
|
||||
#define WLFC_HANGER_MAXITEMS 3072
|
||||
|
||||
#define WLFC_HANGER_ITEM_STATE_FREE 1
|
||||
#define WLFC_HANGER_ITEM_STATE_INUSE 2
|
||||
#define WLFC_HANGER_ITEM_STATE_INUSE_SUPPRESSED 3
|
||||
#define WLFC_HANGER_ITEM_STATE_FLUSHED 4
|
||||
|
||||
#define WLFC_HANGER_PKT_STATE_TXSTATUS 1
|
||||
#define WLFC_HANGER_PKT_STATE_BUSRETURNED 2
|
||||
#define WLFC_HANGER_PKT_STATE_COMPLETE \
|
||||
(WLFC_HANGER_PKT_STATE_TXSTATUS | WLFC_HANGER_PKT_STATE_BUSRETURNED)
|
||||
|
||||
typedef enum {
|
||||
Q_TYPE_PSQ, /**< Power Save Queue, contains both delayed and suppressed packets */
|
||||
Q_TYPE_AFQ /**< At Firmware Queue */
|
||||
} q_type_t;
|
||||
|
||||
typedef enum ewlfc_packet_state {
|
||||
eWLFC_PKTTYPE_NEW, /**< unused in the code (Jan 2015) */
|
||||
eWLFC_PKTTYPE_DELAYED, /**< packet did not enter wlfc yet */
|
||||
eWLFC_PKTTYPE_SUPPRESSED, /**< packet entered wlfc and was suppressed by the dongle */
|
||||
eWLFC_PKTTYPE_MAX
|
||||
} ewlfc_packet_state_t;
|
||||
|
||||
typedef enum ewlfc_mac_entry_action {
|
||||
eWLFC_MAC_ENTRY_ACTION_ADD,
|
||||
eWLFC_MAC_ENTRY_ACTION_DEL,
|
||||
eWLFC_MAC_ENTRY_ACTION_UPDATE,
|
||||
eWLFC_MAC_ENTRY_ACTION_MAX
|
||||
} ewlfc_mac_entry_action_t;
|
||||
|
||||
typedef struct wlfc_hanger_item {
|
||||
uint8 state;
|
||||
uint8 gen;
|
||||
uint8 pkt_state; /**< bitmask containing eg WLFC_HANGER_PKT_STATE_TXCOMPLETE */
|
||||
uint8 pkt_txstatus;
|
||||
uint32 identifier;
|
||||
void* pkt;
|
||||
#ifdef PROP_TXSTATUS_DEBUG
|
||||
uint32 push_time;
|
||||
#endif // endif
|
||||
struct wlfc_hanger_item *next;
|
||||
} wlfc_hanger_item_t;
|
||||
|
||||
/** hanger contains packets that have been posted by the dhd to the dongle and are expected back */
|
||||
typedef struct wlfc_hanger {
|
||||
int max_items;
|
||||
uint32 pushed;
|
||||
uint32 popped;
|
||||
uint32 failed_to_push;
|
||||
uint32 failed_to_pop;
|
||||
uint32 failed_slotfind;
|
||||
uint32 slot_pos;
|
||||
wlfc_hanger_item_t items[1];
|
||||
} wlfc_hanger_t;
|
||||
|
||||
#define WLFC_HANGER_SIZE(n) ((sizeof(wlfc_hanger_t) - \
|
||||
sizeof(wlfc_hanger_item_t)) + ((n)*sizeof(wlfc_hanger_item_t)))
|
||||
|
||||
#define WLFC_STATE_OPEN 1 /**< remote MAC is able to receive packets */
|
||||
#define WLFC_STATE_CLOSE 2 /**< remote MAC is in power save mode */
|
||||
|
||||
#define WLFC_PSQ_PREC_COUNT ((AC_COUNT + 1) * 2) /**< 2 for each AC traffic and bc/mc */
|
||||
#define WLFC_AFQ_PREC_COUNT (AC_COUNT + 1)
|
||||
|
||||
#define WLFC_PSQ_LEN (4096 * 8)
|
||||
|
||||
#ifdef BCMDBUS
|
||||
#define WLFC_FLOWCONTROL_HIWATER 512
|
||||
#define WLFC_FLOWCONTROL_LOWATER (WLFC_FLOWCONTROL_HIWATER / 4)
|
||||
#else
|
||||
#define WLFC_FLOWCONTROL_HIWATER ((4096 * 8) - 256)
|
||||
#define WLFC_FLOWCONTROL_LOWATER 256
|
||||
#endif
|
||||
|
||||
#if (WLFC_FLOWCONTROL_HIWATER >= (WLFC_PSQ_LEN - 256))
|
||||
#undef WLFC_FLOWCONTROL_HIWATER
|
||||
#define WLFC_FLOWCONTROL_HIWATER (WLFC_PSQ_LEN - 256)
|
||||
#undef WLFC_FLOWCONTROL_LOWATER
|
||||
#define WLFC_FLOWCONTROL_LOWATER (WLFC_FLOWCONTROL_HIWATER / 4)
|
||||
#endif // endif
|
||||
|
||||
#define WLFC_LOG_BUF_SIZE (1024*1024)
|
||||
|
||||
/** Properties related to a remote MAC entity */
|
||||
typedef struct wlfc_mac_descriptor {
|
||||
uint8 occupied; /**< if 0, this descriptor is unused and thus can be (re)used */
|
||||
uint8 interface_id;
|
||||
uint8 iftype; /**< eg WLC_E_IF_ROLE_STA */
|
||||
uint8 state; /**< eg WLFC_STATE_OPEN */
|
||||
uint8 ac_bitmap; /**< automatic power save delivery (APSD) */
|
||||
uint8 requested_credit;
|
||||
uint8 requested_packet; /**< unit: [number of packets] */
|
||||
uint8 ea[ETHER_ADDR_LEN];
|
||||
|
||||
/** maintain (MAC,AC) based seq count for packets going to the device. As well as bc/mc. */
|
||||
uint8 seq[AC_COUNT + 1];
|
||||
uint8 generation; /**< toggles between 0 and 1 */
|
||||
struct pktq psq; /**< contains both 'delayed' and 'suppressed' packets */
|
||||
/** packets at firmware queue */
|
||||
struct pktq afq;
|
||||
/** The AC pending bitmap that was reported to the fw at last change */
|
||||
uint8 traffic_lastreported_bmp;
|
||||
/** The new AC pending bitmap */
|
||||
uint8 traffic_pending_bmp;
|
||||
/** 1= send on next opportunity */
|
||||
uint8 send_tim_signal;
|
||||
uint8 mac_handle; /**< mac handles are assigned by the dongle */
|
||||
/** Number of packets at dongle for this entry. */
|
||||
int transit_count;
|
||||
/** Number of suppression to wait before evict from delayQ */
|
||||
int suppr_transit_count;
|
||||
/** pkt sent to bus but no bus TX complete yet */
|
||||
int onbus_pkts_count;
|
||||
/** flag. TRUE when remote MAC is in suppressed state */
|
||||
uint8 suppressed;
|
||||
|
||||
#ifdef PROP_TXSTATUS_DEBUG
|
||||
uint32 dstncredit_sent_packets;
|
||||
uint32 dstncredit_acks;
|
||||
uint32 opened_ct;
|
||||
uint32 closed_ct;
|
||||
#endif // endif
|
||||
struct wlfc_mac_descriptor* prev;
|
||||
struct wlfc_mac_descriptor* next;
|
||||
} wlfc_mac_descriptor_t;
|
||||
|
||||
/** A 'commit' is the hand over of a packet from the host OS layer to the layer below (eg DBUS) */
|
||||
typedef struct dhd_wlfc_commit_info {
|
||||
uint8 needs_hdr;
|
||||
uint8 ac_fifo_credit_spent;
|
||||
ewlfc_packet_state_t pkt_type;
|
||||
wlfc_mac_descriptor_t* mac_entry;
|
||||
void* p;
|
||||
} dhd_wlfc_commit_info_t;
|
||||
|
||||
#define WLFC_DECR_SEQCOUNT(entry, prec) do { if (entry->seq[(prec)] == 0) {\
|
||||
entry->seq[prec] = 0xff; } else entry->seq[prec]--;} while (0)
|
||||
|
||||
#define WLFC_INCR_SEQCOUNT(entry, prec) entry->seq[(prec)]++
|
||||
#define WLFC_SEQCOUNT(entry, prec) entry->seq[(prec)]
|
||||
|
||||
typedef struct athost_wl_stat_counters {
|
||||
uint32 pktin;
|
||||
uint32 pktout;
|
||||
uint32 pkt2bus;
|
||||
uint32 pktdropped;
|
||||
uint32 tlv_parse_failed;
|
||||
uint32 rollback;
|
||||
uint32 rollback_failed;
|
||||
uint32 delayq_full_error;
|
||||
uint32 credit_request_failed;
|
||||
uint32 packet_request_failed;
|
||||
uint32 mac_update_failed;
|
||||
uint32 psmode_update_failed;
|
||||
uint32 interface_update_failed;
|
||||
uint32 wlfc_header_only_pkt;
|
||||
uint32 txstatus_in;
|
||||
uint32 d11_suppress;
|
||||
uint32 wl_suppress;
|
||||
uint32 bad_suppress;
|
||||
uint32 pkt_dropped;
|
||||
uint32 pkt_exptime;
|
||||
uint32 pkt_freed;
|
||||
uint32 pkt_free_err;
|
||||
uint32 psq_wlsup_retx;
|
||||
uint32 psq_wlsup_enq;
|
||||
uint32 psq_d11sup_retx;
|
||||
uint32 psq_d11sup_enq;
|
||||
uint32 psq_hostq_retx;
|
||||
uint32 psq_hostq_enq;
|
||||
uint32 mac_handle_notfound;
|
||||
uint32 wlc_tossed_pkts;
|
||||
uint32 dhd_hdrpulls;
|
||||
uint32 generic_error;
|
||||
/* an extra one for bc/mc traffic */
|
||||
uint32 send_pkts[AC_COUNT + 1];
|
||||
uint32 drop_pkts[WLFC_PSQ_PREC_COUNT];
|
||||
uint32 ooo_pkts[AC_COUNT + 1];
|
||||
#ifdef PROP_TXSTATUS_DEBUG
|
||||
/** all pkt2bus -> txstatus latency accumulated */
|
||||
uint32 latency_sample_count;
|
||||
uint32 total_status_latency;
|
||||
uint32 latency_most_recent;
|
||||
int idx_delta;
|
||||
uint32 deltas[10];
|
||||
uint32 fifo_credits_sent[6];
|
||||
uint32 fifo_credits_back[6];
|
||||
uint32 dropped_qfull[6];
|
||||
uint32 signal_only_pkts_sent;
|
||||
uint32 signal_only_pkts_freed;
|
||||
#endif // endif
|
||||
uint32 cleanup_txq_cnt;
|
||||
uint32 cleanup_psq_cnt;
|
||||
uint32 cleanup_fw_cnt;
|
||||
} athost_wl_stat_counters_t;
|
||||
|
||||
#ifdef PROP_TXSTATUS_DEBUG
|
||||
#define WLFC_HOST_FIFO_CREDIT_INC_SENTCTRS(ctx, ac) do { \
|
||||
(ctx)->stats.fifo_credits_sent[(ac)]++;} while (0)
|
||||
#define WLFC_HOST_FIFO_CREDIT_INC_BACKCTRS(ctx, ac) do { \
|
||||
(ctx)->stats.fifo_credits_back[(ac)]++;} while (0)
|
||||
#define WLFC_HOST_FIFO_DROPPEDCTR_INC(ctx, ac) do { \
|
||||
(ctx)->stats.dropped_qfull[(ac)]++;} while (0)
|
||||
#else
|
||||
#define WLFC_HOST_FIFO_CREDIT_INC_SENTCTRS(ctx, ac) do {} while (0)
|
||||
#define WLFC_HOST_FIFO_CREDIT_INC_BACKCTRS(ctx, ac) do {} while (0)
|
||||
#define WLFC_HOST_FIFO_DROPPEDCTR_INC(ctx, ac) do {} while (0)
|
||||
#endif // endif
|
||||
#define WLFC_PACKET_BOUND 10
|
||||
#define WLFC_FCMODE_NONE 0
|
||||
#define WLFC_FCMODE_IMPLIED_CREDIT 1
|
||||
#define WLFC_FCMODE_EXPLICIT_CREDIT 2
|
||||
#define WLFC_ONLY_AMPDU_HOSTREORDER 3
|
||||
|
||||
/** Reserved credits ratio when borrowed by hihger priority */
|
||||
#define WLFC_BORROW_LIMIT_RATIO 4
|
||||
|
||||
/** How long to defer borrowing in milliseconds */
|
||||
#define WLFC_BORROW_DEFER_PERIOD_MS 100
|
||||
|
||||
/** How long to defer flow control in milliseconds */
|
||||
#define WLFC_FC_DEFER_PERIOD_MS 200
|
||||
|
||||
/** How long to detect occurance per AC in miliseconds */
|
||||
#define WLFC_RX_DETECTION_THRESHOLD_MS 100
|
||||
|
||||
/** Mask to represent available ACs (note: BC/MC is ignored) */
|
||||
#define WLFC_AC_MASK 0xF
|
||||
|
||||
/** flow control specific information, only 1 instance during driver lifetime */
|
||||
typedef struct athost_wl_status_info {
|
||||
uint8 last_seqid_to_wlc;
|
||||
|
||||
/** OSL handle */
|
||||
osl_t *osh;
|
||||
/** dhd public struct pointer */
|
||||
void *dhdp;
|
||||
|
||||
f_commitpkt_t fcommit;
|
||||
void* commit_ctx;
|
||||
|
||||
/** statistics */
|
||||
athost_wl_stat_counters_t stats;
|
||||
|
||||
/** incremented on eg receiving a credit map event from the dongle */
|
||||
int Init_FIFO_credit[AC_COUNT + 2];
|
||||
/** the additional ones are for bc/mc and ATIM FIFO */
|
||||
int FIFO_credit[AC_COUNT + 2];
|
||||
/** Credit borrow counts for each FIFO from each of the other FIFOs */
|
||||
int credits_borrowed[AC_COUNT + 2][AC_COUNT + 2];
|
||||
|
||||
/** packet hanger and MAC->handle lookup table */
|
||||
void *hanger;
|
||||
|
||||
struct {
|
||||
/** table for individual nodes */
|
||||
wlfc_mac_descriptor_t nodes[WLFC_MAC_DESC_TABLE_SIZE];
|
||||
/** table for interfaces */
|
||||
wlfc_mac_descriptor_t interfaces[WLFC_MAX_IFNUM];
|
||||
/* OS may send packets to unknown (unassociated) destinations */
|
||||
/** A place holder for bc/mc and packets to unknown destinations */
|
||||
wlfc_mac_descriptor_t other;
|
||||
} destination_entries;
|
||||
|
||||
wlfc_mac_descriptor_t *active_entry_head; /**< a chain of MAC descriptors */
|
||||
int active_entry_count;
|
||||
|
||||
wlfc_mac_descriptor_t *requested_entry[WLFC_MAC_DESC_TABLE_SIZE];
|
||||
int requested_entry_count;
|
||||
|
||||
/* pkt counts for each interface and ac */
|
||||
int pkt_cnt_in_q[WLFC_MAX_IFNUM][AC_COUNT+1];
|
||||
int pkt_cnt_per_ac[AC_COUNT+1];
|
||||
int pkt_cnt_in_drv[WLFC_MAX_IFNUM][AC_COUNT+1];
|
||||
int pkt_cnt_in_psq;
|
||||
uint8 allow_fc; /**< Boolean */
|
||||
uint32 fc_defer_timestamp;
|
||||
uint32 rx_timestamp[AC_COUNT+1];
|
||||
|
||||
/** ON/OFF state for flow control to the host network interface */
|
||||
uint8 hostif_flow_state[WLFC_MAX_IFNUM];
|
||||
uint8 host_ifidx;
|
||||
|
||||
/** to flow control an OS interface */
|
||||
uint8 toggle_host_if;
|
||||
|
||||
/** To borrow credits */
|
||||
uint8 allow_credit_borrow;
|
||||
|
||||
/** ac number for the first single ac traffic */
|
||||
uint8 single_ac;
|
||||
|
||||
/** Timestamp for the first single ac traffic */
|
||||
uint32 single_ac_timestamp;
|
||||
|
||||
bool bcmc_credit_supported;
|
||||
|
||||
} athost_wl_status_info_t;
|
||||
|
||||
/** Please be mindful that total pkttag space is 32 octets only */
|
||||
typedef struct dhd_pkttag {
|
||||
|
||||
#ifdef BCM_OBJECT_TRACE
|
||||
/* if use this field, keep it at the first 4 bytes */
|
||||
uint32 sn;
|
||||
#endif /* BCM_OBJECT_TRACE */
|
||||
|
||||
/**
|
||||
b[15] - 1 = wlfc packet
|
||||
b[14:13] - encryption exemption
|
||||
b[12 ] - 1 = event channel
|
||||
b[11 ] - 1 = this packet was sent in response to one time packet request,
|
||||
do not increment credit on status for this one. [WLFC_CTL_TYPE_MAC_REQUEST_PACKET].
|
||||
b[10 ] - 1 = signal-only-packet to firmware [i.e. nothing to piggyback on]
|
||||
b[9 ] - 1 = packet is host->firmware (transmit direction)
|
||||
- 0 = packet received from firmware (firmware->host)
|
||||
b[8 ] - 1 = packet was sent due to credit_request (pspoll),
|
||||
packet does not count against FIFO credit.
|
||||
- 0 = normal transaction, packet counts against FIFO credit
|
||||
b[7 ] - 1 = AP, 0 = STA
|
||||
b[6:4] - AC FIFO number
|
||||
b[3:0] - interface index
|
||||
*/
|
||||
uint16 if_flags;
|
||||
|
||||
/**
|
||||
* destination MAC address for this packet so that not every module needs to open the packet
|
||||
* to find this
|
||||
*/
|
||||
uint8 dstn_ether[ETHER_ADDR_LEN];
|
||||
|
||||
/** This 32-bit goes from host to device for every packet. */
|
||||
uint32 htod_tag;
|
||||
|
||||
/** This 16-bit is original d11seq number for every suppressed packet. */
|
||||
uint16 htod_seq;
|
||||
|
||||
/** This address is mac entry for every packet. */
|
||||
void *entry;
|
||||
|
||||
/** bus specific stuff */
|
||||
union {
|
||||
struct {
|
||||
void *stuff;
|
||||
uint32 thing1;
|
||||
uint32 thing2;
|
||||
} sd;
|
||||
|
||||
struct {
|
||||
void *bus;
|
||||
void *urb;
|
||||
} usb;
|
||||
} bus_specific;
|
||||
} dhd_pkttag_t;
|
||||
|
||||
#define DHD_PKTTAG_WLFCPKT_MASK 0x1
|
||||
#define DHD_PKTTAG_WLFCPKT_SHIFT 15
|
||||
#define DHD_PKTTAG_WLFCPKT_SET(tag, value) ((dhd_pkttag_t*)(tag))->if_flags = \
|
||||
(((dhd_pkttag_t*)(tag))->if_flags & \
|
||||
~(DHD_PKTTAG_WLFCPKT_MASK << DHD_PKTTAG_WLFCPKT_SHIFT)) | \
|
||||
(((value) & DHD_PKTTAG_WLFCPKT_MASK) << DHD_PKTTAG_WLFCPKT_SHIFT)
|
||||
#define DHD_PKTTAG_WLFCPKT(tag) ((((dhd_pkttag_t*)(tag))->if_flags >> \
|
||||
DHD_PKTTAG_WLFCPKT_SHIFT) & DHD_PKTTAG_WLFCPKT_MASK)
|
||||
|
||||
#define DHD_PKTTAG_EXEMPT_MASK 0x3
|
||||
#define DHD_PKTTAG_EXEMPT_SHIFT 13
|
||||
#define DHD_PKTTAG_EXEMPT_SET(tag, value) ((dhd_pkttag_t*)(tag))->if_flags = \
|
||||
(((dhd_pkttag_t*)(tag))->if_flags & \
|
||||
~(DHD_PKTTAG_EXEMPT_MASK << DHD_PKTTAG_EXEMPT_SHIFT)) | \
|
||||
(((value) & DHD_PKTTAG_EXEMPT_MASK) << DHD_PKTTAG_EXEMPT_SHIFT)
|
||||
#define DHD_PKTTAG_EXEMPT(tag) ((((dhd_pkttag_t*)(tag))->if_flags >> \
|
||||
DHD_PKTTAG_EXEMPT_SHIFT) & DHD_PKTTAG_EXEMPT_MASK)
|
||||
|
||||
#define DHD_PKTTAG_EVENT_MASK 0x1
|
||||
#define DHD_PKTTAG_EVENT_SHIFT 12
|
||||
#define DHD_PKTTAG_SETEVENT(tag, event) ((dhd_pkttag_t*)(tag))->if_flags = \
|
||||
(((dhd_pkttag_t*)(tag))->if_flags & \
|
||||
~(DHD_PKTTAG_EVENT_MASK << DHD_PKTTAG_EVENT_SHIFT)) | \
|
||||
(((event) & DHD_PKTTAG_EVENT_MASK) << DHD_PKTTAG_EVENT_SHIFT)
|
||||
#define DHD_PKTTAG_EVENT(tag) ((((dhd_pkttag_t*)(tag))->if_flags >> \
|
||||
DHD_PKTTAG_EVENT_SHIFT) & DHD_PKTTAG_EVENT_MASK)
|
||||
|
||||
#define DHD_PKTTAG_ONETIMEPKTRQST_MASK 0x1
|
||||
#define DHD_PKTTAG_ONETIMEPKTRQST_SHIFT 11
|
||||
#define DHD_PKTTAG_SETONETIMEPKTRQST(tag) ((dhd_pkttag_t*)(tag))->if_flags = \
|
||||
(((dhd_pkttag_t*)(tag))->if_flags & \
|
||||
~(DHD_PKTTAG_ONETIMEPKTRQST_MASK << DHD_PKTTAG_ONETIMEPKTRQST_SHIFT)) | \
|
||||
(1 << DHD_PKTTAG_ONETIMEPKTRQST_SHIFT)
|
||||
#define DHD_PKTTAG_ONETIMEPKTRQST(tag) ((((dhd_pkttag_t*)(tag))->if_flags >> \
|
||||
DHD_PKTTAG_ONETIMEPKTRQST_SHIFT) & DHD_PKTTAG_ONETIMEPKTRQST_MASK)
|
||||
|
||||
#define DHD_PKTTAG_SIGNALONLY_MASK 0x1
|
||||
#define DHD_PKTTAG_SIGNALONLY_SHIFT 10
|
||||
#define DHD_PKTTAG_SETSIGNALONLY(tag, signalonly) ((dhd_pkttag_t*)(tag))->if_flags = \
|
||||
(((dhd_pkttag_t*)(tag))->if_flags & \
|
||||
~(DHD_PKTTAG_SIGNALONLY_MASK << DHD_PKTTAG_SIGNALONLY_SHIFT)) | \
|
||||
(((signalonly) & DHD_PKTTAG_SIGNALONLY_MASK) << DHD_PKTTAG_SIGNALONLY_SHIFT)
|
||||
#define DHD_PKTTAG_SIGNALONLY(tag) ((((dhd_pkttag_t*)(tag))->if_flags >> \
|
||||
DHD_PKTTAG_SIGNALONLY_SHIFT) & DHD_PKTTAG_SIGNALONLY_MASK)
|
||||
|
||||
#define DHD_PKTTAG_PKTDIR_MASK 0x1
|
||||
#define DHD_PKTTAG_PKTDIR_SHIFT 9
|
||||
#define DHD_PKTTAG_SETPKTDIR(tag, dir) ((dhd_pkttag_t*)(tag))->if_flags = \
|
||||
(((dhd_pkttag_t*)(tag))->if_flags & \
|
||||
~(DHD_PKTTAG_PKTDIR_MASK << DHD_PKTTAG_PKTDIR_SHIFT)) | \
|
||||
(((dir) & DHD_PKTTAG_PKTDIR_MASK) << DHD_PKTTAG_PKTDIR_SHIFT)
|
||||
#define DHD_PKTTAG_PKTDIR(tag) ((((dhd_pkttag_t*)(tag))->if_flags >> \
|
||||
DHD_PKTTAG_PKTDIR_SHIFT) & DHD_PKTTAG_PKTDIR_MASK)
|
||||
|
||||
#define DHD_PKTTAG_CREDITCHECK_MASK 0x1
|
||||
#define DHD_PKTTAG_CREDITCHECK_SHIFT 8
|
||||
#define DHD_PKTTAG_SETCREDITCHECK(tag, check) ((dhd_pkttag_t*)(tag))->if_flags = \
|
||||
(((dhd_pkttag_t*)(tag))->if_flags & \
|
||||
~(DHD_PKTTAG_CREDITCHECK_MASK << DHD_PKTTAG_CREDITCHECK_SHIFT)) | \
|
||||
(((check) & DHD_PKTTAG_CREDITCHECK_MASK) << DHD_PKTTAG_CREDITCHECK_SHIFT)
|
||||
#define DHD_PKTTAG_CREDITCHECK(tag) ((((dhd_pkttag_t*)(tag))->if_flags >> \
|
||||
DHD_PKTTAG_CREDITCHECK_SHIFT) & DHD_PKTTAG_CREDITCHECK_MASK)
|
||||
|
||||
#define DHD_PKTTAG_IFTYPE_MASK 0x1
|
||||
#define DHD_PKTTAG_IFTYPE_SHIFT 7
|
||||
#define DHD_PKTTAG_SETIFTYPE(tag, isAP) ((dhd_pkttag_t*)(tag))->if_flags = \
|
||||
(((dhd_pkttag_t*)(tag))->if_flags & \
|
||||
~(DHD_PKTTAG_IFTYPE_MASK << DHD_PKTTAG_IFTYPE_SHIFT)) | \
|
||||
(((isAP) & DHD_PKTTAG_IFTYPE_MASK) << DHD_PKTTAG_IFTYPE_SHIFT)
|
||||
#define DHD_PKTTAG_IFTYPE(tag) ((((dhd_pkttag_t*)(tag))->if_flags >> \
|
||||
DHD_PKTTAG_IFTYPE_SHIFT) & DHD_PKTTAG_IFTYPE_MASK)
|
||||
|
||||
#define DHD_PKTTAG_FIFO_MASK 0x7
|
||||
#define DHD_PKTTAG_FIFO_SHIFT 4
|
||||
#define DHD_PKTTAG_SETFIFO(tag, fifo) ((dhd_pkttag_t*)(tag))->if_flags = \
|
||||
(((dhd_pkttag_t*)(tag))->if_flags & ~(DHD_PKTTAG_FIFO_MASK << DHD_PKTTAG_FIFO_SHIFT)) | \
|
||||
(((fifo) & DHD_PKTTAG_FIFO_MASK) << DHD_PKTTAG_FIFO_SHIFT)
|
||||
#define DHD_PKTTAG_FIFO(tag) ((((dhd_pkttag_t*)(tag))->if_flags >> \
|
||||
DHD_PKTTAG_FIFO_SHIFT) & DHD_PKTTAG_FIFO_MASK)
|
||||
|
||||
#define DHD_PKTTAG_IF_MASK 0xf
|
||||
#define DHD_PKTTAG_IF_SHIFT 0
|
||||
#define DHD_PKTTAG_SETIF(tag, if) ((dhd_pkttag_t*)(tag))->if_flags = \
|
||||
(((dhd_pkttag_t*)(tag))->if_flags & ~(DHD_PKTTAG_IF_MASK << DHD_PKTTAG_IF_SHIFT)) | \
|
||||
(((if) & DHD_PKTTAG_IF_MASK) << DHD_PKTTAG_IF_SHIFT)
|
||||
#define DHD_PKTTAG_IF(tag) ((((dhd_pkttag_t*)(tag))->if_flags >> \
|
||||
DHD_PKTTAG_IF_SHIFT) & DHD_PKTTAG_IF_MASK)
|
||||
|
||||
#define DHD_PKTTAG_SETDSTN(tag, dstn_MAC_ea) memcpy(((dhd_pkttag_t*)((tag)))->dstn_ether, \
|
||||
(dstn_MAC_ea), ETHER_ADDR_LEN)
|
||||
#define DHD_PKTTAG_DSTN(tag) ((dhd_pkttag_t*)(tag))->dstn_ether
|
||||
|
||||
#define DHD_PKTTAG_SET_H2DTAG(tag, h2dvalue) ((dhd_pkttag_t*)(tag))->htod_tag = (h2dvalue)
|
||||
#define DHD_PKTTAG_H2DTAG(tag) (((dhd_pkttag_t*)(tag))->htod_tag)
|
||||
|
||||
#define DHD_PKTTAG_SET_H2DSEQ(tag, seq) ((dhd_pkttag_t*)(tag))->htod_seq = (seq)
|
||||
#define DHD_PKTTAG_H2DSEQ(tag) (((dhd_pkttag_t*)(tag))->htod_seq)
|
||||
|
||||
#define DHD_PKTTAG_SET_ENTRY(tag, entry) ((dhd_pkttag_t*)(tag))->entry = (entry)
|
||||
#define DHD_PKTTAG_ENTRY(tag) (((dhd_pkttag_t*)(tag))->entry)
|
||||
|
||||
#define PSQ_SUP_IDX(x) (x * 2 + 1)
|
||||
#define PSQ_DLY_IDX(x) (x * 2)
|
||||
|
||||
#ifdef PROP_TXSTATUS_DEBUG
|
||||
#define DHD_WLFC_CTRINC_MAC_CLOSE(entry) do { (entry)->closed_ct++; } while (0)
|
||||
#define DHD_WLFC_CTRINC_MAC_OPEN(entry) do { (entry)->opened_ct++; } while (0)
|
||||
#else
|
||||
#define DHD_WLFC_CTRINC_MAC_CLOSE(entry) do {} while (0)
|
||||
#define DHD_WLFC_CTRINC_MAC_OPEN(entry) do {} while (0)
|
||||
#endif // endif
|
||||
|
||||
#ifdef BCM_OBJECT_TRACE
|
||||
#define DHD_PKTTAG_SET_SN(tag, val) ((dhd_pkttag_t*)(tag))->sn = (val)
|
||||
#define DHD_PKTTAG_SN(tag) (((dhd_pkttag_t*)(tag))->sn)
|
||||
#endif /* BCM_OBJECT_TRACE */
|
||||
|
||||
/* public functions */
|
||||
int dhd_wlfc_parse_header_info(dhd_pub_t *dhd, void* pktbuf, int tlv_hdr_len,
|
||||
uchar *reorder_info_buf, uint *reorder_info_len);
|
||||
KERNEL_THREAD_RETURN_TYPE dhd_wlfc_transfer_packets(void *data);
|
||||
int dhd_wlfc_commit_packets(dhd_pub_t *dhdp, f_commitpkt_t fcommit,
|
||||
void* commit_ctx, void *pktbuf, bool need_toggle_host_if);
|
||||
int dhd_wlfc_txcomplete(dhd_pub_t *dhd, void *txp, bool success);
|
||||
int dhd_wlfc_init(dhd_pub_t *dhd);
|
||||
#ifdef SUPPORT_P2P_GO_PS
|
||||
int dhd_wlfc_suspend(dhd_pub_t *dhd);
|
||||
int dhd_wlfc_resume(dhd_pub_t *dhd);
|
||||
#endif /* SUPPORT_P2P_GO_PS */
|
||||
int dhd_wlfc_hostreorder_init(dhd_pub_t *dhd);
|
||||
int dhd_wlfc_cleanup_txq(dhd_pub_t *dhd, f_processpkt_t fn, void *arg);
|
||||
int dhd_wlfc_cleanup(dhd_pub_t *dhd, f_processpkt_t fn, void* arg);
|
||||
int dhd_wlfc_deinit(dhd_pub_t *dhd);
|
||||
int dhd_wlfc_interface_event(dhd_pub_t *dhdp, uint8 action, uint8 ifid, uint8 iftype, uint8* ea);
|
||||
int dhd_wlfc_FIFOcreditmap_event(dhd_pub_t *dhdp, uint8* event_data);
|
||||
#ifdef LIMIT_BORROW
|
||||
int dhd_wlfc_disable_credit_borrow_event(dhd_pub_t *dhdp, uint8* event_data);
|
||||
#endif /* LIMIT_BORROW */
|
||||
int dhd_wlfc_BCMCCredit_support_event(dhd_pub_t *dhdp);
|
||||
int dhd_wlfc_enable(dhd_pub_t *dhdp);
|
||||
int dhd_wlfc_dump(dhd_pub_t *dhdp, struct bcmstrbuf *strbuf);
|
||||
int dhd_wlfc_clear_counts(dhd_pub_t *dhd);
|
||||
int dhd_wlfc_get_enable(dhd_pub_t *dhd, bool *val);
|
||||
int dhd_wlfc_get_mode(dhd_pub_t *dhd, int *val);
|
||||
int dhd_wlfc_set_mode(dhd_pub_t *dhd, int val);
|
||||
bool dhd_wlfc_is_supported(dhd_pub_t *dhd);
|
||||
bool dhd_wlfc_is_header_only_pkt(dhd_pub_t * dhd, void *pktbuf);
|
||||
int dhd_wlfc_flowcontrol(dhd_pub_t *dhdp, bool state, bool bAcquireLock);
|
||||
int dhd_wlfc_save_rxpath_ac_time(dhd_pub_t * dhd, uint8 prio);
|
||||
|
||||
int dhd_wlfc_get_module_ignore(dhd_pub_t *dhd, int *val);
|
||||
int dhd_wlfc_set_module_ignore(dhd_pub_t *dhd, int val);
|
||||
int dhd_wlfc_get_credit_ignore(dhd_pub_t *dhd, int *val);
|
||||
int dhd_wlfc_set_credit_ignore(dhd_pub_t *dhd, int val);
|
||||
int dhd_wlfc_get_txstatus_ignore(dhd_pub_t *dhd, int *val);
|
||||
int dhd_wlfc_set_txstatus_ignore(dhd_pub_t *dhd, int val);
|
||||
|
||||
int dhd_wlfc_get_rxpkt_chk(dhd_pub_t *dhd, int *val);
|
||||
int dhd_wlfc_set_rxpkt_chk(dhd_pub_t *dhd, int val);
|
||||
|
||||
#endif /* __wlfc_host_driver_definitions_h__ */
|
||||
@@ -0,0 +1,387 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Common stats definitions for clients of dongle
|
||||
* ports
|
||||
*
|
||||
* Copyright (C) 1999-2019, 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.
|
||||
*
|
||||
* 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: dngl_stats.h 716269 2017-08-17 09:22:46Z $
|
||||
*/
|
||||
|
||||
#ifndef _dngl_stats_h_
|
||||
#define _dngl_stats_h_
|
||||
|
||||
#include <ethernet.h>
|
||||
#include <802.11.h>
|
||||
|
||||
typedef struct {
|
||||
unsigned long rx_packets; /* total packets received */
|
||||
unsigned long tx_packets; /* total packets transmitted */
|
||||
unsigned long rx_bytes; /* total bytes received */
|
||||
unsigned long tx_bytes; /* total bytes transmitted */
|
||||
unsigned long rx_errors; /* bad packets received */
|
||||
unsigned long tx_errors; /* packet transmit problems */
|
||||
unsigned long rx_dropped; /* packets dropped by dongle */
|
||||
unsigned long tx_dropped; /* packets dropped by dongle */
|
||||
unsigned long multicast; /* multicast packets received */
|
||||
} dngl_stats_t;
|
||||
|
||||
typedef int32 wifi_radio;
|
||||
typedef int32 wifi_channel;
|
||||
typedef int32 wifi_rssi;
|
||||
typedef struct { uint16 version; uint16 length; } ver_len;
|
||||
|
||||
typedef enum wifi_channel_width {
|
||||
WIFI_CHAN_WIDTH_20 = 0,
|
||||
WIFI_CHAN_WIDTH_40 = 1,
|
||||
WIFI_CHAN_WIDTH_80 = 2,
|
||||
WIFI_CHAN_WIDTH_160 = 3,
|
||||
WIFI_CHAN_WIDTH_80P80 = 4,
|
||||
WIFI_CHAN_WIDTH_5 = 5,
|
||||
WIFI_CHAN_WIDTH_10 = 6,
|
||||
WIFI_CHAN_WIDTH_INVALID = -1
|
||||
} wifi_channel_width_t;
|
||||
|
||||
typedef enum {
|
||||
WIFI_DISCONNECTED = 0,
|
||||
WIFI_AUTHENTICATING = 1,
|
||||
WIFI_ASSOCIATING = 2,
|
||||
WIFI_ASSOCIATED = 3,
|
||||
WIFI_EAPOL_STARTED = 4, /* if done by firmware/driver */
|
||||
WIFI_EAPOL_COMPLETED = 5, /* if done by firmware/driver */
|
||||
} wifi_connection_state;
|
||||
|
||||
typedef enum {
|
||||
WIFI_ROAMING_IDLE = 0,
|
||||
WIFI_ROAMING_ACTIVE = 1
|
||||
} wifi_roam_state;
|
||||
|
||||
typedef enum {
|
||||
WIFI_INTERFACE_STA = 0,
|
||||
WIFI_INTERFACE_SOFTAP = 1,
|
||||
WIFI_INTERFACE_IBSS = 2,
|
||||
WIFI_INTERFACE_P2P_CLIENT = 3,
|
||||
WIFI_INTERFACE_P2P_GO = 4,
|
||||
WIFI_INTERFACE_NAN = 5,
|
||||
WIFI_INTERFACE_MESH = 6
|
||||
} wifi_interface_mode;
|
||||
|
||||
#define WIFI_CAPABILITY_QOS 0x00000001 /* set for QOS association */
|
||||
#define WIFI_CAPABILITY_PROTECTED 0x00000002 /* set for protected association (802.11
|
||||
* beacon frame control protected bit set)
|
||||
*/
|
||||
#define WIFI_CAPABILITY_INTERWORKING 0x00000004 /* set if 802.11 Extended Capabilities
|
||||
* element interworking bit is set
|
||||
*/
|
||||
#define WIFI_CAPABILITY_HS20 0x00000008 /* set for HS20 association */
|
||||
#define WIFI_CAPABILITY_SSID_UTF8 0x00000010 /* set is 802.11 Extended Capabilities
|
||||
* element UTF-8 SSID bit is set
|
||||
*/
|
||||
#define WIFI_CAPABILITY_COUNTRY 0x00000020 /* set is 802.11 Country Element is present */
|
||||
#define PACK_ATTRIBUTE __attribute__ ((packed))
|
||||
typedef struct {
|
||||
wifi_interface_mode mode; /* interface mode */
|
||||
uint8 mac_addr[6]; /* interface mac address (self) */
|
||||
uint8 PAD[2];
|
||||
wifi_connection_state state; /* connection state (valid for STA, CLI only) */
|
||||
wifi_roam_state roaming; /* roaming state */
|
||||
uint32 capabilities; /* WIFI_CAPABILITY_XXX (self) */
|
||||
uint8 ssid[DOT11_MAX_SSID_LEN+1]; /* null terminated SSID */
|
||||
uint8 bssid[ETHER_ADDR_LEN]; /* bssid */
|
||||
uint8 PAD[1];
|
||||
uint8 ap_country_str[3]; /* country string advertised by AP */
|
||||
uint8 country_str[3]; /* country string for this association */
|
||||
uint8 PAD[2];
|
||||
} wifi_interface_info;
|
||||
|
||||
typedef wifi_interface_info *wifi_interface_handle;
|
||||
|
||||
/* channel information */
|
||||
typedef struct {
|
||||
wifi_channel_width_t width; /* channel width (20, 40, 80, 80+80, 160) */
|
||||
wifi_channel center_freq; /* primary 20 MHz channel */
|
||||
wifi_channel center_freq0; /* center frequency (MHz) first segment */
|
||||
wifi_channel center_freq1; /* center frequency (MHz) second segment */
|
||||
} wifi_channel_info;
|
||||
|
||||
/* wifi rate */
|
||||
typedef struct {
|
||||
uint32 preamble; /* 0: OFDM, 1:CCK, 2:HT 3:VHT 4..7 reserved */
|
||||
uint32 nss; /* 0:1x1, 1:2x2, 3:3x3, 4:4x4 */
|
||||
uint32 bw; /* 0:20MHz, 1:40Mhz, 2:80Mhz, 3:160Mhz */
|
||||
uint32 rateMcsIdx; /* OFDM/CCK rate code would be as per ieee std
|
||||
* in the units of 0.5mbps
|
||||
*/
|
||||
/* HT/VHT it would be mcs index */
|
||||
uint32 reserved; /* reserved */
|
||||
uint32 bitrate; /* units of 100 Kbps */
|
||||
} wifi_rate;
|
||||
|
||||
typedef struct {
|
||||
uint32 preamble :3; /* 0: OFDM, 1:CCK, 2:HT 3:VHT 4..7 reserved */
|
||||
uint32 nss :2; /* 0:1x1, 1:2x2, 3:3x3, 4:4x4 */
|
||||
uint32 bw :3; /* 0:20MHz, 1:40Mhz, 2:80Mhz, 3:160Mhz */
|
||||
uint32 rateMcsIdx :8; /* OFDM/CCK rate code would be as per ieee std
|
||||
* in the units of 0.5mbps HT/VHT it would be
|
||||
* mcs index
|
||||
*/
|
||||
uint32 reserved :16; /* reserved */
|
||||
uint32 bitrate; /* units of 100 Kbps */
|
||||
} wifi_rate_v1;
|
||||
|
||||
/* channel statistics */
|
||||
typedef struct {
|
||||
wifi_channel_info channel; /* channel */
|
||||
uint32 on_time; /* msecs the radio is awake (32 bits number
|
||||
* accruing over time)
|
||||
*/
|
||||
uint32 cca_busy_time; /* msecs the CCA register is busy (32 bits number
|
||||
* accruing over time)
|
||||
*/
|
||||
} wifi_channel_stat;
|
||||
|
||||
/* radio statistics */
|
||||
typedef struct {
|
||||
struct {
|
||||
uint16 version;
|
||||
uint16 length;
|
||||
};
|
||||
wifi_radio radio; /* wifi radio (if multiple radio supported) */
|
||||
uint32 on_time; /* msecs the radio is awake (32 bits number
|
||||
* accruing over time)
|
||||
*/
|
||||
uint32 tx_time; /* msecs the radio is transmitting (32 bits
|
||||
* number accruing over time)
|
||||
*/
|
||||
uint32 rx_time; /* msecs the radio is in active receive (32 bits
|
||||
* number accruing over time)
|
||||
*/
|
||||
uint32 on_time_scan; /* msecs the radio is awake due to all scan (32 bits
|
||||
* number accruing over time)
|
||||
*/
|
||||
uint32 on_time_nbd; /* msecs the radio is awake due to NAN (32 bits
|
||||
* number accruing over time)
|
||||
*/
|
||||
uint32 on_time_gscan; /* msecs the radio is awake due to G?scan (32 bits
|
||||
* number accruing over time)
|
||||
*/
|
||||
uint32 on_time_roam_scan; /* msecs the radio is awake due to roam?scan (32 bits
|
||||
* number accruing over time)
|
||||
*/
|
||||
uint32 on_time_pno_scan; /* msecs the radio is awake due to PNO scan (32 bits
|
||||
* number accruing over time)
|
||||
*/
|
||||
uint32 on_time_hs20; /* msecs the radio is awake due to HS2.0 scans and
|
||||
* GAS exchange (32 bits number accruing over time)
|
||||
*/
|
||||
uint32 num_channels; /* number of channels */
|
||||
wifi_channel_stat channels[1]; /* channel statistics */
|
||||
} wifi_radio_stat;
|
||||
|
||||
typedef struct {
|
||||
wifi_radio radio;
|
||||
uint32 on_time;
|
||||
uint32 tx_time;
|
||||
uint32 rx_time;
|
||||
uint32 on_time_scan;
|
||||
uint32 on_time_nbd;
|
||||
uint32 on_time_gscan;
|
||||
uint32 on_time_roam_scan;
|
||||
uint32 on_time_pno_scan;
|
||||
uint32 on_time_hs20;
|
||||
uint32 num_channels;
|
||||
} wifi_radio_stat_h;
|
||||
|
||||
/* per rate statistics */
|
||||
typedef struct {
|
||||
wifi_rate_v1 rate; /* rate information */
|
||||
uint32 tx_mpdu; /* number of successfully transmitted data pkts (ACK rcvd) */
|
||||
uint32 rx_mpdu; /* number of received data pkts */
|
||||
uint32 mpdu_lost; /* number of data packet losses (no ACK) */
|
||||
uint32 retries; /* total number of data pkt retries */
|
||||
uint32 retries_short; /* number of short data pkt retries */
|
||||
uint32 retries_long; /* number of long data pkt retries */
|
||||
} wifi_rate_stat_v1;
|
||||
|
||||
typedef struct {
|
||||
uint16 version;
|
||||
uint16 length;
|
||||
uint32 tx_mpdu; /* number of successfully transmitted data pkts (ACK rcvd) */
|
||||
uint32 rx_mpdu; /* number of received data pkts */
|
||||
uint32 mpdu_lost; /* number of data packet losses (no ACK) */
|
||||
uint32 retries; /* total number of data pkt retries */
|
||||
uint32 retries_short; /* number of short data pkt retries */
|
||||
uint32 retries_long; /* number of long data pkt retries */
|
||||
wifi_rate rate;
|
||||
} wifi_rate_stat;
|
||||
|
||||
/* access categories */
|
||||
typedef enum {
|
||||
WIFI_AC_VO = 0,
|
||||
WIFI_AC_VI = 1,
|
||||
WIFI_AC_BE = 2,
|
||||
WIFI_AC_BK = 3,
|
||||
WIFI_AC_MAX = 4
|
||||
} wifi_traffic_ac;
|
||||
|
||||
/* wifi peer type */
|
||||
typedef enum
|
||||
{
|
||||
WIFI_PEER_STA,
|
||||
WIFI_PEER_AP,
|
||||
WIFI_PEER_P2P_GO,
|
||||
WIFI_PEER_P2P_CLIENT,
|
||||
WIFI_PEER_NAN,
|
||||
WIFI_PEER_TDLS,
|
||||
WIFI_PEER_INVALID
|
||||
} wifi_peer_type;
|
||||
|
||||
/* per peer statistics */
|
||||
typedef struct {
|
||||
wifi_peer_type type; /* peer type (AP, TDLS, GO etc.) */
|
||||
uint8 peer_mac_address[6]; /* mac address */
|
||||
uint32 capabilities; /* peer WIFI_CAPABILITY_XXX */
|
||||
uint32 num_rate; /* number of rates */
|
||||
wifi_rate_stat rate_stats[1]; /* per rate statistics, number of entries = num_rate */
|
||||
} wifi_peer_info;
|
||||
|
||||
/* per access category statistics */
|
||||
typedef struct {
|
||||
wifi_traffic_ac ac; /* access category (VI, VO, BE, BK) */
|
||||
uint32 tx_mpdu; /* number of successfully transmitted unicast data pkts
|
||||
* (ACK rcvd)
|
||||
*/
|
||||
uint32 rx_mpdu; /* number of received unicast mpdus */
|
||||
uint32 tx_mcast; /* number of succesfully transmitted multicast
|
||||
* data packets
|
||||
*/
|
||||
/* STA case: implies ACK received from AP for the
|
||||
* unicast packet in which mcast pkt was sent
|
||||
*/
|
||||
uint32 rx_mcast; /* number of received multicast data packets */
|
||||
uint32 rx_ampdu; /* number of received unicast a-mpdus */
|
||||
uint32 tx_ampdu; /* number of transmitted unicast a-mpdus */
|
||||
uint32 mpdu_lost; /* number of data pkt losses (no ACK) */
|
||||
uint32 retries; /* total number of data pkt retries */
|
||||
uint32 retries_short; /* number of short data pkt retries */
|
||||
uint32 retries_long; /* number of long data pkt retries */
|
||||
uint32 contention_time_min; /* data pkt min contention time (usecs) */
|
||||
uint32 contention_time_max; /* data pkt max contention time (usecs) */
|
||||
uint32 contention_time_avg; /* data pkt avg contention time (usecs) */
|
||||
uint32 contention_num_samples; /* num of data pkts used for contention statistics */
|
||||
} wifi_wmm_ac_stat;
|
||||
|
||||
/* interface statistics */
|
||||
typedef struct {
|
||||
wifi_interface_handle iface; /* wifi interface */
|
||||
wifi_interface_info info; /* current state of the interface */
|
||||
uint32 beacon_rx; /* access point beacon received count from
|
||||
* connected AP
|
||||
*/
|
||||
uint64 average_tsf_offset; /* average beacon offset encountered (beacon_TSF - TBTT)
|
||||
* The average_tsf_offset field is used so as to calculate
|
||||
* the typical beacon contention time on the channel as well
|
||||
* may be used to debug beacon synchronization and related
|
||||
* power consumption issue
|
||||
*/
|
||||
uint32 leaky_ap_detected; /* indicate that this AP
|
||||
* typically leaks packets beyond
|
||||
* the driver guard time.
|
||||
*/
|
||||
uint32 leaky_ap_avg_num_frames_leaked; /* average number of frame leaked by AP after
|
||||
* frame with PM bit set was ACK'ed by AP
|
||||
*/
|
||||
uint32 leaky_ap_guard_time; /* guard time currently in force
|
||||
* (when implementing IEEE power management
|
||||
* based on frame control PM bit), How long
|
||||
* driver waits before shutting down the radio and after
|
||||
* receiving an ACK for a data frame with PM bit set)
|
||||
*/
|
||||
uint32 mgmt_rx; /* access point mgmt frames received count from
|
||||
* connected AP (including Beacon)
|
||||
*/
|
||||
uint32 mgmt_action_rx; /* action frames received count */
|
||||
uint32 mgmt_action_tx; /* action frames transmit count */
|
||||
wifi_rssi rssi_mgmt; /* access Point Beacon and Management frames RSSI
|
||||
* (averaged)
|
||||
*/
|
||||
wifi_rssi rssi_data; /* access Point Data Frames RSSI (averaged) from
|
||||
* connected AP
|
||||
*/
|
||||
wifi_rssi rssi_ack; /* access Point ACK RSSI (averaged) from
|
||||
* connected AP
|
||||
*/
|
||||
wifi_wmm_ac_stat ac[WIFI_AC_MAX]; /* per ac data packet statistics */
|
||||
uint32 num_peers; /* number of peers */
|
||||
wifi_peer_info peer_info[1]; /* per peer statistics */
|
||||
} wifi_iface_stat;
|
||||
|
||||
#ifdef CONFIG_COMPAT
|
||||
/* interface statistics */
|
||||
typedef struct {
|
||||
compat_uptr_t iface; /* wifi interface */
|
||||
wifi_interface_info info; /* current state of the interface */
|
||||
uint32 beacon_rx; /* access point beacon received count from
|
||||
* connected AP
|
||||
*/
|
||||
uint64 average_tsf_offset; /* average beacon offset encountered (beacon_TSF - TBTT)
|
||||
* The average_tsf_offset field is used so as to calculate
|
||||
* the typical beacon contention time on the channel as well
|
||||
* may be used to debug beacon synchronization and related
|
||||
* power consumption issue
|
||||
*/
|
||||
uint32 leaky_ap_detected; /* indicate that this AP
|
||||
* typically leaks packets beyond
|
||||
* the driver guard time.
|
||||
*/
|
||||
uint32 leaky_ap_avg_num_frames_leaked; /* average number of frame leaked by AP after
|
||||
* frame with PM bit set was ACK'ed by AP
|
||||
*/
|
||||
uint32 leaky_ap_guard_time; /* guard time currently in force
|
||||
* (when implementing IEEE power management
|
||||
* based on frame control PM bit), How long
|
||||
* driver waits before shutting down the radio and after
|
||||
* receiving an ACK for a data frame with PM bit set)
|
||||
*/
|
||||
uint32 mgmt_rx; /* access point mgmt frames received count from
|
||||
* connected AP (including Beacon)
|
||||
*/
|
||||
uint32 mgmt_action_rx; /* action frames received count */
|
||||
uint32 mgmt_action_tx; /* action frames transmit count */
|
||||
wifi_rssi rssi_mgmt; /* access Point Beacon and Management frames RSSI
|
||||
* (averaged)
|
||||
*/
|
||||
wifi_rssi rssi_data; /* access Point Data Frames RSSI (averaged) from
|
||||
* connected AP
|
||||
*/
|
||||
wifi_rssi rssi_ack; /* access Point ACK RSSI (averaged) from
|
||||
* connected AP
|
||||
*/
|
||||
wifi_wmm_ac_stat ac[WIFI_AC_MAX]; /* per ac data packet statistics */
|
||||
uint32 num_peers; /* number of peers */
|
||||
wifi_peer_info peer_info[1]; /* per peer statistics */
|
||||
} compat_wifi_iface_stat;
|
||||
#endif /* CONFIG_COMPAT */
|
||||
|
||||
#endif /* _dngl_stats_h_ */
|
||||
@@ -0,0 +1,44 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Dongle WL Header definitions
|
||||
*
|
||||
* Copyright (C) 1999-2019, 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.
|
||||
*
|
||||
* 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: dngl_wlhdr.h 514727 2014-11-12 03:02:48Z $
|
||||
*/
|
||||
|
||||
#ifndef _dngl_wlhdr_h_
|
||||
#define _dngl_wlhdr_h_
|
||||
|
||||
typedef struct wl_header {
|
||||
uint8 type; /* Header type */
|
||||
uint8 version; /* Header version */
|
||||
int8 rssi; /* RSSI */
|
||||
uint8 pad; /* Unused */
|
||||
} wl_header_t;
|
||||
|
||||
#define WL_HEADER_LEN sizeof(wl_header_t)
|
||||
#define WL_HEADER_TYPE 0
|
||||
#define WL_HEADER_VER 1
|
||||
#endif /* _dngl_wlhdr_h_ */
|
||||
113
drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd_wifi6/frag.c
Normal file
113
drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd_wifi6/frag.c
Normal file
@@ -0,0 +1,113 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* IE/TLV fragmentation/defragmentation support for
|
||||
* Broadcom 802.11bang Networking Device Driver
|
||||
*
|
||||
* Copyright (C) 1999-2019, 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.
|
||||
*
|
||||
* 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$
|
||||
*
|
||||
* <<Broadcom-WL-IPTag/Open:>>
|
||||
*/
|
||||
|
||||
#include <bcmutils.h>
|
||||
#include <frag.h>
|
||||
#include <802.11.h>
|
||||
|
||||
/* defrag a fragmented dot11 ie/tlv. if space does not permit, return the needed
|
||||
* ie length to contain all the fragments with status BCME_BUFTOOSHORT.
|
||||
* out_len is in/out parameter, max length on input, used/required length on output
|
||||
*/
|
||||
int
|
||||
bcm_tlv_dot11_defrag(const void *buf, uint buf_len, uint8 id, bool id_ext,
|
||||
uint8 *out, uint *out_len)
|
||||
{
|
||||
int err = BCME_OK;
|
||||
const bcm_tlv_t *ie;
|
||||
uint tot_len = 0;
|
||||
uint out_left;
|
||||
|
||||
/* find the ie; includes validation */
|
||||
ie = bcm_parse_tlvs_dot11(buf, buf_len, id, id_ext);
|
||||
if (!ie) {
|
||||
err = BCME_IE_NOTFOUND;
|
||||
goto done;
|
||||
}
|
||||
|
||||
out_left = (out && out_len) ? *out_len : 0;
|
||||
|
||||
/* first fragment */
|
||||
tot_len = id_ext ? ie->len - 1 : ie->len;
|
||||
|
||||
/* copy out if output space permits */
|
||||
if (out_left < tot_len) {
|
||||
err = BCME_BUFTOOSHORT;
|
||||
out_left = 0; /* prevent further copy */
|
||||
} else {
|
||||
memcpy(out, &ie->data[id_ext ? 1 : 0], tot_len);
|
||||
out += tot_len;
|
||||
out_left -= tot_len;
|
||||
}
|
||||
|
||||
/* if not fragmened or not fragmentable per 802.11 table 9-77 11md0.1 bail
|
||||
* we can introduce the latter check later
|
||||
*/
|
||||
if (ie->len != BCM_TLV_MAX_DATA_SIZE) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* adjust buf_len to length after ie including it */
|
||||
buf_len -= (uint)(((const uint8 *)ie - (const uint8 *)buf));
|
||||
|
||||
/* update length from fragments, okay if no next ie */
|
||||
while ((ie = bcm_next_tlv(ie, &buf_len)) &&
|
||||
(ie->id == DOT11_MNG_FRAGMENT_ID)) {
|
||||
/* note: buf_len starts at next ie and last frag may be partial */
|
||||
if (out_left < ie->len) {
|
||||
err = BCME_BUFTOOSHORT;
|
||||
out_left = 0;
|
||||
} else {
|
||||
memcpy(out, &ie->data[0], ie->len);
|
||||
out += ie->len;
|
||||
out_left -= ie->len;
|
||||
}
|
||||
|
||||
tot_len += ie->len + BCM_TLV_HDR_SIZE;
|
||||
|
||||
/* all but last should be of max size */
|
||||
if (ie->len < BCM_TLV_MAX_DATA_SIZE) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
done:
|
||||
if (out_len) {
|
||||
*out_len = tot_len;
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
int
|
||||
bcm_tlv_dot11_frag_tot_len(const void *buf, uint buf_len,
|
||||
uint8 id, bool id_ext, uint *ie_len)
|
||||
{
|
||||
return bcm_tlv_dot11_defrag(buf, buf_len, id, id_ext, NULL, ie_len);
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* IE/TLV (de)fragmentation declarations/definitions for
|
||||
* Broadcom 802.11abgn Networking Device Driver
|
||||
*
|
||||
* Copyright (C) 1999-2019, 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.
|
||||
*
|
||||
* 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$
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __FRAG_H__
|
||||
#define __FRAG_H__
|
||||
|
||||
int bcm_tlv_dot11_frag_tot_len(const void *buf, uint buf_len,
|
||||
uint8 id, bool id_ext, uint *ie_len);
|
||||
|
||||
#endif /* __FRAG_H__ */
|
||||
1428
drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd_wifi6/hnd_pktpool.c
Normal file
1428
drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd_wifi6/hnd_pktpool.c
Normal file
File diff suppressed because it is too large
Load Diff
1429
drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd_wifi6/hnd_pktq.c
Normal file
1429
drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd_wifi6/hnd_pktq.c
Normal file
File diff suppressed because it is too large
Load Diff
538
drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd_wifi6/hndlhl.c
Normal file
538
drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd_wifi6/hndlhl.c
Normal file
@@ -0,0 +1,538 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Misc utility routines for accessing lhl specific features
|
||||
* of the SiliconBackplane-based Broadcom chips.
|
||||
*
|
||||
* Copyright (C) 1999-2019, 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.
|
||||
*
|
||||
* 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: hndpmu.c 547757 2015-04-13 10:18:04Z $
|
||||
*/
|
||||
|
||||
#include <hndpmu.h>
|
||||
#include <hndlhl.h>
|
||||
#include <sbchipc.h>
|
||||
#include <hndsoc.h>
|
||||
#include <bcmdevs.h>
|
||||
#include <osl.h>
|
||||
#include <sbgci.h>
|
||||
#include <siutils.h>
|
||||
#include <bcmutils.h>
|
||||
#ifdef BCMULP
|
||||
#include <ulp.h>
|
||||
#endif // endif
|
||||
|
||||
#define SI_LHL_EXT_WAKE_REQ_MASK_MAGIC 0x7FBBF7FF /* magic number for LHL EXT */
|
||||
|
||||
/* PmuRev1 has a 24-bit PMU RsrcReq timer. However it pushes all other bits
|
||||
* upward. To make the code to run for all revs we use a variable to tell how
|
||||
* many bits we need to shift.
|
||||
*/
|
||||
#define FLAGS_SHIFT 14
|
||||
#define LHL_ERROR(args) printf args
|
||||
|
||||
void
|
||||
si_lhl_setup(si_t *sih, osl_t *osh)
|
||||
{
|
||||
if (CHIPID(sih->chip) == BCM43012_CHIP_ID) {
|
||||
/* Enable PMU sleep mode0 */
|
||||
LHL_REG(sih, lhl_top_pwrseq_ctl_adr, LHL_PWRSEQ_CTL, PMU_SLEEP_MODE_2);
|
||||
/* Modify as per the
|
||||
BCM43012/LHL#LHL-RecommendedsettingforvariousPMUSleepModes:
|
||||
*/
|
||||
LHL_REG(sih, lhl_top_pwrup_ctl_adr, LHL_PWRUP_CTL_MASK, LHL_PWRUP_CTL);
|
||||
LHL_REG(sih, lhl_top_pwrup2_ctl_adr, LHL_PWRUP2_CTL_MASK, LHL_PWRUP2_CTL);
|
||||
LHL_REG(sih, lhl_top_pwrdn_ctl_adr, LHL_PWRDN_CTL_MASK, LHL_PWRDN_SLEEP_CNT);
|
||||
LHL_REG(sih, lhl_top_pwrdn2_ctl_adr, LHL_PWRDN2_CTL_MASK, LHL_PWRDN2_CTL);
|
||||
} else if (BCM4347_CHIP(sih->chip)) {
|
||||
if (LHL_IS_PSMODE_1(sih)) {
|
||||
LHL_REG(sih, lhl_top_pwrseq_ctl_adr, LHL_PWRSEQ_CTL, PMU_SLEEP_MODE_1);
|
||||
} else {
|
||||
LHL_REG(sih, lhl_top_pwrseq_ctl_adr, LHL_PWRSEQ_CTL, PMU_SLEEP_MODE_0);
|
||||
}
|
||||
|
||||
LHL_REG(sih, lhl_top_pwrup_ctl_adr, LHL_PWRUP_CTL_MASK, LHL_PWRUP_CTL_4347);
|
||||
LHL_REG(sih, lhl_top_pwrup2_ctl_adr, LHL_PWRUP2_CTL_MASK, LHL_PWRUP2_CTL);
|
||||
LHL_REG(sih, lhl_top_pwrdn_ctl_adr,
|
||||
LHL_PWRDN_CTL_MASK, LHL_PWRDN_SLEEP_CNT);
|
||||
LHL_REG(sih, lhl_top_pwrdn2_ctl_adr, LHL_PWRDN2_CTL_MASK, LHL_PWRDN2_CTL);
|
||||
|
||||
/*
|
||||
* Enable wakeup on GPIO1, PCIE clkreq and perst signal,
|
||||
* GPIO[0] is mapped to GPIO1
|
||||
* GPIO[1] is mapped to PCIE perst
|
||||
* GPIO[2] is mapped to PCIE clkreq
|
||||
*/
|
||||
|
||||
/* GPIO1 */
|
||||
/* Clear any old interrupt status */
|
||||
LHL_REG(sih, gpio_int_st_port_adr[0],
|
||||
1 << PCIE_GPIO1_GPIO_PIN, 1 << PCIE_GPIO1_GPIO_PIN);
|
||||
/* active high level trigger */
|
||||
LHL_REG(sih, gpio_ctrl_iocfg_p_adr[PCIE_GPIO1_GPIO_PIN], ~0,
|
||||
1 << GCI_GPIO_STS_WL_DIN_SELECT);
|
||||
LHL_REG(sih, gpio_int_en_port_adr[0],
|
||||
1 << PCIE_GPIO1_GPIO_PIN, 1 << PCIE_GPIO1_GPIO_PIN);
|
||||
LHL_REG(sih, gpio_int_st_port_adr[0],
|
||||
1 << PCIE_GPIO1_GPIO_PIN, 1 << PCIE_GPIO1_GPIO_PIN);
|
||||
#if !defined(_CFEZ_)
|
||||
si_gci_set_functionsel(sih, 1, CC4347_FNSEL_SAMEASPIN);
|
||||
#endif // endif
|
||||
|
||||
/* PCIE perst */
|
||||
LHL_REG(sih, gpio_int_st_port_adr[0],
|
||||
1 << PCIE_PERST_GPIO_PIN, 1 << PCIE_PERST_GPIO_PIN);
|
||||
LHL_REG(sih, gpio_ctrl_iocfg_p_adr[PCIE_PERST_GPIO_PIN], ~0,
|
||||
(1 << GCI_GPIO_STS_EDGE_TRIG_BIT |
|
||||
1 << GCI_GPIO_STS_WL_DIN_SELECT));
|
||||
LHL_REG(sih, gpio_int_en_port_adr[0],
|
||||
1 << PCIE_PERST_GPIO_PIN, 1 << PCIE_PERST_GPIO_PIN);
|
||||
LHL_REG(sih, gpio_int_st_port_adr[0],
|
||||
1 << PCIE_PERST_GPIO_PIN, 1 << PCIE_PERST_GPIO_PIN);
|
||||
|
||||
/* PCIE clkreq */
|
||||
LHL_REG(sih, gpio_int_st_port_adr[0],
|
||||
1 << PCIE_CLKREQ_GPIO_PIN, 1 << PCIE_CLKREQ_GPIO_PIN);
|
||||
LHL_REG(sih, gpio_ctrl_iocfg_p_adr[PCIE_CLKREQ_GPIO_PIN], ~0,
|
||||
(1 << GCI_GPIO_STS_EDGE_TRIG_BIT |
|
||||
1 << GCI_GPIO_STS_NEG_EDGE_TRIG_BIT |
|
||||
1 << GCI_GPIO_STS_WL_DIN_SELECT));
|
||||
LHL_REG(sih, gpio_int_en_port_adr[0],
|
||||
1 << PCIE_CLKREQ_GPIO_PIN, 1 << PCIE_CLKREQ_GPIO_PIN);
|
||||
LHL_REG(sih, gpio_int_st_port_adr[0],
|
||||
1 << PCIE_CLKREQ_GPIO_PIN, 1 << PCIE_CLKREQ_GPIO_PIN);
|
||||
}
|
||||
}
|
||||
|
||||
/* To skip this function, specify a invalid "lpo_select" value in nvram */
|
||||
int
|
||||
si_lhl_set_lpoclk(si_t *sih, osl_t *osh, uint32 lpo_force)
|
||||
{
|
||||
gciregs_t *gciregs;
|
||||
uint clk_det_cnt, status;
|
||||
int lhl_wlclk_sel;
|
||||
uint32 lpo = 0;
|
||||
int timeout = 0;
|
||||
gciregs = si_setcore(sih, GCI_CORE_ID, 0);
|
||||
|
||||
ASSERT(gciregs != NULL);
|
||||
|
||||
/* Apply nvram override to lpo */
|
||||
if ((lpo_force == LHL_LPO_AUTO) && ((lpo = (uint32)getintvar(NULL, "lpo_select")) == 0)) {
|
||||
lpo = LHL_OSC_32k_ENAB;
|
||||
} else {
|
||||
lpo = lpo_force;
|
||||
}
|
||||
|
||||
/* Power up the desired LPO */
|
||||
switch (lpo) {
|
||||
case LHL_EXT_LPO_ENAB:
|
||||
LHL_REG(sih, lhl_main_ctl_adr, EXTLPO_BUF_PD, 0);
|
||||
lhl_wlclk_sel = LHL_EXT_SEL;
|
||||
break;
|
||||
|
||||
case LHL_LPO1_ENAB:
|
||||
LHL_REG(sih, lhl_main_ctl_adr, LPO1_PD_EN, 0);
|
||||
lhl_wlclk_sel = LHL_LPO1_SEL;
|
||||
break;
|
||||
|
||||
case LHL_LPO2_ENAB:
|
||||
LHL_REG(sih, lhl_main_ctl_adr, LPO2_PD_EN, 0);
|
||||
lhl_wlclk_sel = LHL_LPO2_SEL;
|
||||
break;
|
||||
|
||||
case LHL_OSC_32k_ENAB:
|
||||
LHL_REG(sih, lhl_main_ctl_adr, OSC_32k_PD, 0);
|
||||
lhl_wlclk_sel = LHL_32k_SEL;
|
||||
break;
|
||||
|
||||
default:
|
||||
goto done;
|
||||
}
|
||||
|
||||
LHL_REG(sih, lhl_clk_det_ctl_adr,
|
||||
LHL_CLK_DET_CTL_AD_CNTR_CLK_SEL, lhl_wlclk_sel);
|
||||
|
||||
/* Detect the desired LPO */
|
||||
|
||||
LHL_REG(sih, lhl_clk_det_ctl_adr, LHL_CLK_DET_CTL_ADR_LHL_CNTR_EN, 0);
|
||||
LHL_REG(sih, lhl_clk_det_ctl_adr,
|
||||
LHL_CLK_DET_CTL_ADR_LHL_CNTR_CLR, LHL_CLK_DET_CTL_ADR_LHL_CNTR_CLR);
|
||||
timeout = 0;
|
||||
clk_det_cnt =
|
||||
((R_REG(osh, &gciregs->lhl_clk_det_ctl_adr) & LHL_CLK_DET_CNT) >>
|
||||
LHL_CLK_DET_CNT_SHIFT);
|
||||
while (clk_det_cnt != 0 && timeout <= LPO_SEL_TIMEOUT) {
|
||||
OSL_DELAY(10);
|
||||
clk_det_cnt =
|
||||
((R_REG(osh, &gciregs->lhl_clk_det_ctl_adr) & LHL_CLK_DET_CNT) >>
|
||||
LHL_CLK_DET_CNT_SHIFT);
|
||||
timeout++;
|
||||
}
|
||||
|
||||
if (clk_det_cnt != 0) {
|
||||
LHL_ERROR(("Clock not present as clear did not work timeout = %d\n", timeout));
|
||||
goto error;
|
||||
}
|
||||
LHL_REG(sih, lhl_clk_det_ctl_adr, LHL_CLK_DET_CTL_ADR_LHL_CNTR_CLR, 0);
|
||||
LHL_REG(sih, lhl_clk_det_ctl_adr, LHL_CLK_DET_CTL_ADR_LHL_CNTR_EN,
|
||||
LHL_CLK_DET_CTL_ADR_LHL_CNTR_EN);
|
||||
clk_det_cnt =
|
||||
((R_REG(osh, &gciregs->lhl_clk_det_ctl_adr) & LHL_CLK_DET_CNT) >>
|
||||
LHL_CLK_DET_CNT_SHIFT);
|
||||
timeout = 0;
|
||||
|
||||
while (clk_det_cnt <= CLK_DET_CNT_THRESH && timeout <= LPO_SEL_TIMEOUT) {
|
||||
OSL_DELAY(10);
|
||||
clk_det_cnt =
|
||||
((R_REG(osh, &gciregs->lhl_clk_det_ctl_adr) & LHL_CLK_DET_CNT) >>
|
||||
LHL_CLK_DET_CNT_SHIFT);
|
||||
timeout++;
|
||||
}
|
||||
|
||||
if (timeout >= LPO_SEL_TIMEOUT) {
|
||||
LHL_ERROR(("LPO is not available timeout = %u\n, timeout", timeout));
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* Select the desired LPO */
|
||||
|
||||
LHL_REG(sih, lhl_main_ctl_adr,
|
||||
LHL_MAIN_CTL_ADR_LHL_WLCLK_SEL, (lhl_wlclk_sel) << LPO_SEL_SHIFT);
|
||||
|
||||
status = ((R_REG(osh, &gciregs->lhl_clk_status_adr) & LHL_MAIN_CTL_ADR_FINAL_CLK_SEL) ==
|
||||
(unsigned)(((1 << lhl_wlclk_sel) << LPO_FINAL_SEL_SHIFT))) ? 1 : 0;
|
||||
timeout = 0;
|
||||
while (!status && timeout <= LPO_SEL_TIMEOUT) {
|
||||
OSL_DELAY(10);
|
||||
status =
|
||||
((R_REG(osh, &gciregs->lhl_clk_status_adr) & LHL_MAIN_CTL_ADR_FINAL_CLK_SEL) ==
|
||||
(unsigned)(((1 << lhl_wlclk_sel) << LPO_FINAL_SEL_SHIFT))) ? 1 : 0;
|
||||
timeout++;
|
||||
}
|
||||
|
||||
if (timeout >= LPO_SEL_TIMEOUT) {
|
||||
LHL_ERROR(("LPO is not available timeout = %u\n, timeout", timeout));
|
||||
goto error;
|
||||
}
|
||||
/* Power down the rest of the LPOs */
|
||||
|
||||
if (lpo != LHL_EXT_LPO_ENAB) {
|
||||
LHL_REG(sih, lhl_main_ctl_adr, EXTLPO_BUF_PD, EXTLPO_BUF_PD);
|
||||
}
|
||||
|
||||
if (lpo != LHL_LPO1_ENAB) {
|
||||
LHL_REG(sih, lhl_main_ctl_adr, LPO1_PD_EN, LPO1_PD_EN);
|
||||
LHL_REG(sih, lhl_main_ctl_adr, LPO1_PD_SEL, LPO1_PD_SEL_VAL);
|
||||
}
|
||||
if (lpo != LHL_LPO2_ENAB) {
|
||||
LHL_REG(sih, lhl_main_ctl_adr, LPO2_PD_EN, LPO2_PD_EN);
|
||||
LHL_REG(sih, lhl_main_ctl_adr, LPO2_PD_SEL, LPO2_PD_SEL_VAL);
|
||||
}
|
||||
if (lpo != LHL_OSC_32k_ENAB) {
|
||||
LHL_REG(sih, lhl_main_ctl_adr, OSC_32k_PD, OSC_32k_PD);
|
||||
}
|
||||
if (lpo != RADIO_LPO_ENAB) {
|
||||
si_gci_chipcontrol(sih, CC_GCI_CHIPCTRL_06, LPO_SEL, 0);
|
||||
}
|
||||
done:
|
||||
return BCME_OK;
|
||||
error:
|
||||
ROMMABLE_ASSERT(0);
|
||||
return BCME_ERROR;
|
||||
}
|
||||
|
||||
void
|
||||
si_lhl_timer_config(si_t *sih, osl_t *osh, int timer_type)
|
||||
{
|
||||
uint origidx;
|
||||
pmuregs_t *pmu = NULL;
|
||||
|
||||
/* Remember original core before switch to chipc/pmu */
|
||||
origidx = si_coreidx(sih);
|
||||
if (AOB_ENAB(sih)) {
|
||||
pmu = si_setcore(sih, PMU_CORE_ID, 0);
|
||||
} else {
|
||||
pmu = si_setcoreidx(sih, SI_CC_IDX);
|
||||
}
|
||||
|
||||
ASSERT(pmu != NULL);
|
||||
|
||||
switch (timer_type) {
|
||||
case LHL_MAC_TIMER:
|
||||
/* Enable MAC Timer interrupt */
|
||||
LHL_REG(sih, lhl_wl_mactim0_intrp_adr,
|
||||
(LHL_WL_MACTIM0_INTRP_EN | LHL_WL_MACTIM0_INTRP_EDGE_TRIGGER),
|
||||
(LHL_WL_MACTIM0_INTRP_EN | LHL_WL_MACTIM0_INTRP_EDGE_TRIGGER));
|
||||
|
||||
/* Programs bits for MACPHY_CLK_AVAIL and all its dependent bits in
|
||||
* MacResourceReqMask0.
|
||||
*/
|
||||
PMU_REG(sih, mac_res_req_mask, ~0, si_pmu_rsrc_macphy_clk_deps(sih, osh, 0));
|
||||
|
||||
/* One time init of mac_res_req_timer to enable interrupt and clock request */
|
||||
HND_PMU_SYNC_WR(sih, pmu, pmu, osh,
|
||||
PMUREGADDR(sih, pmu, pmu, mac_res_req_timer),
|
||||
((PRRT_ALP_REQ | PRRT_HQ_REQ | PRRT_INTEN) << FLAGS_SHIFT));
|
||||
|
||||
if (si_numd11coreunits(sih) > 1) {
|
||||
LHL_REG(sih, lhl_wl_mactim1_intrp_adr,
|
||||
(LHL_WL_MACTIM0_INTRP_EN | LHL_WL_MACTIM0_INTRP_EDGE_TRIGGER),
|
||||
(LHL_WL_MACTIM0_INTRP_EN | LHL_WL_MACTIM0_INTRP_EDGE_TRIGGER));
|
||||
|
||||
PMU_REG(sih, mac_res_req_mask1, ~0,
|
||||
si_pmu_rsrc_macphy_clk_deps(sih, osh, 1));
|
||||
|
||||
HND_PMU_SYNC_WR(sih, pmu, pmu, osh,
|
||||
PMUREGADDR(sih, pmu, pmu, mac_res_req_timer1),
|
||||
((PRRT_ALP_REQ | PRRT_HQ_REQ | PRRT_INTEN) << FLAGS_SHIFT));
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case LHL_ARM_TIMER:
|
||||
/* Enable ARM Timer interrupt */
|
||||
LHL_REG(sih, lhl_wl_armtim0_intrp_adr,
|
||||
(LHL_WL_ARMTIM0_INTRP_EN | LHL_WL_ARMTIM0_INTRP_EDGE_TRIGGER),
|
||||
(LHL_WL_ARMTIM0_INTRP_EN | LHL_WL_ARMTIM0_INTRP_EDGE_TRIGGER));
|
||||
|
||||
/* Programs bits for HT_AVAIL and all its dependent bits in ResourceReqMask0 */
|
||||
PMU_REG(sih, res_req_mask, ~0, si_pmu_rsrc_ht_avail_clk_deps(sih, osh));
|
||||
|
||||
/* One time init of res_req_timer to enable interrupt and clock request
|
||||
* For low power request only ALP (HT_AVAIL is anyway requested by res_req_mask)
|
||||
*/
|
||||
HND_PMU_SYNC_WR(sih, pmu, pmu, osh,
|
||||
PMUREGADDR(sih, pmu, pmu, res_req_timer),
|
||||
((PRRT_ALP_REQ | PRRT_HQ_REQ | PRRT_INTEN) << FLAGS_SHIFT));
|
||||
break;
|
||||
}
|
||||
|
||||
/* Return to original core */
|
||||
si_setcoreidx(sih, origidx);
|
||||
}
|
||||
|
||||
void
|
||||
si_lhl_timer_enable(si_t *sih)
|
||||
{
|
||||
/* Enable clks for pmu int propagation */
|
||||
PMU_REG(sih, pmuintctrl0, PMU_INTC_ALP_REQ, PMU_INTC_ALP_REQ);
|
||||
|
||||
PMU_REG(sih, pmuintmask0, RSRC_INTR_MASK_TIMER_INT_0, RSRC_INTR_MASK_TIMER_INT_0);
|
||||
LHL_REG(sih, lhl_main_ctl_adr, LHL_FAST_WRITE_EN, LHL_FAST_WRITE_EN);
|
||||
PMU_REG(sih, pmucontrol_ext, PCTL_EXT_USE_LHL_TIMER, PCTL_EXT_USE_LHL_TIMER);
|
||||
}
|
||||
|
||||
void
|
||||
si_lhl_ilp_config(si_t *sih, osl_t *osh, uint32 ilp_period)
|
||||
{
|
||||
gciregs_t *gciregs;
|
||||
if (CHIPID(sih->chip) == BCM43012_CHIP_ID) {
|
||||
gciregs = si_setcore(sih, GCI_CORE_ID, 0);
|
||||
ASSERT(gciregs != NULL);
|
||||
W_REG(osh, &gciregs->lhl_wl_ilp_val_adr, ilp_period);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef BCMULP
|
||||
void
|
||||
si_lhl_disable_sdio_wakeup(si_t *sih)
|
||||
{
|
||||
/* Disable the interrupt */
|
||||
LHL_REG(sih, gpio_int_en_port_adr[0], (1 << ULP_SDIO_CMD_PIN), 0);
|
||||
|
||||
/* Clear the pending interrupt status */
|
||||
LHL_REG(sih, gpio_int_st_port_adr[0], (1 << ULP_SDIO_CMD_PIN), (1 << ULP_SDIO_CMD_PIN));
|
||||
}
|
||||
|
||||
void
|
||||
si_lhl_enable_sdio_wakeup(si_t *sih, osl_t *osh)
|
||||
{
|
||||
|
||||
gciregs_t *gciregs;
|
||||
pmuregs_t *pmu;
|
||||
gciregs = si_setcore(sih, GCI_CORE_ID, 0);
|
||||
ASSERT(gciregs != NULL);
|
||||
if (CHIPID(sih->chip) == BCM43012_CHIP_ID) {
|
||||
/* For SDIO_CMD configure P8 for wake on negedge
|
||||
* LHL 0 -> edge trigger intr mode,
|
||||
* 1 -> neg edge trigger intr mode ,
|
||||
* 6 -> din from wl side enable
|
||||
*/
|
||||
OR_REG(osh, &gciregs->gpio_ctrl_iocfg_p_adr[ULP_SDIO_CMD_PIN],
|
||||
(1 << GCI_GPIO_STS_EDGE_TRIG_BIT |
|
||||
1 << GCI_GPIO_STS_NEG_EDGE_TRIG_BIT |
|
||||
1 << GCI_GPIO_STS_WL_DIN_SELECT));
|
||||
/* Clear any old interrupt status */
|
||||
OR_REG(osh, &gciregs->gpio_int_st_port_adr[0], 1 << ULP_SDIO_CMD_PIN);
|
||||
|
||||
/* LHL GPIO[8] intr en , GPIO[8] is mapped to SDIO_CMD */
|
||||
/* Enable P8 to generate interrupt */
|
||||
OR_REG(osh, &gciregs->gpio_int_en_port_adr[0], 1 << ULP_SDIO_CMD_PIN);
|
||||
|
||||
/* Clear LHL GPIO status to trigger GCI Interrupt */
|
||||
OR_REG(osh, &gciregs->gci_intstat, GCI_INTSTATUS_LHLWLWAKE);
|
||||
/* Enable LHL GPIO Interrupt to trigger GCI Interrupt */
|
||||
OR_REG(osh, &gciregs->gci_intmask, GCI_INTMASK_LHLWLWAKE);
|
||||
OR_REG(osh, &gciregs->gci_wakemask, GCI_WAKEMASK_LHLWLWAKE);
|
||||
/* Note ->Enable GCI interrupt to trigger Chipcommon interrupt
|
||||
* Set EciGciIntEn in IntMask and will be done from FCBS saved tuple
|
||||
*/
|
||||
/* Enable LHL to trigger extWake upto HT_AVAIL */
|
||||
/* LHL GPIO Interrupt is mapped to extWake[7] */
|
||||
pmu = si_setcore(sih, PMU_CORE_ID, 0);
|
||||
ASSERT(pmu != NULL);
|
||||
/* Set bit 4 and 7 in ExtWakeMask */
|
||||
W_REG(osh, &pmu->extwakemask[0], CI_ECI | CI_WECI);
|
||||
/* Program bits for MACPHY_CLK_AVAIL rsrc in ExtWakeReqMaskN */
|
||||
W_REG(osh, &pmu->extwakereqmask[0], SI_LHL_EXT_WAKE_REQ_MASK_MAGIC);
|
||||
/* Program 0 (no need to request explicitly for any backplane clk) */
|
||||
W_REG(osh, &pmu->extwakectrl, 0x0);
|
||||
/* Note: Configure MAC/Ucode to receive interrupt
|
||||
* it will be done from saved tuple using FCBS code
|
||||
*/
|
||||
}
|
||||
}
|
||||
#endif /* BCMULP */
|
||||
|
||||
lhl_reg_set_t lv_sleep_mode_4369_lhl_reg_set[] =
|
||||
{
|
||||
/* set wl_sleep_en */
|
||||
{LHL_REG_OFF(lhl_top_pwrseq_ctl_adr), (1 << 0), (1 << 0)},
|
||||
|
||||
/* set top_pwrsw_en, top_slb_en, top_iso_en */
|
||||
{LHL_REG_OFF(lhl_top_pwrseq_ctl_adr), BCM_MASK32(5, 3), (0x0 << 3)},
|
||||
|
||||
/* set VMUX_asr_sel_en */
|
||||
{LHL_REG_OFF(lhl_top_pwrseq_ctl_adr), (1 << 8), (1 << 8)},
|
||||
|
||||
/* lhl_lp_main_ctl_adr, disable lp_mode_en, set CSR and ASR field enables for LV mode */
|
||||
{LHL_REG_OFF(lhl_lp_main_ctl_adr), BCM_MASK32(21, 0), 0x3F89FF},
|
||||
|
||||
/* lhl_lp_main_ctl1_adr, set CSR field values - CSR_adj - 0.64V and trim_adj -5mV */
|
||||
{LHL_REG_OFF(lhl_lp_main_ctl1_adr), BCM_MASK32(23, 0), 0x9E8F97},
|
||||
|
||||
/* lhl_lp_main_ctl2_adr, set ASR field values - ASR_adj - 0.76V and trim_adj +5mV */
|
||||
{LHL_REG_OFF(lhl_lp_main_ctl2_adr), BCM_MASK32(13, 0), 0x07EE},
|
||||
|
||||
/* lhl_lp_dn_ctl_adr, set down count for CSR fields- adj, mode, overi_dis */
|
||||
{LHL_REG_OFF(lhl_lp_dn_ctl_adr), ~0, ((LHL4369_CSR_OVERI_DIS_DWN_CNT << 16) |
|
||||
(LHL4369_CSR_MODE_DWN_CNT << 8) | (LHL4369_CSR_ADJ_DWN_CNT << 0))},
|
||||
|
||||
/* lhl_lp_up_ctl_adr, set up count for CSR fields- adj, mode, overi_dis */
|
||||
{LHL_REG_OFF(lhl_lp_up_ctl_adr), ~0, ((LHL4369_CSR_OVERI_DIS_UP_CNT << 16) |
|
||||
(LHL4369_CSR_MODE_UP_CNT << 8) | (LHL4369_CSR_ADJ_UP_CNT << 0))},
|
||||
|
||||
/* lhl_lp_dn_ctl1_adr, set down count for hpbg_chop_dis, ASR_adj, vddc_sw_dis */
|
||||
{LHL_REG_OFF(lhl_lp_dn_ctl1_adr), ~0, ((LHL4369_VDDC_SW_DIS_DWN_CNT << 24) |
|
||||
(LHL4369_ASR_ADJ_DWN_CNT << 16) | (LHL4369_HPBG_CHOP_DIS_DWN_CNT << 0))},
|
||||
|
||||
/* lhl_lp_up_ctl1_adr, set up count for hpbg_chop_dis, ASR_adj, vddc_sw_dis */
|
||||
{LHL_REG_OFF(lhl_lp_up_ctl1_adr), ~0, ((LHL4369_VDDC_SW_DIS_UP_CNT << 24) |
|
||||
(LHL4369_ASR_ADJ_UP_CNT << 16) | (LHL4369_HPBG_CHOP_DIS_UP_CNT << 0))},
|
||||
|
||||
/* lhl_lp_dn_ctl4_adr, set down count for ASR fields -
|
||||
* clk4m_dis, lppfm_mode, mode_sel, manual_mode
|
||||
*/
|
||||
{LHL_REG_OFF(lhl_lp_dn_ctl4_adr), ~0, ((LHL4369_ASR_MANUAL_MODE_DWN_CNT << 24) |
|
||||
(LHL4369_ASR_MODE_SEL_DWN_CNT << 16) | (LHL4369_ASR_LPPFM_MODE_DWN_CNT << 8) |
|
||||
(LHL4369_ASR_CLK4M_DIS_DWN_CNT << 0))},
|
||||
|
||||
/* lhl_lp_up_ctl4_adr, set up count for ASR fields -
|
||||
* clk4m_dis, lppfm_mode, mode_sel, manual_mode
|
||||
*/
|
||||
{LHL_REG_OFF(lhl_lp_up_ctl4_adr), ~0, ((LHL4369_ASR_MANUAL_MODE_UP_CNT << 24) |
|
||||
(LHL4369_ASR_MODE_SEL_UP_CNT << 16)| (LHL4369_ASR_LPPFM_MODE_UP_CNT << 8) |
|
||||
(LHL4369_ASR_CLK4M_DIS_UP_CNT << 0))},
|
||||
|
||||
/* lhl_lp_dn_ctl3_adr, set down count for hpbg_pu, srbg_ref, ASR_overi_dis,
|
||||
* CSR_pfm_pwr_slice_en
|
||||
*/
|
||||
{LHL_REG_OFF(lhl_lp_dn_ctl3_adr), ~0, ((LHL4369_PFM_PWR_SLICE_DWN_CNT << 24) |
|
||||
(LHL4369_ASR_OVERI_DIS_DWN_CNT << 16) | (LHL4369_SRBG_REF_SEL_DWN_CNT << 8) |
|
||||
(LHL4369_HPBG_PU_EN_DWN_CNT << 0))},
|
||||
|
||||
/* lhl_lp_up_ctl3_adr, set up count for hpbg_pu, srbg_ref, ASR_overi_dis,
|
||||
* CSR_pfm_pwr_slice_en
|
||||
*/
|
||||
{LHL_REG_OFF(lhl_lp_up_ctl3_adr), ~0, ((LHL4369_PFM_PWR_SLICE_UP_CNT << 24) |
|
||||
(LHL4369_ASR_OVERI_DIS_UP_CNT << 16) | (LHL4369_SRBG_REF_SEL_UP_CNT << 8) |
|
||||
(LHL4369_HPBG_PU_EN_UP_CNT << 0))},
|
||||
|
||||
/* lhl_lp_dn_ctl2_adr, set down count for CSR_trim_adj */
|
||||
{LHL_REG_OFF(lhl_lp_dn_ctl2_adr), ~0, (LHL4369_CSR_TRIM_ADJ_DWN_CNT << 16)},
|
||||
|
||||
/* lhl_lp_up_ctl2_adr, set up count for CSR_trim_adj */
|
||||
{LHL_REG_OFF(lhl_lp_up_ctl2_adr), ~0, (LHL4369_CSR_TRIM_ADJ_UP_CNT << 16)},
|
||||
|
||||
/* lhl_lp_dn_ctl5_adr, set down count for ASR_trim_adj */
|
||||
{LHL_REG_OFF(lhl_lp_dn_ctl5_adr), ~0, (LHL4369_ASR_TRIM_ADJ_DWN_CNT << 0)},
|
||||
|
||||
/* lhl_lp_up_ctl5_adr, set down count for ASR_trim_adj */
|
||||
{LHL_REG_OFF(lhl_lp_up_ctl5_adr), ~0, (LHL4369_ASR_TRIM_ADJ_UP_CNT << 0)},
|
||||
|
||||
/* Change the default down count values for the resources */
|
||||
/* lhl_top_pwrdn_ctl_adr, set down count for top_level_sleep, iso, slb and pwrsw */
|
||||
{LHL_REG_OFF(lhl_top_pwrdn_ctl_adr), ~0, ((LHL4369_PWRSW_EN_DWN_CNT << 24) |
|
||||
(LHL4369_SLB_EN_DWN_CNT << 16) | (LHL4369_ISO_EN_DWN_CNT << 8))},
|
||||
|
||||
/* lhl_top_pwrdn2_ctl_adr, set down count for VMUX_asr_sel */
|
||||
{LHL_REG_OFF(lhl_top_pwrdn2_ctl_adr), ~0, (LHL4369_VMUX_ASR_SEL_DWN_CNT << 16)},
|
||||
|
||||
/* Change the default up count values for the resources */
|
||||
/* lhl_top_pwrup_ctl_adr, set up count for top_level_sleep, iso, slb and pwrsw */
|
||||
{LHL_REG_OFF(lhl_top_pwrup_ctl_adr), ~0, ((LHL4369_PWRSW_EN_UP_CNT << 24) |
|
||||
(LHL4369_SLB_EN_UP_CNT << 16) | (LHL4369_ISO_EN_UP_CNT << 8))},
|
||||
|
||||
/* lhl_top_pwrdn2_ctl_adr, set down count for VMUX_asr_sel */
|
||||
{LHL_REG_OFF(lhl_top_pwrup2_ctl_adr), ~0, ((LHL4369_VMUX_ASR_SEL_UP_CNT << 16))},
|
||||
|
||||
/* Enable lhl interrupt */
|
||||
{LHL_REG_OFF(gci_intmask), (1 << 30), (1 << 30)},
|
||||
|
||||
/* Enable LHL Wake up */
|
||||
{LHL_REG_OFF(gci_wakemask), (1 << 30), (1 << 30)},
|
||||
|
||||
/* Making forceOTPpwrOn 0 */
|
||||
{LHL_REG_OFF(otpcontrol), (1 << 16), 0}
|
||||
};
|
||||
|
||||
/* LV sleep mode summary:
|
||||
* LV mode is where both ABUCK and CBUCK are programmed to low voltages during
|
||||
* sleep, and VMUX selects ABUCK as VDDOUT_AON. LPLDO needs to power off.
|
||||
* With ASR ON, LPLDO OFF
|
||||
*/
|
||||
void
|
||||
si_set_lv_sleep_mode_lhl_config_4369(si_t *sih)
|
||||
{
|
||||
uint i;
|
||||
uint coreidx = si_findcoreidx(sih, GCI_CORE_ID, 0);
|
||||
lhl_reg_set_t *regs = lv_sleep_mode_4369_lhl_reg_set;
|
||||
|
||||
/* Enable LHL LV mode:
|
||||
* lhl_top_pwrseq_ctl_adr, set wl_sleep_en, iso_en, slb_en, pwrsw_en,VMUX_asr_sel_en
|
||||
*/
|
||||
for (i = 0; i < ARRAYSIZE(lv_sleep_mode_4369_lhl_reg_set); i++) {
|
||||
si_corereg(sih, coreidx, regs[i].offset, regs[i].mask, regs[i].val);
|
||||
}
|
||||
}
|
||||
430
drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd_wifi6/hndmem.c
Normal file
430
drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd_wifi6/hndmem.c
Normal file
@@ -0,0 +1,430 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Utility routines for configuring different memories in Broadcom chips.
|
||||
*
|
||||
* Copyright (C) 1999-2019, 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.
|
||||
*
|
||||
* 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: $
|
||||
*/
|
||||
|
||||
#include <typedefs.h>
|
||||
#include <sbchipc.h>
|
||||
#include <hndsoc.h>
|
||||
#include <bcmdevs.h>
|
||||
#include <osl.h>
|
||||
#include <sbgci.h>
|
||||
#include <siutils.h>
|
||||
#include <bcmutils.h>
|
||||
#include <hndmem.h>
|
||||
|
||||
#define IS_MEMTYPE_VALID(mem) ((mem >= MEM_SOCRAM) && (mem < MEM_MAX))
|
||||
#define IS_MEMCONFIG_VALID(cfg) ((cfg >= PDA_CONFIG_CLEAR) && (cfg < PDA_CONFIG_MAX))
|
||||
|
||||
/* Returns the number of banks in a given memory */
|
||||
int
|
||||
hndmem_num_banks(si_t *sih, int mem)
|
||||
{
|
||||
uint32 savecore, mem_info;
|
||||
int num_banks = 0;
|
||||
gciregs_t *gciregs;
|
||||
osl_t *osh = si_osh(sih);
|
||||
|
||||
if (!IS_MEMTYPE_VALID(mem)) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
savecore = si_coreidx(sih);
|
||||
|
||||
/* TODO: Check whether SOCRAM core is present or not. If not, bail out */
|
||||
/* In future we need to add code for TCM based chips as well */
|
||||
if (!si_setcore(sih, SOCRAM_CORE_ID, 0)) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (sih->gcirev >= 9) {
|
||||
gciregs = si_setcore(sih, GCI_CORE_ID, 0);
|
||||
|
||||
mem_info = R_REG(osh, &gciregs->wlan_mem_info);
|
||||
|
||||
switch (mem) {
|
||||
case MEM_SOCRAM:
|
||||
num_banks = (mem_info & WLAN_MEM_INFO_REG_NUMSOCRAMBANKS_MASK) >>
|
||||
WLAN_MEM_INFO_REG_NUMSOCRAMBANKS_SHIFT;
|
||||
break;
|
||||
case MEM_BM:
|
||||
num_banks = (mem_info & WLAN_MEM_INFO_REG_NUMD11MACBM_MASK) >>
|
||||
WLAN_MEM_INFO_REG_NUMD11MACBM_SHIFT;
|
||||
break;
|
||||
case MEM_UCM:
|
||||
num_banks = (mem_info & WLAN_MEM_INFO_REG_NUMD11MACUCM_MASK) >>
|
||||
WLAN_MEM_INFO_REG_NUMD11MACUCM_SHIFT;
|
||||
break;
|
||||
case MEM_SHM:
|
||||
num_banks = (mem_info & WLAN_MEM_INFO_REG_NUMD11MACSHM_MASK) >>
|
||||
WLAN_MEM_INFO_REG_NUMD11MACSHM_SHIFT;
|
||||
break;
|
||||
default:
|
||||
ASSERT(0);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
/* TODO: Figure out bank information using SOCRAM registers */
|
||||
}
|
||||
|
||||
si_setcoreidx(sih, savecore);
|
||||
exit:
|
||||
return num_banks;
|
||||
}
|
||||
|
||||
/* Returns the size of a give bank in a given memory */
|
||||
int
|
||||
hndmem_bank_size(si_t *sih, hndmem_type_t mem, int bank_num)
|
||||
{
|
||||
uint32 savecore, bank_info, reg_data;
|
||||
int bank_sz = 0;
|
||||
gciregs_t *gciregs;
|
||||
osl_t *osh = si_osh(sih);
|
||||
|
||||
if (!IS_MEMTYPE_VALID(mem)) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
savecore = si_coreidx(sih);
|
||||
|
||||
/* TODO: Check whether SOCRAM core is present or not. If not, bail out */
|
||||
/* In future we need to add code for TCM based chips as well */
|
||||
if (!si_setcore(sih, SOCRAM_CORE_ID, 0)) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (sih->gcirev >= 9) {
|
||||
gciregs = si_setcore(sih, GCI_CORE_ID, 0);
|
||||
|
||||
reg_data = ((mem &
|
||||
GCI_INDIRECT_ADDRESS_REG_GPIOINDEX_MASK) <<
|
||||
GCI_INDIRECT_ADDRESS_REG_GPIOINDEX_SHIFT) |
|
||||
((bank_num & GCI_INDIRECT_ADDRESS_REG_REGINDEX_MASK)
|
||||
<< GCI_INDIRECT_ADDRESS_REG_REGINDEX_SHIFT);
|
||||
W_REG(osh, &gciregs->gci_indirect_addr, reg_data);
|
||||
|
||||
bank_info = R_REG(osh, &gciregs->wlan_bankxinfo);
|
||||
bank_sz = (bank_info & WLAN_BANKXINFO_BANK_SIZE_MASK) >>
|
||||
WLAN_BANKXINFO_BANK_SIZE_SHIFT;
|
||||
} else {
|
||||
/* TODO: Figure out bank size using SOCRAM registers */
|
||||
}
|
||||
|
||||
si_setcoreidx(sih, savecore);
|
||||
exit:
|
||||
return bank_sz;
|
||||
}
|
||||
|
||||
/* Returns the start address of given memory */
|
||||
uint32
|
||||
hndmem_mem_base(si_t *sih, hndmem_type_t mem)
|
||||
{
|
||||
uint32 savecore, base_addr = 0;
|
||||
|
||||
/* Currently only support of SOCRAM is available in hardware */
|
||||
if (mem != MEM_SOCRAM) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
savecore = si_coreidx(sih);
|
||||
|
||||
if (si_setcore(sih, SOCRAM_CORE_ID, 0))
|
||||
{
|
||||
base_addr = si_get_slaveport_addr(sih, CORE_SLAVE_PORT_1,
|
||||
CORE_BASE_ADDR_0, SOCRAM_CORE_ID, 0);
|
||||
} else {
|
||||
/* TODO: Add code to get the base address of TCM */
|
||||
base_addr = 0;
|
||||
}
|
||||
|
||||
si_setcoreidx(sih, savecore);
|
||||
|
||||
exit:
|
||||
return base_addr;
|
||||
}
|
||||
|
||||
#ifdef BCMDEBUG
|
||||
char *hndmem_type_str[] =
|
||||
{
|
||||
"SOCRAM", /* 0 */
|
||||
"BM", /* 1 */
|
||||
"UCM", /* 2 */
|
||||
"SHM", /* 3 */
|
||||
};
|
||||
|
||||
/* Dumps the complete memory information */
|
||||
void
|
||||
hndmem_dump_meminfo_all(si_t *sih)
|
||||
{
|
||||
int mem, bank, bank_cnt, bank_sz;
|
||||
|
||||
for (mem = MEM_SOCRAM; mem < MEM_MAX; mem++) {
|
||||
bank_cnt = hndmem_num_banks(sih, mem);
|
||||
|
||||
printf("\nMemtype: %s\n", hndmem_type_str[mem]);
|
||||
for (bank = 0; bank < bank_cnt; bank++) {
|
||||
bank_sz = hndmem_bank_size(sih, mem, bank);
|
||||
printf("Bank-%d: %d KB\n", bank, bank_sz);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* BCMDEBUG */
|
||||
|
||||
/* Configures the Sleep PDA for a particular bank for a given memory type */
|
||||
int
|
||||
hndmem_sleeppda_bank_config(si_t *sih, hndmem_type_t mem, int bank_num,
|
||||
hndmem_config_t config, uint32 pda)
|
||||
{
|
||||
uint32 savecore, reg_data;
|
||||
gciregs_t *gciregs;
|
||||
int err = BCME_OK;
|
||||
osl_t *osh = si_osh(sih);
|
||||
|
||||
/* TODO: Check whether SOCRAM core is present or not. If not, bail out */
|
||||
/* In future we need to add code for TCM based chips as well */
|
||||
if (!si_setcore(sih, SOCRAM_CORE_ID, 0)) {
|
||||
err = BCME_UNSUPPORTED;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* Sleep PDA is supported only by GCI rev >= 9 */
|
||||
if (sih->gcirev < 9) {
|
||||
err = BCME_UNSUPPORTED;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (!IS_MEMTYPE_VALID(mem)) {
|
||||
err = BCME_BADOPTION;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (!IS_MEMCONFIG_VALID(config)) {
|
||||
err = BCME_BADOPTION;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
savecore = si_coreidx(sih);
|
||||
gciregs = si_setcore(sih, GCI_CORE_ID, 0);
|
||||
|
||||
reg_data = ((mem &
|
||||
GCI_INDIRECT_ADDRESS_REG_GPIOINDEX_MASK) <<
|
||||
GCI_INDIRECT_ADDRESS_REG_GPIOINDEX_SHIFT) |
|
||||
((bank_num & GCI_INDIRECT_ADDRESS_REG_REGINDEX_MASK)
|
||||
<< GCI_INDIRECT_ADDRESS_REG_REGINDEX_SHIFT);
|
||||
|
||||
W_REG(osh, &gciregs->gci_indirect_addr, reg_data);
|
||||
|
||||
if (config == PDA_CONFIG_SET_PARTIAL) {
|
||||
W_REG(osh, &gciregs->wlan_bankxsleeppda, pda);
|
||||
W_REG(osh, &gciregs->wlan_bankxkill, 0);
|
||||
}
|
||||
else if (config == PDA_CONFIG_SET_FULL) {
|
||||
W_REG(osh, &gciregs->wlan_bankxsleeppda, WLAN_BANKX_SLEEPPDA_REG_SLEEPPDA_MASK);
|
||||
W_REG(osh, &gciregs->wlan_bankxkill, WLAN_BANKX_PKILL_REG_SLEEPPDA_MASK);
|
||||
} else {
|
||||
W_REG(osh, &gciregs->wlan_bankxsleeppda, 0);
|
||||
W_REG(osh, &gciregs->wlan_bankxkill, 0);
|
||||
}
|
||||
|
||||
si_setcoreidx(sih, savecore);
|
||||
|
||||
exit:
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Configures the Active PDA for a particular bank for a given memory type */
|
||||
int
|
||||
hndmem_activepda_bank_config(si_t *sih, hndmem_type_t mem,
|
||||
int bank_num, hndmem_config_t config, uint32 pda)
|
||||
{
|
||||
uint32 savecore, reg_data;
|
||||
gciregs_t *gciregs;
|
||||
int err = BCME_OK;
|
||||
osl_t *osh = si_osh(sih);
|
||||
|
||||
if (!IS_MEMTYPE_VALID(mem)) {
|
||||
err = BCME_BADOPTION;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (!IS_MEMCONFIG_VALID(config)) {
|
||||
err = BCME_BADOPTION;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
savecore = si_coreidx(sih);
|
||||
|
||||
/* TODO: Check whether SOCRAM core is present or not. If not, bail out */
|
||||
/* In future we need to add code for TCM based chips as well */
|
||||
if (!si_setcore(sih, SOCRAM_CORE_ID, 0)) {
|
||||
err = BCME_UNSUPPORTED;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (sih->gcirev >= 9) {
|
||||
gciregs = si_setcore(sih, GCI_CORE_ID, 0);
|
||||
|
||||
reg_data = ((mem &
|
||||
GCI_INDIRECT_ADDRESS_REG_GPIOINDEX_MASK) <<
|
||||
GCI_INDIRECT_ADDRESS_REG_GPIOINDEX_SHIFT) |
|
||||
((bank_num & GCI_INDIRECT_ADDRESS_REG_REGINDEX_MASK)
|
||||
<< GCI_INDIRECT_ADDRESS_REG_REGINDEX_SHIFT);
|
||||
|
||||
W_REG(osh, &gciregs->gci_indirect_addr, reg_data);
|
||||
|
||||
if (config == PDA_CONFIG_SET_PARTIAL) {
|
||||
W_REG(osh, &gciregs->wlan_bankxactivepda, pda);
|
||||
}
|
||||
else if (config == PDA_CONFIG_SET_FULL) {
|
||||
W_REG(osh, &gciregs->wlan_bankxactivepda,
|
||||
WLAN_BANKX_SLEEPPDA_REG_SLEEPPDA_MASK);
|
||||
} else {
|
||||
W_REG(osh, &gciregs->wlan_bankxactivepda, 0);
|
||||
}
|
||||
} else {
|
||||
/* TODO: Configure SOCRAM PDA using SOCRAM registers */
|
||||
err = BCME_UNSUPPORTED;
|
||||
}
|
||||
|
||||
si_setcoreidx(sih, savecore);
|
||||
|
||||
exit:
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Configures the Sleep PDA for all the banks for a given memory type */
|
||||
int
|
||||
hndmem_sleeppda_config(si_t *sih, hndmem_type_t mem, hndmem_config_t config)
|
||||
{
|
||||
int bank;
|
||||
int num_banks = hndmem_num_banks(sih, mem);
|
||||
int err = BCME_OK;
|
||||
|
||||
/* Sleep PDA is supported only by GCI rev >= 9 */
|
||||
if (sih->gcirev < 9) {
|
||||
err = BCME_UNSUPPORTED;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (!IS_MEMTYPE_VALID(mem)) {
|
||||
err = BCME_BADOPTION;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (!IS_MEMCONFIG_VALID(config)) {
|
||||
err = BCME_BADOPTION;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
for (bank = 0; bank < num_banks; bank++)
|
||||
{
|
||||
err = hndmem_sleeppda_bank_config(sih, mem, bank, config, 0);
|
||||
}
|
||||
|
||||
exit:
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Configures the Active PDA for all the banks for a given memory type */
|
||||
int
|
||||
hndmem_activepda_config(si_t *sih, hndmem_type_t mem, hndmem_config_t config)
|
||||
{
|
||||
int bank;
|
||||
int num_banks = hndmem_num_banks(sih, mem);
|
||||
int err = BCME_OK;
|
||||
|
||||
if (!IS_MEMTYPE_VALID(mem)) {
|
||||
err = BCME_BADOPTION;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (!IS_MEMCONFIG_VALID(config)) {
|
||||
err = BCME_BADOPTION;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
for (bank = 0; bank < num_banks; bank++)
|
||||
{
|
||||
err = hndmem_activepda_bank_config(sih, mem, bank, config, 0);
|
||||
}
|
||||
|
||||
exit:
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Turn off/on all the possible banks in a given memory range.
|
||||
* Currently this works only for SOCRAM as this is restricted by HW.
|
||||
*/
|
||||
int
|
||||
hndmem_activepda_mem_config(si_t *sih, hndmem_type_t mem, uint32 mem_start,
|
||||
uint32 size, hndmem_config_t config)
|
||||
{
|
||||
int bank, bank_sz, num_banks;
|
||||
int mem_end;
|
||||
int bank_start_addr, bank_end_addr;
|
||||
int err = BCME_OK;
|
||||
|
||||
/* We can get bank size for only SOCRAM/TCM only. Support is not avilable
|
||||
* for other memories (BM, UCM and SHM)
|
||||
*/
|
||||
if (mem != MEM_SOCRAM) {
|
||||
err = BCME_UNSUPPORTED;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
num_banks = hndmem_num_banks(sih, mem);
|
||||
bank_start_addr = hndmem_mem_base(sih, mem);
|
||||
mem_end = mem_start + size - 1;
|
||||
|
||||
for (bank = 0; bank < num_banks; bank++)
|
||||
{
|
||||
/* Bank size is spcified in bankXinfo register in terms on KBs */
|
||||
bank_sz = 1024 * hndmem_bank_size(sih, mem, bank);
|
||||
|
||||
bank_end_addr = bank_start_addr + bank_sz - 1;
|
||||
|
||||
if (config == PDA_CONFIG_SET_FULL) {
|
||||
/* Check if the bank is completely overlapping with the given mem range */
|
||||
if ((mem_start <= bank_start_addr) && (mem_end >= bank_end_addr)) {
|
||||
err = hndmem_activepda_bank_config(sih, mem, bank, config, 0);
|
||||
}
|
||||
} else {
|
||||
/* Check if the bank is completely overlaped with the given mem range */
|
||||
if (((mem_start <= bank_start_addr) && (mem_end >= bank_end_addr)) ||
|
||||
/* Check if the bank is partially overlaped with the given range */
|
||||
((mem_start <= bank_end_addr) && (mem_end >= bank_start_addr))) {
|
||||
err = hndmem_activepda_bank_config(sih, mem, bank, config, 0);
|
||||
}
|
||||
}
|
||||
|
||||
bank_start_addr += bank_sz;
|
||||
}
|
||||
|
||||
exit:
|
||||
return err;
|
||||
}
|
||||
789
drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd_wifi6/hndpmu.c
Normal file
789
drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd_wifi6/hndpmu.c
Normal file
@@ -0,0 +1,789 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Misc utility routines for accessing PMU corerev specific features
|
||||
* of the SiliconBackplane-based Broadcom chips.
|
||||
*
|
||||
* Copyright (C) 1999-2019, 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.
|
||||
*
|
||||
* 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: hndpmu.c 783841 2018-10-09 06:24:16Z $
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Note: this file contains PLL/FLL related functions. A chip can contain multiple PLLs/FLLs.
|
||||
* However, in the context of this file the baseband ('BB') PLL/FLL is referred to.
|
||||
*
|
||||
* Throughout this code, the prefixes 'pmu1_' and 'pmu2_' are used.
|
||||
* They refer to different revisions of the PMU (which is at revision 18 @ Apr 25, 2012)
|
||||
* pmu1_ marks the transition from PLL to ADFLL (Digital Frequency Locked Loop). It supports
|
||||
* fractional frequency generation. pmu2_ does not support fractional frequency generation.
|
||||
*/
|
||||
|
||||
#include <bcm_cfg.h>
|
||||
#include <typedefs.h>
|
||||
#include <bcmdefs.h>
|
||||
#include <osl.h>
|
||||
#include <bcmutils.h>
|
||||
#include <siutils.h>
|
||||
#include <bcmdevs.h>
|
||||
#include <hndsoc.h>
|
||||
#include <sbchipc.h>
|
||||
#include <hndchipc.h>
|
||||
#include <hndpmu.h>
|
||||
#include <hndlhl.h>
|
||||
#if defined(BCMULP)
|
||||
#include <ulp.h>
|
||||
#endif /* defined(BCMULP) */
|
||||
#include <sbgci.h>
|
||||
#ifdef EVENT_LOG_COMPILE
|
||||
#include <event_log.h>
|
||||
#endif // endif
|
||||
#include <sbgci.h>
|
||||
#include <lpflags.h>
|
||||
|
||||
#define PMU_ERROR(args)
|
||||
|
||||
#define PMU_MSG(args)
|
||||
|
||||
/* To check in verbose debugging messages not intended
|
||||
* to be on except on private builds.
|
||||
*/
|
||||
#define PMU_NONE(args)
|
||||
#define flags_shift 14
|
||||
|
||||
/** contains resource bit positions for a specific chip */
|
||||
struct rsc_per_chip_s {
|
||||
uint8 ht_avail;
|
||||
uint8 macphy_clkavail;
|
||||
uint8 ht_start;
|
||||
uint8 otp_pu;
|
||||
uint8 macphy_aux_clkavail;
|
||||
};
|
||||
|
||||
typedef struct rsc_per_chip_s rsc_per_chip_t;
|
||||
|
||||
#if defined(BCMPMU_STATS) && !defined(BCMPMU_STATS_DISABLED)
|
||||
bool _pmustatsenab = TRUE;
|
||||
#else
|
||||
bool _pmustatsenab = FALSE;
|
||||
#endif /* BCMPMU_STATS */
|
||||
|
||||
/**
|
||||
* Balance between stable SDIO operation and power consumption is achieved using this function.
|
||||
* Note that each drive strength table is for a specific VDDIO of the SDIO pads, ideally this
|
||||
* function should read the VDDIO itself to select the correct table. For now it has been solved
|
||||
* with the 'BCM_SDIO_VDDIO' preprocessor constant.
|
||||
*
|
||||
* 'drivestrength': desired pad drive strength in mA. Drive strength of 0 requests tri-state (if
|
||||
* hardware supports this), if no hw support drive strength is not programmed.
|
||||
*/
|
||||
void
|
||||
si_sdiod_drive_strength_init(si_t *sih, osl_t *osh, uint32 drivestrength)
|
||||
{
|
||||
/*
|
||||
* Note:
|
||||
* This function used to set the SDIO drive strength via PMU_CHIPCTL1 for the
|
||||
* 43143, 4330, 4334, 4336, 43362 chips. These chips are now no longer supported, so
|
||||
* the code has been deleted.
|
||||
* Newer chips have the SDIO drive strength setting via a GCI Chip Control register,
|
||||
* but the bit definitions are chip-specific. We are keeping this function available
|
||||
* (accessed via DHD 'sdiod_drive' IOVar) in case these newer chips need to provide access.
|
||||
*/
|
||||
UNUSED_PARAMETER(sih);
|
||||
UNUSED_PARAMETER(osh);
|
||||
UNUSED_PARAMETER(drivestrength);
|
||||
}
|
||||
|
||||
void
|
||||
si_switch_pmu_dependency(si_t *sih, uint mode)
|
||||
{
|
||||
#ifdef DUAL_PMU_SEQUENCE
|
||||
osl_t *osh = si_osh(sih);
|
||||
uint32 current_res_state;
|
||||
uint32 min_mask, max_mask;
|
||||
const pmu_res_depend_t *pmu_res_depend_table = NULL;
|
||||
uint pmu_res_depend_table_sz = 0;
|
||||
uint origidx;
|
||||
pmuregs_t *pmu;
|
||||
chipcregs_t *cc;
|
||||
BCM_REFERENCE(cc);
|
||||
|
||||
origidx = si_coreidx(sih);
|
||||
if (AOB_ENAB(sih)) {
|
||||
pmu = si_setcore(sih, PMU_CORE_ID, 0);
|
||||
cc = si_setcore(sih, CC_CORE_ID, 0);
|
||||
} else {
|
||||
pmu = si_setcoreidx(sih, SI_CC_IDX);
|
||||
cc = si_setcoreidx(sih, SI_CC_IDX);
|
||||
}
|
||||
ASSERT(pmu != NULL);
|
||||
|
||||
current_res_state = R_REG(osh, &pmu->res_state);
|
||||
min_mask = R_REG(osh, &pmu->min_res_mask);
|
||||
max_mask = R_REG(osh, &pmu->max_res_mask);
|
||||
W_REG(osh, &pmu->min_res_mask, (min_mask | current_res_state));
|
||||
switch (mode) {
|
||||
case PMU_4364_1x1_MODE:
|
||||
{
|
||||
if (CHIPID(sih->chip) == BCM4364_CHIP_ID) {
|
||||
pmu_res_depend_table = bcm4364a0_res_depend_1x1;
|
||||
pmu_res_depend_table_sz =
|
||||
ARRAYSIZE(bcm4364a0_res_depend_1x1);
|
||||
max_mask = PMU_4364_MAX_MASK_1x1;
|
||||
W_REG(osh, &pmu->res_table_sel, RES4364_SR_SAVE_RESTORE);
|
||||
W_REG(osh, &pmu->res_updn_timer, PMU_4364_SAVE_RESTORE_UPDNTIME_1x1);
|
||||
#if defined(SAVERESTORE)
|
||||
if (SR_ENAB()) {
|
||||
/* Disable 3x3 SR engine */
|
||||
W_REG(osh, &cc->sr1_control0,
|
||||
CC_SR0_4364_SR_ENG_CLK_EN |
|
||||
CC_SR0_4364_SR_RSRC_TRIGGER |
|
||||
CC_SR0_4364_SR_WD_MEM_MIN_DIV |
|
||||
CC_SR0_4364_SR_INVERT_CLK |
|
||||
CC_SR0_4364_SR_ENABLE_HT |
|
||||
CC_SR0_4364_SR_ALLOW_PIC |
|
||||
CC_SR0_4364_SR_PMU_MEM_DISABLE);
|
||||
}
|
||||
#endif /* SAVERESTORE */
|
||||
}
|
||||
break;
|
||||
}
|
||||
case PMU_4364_3x3_MODE:
|
||||
{
|
||||
if (CHIPID(sih->chip) == BCM4364_CHIP_ID) {
|
||||
W_REG(osh, &pmu->res_table_sel, RES4364_SR_SAVE_RESTORE);
|
||||
W_REG(osh, &pmu->res_updn_timer,
|
||||
PMU_4364_SAVE_RESTORE_UPDNTIME_3x3);
|
||||
/* Change the dependency table only if required */
|
||||
if ((max_mask != PMU_4364_MAX_MASK_3x3) ||
|
||||
(max_mask != PMU_4364_MAX_MASK_RSDB)) {
|
||||
pmu_res_depend_table = bcm4364a0_res_depend_rsdb;
|
||||
pmu_res_depend_table_sz =
|
||||
ARRAYSIZE(bcm4364a0_res_depend_rsdb);
|
||||
max_mask = PMU_4364_MAX_MASK_3x3;
|
||||
}
|
||||
#if defined(SAVERESTORE)
|
||||
if (SR_ENAB()) {
|
||||
/* Enable 3x3 SR engine */
|
||||
W_REG(osh, &cc->sr1_control0,
|
||||
CC_SR0_4364_SR_ENG_CLK_EN |
|
||||
CC_SR0_4364_SR_RSRC_TRIGGER |
|
||||
CC_SR0_4364_SR_WD_MEM_MIN_DIV |
|
||||
CC_SR0_4364_SR_INVERT_CLK |
|
||||
CC_SR0_4364_SR_ENABLE_HT |
|
||||
CC_SR0_4364_SR_ALLOW_PIC |
|
||||
CC_SR0_4364_SR_PMU_MEM_DISABLE |
|
||||
CC_SR0_4364_SR_ENG_EN_MASK);
|
||||
}
|
||||
#endif /* SAVERESTORE */
|
||||
}
|
||||
break;
|
||||
}
|
||||
case PMU_4364_RSDB_MODE:
|
||||
default:
|
||||
{
|
||||
if (CHIPID(sih->chip) == BCM4364_CHIP_ID) {
|
||||
W_REG(osh, &pmu->res_table_sel, RES4364_SR_SAVE_RESTORE);
|
||||
W_REG(osh, &pmu->res_updn_timer,
|
||||
PMU_4364_SAVE_RESTORE_UPDNTIME_3x3);
|
||||
/* Change the dependency table only if required */
|
||||
if ((max_mask != PMU_4364_MAX_MASK_3x3) ||
|
||||
(max_mask != PMU_4364_MAX_MASK_RSDB)) {
|
||||
pmu_res_depend_table =
|
||||
bcm4364a0_res_depend_rsdb;
|
||||
pmu_res_depend_table_sz =
|
||||
ARRAYSIZE(bcm4364a0_res_depend_rsdb);
|
||||
max_mask = PMU_4364_MAX_MASK_RSDB;
|
||||
}
|
||||
#if defined(SAVERESTORE)
|
||||
if (SR_ENAB()) {
|
||||
/* Enable 3x3 SR engine */
|
||||
W_REG(osh, &cc->sr1_control0,
|
||||
CC_SR0_4364_SR_ENG_CLK_EN |
|
||||
CC_SR0_4364_SR_RSRC_TRIGGER |
|
||||
CC_SR0_4364_SR_WD_MEM_MIN_DIV |
|
||||
CC_SR0_4364_SR_INVERT_CLK |
|
||||
CC_SR0_4364_SR_ENABLE_HT |
|
||||
CC_SR0_4364_SR_ALLOW_PIC |
|
||||
CC_SR0_4364_SR_PMU_MEM_DISABLE |
|
||||
CC_SR0_4364_SR_ENG_EN_MASK);
|
||||
}
|
||||
#endif /* SAVERESTORE */
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
si_pmu_resdeptbl_upd(sih, osh, pmu, pmu_res_depend_table, pmu_res_depend_table_sz);
|
||||
W_REG(osh, &pmu->max_res_mask, max_mask);
|
||||
W_REG(osh, &pmu->min_res_mask, min_mask);
|
||||
si_pmu_wait_for_steady_state(sih, osh, pmu);
|
||||
/* Add some delay; allow resources to come up and settle. */
|
||||
OSL_DELAY(200);
|
||||
si_setcoreidx(sih, origidx);
|
||||
#endif /* DUAL_PMU_SEQUENCE */
|
||||
}
|
||||
|
||||
#if defined(BCMULP)
|
||||
|
||||
int
|
||||
si_pmu_ulp_register(si_t *sih)
|
||||
{
|
||||
return ulp_p1_module_register(ULP_MODULE_ID_PMU, &ulp_pmu_ctx, (void *)sih);
|
||||
}
|
||||
|
||||
static uint
|
||||
si_pmu_ulp_get_retention_size_cb(void *handle, ulp_ext_info_t *einfo)
|
||||
{
|
||||
ULP_DBG(("%s: sz: %d\n", __FUNCTION__, sizeof(si_pmu_ulp_cr_dat_t)));
|
||||
return sizeof(si_pmu_ulp_cr_dat_t);
|
||||
}
|
||||
|
||||
static int
|
||||
si_pmu_ulp_enter_cb(void *handle, ulp_ext_info_t *einfo, uint8 *cache_data)
|
||||
{
|
||||
si_pmu_ulp_cr_dat_t crinfo = {0};
|
||||
crinfo.ilpcycles_per_sec = ilpcycles_per_sec;
|
||||
ULP_DBG(("%s: ilpcycles_per_sec: %x\n", __FUNCTION__, ilpcycles_per_sec));
|
||||
memcpy(cache_data, (void*)&crinfo, sizeof(crinfo));
|
||||
return BCME_OK;
|
||||
}
|
||||
|
||||
static int
|
||||
si_pmu_ulp_exit_cb(void *handle, uint8 *cache_data,
|
||||
uint8 *p2_cache_data)
|
||||
{
|
||||
si_pmu_ulp_cr_dat_t *crinfo = (si_pmu_ulp_cr_dat_t *)cache_data;
|
||||
|
||||
ilpcycles_per_sec = crinfo->ilpcycles_per_sec;
|
||||
ULP_DBG(("%s: ilpcycles_per_sec: %x, cache_data: %p\n", __FUNCTION__,
|
||||
ilpcycles_per_sec, cache_data));
|
||||
return BCME_OK;
|
||||
}
|
||||
|
||||
void
|
||||
si_pmu_ulp_chipconfig(si_t *sih, osl_t *osh)
|
||||
{
|
||||
uint32 reg_val;
|
||||
|
||||
BCM_REFERENCE(reg_val);
|
||||
|
||||
if (CHIPID(sih->chip) == BCM43012_CHIP_ID) {
|
||||
/* DS1 reset and clk enable init value config */
|
||||
si_pmu_chipcontrol(sih, PMU_CHIPCTL14, ~0x0,
|
||||
(PMUCCTL14_43012_ARMCM3_RESET_INITVAL |
|
||||
PMUCCTL14_43012_DOT11MAC_CLKEN_INITVAL |
|
||||
PMUCCTL14_43012_SDIOD_RESET_INIVAL |
|
||||
PMUCCTL14_43012_SDIO_CLK_DMN_RESET_INITVAL |
|
||||
PMUCCTL14_43012_SOCRAM_CLKEN_INITVAL |
|
||||
PMUCCTL14_43012_M2MDMA_RESET_INITVAL |
|
||||
PMUCCTL14_43012_DOT11MAC_PHY_CLK_EN_INITVAL |
|
||||
PMUCCTL14_43012_DOT11MAC_PHY_CNTL_EN_INITVAL));
|
||||
|
||||
/* Clear SFlash clock request and enable High Quality clock */
|
||||
CHIPC_REG(sih, clk_ctl_st, CCS_SFLASH_CLKREQ | CCS_HQCLKREQ, CCS_HQCLKREQ);
|
||||
|
||||
reg_val = PMU_REG(sih, min_res_mask, ~0x0, ULP_MIN_RES_MASK);
|
||||
ULP_DBG(("si_pmu_ulp_chipconfig: min_res_mask: 0x%08x\n", reg_val));
|
||||
|
||||
/* Force power switch off */
|
||||
si_pmu_chipcontrol(sih, PMU_CHIPCTL2,
|
||||
(PMUCCTL02_43012_SUBCORE_PWRSW_FORCE_ON |
|
||||
PMUCCTL02_43012_PHY_PWRSW_FORCE_ON), 0);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
si_pmu_ulp_ilp_config(si_t *sih, osl_t *osh, uint32 ilp_period)
|
||||
{
|
||||
pmuregs_t *pmu;
|
||||
pmu = si_setcoreidx(sih, si_findcoreidx(sih, PMU_CORE_ID, 0));
|
||||
W_REG(osh, &pmu->ILPPeriod, ilp_period);
|
||||
si_lhl_ilp_config(sih, osh, ilp_period);
|
||||
}
|
||||
|
||||
/** Initialize DS1 PMU hardware resources */
|
||||
void
|
||||
si_pmu_ds1_res_init(si_t *sih, osl_t *osh)
|
||||
{
|
||||
pmuregs_t *pmu;
|
||||
uint origidx;
|
||||
const pmu_res_updown_t *pmu_res_updown_table = NULL;
|
||||
uint pmu_res_updown_table_sz = 0;
|
||||
|
||||
/* Remember original core before switch to chipc/pmu */
|
||||
origidx = si_coreidx(sih);
|
||||
if (AOB_ENAB(sih)) {
|
||||
pmu = si_setcore(sih, PMU_CORE_ID, 0);
|
||||
} else {
|
||||
pmu = si_setcoreidx(sih, SI_CC_IDX);
|
||||
}
|
||||
ASSERT(pmu != NULL);
|
||||
|
||||
switch (CHIPID(sih->chip)) {
|
||||
case BCM43012_CHIP_ID:
|
||||
pmu_res_updown_table = bcm43012a0_res_updown_ds1;
|
||||
pmu_res_updown_table_sz = ARRAYSIZE(bcm43012a0_res_updown_ds1);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* Program up/down timers */
|
||||
while (pmu_res_updown_table_sz--) {
|
||||
ASSERT(pmu_res_updown_table != NULL);
|
||||
PMU_MSG(("DS1: Changing rsrc %d res_updn_timer to 0x%x\n",
|
||||
pmu_res_updown_table[pmu_res_updown_table_sz].resnum,
|
||||
pmu_res_updown_table[pmu_res_updown_table_sz].updown));
|
||||
W_REG(osh, &pmu->res_table_sel,
|
||||
pmu_res_updown_table[pmu_res_updown_table_sz].resnum);
|
||||
W_REG(osh, &pmu->res_updn_timer,
|
||||
pmu_res_updown_table[pmu_res_updown_table_sz].updown);
|
||||
}
|
||||
|
||||
/* Return to original core */
|
||||
si_setcoreidx(sih, origidx);
|
||||
}
|
||||
|
||||
#endif /* defined(BCMULP) */
|
||||
|
||||
uint32
|
||||
si_pmu_wake_bit_offset(si_t *sih)
|
||||
{
|
||||
uint32 wakebit;
|
||||
|
||||
switch (CHIPID(sih->chip)) {
|
||||
case BCM4347_CHIP_GRPID:
|
||||
wakebit = CC2_4347_GCI2WAKE_MASK;
|
||||
break;
|
||||
default:
|
||||
wakebit = 0;
|
||||
ASSERT(0);
|
||||
break;
|
||||
}
|
||||
|
||||
return wakebit;
|
||||
}
|
||||
|
||||
void si_pmu_set_min_res_mask(si_t *sih, osl_t *osh, uint min_res_mask)
|
||||
{
|
||||
pmuregs_t *pmu;
|
||||
uint origidx;
|
||||
|
||||
/* Remember original core before switch to chipc/pmu */
|
||||
origidx = si_coreidx(sih);
|
||||
if (AOB_ENAB(sih)) {
|
||||
pmu = si_setcore(sih, PMU_CORE_ID, 0);
|
||||
}
|
||||
else {
|
||||
pmu = si_setcoreidx(sih, SI_CC_IDX);
|
||||
}
|
||||
ASSERT(pmu != NULL);
|
||||
|
||||
W_REG(osh, &pmu->min_res_mask, min_res_mask);
|
||||
OSL_DELAY(100);
|
||||
|
||||
/* Return to original core */
|
||||
si_setcoreidx(sih, origidx);
|
||||
}
|
||||
|
||||
bool
|
||||
si_pmu_cap_fast_lpo(si_t *sih)
|
||||
{
|
||||
return (PMU_REG(sih, core_cap_ext, 0, 0) & PCAP_EXT_USE_MUXED_ILP_CLK_MASK) ? TRUE : FALSE;
|
||||
}
|
||||
|
||||
int
|
||||
si_pmu_fast_lpo_disable(si_t *sih)
|
||||
{
|
||||
if (!si_pmu_cap_fast_lpo(sih)) {
|
||||
PMU_ERROR(("%s: No Fast LPO capability\n", __FUNCTION__));
|
||||
return BCME_ERROR;
|
||||
}
|
||||
|
||||
PMU_REG(sih, pmucontrol_ext,
|
||||
PCTL_EXT_FASTLPO_ENAB |
|
||||
PCTL_EXT_FASTLPO_SWENAB |
|
||||
PCTL_EXT_FASTLPO_PCIE_SWENAB,
|
||||
0);
|
||||
OSL_DELAY(1000);
|
||||
return BCME_OK;
|
||||
}
|
||||
|
||||
#ifdef BCMPMU_STATS
|
||||
/*
|
||||
* 8 pmu statistics timer default map
|
||||
*
|
||||
* for CORE_RDY_AUX measure, set as below for timer 6 and 7 instead of CORE_RDY_MAIN.
|
||||
* //core-n active duration : pmu_rsrc_state(CORE_RDY_AUX)
|
||||
* { SRC_CORE_RDY_AUX, FALSE, TRUE, LEVEL_HIGH},
|
||||
* //core-n active duration : pmu_rsrc_state(CORE_RDY_AUX)
|
||||
* { SRC_CORE_RDY_AUX, FALSE, TRUE, EDGE_RISE}
|
||||
*/
|
||||
static pmu_stats_timer_t pmustatstimer[] = {
|
||||
{ SRC_LINK_IN_L12, FALSE, TRUE, PMU_STATS_LEVEL_HIGH}, //link_in_l12
|
||||
{ SRC_LINK_IN_L23, FALSE, TRUE, PMU_STATS_LEVEL_HIGH}, //link_in_l23
|
||||
{ SRC_PM_ST_IN_D0, FALSE, TRUE, PMU_STATS_LEVEL_HIGH}, //pm_st_in_d0
|
||||
{ SRC_PM_ST_IN_D3, FALSE, TRUE, PMU_STATS_LEVEL_HIGH}, //pm_st_in_d3
|
||||
//deep-sleep duration : pmu_rsrc_state(XTAL_PU)
|
||||
{ SRC_XTAL_PU, FALSE, TRUE, PMU_STATS_LEVEL_LOW},
|
||||
//deep-sleep entry count : pmu_rsrc_state(XTAL_PU)
|
||||
{ SRC_XTAL_PU, FALSE, TRUE, PMU_STATS_EDGE_FALL},
|
||||
//core-n active duration : pmu_rsrc_state(CORE_RDY_MAIN)
|
||||
{ SRC_CORE_RDY_MAIN, FALSE, TRUE, PMU_STATS_LEVEL_HIGH},
|
||||
//core-n active duration : pmu_rsrc_state(CORE_RDY_MAIN)
|
||||
{ SRC_CORE_RDY_MAIN, FALSE, TRUE, PMU_STATS_EDGE_RISE}
|
||||
};
|
||||
|
||||
static void
|
||||
si_pmustatstimer_update(osl_t *osh, pmuregs_t *pmu, uint8 timerid)
|
||||
{
|
||||
uint32 stats_timer_ctrl;
|
||||
|
||||
W_REG(osh, &pmu->pmu_statstimer_addr, timerid);
|
||||
stats_timer_ctrl =
|
||||
((pmustatstimer[timerid].src_num << PMU_ST_SRC_SHIFT) &
|
||||
PMU_ST_SRC_MASK) |
|
||||
((pmustatstimer[timerid].cnt_mode << PMU_ST_CNT_MODE_SHIFT) &
|
||||
PMU_ST_CNT_MODE_MASK) |
|
||||
((pmustatstimer[timerid].enable << PMU_ST_EN_SHIFT) & PMU_ST_EN_MASK) |
|
||||
((pmustatstimer[timerid].int_enable << PMU_ST_INT_EN_SHIFT) & PMU_ST_INT_EN_MASK);
|
||||
W_REG(osh, &pmu->pmu_statstimer_ctrl, stats_timer_ctrl);
|
||||
W_REG(osh, &pmu->pmu_statstimer_N, 0);
|
||||
}
|
||||
|
||||
void
|
||||
si_pmustatstimer_int_enable(si_t *sih)
|
||||
{
|
||||
pmuregs_t *pmu;
|
||||
uint origidx;
|
||||
osl_t *osh = si_osh(sih);
|
||||
|
||||
/* Remember original core before switch to chipc/pmu */
|
||||
origidx = si_coreidx(sih);
|
||||
if (AOB_ENAB(sih)) {
|
||||
pmu = si_setcore(sih, PMU_CORE_ID, 0);
|
||||
} else {
|
||||
pmu = si_setcoreidx(sih, SI_CC_IDX);
|
||||
}
|
||||
ASSERT(pmu != NULL);
|
||||
|
||||
OR_REG(osh, &pmu->pmuintmask0, PMU_INT_STAT_TIMER_INT_MASK);
|
||||
|
||||
/* Return to original core */
|
||||
si_setcoreidx(sih, origidx);
|
||||
}
|
||||
|
||||
void
|
||||
si_pmustatstimer_int_disable(si_t *sih)
|
||||
{
|
||||
pmuregs_t *pmu;
|
||||
uint origidx;
|
||||
osl_t *osh = si_osh(sih);
|
||||
|
||||
/* Remember original core before switch to chipc/pmu */
|
||||
origidx = si_coreidx(sih);
|
||||
if (AOB_ENAB(sih)) {
|
||||
pmu = si_setcore(sih, PMU_CORE_ID, 0);
|
||||
} else {
|
||||
pmu = si_setcoreidx(sih, SI_CC_IDX);
|
||||
}
|
||||
ASSERT(pmu != NULL);
|
||||
|
||||
AND_REG(osh, &pmu->pmuintmask0, ~PMU_INT_STAT_TIMER_INT_MASK);
|
||||
|
||||
/* Return to original core */
|
||||
si_setcoreidx(sih, origidx);
|
||||
}
|
||||
|
||||
void
|
||||
si_pmustatstimer_init(si_t *sih)
|
||||
{
|
||||
pmuregs_t *pmu;
|
||||
uint origidx;
|
||||
osl_t *osh = si_osh(sih);
|
||||
uint32 core_cap_ext;
|
||||
uint8 max_stats_timer_num;
|
||||
int8 i;
|
||||
|
||||
/* Remember original core before switch to chipc/pmu */
|
||||
origidx = si_coreidx(sih);
|
||||
if (AOB_ENAB(sih)) {
|
||||
pmu = si_setcore(sih, PMU_CORE_ID, 0);
|
||||
} else {
|
||||
pmu = si_setcoreidx(sih, SI_CC_IDX);
|
||||
}
|
||||
ASSERT(pmu != NULL);
|
||||
|
||||
core_cap_ext = R_REG(osh, &pmu->core_cap_ext);
|
||||
|
||||
max_stats_timer_num = ((core_cap_ext & PCAP_EXT_ST_NUM_MASK) >> PCAP_EXT_ST_NUM_SHIFT) + 1;
|
||||
|
||||
for (i = 0; i < max_stats_timer_num; i++) {
|
||||
si_pmustatstimer_update(osh, pmu, i);
|
||||
}
|
||||
|
||||
OR_REG(osh, &pmu->pmuintmask0, PMU_INT_STAT_TIMER_INT_MASK);
|
||||
|
||||
/* Return to original core */
|
||||
si_setcoreidx(sih, origidx);
|
||||
}
|
||||
|
||||
void
|
||||
si_pmustatstimer_dump(si_t *sih)
|
||||
{
|
||||
pmuregs_t *pmu;
|
||||
uint origidx;
|
||||
osl_t *osh = si_osh(sih);
|
||||
uint32 core_cap_ext, pmucapabilities, AlpPeriod, ILPPeriod, pmuintmask0, pmuintstatus;
|
||||
uint8 max_stats_timer_num, max_stats_timer_src_num;
|
||||
uint32 stat_timer_ctrl, stat_timer_N;
|
||||
uint8 i;
|
||||
uint32 current_time_ms = OSL_SYSUPTIME();
|
||||
|
||||
/* Remember original core before switch to chipc/pmu */
|
||||
origidx = si_coreidx(sih);
|
||||
if (AOB_ENAB(sih)) {
|
||||
pmu = si_setcore(sih, PMU_CORE_ID, 0);
|
||||
} else {
|
||||
pmu = si_setcoreidx(sih, SI_CC_IDX);
|
||||
}
|
||||
ASSERT(pmu != NULL);
|
||||
|
||||
pmucapabilities = R_REG(osh, &pmu->pmucapabilities);
|
||||
core_cap_ext = R_REG(osh, &pmu->core_cap_ext);
|
||||
AlpPeriod = R_REG(osh, &pmu->slowclkperiod);
|
||||
ILPPeriod = R_REG(osh, &pmu->ILPPeriod);
|
||||
|
||||
max_stats_timer_num = ((core_cap_ext & PCAP_EXT_ST_NUM_MASK) >>
|
||||
PCAP_EXT_ST_NUM_SHIFT) + 1;
|
||||
max_stats_timer_src_num = ((core_cap_ext & PCAP_EXT_ST_SRC_NUM_MASK) >>
|
||||
PCAP_EXT_ST_SRC_NUM_SHIFT) + 1;
|
||||
|
||||
pmuintstatus = R_REG(osh, &pmu->pmuintstatus);
|
||||
pmuintmask0 = R_REG(osh, &pmu->pmuintmask0);
|
||||
|
||||
PMU_ERROR(("%s : TIME %d\n", __FUNCTION__, current_time_ms));
|
||||
|
||||
PMU_ERROR(("\tMAX Timer Num %d, MAX Source Num %d\n",
|
||||
max_stats_timer_num, max_stats_timer_src_num));
|
||||
PMU_ERROR(("\tpmucapabilities 0x%8x, core_cap_ext 0x%8x, AlpPeriod 0x%8x, ILPPeriod 0x%8x, "
|
||||
"pmuintmask0 0x%8x, pmuintstatus 0x%8x, pmurev %d\n",
|
||||
pmucapabilities, core_cap_ext, AlpPeriod, ILPPeriod,
|
||||
pmuintmask0, pmuintstatus, PMUREV(sih->pmurev)));
|
||||
|
||||
for (i = 0; i < max_stats_timer_num; i++) {
|
||||
W_REG(osh, &pmu->pmu_statstimer_addr, i);
|
||||
stat_timer_ctrl = R_REG(osh, &pmu->pmu_statstimer_ctrl);
|
||||
stat_timer_N = R_REG(osh, &pmu->pmu_statstimer_N);
|
||||
PMU_ERROR(("\t Timer %d : control 0x%8x, %d\n",
|
||||
i, stat_timer_ctrl, stat_timer_N));
|
||||
}
|
||||
|
||||
/* Return to original core */
|
||||
si_setcoreidx(sih, origidx);
|
||||
}
|
||||
|
||||
void
|
||||
si_pmustatstimer_start(si_t *sih, uint8 timerid)
|
||||
{
|
||||
pmuregs_t *pmu;
|
||||
uint origidx;
|
||||
osl_t *osh = si_osh(sih);
|
||||
|
||||
/* Remember original core before switch to chipc/pmu */
|
||||
origidx = si_coreidx(sih);
|
||||
if (AOB_ENAB(sih)) {
|
||||
pmu = si_setcore(sih, PMU_CORE_ID, 0);
|
||||
} else {
|
||||
pmu = si_setcoreidx(sih, SI_CC_IDX);
|
||||
}
|
||||
ASSERT(pmu != NULL);
|
||||
|
||||
pmustatstimer[timerid].enable = TRUE;
|
||||
|
||||
W_REG(osh, &pmu->pmu_statstimer_addr, timerid);
|
||||
OR_REG(osh, &pmu->pmu_statstimer_ctrl, PMU_ST_ENAB << PMU_ST_EN_SHIFT);
|
||||
|
||||
/* Return to original core */
|
||||
si_setcoreidx(sih, origidx);
|
||||
}
|
||||
|
||||
void
|
||||
si_pmustatstimer_stop(si_t *sih, uint8 timerid)
|
||||
{
|
||||
pmuregs_t *pmu;
|
||||
uint origidx;
|
||||
osl_t *osh = si_osh(sih);
|
||||
|
||||
/* Remember original core before switch to chipc/pmu */
|
||||
origidx = si_coreidx(sih);
|
||||
if (AOB_ENAB(sih)) {
|
||||
pmu = si_setcore(sih, PMU_CORE_ID, 0);
|
||||
} else {
|
||||
pmu = si_setcoreidx(sih, SI_CC_IDX);
|
||||
}
|
||||
ASSERT(pmu != NULL);
|
||||
|
||||
pmustatstimer[timerid].enable = FALSE;
|
||||
|
||||
W_REG(osh, &pmu->pmu_statstimer_addr, timerid);
|
||||
AND_REG(osh, &pmu->pmu_statstimer_ctrl, ~(PMU_ST_ENAB << PMU_ST_EN_SHIFT));
|
||||
|
||||
/* Return to original core */
|
||||
si_setcoreidx(sih, origidx);
|
||||
}
|
||||
|
||||
void
|
||||
si_pmustatstimer_clear(si_t *sih, uint8 timerid)
|
||||
{
|
||||
pmuregs_t *pmu;
|
||||
uint origidx;
|
||||
osl_t *osh = si_osh(sih);
|
||||
|
||||
/* Remember original core before switch to chipc/pmu */
|
||||
origidx = si_coreidx(sih);
|
||||
if (AOB_ENAB(sih)) {
|
||||
pmu = si_setcore(sih, PMU_CORE_ID, 0);
|
||||
} else {
|
||||
pmu = si_setcoreidx(sih, SI_CC_IDX);
|
||||
}
|
||||
ASSERT(pmu != NULL);
|
||||
|
||||
W_REG(osh, &pmu->pmu_statstimer_addr, timerid);
|
||||
W_REG(osh, &pmu->pmu_statstimer_N, 0);
|
||||
|
||||
/* Return to original core */
|
||||
si_setcoreidx(sih, origidx);
|
||||
}
|
||||
|
||||
void
|
||||
si_pmustatstimer_clear_overflow(si_t *sih)
|
||||
{
|
||||
uint8 i;
|
||||
uint32 core_cap_ext;
|
||||
uint8 max_stats_timer_num;
|
||||
uint32 timerN;
|
||||
pmuregs_t *pmu;
|
||||
uint origidx;
|
||||
osl_t *osh = si_osh(sih);
|
||||
|
||||
/* Remember original core before switch to chipc/pmu */
|
||||
origidx = si_coreidx(sih);
|
||||
if (AOB_ENAB(sih)) {
|
||||
pmu = si_setcore(sih, PMU_CORE_ID, 0);
|
||||
} else {
|
||||
pmu = si_setcoreidx(sih, SI_CC_IDX);
|
||||
}
|
||||
ASSERT(pmu != NULL);
|
||||
|
||||
core_cap_ext = R_REG(osh, &pmu->core_cap_ext);
|
||||
max_stats_timer_num = ((core_cap_ext & PCAP_EXT_ST_NUM_MASK) >> PCAP_EXT_ST_NUM_SHIFT) + 1;
|
||||
|
||||
for (i = 0; i < max_stats_timer_num; i++) {
|
||||
W_REG(osh, &pmu->pmu_statstimer_addr, i);
|
||||
timerN = R_REG(osh, &pmu->pmu_statstimer_N);
|
||||
if (timerN == 0xFFFFFFFF) {
|
||||
PMU_ERROR(("pmustatstimer overflow clear - timerid : %d\n", i));
|
||||
si_pmustatstimer_clear(sih, i);
|
||||
}
|
||||
}
|
||||
|
||||
/* Return to original core */
|
||||
si_setcoreidx(sih, origidx);
|
||||
}
|
||||
|
||||
uint32
|
||||
si_pmustatstimer_read(si_t *sih, uint8 timerid)
|
||||
{
|
||||
pmuregs_t *pmu;
|
||||
uint origidx;
|
||||
osl_t *osh = si_osh(sih);
|
||||
uint32 stats_timer_N;
|
||||
|
||||
/* Remember original core before switch to chipc/pmu */
|
||||
origidx = si_coreidx(sih);
|
||||
if (AOB_ENAB(sih)) {
|
||||
pmu = si_setcore(sih, PMU_CORE_ID, 0);
|
||||
} else {
|
||||
pmu = si_setcoreidx(sih, SI_CC_IDX);
|
||||
}
|
||||
ASSERT(pmu != NULL);
|
||||
|
||||
W_REG(osh, &pmu->pmu_statstimer_addr, timerid);
|
||||
stats_timer_N = R_REG(osh, &pmu->pmu_statstimer_N);
|
||||
|
||||
/* Return to original core */
|
||||
si_setcoreidx(sih, origidx);
|
||||
|
||||
return stats_timer_N;
|
||||
}
|
||||
|
||||
void
|
||||
si_pmustatstimer_cfg_src_num(si_t *sih, uint8 src_num, uint8 timerid)
|
||||
{
|
||||
pmuregs_t *pmu;
|
||||
uint origidx;
|
||||
osl_t *osh = si_osh(sih);
|
||||
|
||||
/* Remember original core before switch to chipc/pmu */
|
||||
origidx = si_coreidx(sih);
|
||||
if (AOB_ENAB(sih)) {
|
||||
pmu = si_setcore(sih, PMU_CORE_ID, 0);
|
||||
} else {
|
||||
pmu = si_setcoreidx(sih, SI_CC_IDX);
|
||||
}
|
||||
ASSERT(pmu != NULL);
|
||||
|
||||
pmustatstimer[timerid].src_num = src_num;
|
||||
si_pmustatstimer_update(osh, pmu, timerid);
|
||||
|
||||
/* Return to original core */
|
||||
si_setcoreidx(sih, origidx);
|
||||
}
|
||||
|
||||
void
|
||||
si_pmustatstimer_cfg_cnt_mode(si_t *sih, uint8 cnt_mode, uint8 timerid)
|
||||
{
|
||||
pmuregs_t *pmu;
|
||||
uint origidx;
|
||||
osl_t *osh = si_osh(sih);
|
||||
|
||||
/* Remember original core before switch to chipc/pmu */
|
||||
origidx = si_coreidx(sih);
|
||||
if (AOB_ENAB(sih)) {
|
||||
pmu = si_setcore(sih, PMU_CORE_ID, 0);
|
||||
} else {
|
||||
pmu = si_setcoreidx(sih, SI_CC_IDX);
|
||||
}
|
||||
ASSERT(pmu != NULL);
|
||||
|
||||
pmustatstimer[timerid].cnt_mode = cnt_mode;
|
||||
si_pmustatstimer_update(osh, pmu, timerid);
|
||||
|
||||
/* Return to original core */
|
||||
si_setcoreidx(sih, origidx);
|
||||
}
|
||||
#endif /* BCMPMU_STATS */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,140 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* 802.11e protocol header file
|
||||
*
|
||||
* Copyright (C) 1999-2019, 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.
|
||||
*
|
||||
* 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: 802.11e.h 785355 2018-10-18 05:32:56Z $
|
||||
*/
|
||||
|
||||
#ifndef _802_11e_H_
|
||||
#define _802_11e_H_
|
||||
|
||||
#ifndef _TYPEDEFS_H_
|
||||
#include <typedefs.h>
|
||||
#endif // endif
|
||||
|
||||
/* This marks the start of a packed structure section. */
|
||||
#include <packed_section_start.h>
|
||||
|
||||
/* WME Traffic Specification (TSPEC) element */
|
||||
#define WME_TSPEC_HDR_LEN 2 /* WME TSPEC header length */
|
||||
#define WME_TSPEC_BODY_OFF 2 /* WME TSPEC body offset */
|
||||
|
||||
#define WME_CATEGORY_CODE_OFFSET 0 /* WME Category code offset */
|
||||
#define WME_ACTION_CODE_OFFSET 1 /* WME Action code offset */
|
||||
#define WME_TOKEN_CODE_OFFSET 2 /* WME Token code offset */
|
||||
#define WME_STATUS_CODE_OFFSET 3 /* WME Status code offset */
|
||||
|
||||
BWL_PRE_PACKED_STRUCT struct tsinfo {
|
||||
uint8 octets[3];
|
||||
} BWL_POST_PACKED_STRUCT;
|
||||
|
||||
typedef struct tsinfo tsinfo_t;
|
||||
|
||||
/* 802.11e TSPEC IE */
|
||||
typedef BWL_PRE_PACKED_STRUCT struct tspec {
|
||||
uint8 oui[DOT11_OUI_LEN]; /* WME_OUI */
|
||||
uint8 type; /* WME_TYPE */
|
||||
uint8 subtype; /* WME_SUBTYPE_TSPEC */
|
||||
uint8 version; /* WME_VERSION */
|
||||
tsinfo_t tsinfo; /* TS Info bit field */
|
||||
uint16 nom_msdu_size; /* (Nominal or fixed) MSDU Size (bytes) */
|
||||
uint16 max_msdu_size; /* Maximum MSDU Size (bytes) */
|
||||
uint32 min_srv_interval; /* Minimum Service Interval (us) */
|
||||
uint32 max_srv_interval; /* Maximum Service Interval (us) */
|
||||
uint32 inactivity_interval; /* Inactivity Interval (us) */
|
||||
uint32 suspension_interval; /* Suspension Interval (us) */
|
||||
uint32 srv_start_time; /* Service Start Time (us) */
|
||||
uint32 min_data_rate; /* Minimum Data Rate (bps) */
|
||||
uint32 mean_data_rate; /* Mean Data Rate (bps) */
|
||||
uint32 peak_data_rate; /* Peak Data Rate (bps) */
|
||||
uint32 max_burst_size; /* Maximum Burst Size (bytes) */
|
||||
uint32 delay_bound; /* Delay Bound (us) */
|
||||
uint32 min_phy_rate; /* Minimum PHY Rate (bps) */
|
||||
uint16 surplus_bw; /* Surplus Bandwidth Allowance (range 1.0-8.0) */
|
||||
uint16 medium_time; /* Medium Time (32 us/s periods) */
|
||||
} BWL_POST_PACKED_STRUCT tspec_t;
|
||||
|
||||
#define WME_TSPEC_LEN (sizeof(tspec_t)) /* not including 2-bytes of header */
|
||||
|
||||
/* ts_info */
|
||||
/* 802.1D priority is duplicated - bits 13-11 AND bits 3-1 */
|
||||
#define TS_INFO_TID_SHIFT 1 /* TS info. TID shift */
|
||||
#define TS_INFO_TID_MASK (0xf << TS_INFO_TID_SHIFT) /* TS info. TID mask */
|
||||
#define TS_INFO_CONTENTION_SHIFT 7 /* TS info. contention shift */
|
||||
#define TS_INFO_CONTENTION_MASK (0x1 << TS_INFO_CONTENTION_SHIFT) /* TS info. contention mask */
|
||||
#define TS_INFO_DIRECTION_SHIFT 5 /* TS info. direction shift */
|
||||
#define TS_INFO_DIRECTION_MASK (0x3 << TS_INFO_DIRECTION_SHIFT) /* TS info. direction mask */
|
||||
#define TS_INFO_PSB_SHIFT 2 /* TS info. PSB bit Shift */
|
||||
#define TS_INFO_PSB_MASK (1 << TS_INFO_PSB_SHIFT) /* TS info. PSB mask */
|
||||
#define TS_INFO_UPLINK (0 << TS_INFO_DIRECTION_SHIFT) /* TS info. uplink */
|
||||
#define TS_INFO_DOWNLINK (1 << TS_INFO_DIRECTION_SHIFT) /* TS info. downlink */
|
||||
#define TS_INFO_BIDIRECTIONAL (3 << TS_INFO_DIRECTION_SHIFT) /* TS info. bidirectional */
|
||||
#define TS_INFO_USER_PRIO_SHIFT 3 /* TS info. user priority shift */
|
||||
/* TS info. user priority mask */
|
||||
#define TS_INFO_USER_PRIO_MASK (0x7 << TS_INFO_USER_PRIO_SHIFT)
|
||||
|
||||
/* Macro to get/set bit(s) field in TSINFO */
|
||||
#define WLC_CAC_GET_TID(pt) ((((pt).octets[0]) & TS_INFO_TID_MASK) >> TS_INFO_TID_SHIFT)
|
||||
#define WLC_CAC_GET_DIR(pt) ((((pt).octets[0]) & \
|
||||
TS_INFO_DIRECTION_MASK) >> TS_INFO_DIRECTION_SHIFT)
|
||||
#define WLC_CAC_GET_PSB(pt) ((((pt).octets[1]) & TS_INFO_PSB_MASK) >> TS_INFO_PSB_SHIFT)
|
||||
#define WLC_CAC_GET_USER_PRIO(pt) ((((pt).octets[1]) & \
|
||||
TS_INFO_USER_PRIO_MASK) >> TS_INFO_USER_PRIO_SHIFT)
|
||||
|
||||
#define WLC_CAC_SET_TID(pt, id) ((((pt).octets[0]) & (~TS_INFO_TID_MASK)) | \
|
||||
((id) << TS_INFO_TID_SHIFT))
|
||||
#define WLC_CAC_SET_USER_PRIO(pt, prio) ((((pt).octets[0]) & (~TS_INFO_USER_PRIO_MASK)) | \
|
||||
((prio) << TS_INFO_USER_PRIO_SHIFT))
|
||||
|
||||
/* 802.11e QBSS Load IE */
|
||||
#define QBSS_LOAD_IE_LEN 5 /* QBSS Load IE length */
|
||||
#define QBSS_LOAD_AAC_OFF 3 /* AAC offset in IE */
|
||||
|
||||
#define CAC_ADDTS_RESP_TIMEOUT 1000 /* default ADDTS response timeout in ms */
|
||||
/* DEFVAL dot11ADDTSResponseTimeout = 1s */
|
||||
|
||||
/* 802.11e ADDTS status code */
|
||||
#define DOT11E_STATUS_ADMISSION_ACCEPTED 0 /* TSPEC Admission accepted status */
|
||||
#define DOT11E_STATUS_ADDTS_INVALID_PARAM 1 /* TSPEC invalid parameter status */
|
||||
#define DOT11E_STATUS_ADDTS_REFUSED_NSBW 3 /* ADDTS refused (non-sufficient BW) */
|
||||
#define DOT11E_STATUS_ADDTS_REFUSED_AWHILE 47 /* ADDTS refused but could retry later */
|
||||
#ifdef BCMCCX
|
||||
#define CCX_STATUS_ASSOC_DENIED_UNKNOWN 0xc8 /* unspecified QoS related failure */
|
||||
#define CCX_STATUS_ASSOC_DENIED_AP_POLICY 0xc9 /* TSPEC refused due to AP policy */
|
||||
#define CCX_STATUS_ASSOC_DENIED_NO_BW 0xca /* Assoc denied due to AP insufficient BW */
|
||||
#define CCX_STATUS_ASSOC_DENIED_BAD_PARAM 0xcb /* one or more TSPEC with invalid parameter */
|
||||
#endif /* BCMCCX */
|
||||
|
||||
/* 802.11e DELTS status code */
|
||||
#define DOT11E_STATUS_QSTA_LEAVE_QBSS 36 /* STA leave QBSS */
|
||||
#define DOT11E_STATUS_END_TS 37 /* END TS */
|
||||
#define DOT11E_STATUS_UNKNOWN_TS 38 /* UNKNOWN TS */
|
||||
#define DOT11E_STATUS_QSTA_REQ_TIMEOUT 39 /* STA ADDTS request timeout */
|
||||
|
||||
/* This marks the end of a packed structure section. */
|
||||
#include <packed_section_end.h>
|
||||
|
||||
#endif /* _802_11e_CAC_H_ */
|
||||
@@ -0,0 +1,335 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Fundamental types and constants relating to 802.11s Mesh
|
||||
*
|
||||
* Copyright (C) 1999-2019, 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.
|
||||
*
|
||||
* 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: 802.11s.h 700076 2017-05-17 14:42:22Z $
|
||||
*/
|
||||
|
||||
#ifndef _802_11s_h_
|
||||
#define _802_11s_h_
|
||||
|
||||
/* This marks the start of a packed structure section. */
|
||||
#include <packed_section_start.h>
|
||||
|
||||
#define DOT11_MESH_FLAGS_AE_MASK 0x3
|
||||
#define DOT11_MESH_FLAGS_AE_SHIFT 0
|
||||
|
||||
#define DOT11_MESH_CONNECTED_AS_SET 7
|
||||
#define DOT11_MESH_NUMBER_PEERING_SET 1
|
||||
#define DOT11_MESH_MESH_GWSET 0
|
||||
|
||||
#define DOT11_MESH_ACTION_LINK_MET_REP 0
|
||||
#define DOT11_MESH_ACTION_PATH_SEL 1
|
||||
#define DOT11_MESH_ACTION_GATE_ANN 2
|
||||
#define DOT11_MESH_ACTION_CONG_CONT_NOTIF 3
|
||||
#define DOT11_MESH_ACTION_MCCA_SETUP_REQ 4
|
||||
#define DOT11_MESH_ACTION_MCCA_SETUP_REP 5
|
||||
#define DOT11_MESH_ACTION_MCCA_ADVT_REQ 6
|
||||
#define DOT11_MESH_ACTION_MCCA_ADVT 7
|
||||
#define DOT11_MESH_ACTION_MCCA_TEARDOWN 8
|
||||
#define DOT11_MESH_ACTION_TBTT_ADJ_REQ 9
|
||||
#define DOT11_MESH_ACTION_TBTT_ADJ_RESP 10
|
||||
|
||||
/* self-protected action field values: 7-57v24 */
|
||||
#define DOT11_SELFPROT_ACTION_MESH_PEER_OPEN 1
|
||||
#define DOT11_SELFPROT_ACTION_MESH_PEER_CONFM 2
|
||||
#define DOT11_SELFPROT_ACTION_MESH_PEER_CLOSE 3
|
||||
#define DOT11_SELFPROT_ACTION_MESH_PEER_GK_INF 4
|
||||
#define DOT11_SELFPROT_ACTION_MESH_PEER_GK_ACK 5
|
||||
|
||||
#define DOT11_MESH_AUTH_PROTO_NONE 0
|
||||
#define DOT11_MESH_AUTH_PROTO_SAE 1
|
||||
#define DOT11_MESH_AUTH_PROTO_8021X 2
|
||||
#define DOT11_MESH_AUTH_PROTO_VS 255
|
||||
|
||||
#define DOT11_MESH_PATHSEL_LEN 2
|
||||
#define DOT11_MESH_PERR_LEN1 2 /* Least PERR length fixed */
|
||||
#define DOT11_MESH_PERR_LEN2 13 /* Least PERR length variable */
|
||||
#define DOT11_MESH_PREP_LEN 31 /* Least PREP length */
|
||||
#define DOT11_MESH_PREQ_LEN 37 /* Least PREQ length */
|
||||
|
||||
#define DOT11_MESH_PATHSEL_PROTID_HWMP 1
|
||||
#define DOT11_MESH_PATHSEL_METRICID_ALM 1 /* Air link metric */
|
||||
#define DOT11_MESH_CONGESTCTRL_NONE 0
|
||||
#define DOT11_MESH_CONGESTCTRL_SP 1
|
||||
#define DOT11_MESH_SYNCMETHOD_NOFFSET 1
|
||||
|
||||
BWL_PRE_PACKED_STRUCT struct dot11_meshctrl_hdr {
|
||||
uint8 flags; /* flag bits such as ae etc */
|
||||
uint8 ttl; /* time to live */
|
||||
uint32 seq; /* sequence control */
|
||||
struct ether_addr a5; /* optional address 5 */
|
||||
struct ether_addr a6; /* optional address 6 */
|
||||
} BWL_POST_PACKED_STRUCT;
|
||||
|
||||
/* Mesh Path Selection Action Frame */
|
||||
BWL_PRE_PACKED_STRUCT struct dot11_mesh_pathsel {
|
||||
uint8 category;
|
||||
uint8 meshaction;
|
||||
uint8 data[];
|
||||
} BWL_POST_PACKED_STRUCT;
|
||||
typedef struct dot11_mesh_pathsel dot11_mesh_pathsel_t;
|
||||
|
||||
/* Mesh PREQ IE */
|
||||
BWL_PRE_PACKED_STRUCT struct mesh_preq_ie {
|
||||
uint8 id;
|
||||
uint8 len;
|
||||
uint8 flags;
|
||||
uint8 hop_count;
|
||||
uint8 ttl;
|
||||
uint32 pathdis_id;
|
||||
struct ether_addr originator_addr;
|
||||
uint32 originator_seq;
|
||||
union {
|
||||
BWL_PRE_PACKED_STRUCT struct {
|
||||
struct ether_addr target_ext_add;
|
||||
uint32 lifetime;
|
||||
uint32 metric;
|
||||
uint8 target_count;
|
||||
uint8 data[];
|
||||
} BWL_POST_PACKED_STRUCT oea;
|
||||
|
||||
BWL_PRE_PACKED_STRUCT struct {
|
||||
uint32 lifetime;
|
||||
uint32 metric;
|
||||
uint8 target_count;
|
||||
uint8 data[];
|
||||
} BWL_POST_PACKED_STRUCT noea;
|
||||
} u;
|
||||
} BWL_POST_PACKED_STRUCT;
|
||||
typedef struct mesh_preq_ie mesh_preq_ie_t;
|
||||
|
||||
/* Target info (part of Mesh PREQ IE) */
|
||||
BWL_PRE_PACKED_STRUCT struct mesh_targetinfo {
|
||||
uint8 target_flag;
|
||||
struct ether_addr target_addr;
|
||||
uint32 target_seq;
|
||||
} BWL_POST_PACKED_STRUCT;
|
||||
typedef struct mesh_targetinfo mesh_targetinfo_t;
|
||||
|
||||
/* Mesh PREP IE */
|
||||
BWL_PRE_PACKED_STRUCT struct mesh_prep_ie {
|
||||
uint8 id;
|
||||
uint8 len;
|
||||
uint8 flags;
|
||||
uint8 hop_count;
|
||||
uint8 ttl;
|
||||
struct ether_addr target_addr;
|
||||
uint32 target_seq;
|
||||
union {
|
||||
BWL_PRE_PACKED_STRUCT struct {
|
||||
struct ether_addr target_ext_add;
|
||||
uint32 lifetime;
|
||||
uint32 metric;
|
||||
uint8 target_count;
|
||||
struct ether_addr originator_addr;
|
||||
uint32 originator_seq;
|
||||
} BWL_POST_PACKED_STRUCT oea;
|
||||
|
||||
BWL_PRE_PACKED_STRUCT struct {
|
||||
uint32 lifetime;
|
||||
uint32 metric;
|
||||
uint8 target_count;
|
||||
struct ether_addr originator_addr;
|
||||
uint32 originator_seq;
|
||||
} BWL_POST_PACKED_STRUCT noea;
|
||||
} u;
|
||||
} BWL_POST_PACKED_STRUCT;
|
||||
typedef struct mesh_prep_ie mesh_prep_ie_t;
|
||||
|
||||
/* Mesh PERR IE */
|
||||
struct mesh_perr_ie {
|
||||
uint8 id;
|
||||
uint8 len;
|
||||
uint8 ttl;
|
||||
uint8 num_dest;
|
||||
uint8 data[];
|
||||
};
|
||||
typedef struct mesh_perr_ie mesh_perr_ie_t;
|
||||
|
||||
/* Destination info is part of PERR IE */
|
||||
BWL_PRE_PACKED_STRUCT struct mesh_perr_destinfo {
|
||||
uint8 flags;
|
||||
struct ether_addr destination_addr;
|
||||
uint32 dest_seq;
|
||||
union {
|
||||
BWL_PRE_PACKED_STRUCT struct {
|
||||
struct ether_addr dest_ext_addr;
|
||||
} BWL_POST_PACKED_STRUCT dea;
|
||||
|
||||
BWL_PRE_PACKED_STRUCT struct {
|
||||
/* 1 byte reason code to be populated manually in software */
|
||||
uint16 reason_code;
|
||||
} BWL_POST_PACKED_STRUCT nodea;
|
||||
} u;
|
||||
} BWL_POST_PACKED_STRUCT;
|
||||
typedef struct mesh_perr_destinfo mesh_perr_destinfo_t;
|
||||
|
||||
/* Mesh peering action frame hdr */
|
||||
BWL_PRE_PACKED_STRUCT struct mesh_peering_frmhdr {
|
||||
uint8 category;
|
||||
uint8 action;
|
||||
union {
|
||||
struct {
|
||||
uint16 capability;
|
||||
} open;
|
||||
struct {
|
||||
uint16 capability;
|
||||
uint16 AID;
|
||||
} confirm;
|
||||
uint8 data[1];
|
||||
} u;
|
||||
} BWL_POST_PACKED_STRUCT;
|
||||
typedef struct mesh_peering_frmhdr mesh_peering_frmhdr_t;
|
||||
|
||||
/* Mesh peering mgmt IE */
|
||||
BWL_PRE_PACKED_STRUCT struct mesh_peer_mgmt_ie_common {
|
||||
uint16 mesh_peer_prot_id;
|
||||
uint16 local_link_id;
|
||||
} BWL_POST_PACKED_STRUCT;
|
||||
typedef struct mesh_peer_mgmt_ie_common mesh_peer_mgmt_ie_common_t;
|
||||
#define MESH_PEER_MGMT_IE_OPEN_LEN (4)
|
||||
|
||||
BWL_PRE_PACKED_STRUCT struct mesh_peer_mgmt_ie_cfm {
|
||||
mesh_peer_mgmt_ie_common_t common;
|
||||
uint16 peer_link_id;
|
||||
} BWL_POST_PACKED_STRUCT;
|
||||
typedef struct mesh_peer_mgmt_ie_cfm mesh_peer_mgmt_ie_cfm_t;
|
||||
#define MESH_PEER_MGMT_IE_CONF_LEN (6)
|
||||
|
||||
BWL_PRE_PACKED_STRUCT struct mesh_peer_mgmt_ie_close {
|
||||
mesh_peer_mgmt_ie_common_t common;
|
||||
/* uint16 peer_link_id;
|
||||
* simplicity: not supported, TODO for future
|
||||
*/
|
||||
uint16 reason_code;
|
||||
} BWL_POST_PACKED_STRUCT;
|
||||
typedef struct mesh_peer_mgmt_ie_close mesh_peer_mgmt_ie_close_t;
|
||||
#define MESH_PEER_MGMT_IE_CLOSE_LEN (6)
|
||||
|
||||
struct mesh_config_ie {
|
||||
uint8 activ_path_sel_prot_id;
|
||||
uint8 activ_path_sel_metric_id;
|
||||
uint8 cong_ctl_mode_id;
|
||||
uint8 sync_method_id;
|
||||
uint8 auth_prot_id;
|
||||
uint8 mesh_formation_info;
|
||||
uint8 mesh_cap;
|
||||
};
|
||||
typedef struct mesh_config_ie mesh_config_ie_t;
|
||||
#define MESH_CONFIG_IE_LEN (7)
|
||||
|
||||
/* Mesh peering states */
|
||||
#define MESH_PEERING_IDLE 0
|
||||
#define MESH_PEERING_OPEN_SNT 1
|
||||
#define MESH_PEERING_CNF_RCVD 2
|
||||
#define MESH_PEERING_OPEN_RCVD 3
|
||||
#define MESH_PEERING_ESTAB 4
|
||||
#define MESH_PEERING_HOLDING 5
|
||||
#define MESH_PEERING_LAST_STATE 6
|
||||
/* for debugging: mapping strings */
|
||||
#define MESH_PEERING_STATE_STRINGS \
|
||||
{"IDLE ", "OPNSNT", "CNFRCV", "OPNRCV", "ESTAB ", "HOLDNG"}
|
||||
|
||||
#ifdef WLMESH
|
||||
typedef BWL_PRE_PACKED_STRUCT struct mesh_peer_info {
|
||||
/* mesh_peer_instance as given in the spec. Note that, peer address
|
||||
* is stored in scb
|
||||
*/
|
||||
uint16 mesh_peer_prot_id;
|
||||
uint16 local_link_id;
|
||||
uint16 peer_link_id;
|
||||
/* AID generated by *peer* to self & received in peer_confirm */
|
||||
uint16 peer_aid;
|
||||
|
||||
/* TODO: no mention in spec? possibly used in PS case. Note that aid generated
|
||||
* from self to peer is stored in scb.
|
||||
*/
|
||||
uint8 state;
|
||||
/* TODO: struct mesh_peer_info *next; this field is required
|
||||
* if multiple peerings per same src is allowed, which is
|
||||
* true as per spec.
|
||||
*/
|
||||
} BWL_POST_PACKED_STRUCT mesh_peer_info_t;
|
||||
|
||||
typedef BWL_PRE_PACKED_STRUCT struct mesh_peer_info_ext {
|
||||
mesh_peer_info_t peer_info;
|
||||
uint16 local_aid; /* AID generated by *local* to peer */
|
||||
struct ether_addr ea; /* peer ea */
|
||||
uint32 entry_state; /* see MESH_PEER_ENTRY_STATE_ACTIVE etc; valid
|
||||
* ONLY for internal peering requests
|
||||
*/
|
||||
int rssi;
|
||||
} BWL_POST_PACKED_STRUCT mesh_peer_info_ext_t;
|
||||
|
||||
/* #ifdef WLMESH */
|
||||
typedef BWL_PRE_PACKED_STRUCT struct mesh_peer_info_dump {
|
||||
uint32 buflen;
|
||||
uint32 version;
|
||||
uint32 count; /* number of results */
|
||||
mesh_peer_info_ext_t mpi_ext[1];
|
||||
} BWL_POST_PACKED_STRUCT mesh_peer_info_dump_t;
|
||||
#define WL_MESH_PEER_RES_FIXED_SIZE (sizeof(mesh_peer_info_dump_t) - sizeof(mesh_peer_info_ext_t))
|
||||
|
||||
#endif /* WLMESH */
|
||||
|
||||
/* once an entry is added into mesh_peer_list, if peering is lost, it will
|
||||
* get retried for peering, MAX_MESH_PEER_ENTRY_RETRIES times. after wards, it
|
||||
* wont get retried and will be moved to MESH_PEER_ENTRY_STATE_TIMEDOUT state,
|
||||
* until user adds it again explicitely, when its entry_state is changed
|
||||
* to MESH_PEER_ENTRY_STATE_ACTIVE and tried again.
|
||||
*/
|
||||
#define MAX_MESH_SELF_PEER_ENTRY_RETRIES 3
|
||||
#define MESH_SELF_PEER_ENTRY_STATE_ACTIVE 1
|
||||
#define MESH_SELF_PEER_ENTRY_STATE_TIMEDOUT 2
|
||||
|
||||
/** Mesh Channel Switch Parameter IE data structure */
|
||||
BWL_PRE_PACKED_STRUCT struct dot11_mcsp_body {
|
||||
uint8 ttl; /* remaining number of hops allowed for this element. */
|
||||
uint8 flags; /* attributes of this channel switch attempt */
|
||||
uint8 reason; /* reason for the mesh channel switch */
|
||||
uint16 precedence; /* random value in the range 0 to 65535 */
|
||||
} BWL_POST_PACKED_STRUCT;
|
||||
|
||||
#define DOT11_MCSP_TTL_DEFAULT 1
|
||||
#define DOT11_MCSP_FLAG_TRANS_RESTRICT 0x1 /* no transmit except frames with mcsp */
|
||||
#define DOT11_MCSP_FLAG_INIT 0x2 /* initiates the channel switch attempt */
|
||||
#define DOT11_MCSP_FLAG_REASON 0x4 /* validity of reason code field */
|
||||
#define DOT11_MCSP_REASON_REGULATORY 0 /* meet regulatory requirements */
|
||||
#define DOT11_MCSP_REASON_UNSPECIFIED 1 /* unspecified reason */
|
||||
|
||||
BWL_PRE_PACKED_STRUCT struct dot11_mesh_csp {
|
||||
uint8 id; /* id DOT11_MNG_MESH_CSP_ID */
|
||||
uint8 len; /* length of IE */
|
||||
struct dot11_mcsp_body body; /* body of the ie */
|
||||
} BWL_POST_PACKED_STRUCT;
|
||||
typedef struct dot11_mesh_csp dot11_mesh_csp_ie_t;
|
||||
#define DOT11_MESH_CSP_IE_LEN 5 /* length of mesh channel switch parameter IE body */
|
||||
|
||||
/* This marks the end of a packed structure section. */
|
||||
#include <packed_section_end.h>
|
||||
|
||||
#endif /* #ifndef _802_11s_H_ */
|
||||
@@ -0,0 +1,54 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Fundamental types and constants relating to 802.1D
|
||||
*
|
||||
* Copyright (C) 1999-2019, 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.
|
||||
*
|
||||
* 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: 802.1d.h 700076 2017-05-17 14:42:22Z $
|
||||
*/
|
||||
|
||||
#ifndef _802_1_D_
|
||||
#define _802_1_D_
|
||||
|
||||
/* 802.1D priority defines */
|
||||
#define PRIO_8021D_NONE 2 /* None = - */
|
||||
#define PRIO_8021D_BK 1 /* BK - Background */
|
||||
#define PRIO_8021D_BE 0 /* BE - Best-effort */
|
||||
#define PRIO_8021D_EE 3 /* EE - Excellent-effort */
|
||||
#define PRIO_8021D_CL 4 /* CL - Controlled Load */
|
||||
#define PRIO_8021D_VI 5 /* Vi - Video */
|
||||
#define PRIO_8021D_VO 6 /* Vo - Voice */
|
||||
#define PRIO_8021D_NC 7 /* NC - Network Control */
|
||||
#define MAXPRIO 7 /* 0-7 */
|
||||
#define NUMPRIO (MAXPRIO + 1)
|
||||
|
||||
#define ALLPRIO -1 /* All prioirty */
|
||||
|
||||
/* Converts prio to precedence since the numerical value of
|
||||
* PRIO_8021D_BE and PRIO_8021D_NONE are swapped.
|
||||
*/
|
||||
#define PRIO2PREC(prio) \
|
||||
(((prio) == PRIO_8021D_NONE || (prio) == PRIO_8021D_BE) ? ((prio^2)) : (prio))
|
||||
|
||||
#endif /* _802_1_D__ */
|
||||
@@ -0,0 +1,56 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Fundamental constants relating to 802.3
|
||||
*
|
||||
* Copyright (C) 1999-2019, 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.
|
||||
*
|
||||
* 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: 802.3.h 700076 2017-05-17 14:42:22Z $
|
||||
*/
|
||||
|
||||
#ifndef _802_3_h_
|
||||
#define _802_3_h_
|
||||
|
||||
/* This marks the start of a packed structure section. */
|
||||
#include <packed_section_start.h>
|
||||
|
||||
#define SNAP_HDR_LEN 6 /* 802.3 SNAP header length */
|
||||
#define DOT3_OUI_LEN 3 /* 802.3 oui length */
|
||||
|
||||
BWL_PRE_PACKED_STRUCT struct dot3_mac_llc_snap_header {
|
||||
uint8 ether_dhost[ETHER_ADDR_LEN]; /* dest mac */
|
||||
uint8 ether_shost[ETHER_ADDR_LEN]; /* src mac */
|
||||
uint16 length; /* frame length incl header */
|
||||
uint8 dsap; /* always 0xAA */
|
||||
uint8 ssap; /* always 0xAA */
|
||||
uint8 ctl; /* always 0x03 */
|
||||
uint8 oui[DOT3_OUI_LEN]; /* RFC1042: 0x00 0x00 0x00
|
||||
* Bridge-Tunnel: 0x00 0x00 0xF8
|
||||
*/
|
||||
uint16 type; /* ethertype */
|
||||
} BWL_POST_PACKED_STRUCT;
|
||||
|
||||
/* This marks the end of a packed structure section. */
|
||||
#include <packed_section_end.h>
|
||||
|
||||
#endif /* #ifndef _802_3_h_ */
|
||||
@@ -0,0 +1,430 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Broadcom AMBA Interconnect definitions.
|
||||
*
|
||||
* Copyright (C) 1999-2019, 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.
|
||||
*
|
||||
* 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: aidmp.h 617751 2016-02-08 09:04:22Z $
|
||||
*/
|
||||
|
||||
#ifndef _AIDMP_H
|
||||
#define _AIDMP_H
|
||||
|
||||
/* Manufacturer Ids */
|
||||
#define MFGID_ARM 0x43b
|
||||
#define MFGID_BRCM 0x4bf
|
||||
#define MFGID_MIPS 0x4a7
|
||||
|
||||
/* Component Classes */
|
||||
#define CC_SIM 0
|
||||
#define CC_EROM 1
|
||||
#define CC_CORESIGHT 9
|
||||
#define CC_VERIF 0xb
|
||||
#define CC_OPTIMO 0xd
|
||||
#define CC_GEN 0xe
|
||||
#define CC_PRIMECELL 0xf
|
||||
|
||||
/* Enumeration ROM registers */
|
||||
#define ER_EROMENTRY 0x000
|
||||
#define ER_REMAPCONTROL 0xe00
|
||||
#define ER_REMAPSELECT 0xe04
|
||||
#define ER_MASTERSELECT 0xe10
|
||||
#define ER_ITCR 0xf00
|
||||
#define ER_ITIP 0xf04
|
||||
|
||||
/* Erom entries */
|
||||
#define ER_TAG 0xe
|
||||
#define ER_TAG1 0x6
|
||||
#define ER_VALID 1
|
||||
#define ER_CI 0
|
||||
#define ER_MP 2
|
||||
#define ER_ADD 4
|
||||
#define ER_END 0xe
|
||||
#define ER_BAD 0xffffffff
|
||||
#define ER_SZ_MAX 4096 /* 4KB */
|
||||
|
||||
/* EROM CompIdentA */
|
||||
#define CIA_MFG_MASK 0xfff00000
|
||||
#define CIA_MFG_SHIFT 20
|
||||
#define CIA_CID_MASK 0x000fff00
|
||||
#define CIA_CID_SHIFT 8
|
||||
#define CIA_CCL_MASK 0x000000f0
|
||||
#define CIA_CCL_SHIFT 4
|
||||
|
||||
/* EROM CompIdentB */
|
||||
#define CIB_REV_MASK 0xff000000
|
||||
#define CIB_REV_SHIFT 24
|
||||
#define CIB_NSW_MASK 0x00f80000
|
||||
#define CIB_NSW_SHIFT 19
|
||||
#define CIB_NMW_MASK 0x0007c000
|
||||
#define CIB_NMW_SHIFT 14
|
||||
#define CIB_NSP_MASK 0x00003e00
|
||||
#define CIB_NSP_SHIFT 9
|
||||
#define CIB_NMP_MASK 0x000001f0
|
||||
#define CIB_NMP_SHIFT 4
|
||||
|
||||
/* EROM MasterPortDesc */
|
||||
#define MPD_MUI_MASK 0x0000ff00
|
||||
#define MPD_MUI_SHIFT 8
|
||||
#define MPD_MP_MASK 0x000000f0
|
||||
#define MPD_MP_SHIFT 4
|
||||
|
||||
/* EROM AddrDesc */
|
||||
#define AD_ADDR_MASK 0xfffff000
|
||||
#define AD_SP_MASK 0x00000f00
|
||||
#define AD_SP_SHIFT 8
|
||||
#define AD_ST_MASK 0x000000c0
|
||||
#define AD_ST_SHIFT 6
|
||||
#define AD_ST_SLAVE 0x00000000
|
||||
#define AD_ST_BRIDGE 0x00000040
|
||||
#define AD_ST_SWRAP 0x00000080
|
||||
#define AD_ST_MWRAP 0x000000c0
|
||||
#define AD_SZ_MASK 0x00000030
|
||||
#define AD_SZ_SHIFT 4
|
||||
#define AD_SZ_4K 0x00000000
|
||||
#define AD_SZ_8K 0x00000010
|
||||
#define AD_SZ_16K 0x00000020
|
||||
#define AD_SZ_SZD 0x00000030
|
||||
#define AD_AG32 0x00000008
|
||||
#define AD_ADDR_ALIGN 0x00000fff
|
||||
#define AD_SZ_BASE 0x00001000 /* 4KB */
|
||||
|
||||
/* EROM SizeDesc */
|
||||
#define SD_SZ_MASK 0xfffff000
|
||||
#define SD_SG32 0x00000008
|
||||
#define SD_SZ_ALIGN 0x00000fff
|
||||
|
||||
#if !defined(_LANGUAGE_ASSEMBLY) && !defined(__ASSEMBLY__)
|
||||
|
||||
typedef volatile struct _aidmp {
|
||||
uint32 oobselina30; /* 0x000 */
|
||||
uint32 oobselina74; /* 0x004 */
|
||||
uint32 PAD[6];
|
||||
uint32 oobselinb30; /* 0x020 */
|
||||
uint32 oobselinb74; /* 0x024 */
|
||||
uint32 PAD[6];
|
||||
uint32 oobselinc30; /* 0x040 */
|
||||
uint32 oobselinc74; /* 0x044 */
|
||||
uint32 PAD[6];
|
||||
uint32 oobselind30; /* 0x060 */
|
||||
uint32 oobselind74; /* 0x064 */
|
||||
uint32 PAD[38];
|
||||
uint32 oobselouta30; /* 0x100 */
|
||||
uint32 oobselouta74; /* 0x104 */
|
||||
uint32 PAD[6];
|
||||
uint32 oobseloutb30; /* 0x120 */
|
||||
uint32 oobseloutb74; /* 0x124 */
|
||||
uint32 PAD[6];
|
||||
uint32 oobseloutc30; /* 0x140 */
|
||||
uint32 oobseloutc74; /* 0x144 */
|
||||
uint32 PAD[6];
|
||||
uint32 oobseloutd30; /* 0x160 */
|
||||
uint32 oobseloutd74; /* 0x164 */
|
||||
uint32 PAD[38];
|
||||
uint32 oobsynca; /* 0x200 */
|
||||
uint32 oobseloutaen; /* 0x204 */
|
||||
uint32 PAD[6];
|
||||
uint32 oobsyncb; /* 0x220 */
|
||||
uint32 oobseloutben; /* 0x224 */
|
||||
uint32 PAD[6];
|
||||
uint32 oobsyncc; /* 0x240 */
|
||||
uint32 oobseloutcen; /* 0x244 */
|
||||
uint32 PAD[6];
|
||||
uint32 oobsyncd; /* 0x260 */
|
||||
uint32 oobseloutden; /* 0x264 */
|
||||
uint32 PAD[38];
|
||||
uint32 oobaextwidth; /* 0x300 */
|
||||
uint32 oobainwidth; /* 0x304 */
|
||||
uint32 oobaoutwidth; /* 0x308 */
|
||||
uint32 PAD[5];
|
||||
uint32 oobbextwidth; /* 0x320 */
|
||||
uint32 oobbinwidth; /* 0x324 */
|
||||
uint32 oobboutwidth; /* 0x328 */
|
||||
uint32 PAD[5];
|
||||
uint32 oobcextwidth; /* 0x340 */
|
||||
uint32 oobcinwidth; /* 0x344 */
|
||||
uint32 oobcoutwidth; /* 0x348 */
|
||||
uint32 PAD[5];
|
||||
uint32 oobdextwidth; /* 0x360 */
|
||||
uint32 oobdinwidth; /* 0x364 */
|
||||
uint32 oobdoutwidth; /* 0x368 */
|
||||
uint32 PAD[37];
|
||||
uint32 ioctrlset; /* 0x400 */
|
||||
uint32 ioctrlclear; /* 0x404 */
|
||||
uint32 ioctrl; /* 0x408 */
|
||||
uint32 PAD[61];
|
||||
uint32 iostatus; /* 0x500 */
|
||||
uint32 PAD[127];
|
||||
uint32 ioctrlwidth; /* 0x700 */
|
||||
uint32 iostatuswidth; /* 0x704 */
|
||||
uint32 PAD[62];
|
||||
uint32 resetctrl; /* 0x800 */
|
||||
uint32 resetstatus; /* 0x804 */
|
||||
uint32 resetreadid; /* 0x808 */
|
||||
uint32 resetwriteid; /* 0x80c */
|
||||
uint32 PAD[60];
|
||||
uint32 errlogctrl; /* 0x900 */
|
||||
uint32 errlogdone; /* 0x904 */
|
||||
uint32 errlogstatus; /* 0x908 */
|
||||
uint32 errlogaddrlo; /* 0x90c */
|
||||
uint32 errlogaddrhi; /* 0x910 */
|
||||
uint32 errlogid; /* 0x914 */
|
||||
uint32 errloguser; /* 0x918 */
|
||||
uint32 errlogflags; /* 0x91c */
|
||||
uint32 PAD[56];
|
||||
uint32 intstatus; /* 0xa00 */
|
||||
uint32 PAD[255];
|
||||
uint32 config; /* 0xe00 */
|
||||
uint32 PAD[63];
|
||||
uint32 itcr; /* 0xf00 */
|
||||
uint32 PAD[3];
|
||||
uint32 itipooba; /* 0xf10 */
|
||||
uint32 itipoobb; /* 0xf14 */
|
||||
uint32 itipoobc; /* 0xf18 */
|
||||
uint32 itipoobd; /* 0xf1c */
|
||||
uint32 PAD[4];
|
||||
uint32 itipoobaout; /* 0xf30 */
|
||||
uint32 itipoobbout; /* 0xf34 */
|
||||
uint32 itipoobcout; /* 0xf38 */
|
||||
uint32 itipoobdout; /* 0xf3c */
|
||||
uint32 PAD[4];
|
||||
uint32 itopooba; /* 0xf50 */
|
||||
uint32 itopoobb; /* 0xf54 */
|
||||
uint32 itopoobc; /* 0xf58 */
|
||||
uint32 itopoobd; /* 0xf5c */
|
||||
uint32 PAD[4];
|
||||
uint32 itopoobain; /* 0xf70 */
|
||||
uint32 itopoobbin; /* 0xf74 */
|
||||
uint32 itopoobcin; /* 0xf78 */
|
||||
uint32 itopoobdin; /* 0xf7c */
|
||||
uint32 PAD[4];
|
||||
uint32 itopreset; /* 0xf90 */
|
||||
uint32 PAD[15];
|
||||
uint32 peripherialid4; /* 0xfd0 */
|
||||
uint32 peripherialid5; /* 0xfd4 */
|
||||
uint32 peripherialid6; /* 0xfd8 */
|
||||
uint32 peripherialid7; /* 0xfdc */
|
||||
uint32 peripherialid0; /* 0xfe0 */
|
||||
uint32 peripherialid1; /* 0xfe4 */
|
||||
uint32 peripherialid2; /* 0xfe8 */
|
||||
uint32 peripherialid3; /* 0xfec */
|
||||
uint32 componentid0; /* 0xff0 */
|
||||
uint32 componentid1; /* 0xff4 */
|
||||
uint32 componentid2; /* 0xff8 */
|
||||
uint32 componentid3; /* 0xffc */
|
||||
} aidmp_t;
|
||||
|
||||
#endif /* !_LANGUAGE_ASSEMBLY && !__ASSEMBLY__ */
|
||||
|
||||
/* Out-of-band Router registers */
|
||||
#define OOB_BUSCONFIG 0x020
|
||||
#define OOB_STATUSA 0x100
|
||||
#define OOB_STATUSB 0x104
|
||||
#define OOB_STATUSC 0x108
|
||||
#define OOB_STATUSD 0x10c
|
||||
#define OOB_ENABLEA0 0x200
|
||||
#define OOB_ENABLEA1 0x204
|
||||
#define OOB_ENABLEA2 0x208
|
||||
#define OOB_ENABLEA3 0x20c
|
||||
#define OOB_ENABLEB0 0x280
|
||||
#define OOB_ENABLEB1 0x284
|
||||
#define OOB_ENABLEB2 0x288
|
||||
#define OOB_ENABLEB3 0x28c
|
||||
#define OOB_ENABLEC0 0x300
|
||||
#define OOB_ENABLEC1 0x304
|
||||
#define OOB_ENABLEC2 0x308
|
||||
#define OOB_ENABLEC3 0x30c
|
||||
#define OOB_ENABLED0 0x380
|
||||
#define OOB_ENABLED1 0x384
|
||||
#define OOB_ENABLED2 0x388
|
||||
#define OOB_ENABLED3 0x38c
|
||||
#define OOB_ITCR 0xf00
|
||||
#define OOB_ITIPOOBA 0xf10
|
||||
#define OOB_ITIPOOBB 0xf14
|
||||
#define OOB_ITIPOOBC 0xf18
|
||||
#define OOB_ITIPOOBD 0xf1c
|
||||
#define OOB_ITOPOOBA 0xf30
|
||||
#define OOB_ITOPOOBB 0xf34
|
||||
#define OOB_ITOPOOBC 0xf38
|
||||
#define OOB_ITOPOOBD 0xf3c
|
||||
|
||||
/* DMP wrapper registers */
|
||||
#define AI_OOBSELINA30 0x000
|
||||
#define AI_OOBSELINA74 0x004
|
||||
#define AI_OOBSELINB30 0x020
|
||||
#define AI_OOBSELINB74 0x024
|
||||
#define AI_OOBSELINC30 0x040
|
||||
#define AI_OOBSELINC74 0x044
|
||||
#define AI_OOBSELIND30 0x060
|
||||
#define AI_OOBSELIND74 0x064
|
||||
#define AI_OOBSELOUTA30 0x100
|
||||
#define AI_OOBSELOUTA74 0x104
|
||||
#define AI_OOBSELOUTB30 0x120
|
||||
#define AI_OOBSELOUTB74 0x124
|
||||
#define AI_OOBSELOUTC30 0x140
|
||||
#define AI_OOBSELOUTC74 0x144
|
||||
#define AI_OOBSELOUTD30 0x160
|
||||
#define AI_OOBSELOUTD74 0x164
|
||||
#define AI_OOBSYNCA 0x200
|
||||
#define AI_OOBSELOUTAEN 0x204
|
||||
#define AI_OOBSYNCB 0x220
|
||||
#define AI_OOBSELOUTBEN 0x224
|
||||
#define AI_OOBSYNCC 0x240
|
||||
#define AI_OOBSELOUTCEN 0x244
|
||||
#define AI_OOBSYNCD 0x260
|
||||
#define AI_OOBSELOUTDEN 0x264
|
||||
#define AI_OOBAEXTWIDTH 0x300
|
||||
#define AI_OOBAINWIDTH 0x304
|
||||
#define AI_OOBAOUTWIDTH 0x308
|
||||
#define AI_OOBBEXTWIDTH 0x320
|
||||
#define AI_OOBBINWIDTH 0x324
|
||||
#define AI_OOBBOUTWIDTH 0x328
|
||||
#define AI_OOBCEXTWIDTH 0x340
|
||||
#define AI_OOBCINWIDTH 0x344
|
||||
#define AI_OOBCOUTWIDTH 0x348
|
||||
#define AI_OOBDEXTWIDTH 0x360
|
||||
#define AI_OOBDINWIDTH 0x364
|
||||
#define AI_OOBDOUTWIDTH 0x368
|
||||
|
||||
#define AI_IOCTRLSET 0x400
|
||||
#define AI_IOCTRLCLEAR 0x404
|
||||
#define AI_IOCTRL 0x408
|
||||
#define AI_IOSTATUS 0x500
|
||||
#define AI_RESETCTRL 0x800
|
||||
#define AI_RESETSTATUS 0x804
|
||||
|
||||
#define AI_IOCTRLWIDTH 0x700
|
||||
#define AI_IOSTATUSWIDTH 0x704
|
||||
|
||||
#define AI_RESETREADID 0x808
|
||||
#define AI_RESETWRITEID 0x80c
|
||||
#define AI_ERRLOGCTRL 0x900
|
||||
#define AI_ERRLOGDONE 0x904
|
||||
#define AI_ERRLOGSTATUS 0x908
|
||||
#define AI_ERRLOGADDRLO 0x90c
|
||||
#define AI_ERRLOGADDRHI 0x910
|
||||
#define AI_ERRLOGID 0x914
|
||||
#define AI_ERRLOGUSER 0x918
|
||||
#define AI_ERRLOGFLAGS 0x91c
|
||||
#define AI_INTSTATUS 0xa00
|
||||
#define AI_CONFIG 0xe00
|
||||
#define AI_ITCR 0xf00
|
||||
#define AI_ITIPOOBA 0xf10
|
||||
#define AI_ITIPOOBB 0xf14
|
||||
#define AI_ITIPOOBC 0xf18
|
||||
#define AI_ITIPOOBD 0xf1c
|
||||
#define AI_ITIPOOBAOUT 0xf30
|
||||
#define AI_ITIPOOBBOUT 0xf34
|
||||
#define AI_ITIPOOBCOUT 0xf38
|
||||
#define AI_ITIPOOBDOUT 0xf3c
|
||||
#define AI_ITOPOOBA 0xf50
|
||||
#define AI_ITOPOOBB 0xf54
|
||||
#define AI_ITOPOOBC 0xf58
|
||||
#define AI_ITOPOOBD 0xf5c
|
||||
#define AI_ITOPOOBAIN 0xf70
|
||||
#define AI_ITOPOOBBIN 0xf74
|
||||
#define AI_ITOPOOBCIN 0xf78
|
||||
#define AI_ITOPOOBDIN 0xf7c
|
||||
#define AI_ITOPRESET 0xf90
|
||||
#define AI_PERIPHERIALID4 0xfd0
|
||||
#define AI_PERIPHERIALID5 0xfd4
|
||||
#define AI_PERIPHERIALID6 0xfd8
|
||||
#define AI_PERIPHERIALID7 0xfdc
|
||||
#define AI_PERIPHERIALID0 0xfe0
|
||||
#define AI_PERIPHERIALID1 0xfe4
|
||||
#define AI_PERIPHERIALID2 0xfe8
|
||||
#define AI_PERIPHERIALID3 0xfec
|
||||
#define AI_COMPONENTID0 0xff0
|
||||
#define AI_COMPONENTID1 0xff4
|
||||
#define AI_COMPONENTID2 0xff8
|
||||
#define AI_COMPONENTID3 0xffc
|
||||
|
||||
/* resetctrl */
|
||||
#define AIRC_RESET 1
|
||||
|
||||
/* errlogctrl */
|
||||
#define AIELC_TO_EXP_MASK 0x0000001f0 /* backplane timeout exponent */
|
||||
#define AIELC_TO_EXP_SHIFT 4
|
||||
#define AIELC_TO_ENAB_SHIFT 9 /* backplane timeout enable */
|
||||
|
||||
/* errlogdone */
|
||||
#define AIELD_ERRDONE_MASK 0x3
|
||||
|
||||
/* errlogstatus */
|
||||
#define AIELS_SLAVE_ERR 0x1
|
||||
#define AIELS_TIMEOUT 0x2
|
||||
#define AIELS_DECODE 0x3
|
||||
#define AIELS_TIMEOUT_MASK 0x3
|
||||
|
||||
/* errorlog status bit map, for SW use */
|
||||
#define AXI_WRAP_STS_NONE (0)
|
||||
#define AXI_WRAP_STS_TIMEOUT (1<<0)
|
||||
#define AXI_WRAP_STS_SLAVE_ERR (1<<1)
|
||||
#define AXI_WRAP_STS_DECODE_ERR (1<<2)
|
||||
#define AXI_WRAP_STS_PCI_RD_ERR (1<<3)
|
||||
#define AXI_WRAP_STS_WRAP_RD_ERR (1<<4)
|
||||
#define AXI_WRAP_STS_SET_CORE_FAIL (1<<5)
|
||||
|
||||
/* errlogFrags */
|
||||
#define AXI_ERRLOG_FLAGS_WRITE_REQ (1<<24)
|
||||
|
||||
/* config */
|
||||
#define AICFG_OOB 0x00000020
|
||||
#define AICFG_IOS 0x00000010
|
||||
#define AICFG_IOC 0x00000008
|
||||
#define AICFG_TO 0x00000004
|
||||
#define AICFG_ERRL 0x00000002
|
||||
#define AICFG_RST 0x00000001
|
||||
|
||||
/* bit defines for AI_OOBSELOUTB74 reg */
|
||||
#define OOB_SEL_OUTEN_B_5 15
|
||||
#define OOB_SEL_OUTEN_B_6 23
|
||||
|
||||
/* AI_OOBSEL for A/B/C/D, 0-7 */
|
||||
#define AI_OOBSEL_MASK 0x1F
|
||||
#define AI_OOBSEL_0_SHIFT 0
|
||||
#define AI_OOBSEL_1_SHIFT 8
|
||||
#define AI_OOBSEL_2_SHIFT 16
|
||||
#define AI_OOBSEL_3_SHIFT 24
|
||||
#define AI_OOBSEL_4_SHIFT 0
|
||||
#define AI_OOBSEL_5_SHIFT 8
|
||||
#define AI_OOBSEL_6_SHIFT 16
|
||||
#define AI_OOBSEL_7_SHIFT 24
|
||||
#define AI_IOCTRL_ENABLE_D11_PME (1 << 14)
|
||||
|
||||
/* bit Specific for AI_OOBSELOUTB30 */
|
||||
#define OOB_B_ALP_REQUEST 0
|
||||
#define OOB_B_HT_REQUEST 1
|
||||
#define OOB_B_ILP_REQUEST 2
|
||||
#define OOB_B_ALP_AVAIL_REQUEST 3
|
||||
#define OOB_B_HT_AVAIL_REQUEST 4
|
||||
|
||||
/* mask for interrupts from each core to wrapper */
|
||||
#define AI_OOBSELINA74_CORE_MASK 0x80808080
|
||||
#define AI_OOBSELINA30_CORE_MASK 0x80808080
|
||||
|
||||
/* axi id mask in the error log id */
|
||||
#define AI_ERRLOGID_AXI_ID_MASK 0x07
|
||||
|
||||
#endif /* _AIDMP_H */
|
||||
@@ -0,0 +1,33 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* BCM common config options
|
||||
*
|
||||
* Copyright (C) 1999-2019, 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.
|
||||
*
|
||||
* 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: bcm_cfg.h 672943 2016-11-30 08:54:06Z $
|
||||
*/
|
||||
|
||||
#ifndef _bcm_cfg_h_
|
||||
#define _bcm_cfg_h_
|
||||
#endif /* _bcm_cfg_h_ */
|
||||
@@ -0,0 +1,351 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Memory pools library, Public interface
|
||||
*
|
||||
* API Overview
|
||||
*
|
||||
* This package provides a memory allocation subsystem based on pools of
|
||||
* homogenous objects.
|
||||
*
|
||||
* Instrumentation is available for reporting memory utilization both
|
||||
* on a per-data-structure basis and system wide.
|
||||
*
|
||||
* There are two main types defined in this API.
|
||||
*
|
||||
* pool manager: A singleton object that acts as a factory for
|
||||
* pool allocators. It also is used for global
|
||||
* instrumentation, such as reporting all blocks
|
||||
* in use across all data structures. The pool manager
|
||||
* creates and provides individual memory pools
|
||||
* upon request to application code.
|
||||
*
|
||||
* memory pool: An object for allocating homogenous memory blocks.
|
||||
*
|
||||
* Global identifiers in this module use the following prefixes:
|
||||
* bcm_mpm_* Memory pool manager
|
||||
* bcm_mp_* Memory pool
|
||||
*
|
||||
* There are two main types of memory pools:
|
||||
*
|
||||
* prealloc: The contiguous memory block of objects can either be supplied
|
||||
* by the client or malloc'ed by the memory manager. The objects are
|
||||
* allocated out of a block of memory and freed back to the block.
|
||||
*
|
||||
* heap: The memory pool allocator uses the heap (malloc/free) for memory.
|
||||
* In this case, the pool allocator is just providing statistics
|
||||
* and instrumentation on top of the heap, without modifying the heap
|
||||
* allocation implementation.
|
||||
*
|
||||
* Copyright (C) 1999-2019, 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.
|
||||
*
|
||||
* 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: bcm_mpool_pub.h 535090 2015-02-17 04:49:01Z $
|
||||
*/
|
||||
|
||||
#ifndef _BCM_MPOOL_PUB_H
|
||||
#define _BCM_MPOOL_PUB_H 1
|
||||
|
||||
#include <typedefs.h> /* needed for uint16 */
|
||||
|
||||
/*
|
||||
**************************************************************************
|
||||
*
|
||||
* Type definitions, handles
|
||||
*
|
||||
**************************************************************************
|
||||
*/
|
||||
|
||||
/* Forward declaration of OSL handle. */
|
||||
struct osl_info;
|
||||
|
||||
/* Forward declaration of string buffer. */
|
||||
struct bcmstrbuf;
|
||||
|
||||
/*
|
||||
* Opaque type definition for the pool manager handle. This object is used for global
|
||||
* memory pool operations such as obtaining a new pool, deleting a pool, iterating and
|
||||
* instrumentation/debugging.
|
||||
*/
|
||||
struct bcm_mpm_mgr;
|
||||
typedef struct bcm_mpm_mgr *bcm_mpm_mgr_h;
|
||||
|
||||
/*
|
||||
* Opaque type definition for an instance of a pool. This handle is used for allocating
|
||||
* and freeing memory through the pool, as well as management/instrumentation on this
|
||||
* specific pool.
|
||||
*/
|
||||
struct bcm_mp_pool;
|
||||
typedef struct bcm_mp_pool *bcm_mp_pool_h;
|
||||
|
||||
/*
|
||||
* To make instrumentation more readable, every memory
|
||||
* pool must have a readable name. Pool names are up to
|
||||
* 8 bytes including '\0' termination. (7 printable characters.)
|
||||
*/
|
||||
#define BCM_MP_NAMELEN 8
|
||||
|
||||
/*
|
||||
* Type definition for pool statistics.
|
||||
*/
|
||||
typedef struct bcm_mp_stats {
|
||||
char name[BCM_MP_NAMELEN]; /* Name of this pool. */
|
||||
unsigned int objsz; /* Object size allocated in this pool */
|
||||
uint16 nobj; /* Total number of objects in this pool */
|
||||
uint16 num_alloc; /* Number of objects currently allocated */
|
||||
uint16 high_water; /* Max number of allocated objects. */
|
||||
uint16 failed_alloc; /* Failed allocations. */
|
||||
} bcm_mp_stats_t;
|
||||
|
||||
/*
|
||||
**************************************************************************
|
||||
*
|
||||
* API Routines on the pool manager.
|
||||
*
|
||||
**************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
* bcm_mpm_init() - initialize the whole memory pool system.
|
||||
*
|
||||
* Parameters:
|
||||
* osh: INPUT Operating system handle. Needed for heap memory allocation.
|
||||
* max_pools: INPUT Maximum number of mempools supported.
|
||||
* mgr: OUTPUT The handle is written with the new pools manager object/handle.
|
||||
*
|
||||
* Returns:
|
||||
* BCME_OK Object initialized successfully. May be used.
|
||||
* BCME_NOMEM Initialization failed due to no memory. Object must not be used.
|
||||
*/
|
||||
int bcm_mpm_init(struct osl_info *osh, int max_pools, bcm_mpm_mgr_h *mgrp);
|
||||
|
||||
/*
|
||||
* bcm_mpm_deinit() - de-initialize the whole memory pool system.
|
||||
*
|
||||
* Parameters:
|
||||
* mgr: INPUT Pointer to pool manager handle.
|
||||
*
|
||||
* Returns:
|
||||
* BCME_OK Memory pool manager successfully de-initialized.
|
||||
* other Indicated error occured during de-initialization.
|
||||
*/
|
||||
int bcm_mpm_deinit(bcm_mpm_mgr_h *mgrp);
|
||||
|
||||
/*
|
||||
* bcm_mpm_create_prealloc_pool() - Create a new pool for fixed size objects. The
|
||||
* pool uses a contiguous block of pre-alloced
|
||||
* memory. The memory block may either be provided
|
||||
* by the client or dynamically allocated by the
|
||||
* pool manager.
|
||||
*
|
||||
* Parameters:
|
||||
* mgr: INPUT The handle to the pool manager
|
||||
* obj_sz: INPUT Size of objects that will be allocated by the new pool
|
||||
* Must be >= sizeof(void *).
|
||||
* nobj: INPUT Maximum number of concurrently existing objects to support
|
||||
* memstart INPUT Pointer to the memory to use, or NULL to malloc()
|
||||
* memsize INPUT Number of bytes referenced from memstart (for error checking).
|
||||
* Must be 0 if 'memstart' is NULL.
|
||||
* poolname INPUT For instrumentation, the name of the pool
|
||||
* newp: OUTPUT The handle for the new pool, if creation is successful
|
||||
*
|
||||
* Returns:
|
||||
* BCME_OK Pool created ok.
|
||||
* other Pool not created due to indicated error. newpoolp set to NULL.
|
||||
*
|
||||
*
|
||||
*/
|
||||
int bcm_mpm_create_prealloc_pool(bcm_mpm_mgr_h mgr,
|
||||
unsigned int obj_sz,
|
||||
int nobj,
|
||||
void *memstart,
|
||||
unsigned int memsize,
|
||||
const char poolname[BCM_MP_NAMELEN],
|
||||
bcm_mp_pool_h *newp);
|
||||
|
||||
/*
|
||||
* bcm_mpm_delete_prealloc_pool() - Delete a memory pool. This should only be called after
|
||||
* all memory objects have been freed back to the pool.
|
||||
*
|
||||
* Parameters:
|
||||
* mgr: INPUT The handle to the pools manager
|
||||
* pool: INPUT The handle of the pool to delete
|
||||
*
|
||||
* Returns:
|
||||
* BCME_OK Pool deleted ok.
|
||||
* other Pool not deleted due to indicated error.
|
||||
*
|
||||
*/
|
||||
int bcm_mpm_delete_prealloc_pool(bcm_mpm_mgr_h mgr, bcm_mp_pool_h *poolp);
|
||||
|
||||
/*
|
||||
* bcm_mpm_create_heap_pool() - Create a new pool for fixed size objects. The memory
|
||||
* pool allocator uses the heap (malloc/free) for memory.
|
||||
* In this case, the pool allocator is just providing
|
||||
* statistics and instrumentation on top of the heap,
|
||||
* without modifying the heap allocation implementation.
|
||||
*
|
||||
* Parameters:
|
||||
* mgr: INPUT The handle to the pool manager
|
||||
* obj_sz: INPUT Size of objects that will be allocated by the new pool
|
||||
* poolname INPUT For instrumentation, the name of the pool
|
||||
* newp: OUTPUT The handle for the new pool, if creation is successful
|
||||
*
|
||||
* Returns:
|
||||
* BCME_OK Pool created ok.
|
||||
* other Pool not created due to indicated error. newpoolp set to NULL.
|
||||
*
|
||||
*
|
||||
*/
|
||||
int bcm_mpm_create_heap_pool(bcm_mpm_mgr_h mgr, unsigned int obj_sz,
|
||||
const char poolname[BCM_MP_NAMELEN],
|
||||
bcm_mp_pool_h *newp);
|
||||
|
||||
/*
|
||||
* bcm_mpm_delete_heap_pool() - Delete a memory pool. This should only be called after
|
||||
* all memory objects have been freed back to the pool.
|
||||
*
|
||||
* Parameters:
|
||||
* mgr: INPUT The handle to the pools manager
|
||||
* pool: INPUT The handle of the pool to delete
|
||||
*
|
||||
* Returns:
|
||||
* BCME_OK Pool deleted ok.
|
||||
* other Pool not deleted due to indicated error.
|
||||
*
|
||||
*/
|
||||
int bcm_mpm_delete_heap_pool(bcm_mpm_mgr_h mgr, bcm_mp_pool_h *poolp);
|
||||
|
||||
/*
|
||||
* bcm_mpm_stats() - Return stats for all pools
|
||||
*
|
||||
* Parameters:
|
||||
* mgr: INPUT The handle to the pools manager
|
||||
* stats: OUTPUT Array of pool statistics.
|
||||
* nentries: MOD Max elements in 'stats' array on INPUT. Actual number
|
||||
* of array elements copied to 'stats' on OUTPUT.
|
||||
*
|
||||
* Returns:
|
||||
* BCME_OK Ok
|
||||
* other Error getting stats.
|
||||
*
|
||||
*/
|
||||
int bcm_mpm_stats(bcm_mpm_mgr_h mgr, bcm_mp_stats_t *stats, int *nentries);
|
||||
|
||||
/*
|
||||
* bcm_mpm_dump() - Display statistics on all pools
|
||||
*
|
||||
* Parameters:
|
||||
* mgr: INPUT The handle to the pools manager
|
||||
* b: OUTPUT Output buffer.
|
||||
*
|
||||
* Returns:
|
||||
* BCME_OK Ok
|
||||
* other Error during dump.
|
||||
*
|
||||
*/
|
||||
int bcm_mpm_dump(bcm_mpm_mgr_h mgr, struct bcmstrbuf *b);
|
||||
|
||||
/*
|
||||
* bcm_mpm_get_obj_size() - The size of memory objects may need to be padded to
|
||||
* compensate for alignment requirements of the objects.
|
||||
* This function provides the padded object size. If clients
|
||||
* pre-allocate a memory slab for a memory pool, the
|
||||
* padded object size should be used by the client to allocate
|
||||
* the memory slab (in order to provide sufficent space for
|
||||
* the maximum number of objects).
|
||||
*
|
||||
* Parameters:
|
||||
* mgr: INPUT The handle to the pools manager.
|
||||
* obj_sz: INPUT Input object size.
|
||||
* padded_obj_sz: OUTPUT Padded object size.
|
||||
*
|
||||
* Returns:
|
||||
* BCME_OK Ok
|
||||
* BCME_BADARG Bad arguments.
|
||||
*
|
||||
*/
|
||||
int bcm_mpm_get_obj_size(bcm_mpm_mgr_h mgr, unsigned int obj_sz, unsigned int *padded_obj_sz);
|
||||
|
||||
/*
|
||||
***************************************************************************
|
||||
*
|
||||
* API Routines on a specific pool.
|
||||
*
|
||||
***************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
* bcm_mp_alloc() - Allocate a memory pool object.
|
||||
*
|
||||
* Parameters:
|
||||
* pool: INPUT The handle to the pool.
|
||||
*
|
||||
* Returns:
|
||||
* A pointer to the new object. NULL on error.
|
||||
*
|
||||
*/
|
||||
void* bcm_mp_alloc(bcm_mp_pool_h pool);
|
||||
|
||||
/*
|
||||
* bcm_mp_free() - Free a memory pool object.
|
||||
*
|
||||
* Parameters:
|
||||
* pool: INPUT The handle to the pool.
|
||||
* objp: INPUT A pointer to the object to free.
|
||||
*
|
||||
* Returns:
|
||||
* BCME_OK Ok
|
||||
* other Error during free.
|
||||
*
|
||||
*/
|
||||
int bcm_mp_free(bcm_mp_pool_h pool, void *objp);
|
||||
|
||||
/*
|
||||
* bcm_mp_stats() - Return stats for this pool
|
||||
*
|
||||
* Parameters:
|
||||
* pool: INPUT The handle to the pool
|
||||
* stats: OUTPUT Pool statistics
|
||||
*
|
||||
* Returns:
|
||||
* BCME_OK Ok
|
||||
* other Error getting statistics.
|
||||
*
|
||||
*/
|
||||
void bcm_mp_stats(bcm_mp_pool_h pool, bcm_mp_stats_t *stats);
|
||||
|
||||
/*
|
||||
* bcm_mp_dump() - Dump a pool
|
||||
*
|
||||
* Parameters:
|
||||
* pool: INPUT The handle to the pool
|
||||
* b OUTPUT Output buffer
|
||||
*
|
||||
* Returns:
|
||||
* BCME_OK Ok
|
||||
* other Error during dump.
|
||||
*
|
||||
*/
|
||||
int bcm_mp_dump(bcm_mp_pool_h pool, struct bcmstrbuf *b);
|
||||
|
||||
#endif /* _BCM_MPOOL_PUB_H */
|
||||
@@ -0,0 +1,614 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* bcm_ring.h : Ring context abstraction
|
||||
* The ring context tracks the WRITE and READ indices where elements may be
|
||||
* produced and consumed respectively. All elements in the ring need to be
|
||||
* fixed size.
|
||||
*
|
||||
* NOTE: A ring of size N, may only hold N-1 elements.
|
||||
*
|
||||
* Copyright (C) 1999-2019, 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.
|
||||
*
|
||||
* 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: bcm_ring.h 700321 2017-05-18 16:09:07Z $
|
||||
*/
|
||||
#ifndef __bcm_ring_included__
|
||||
#define __bcm_ring_included__
|
||||
/*
|
||||
* API Notes:
|
||||
*
|
||||
* Ring manipulation API allows for:
|
||||
* Pending operations: Often before some work can be completed, it may be
|
||||
* desired that several resources are available, e.g. space for production in
|
||||
* a ring. Approaches such as, #1) reserve resources one by one and return them
|
||||
* if another required resource is not available, or #2) employ a two pass
|
||||
* algorithm of first testing whether all resources are available, have a
|
||||
* an impact on performance critical code. The approach taken here is more akin
|
||||
* to approach #2, where a test for resource availability essentially also
|
||||
* provides the index for production in an un-committed state.
|
||||
* The same approach is taken for the consumer side.
|
||||
*
|
||||
* - Pending production: Fetch the next index where a ring element may be
|
||||
* produced. The caller may not commit the WRITE of the element.
|
||||
* - Pending consumption: Fetch the next index where a ring element may be
|
||||
* consumed. The caller may not commut the READ of the element.
|
||||
*
|
||||
* Producer side API:
|
||||
* - bcm_ring_is_full : Test whether ring is full
|
||||
* - bcm_ring_prod : Fetch index where an element may be produced (commit)
|
||||
* - bcm_ring_prod_pend: Fetch index where an element may be produced (pending)
|
||||
* - bcm_ring_prod_done: Commit a previous pending produce fetch
|
||||
* - bcm_ring_prod_avail: Fetch total number free slots eligible for production
|
||||
*
|
||||
* Consumer side API:
|
||||
* - bcm_ring_is_empty : Test whether ring is empty
|
||||
* - bcm_ring_cons : Fetch index where an element may be consumed (commit)
|
||||
* - bcm_ring_cons_pend: Fetch index where an element may be consumed (pending)
|
||||
* - bcm_ring_cons_done: Commit a previous pending consume fetch
|
||||
* - bcm_ring_cons_avail: Fetch total number elements eligible for consumption
|
||||
*
|
||||
* - bcm_ring_sync_read: Sync read offset in peer ring, from local ring
|
||||
* - bcm_ring_sync_write: Sync write offset in peer ring, from local ring
|
||||
*
|
||||
* +----------------------------------------------------------------------------
|
||||
*
|
||||
* Design Notes:
|
||||
* Following items are not tracked in a ring context (design decision)
|
||||
* - width of a ring element.
|
||||
* - depth of the ring.
|
||||
* - base of the buffer, where the elements are stored.
|
||||
* - count of number of free slots in the ring
|
||||
*
|
||||
* Implementation Notes:
|
||||
* - When BCM_RING_DEBUG is enabled, need explicit bcm_ring_init().
|
||||
* - BCM_RING_EMPTY and BCM_RING_FULL are (-1)
|
||||
*
|
||||
* +----------------------------------------------------------------------------
|
||||
*
|
||||
* Usage Notes:
|
||||
* An application may incarnate a ring of some fixed sized elements, by defining
|
||||
* - a ring data buffer to store the ring elements.
|
||||
* - depth of the ring (max number of elements managed by ring context).
|
||||
* Preferrably, depth may be represented as a constant.
|
||||
* - width of a ring element: to be used in pointer arithmetic with the ring's
|
||||
* data buffer base and an index to fetch the ring element.
|
||||
*
|
||||
* Use bcm_workq_t to instantiate a pair of workq constructs, one for the
|
||||
* producer and the other for the consumer, both pointing to the same circular
|
||||
* buffer. The producer may operate on it's own local workq and flush the write
|
||||
* index to the consumer. Likewise the consumer may use its local workq and
|
||||
* flush the read index to the producer. This way we do not repeatedly access
|
||||
* the peer's context. The two peers may reside on different CPU cores with a
|
||||
* private L1 data cache.
|
||||
* +----------------------------------------------------------------------------
|
||||
*
|
||||
* Copyright (C) 1999-2019, 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.
|
||||
*
|
||||
* 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: bcm_ring.h 700321 2017-05-18 16:09:07Z $
|
||||
*
|
||||
* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*-
|
||||
* vim: set ts=4 noet sw=4 tw=80:
|
||||
*
|
||||
* +----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifdef ____cacheline_aligned
|
||||
#define __ring_aligned ____cacheline_aligned
|
||||
#else
|
||||
#define __ring_aligned
|
||||
#endif // endif
|
||||
|
||||
/* Conditional compile for debug */
|
||||
/* #define BCM_RING_DEBUG */
|
||||
|
||||
#define BCM_RING_EMPTY (-1)
|
||||
#define BCM_RING_FULL (-1)
|
||||
#define BCM_RING_NULL ((bcm_ring_t *)NULL)
|
||||
|
||||
#if defined(BCM_RING_DEBUG)
|
||||
#define RING_ASSERT(exp) ASSERT(exp)
|
||||
#define BCM_RING_IS_VALID(ring) (((ring) != BCM_RING_NULL) && \
|
||||
((ring)->self == (ring)))
|
||||
#else /* ! BCM_RING_DEBUG */
|
||||
#define RING_ASSERT(exp) do {} while (0)
|
||||
#define BCM_RING_IS_VALID(ring) ((ring) != BCM_RING_NULL)
|
||||
#endif /* ! BCM_RING_DEBUG */
|
||||
|
||||
#define BCM_RING_SIZE_IS_VALID(ring_size) ((ring_size) > 0)
|
||||
|
||||
/*
|
||||
* +----------------------------------------------------------------------------
|
||||
* Ring Context
|
||||
* +----------------------------------------------------------------------------
|
||||
*/
|
||||
typedef struct bcm_ring { /* Ring context */
|
||||
#if defined(BCM_RING_DEBUG)
|
||||
struct bcm_ring *self; /* ptr to self for IS VALID test */
|
||||
#endif /* BCM_RING_DEBUG */
|
||||
int write __ring_aligned; /* WRITE index in a circular ring */
|
||||
int read __ring_aligned; /* READ index in a circular ring */
|
||||
} bcm_ring_t;
|
||||
|
||||
static INLINE void bcm_ring_init(bcm_ring_t *ring);
|
||||
static INLINE void bcm_ring_copy(bcm_ring_t *to, bcm_ring_t *from);
|
||||
static INLINE bool bcm_ring_is_empty(bcm_ring_t *ring);
|
||||
|
||||
static INLINE int __bcm_ring_next_write(bcm_ring_t *ring, const int ring_size);
|
||||
|
||||
static INLINE bool __bcm_ring_full(bcm_ring_t *ring, int next_write);
|
||||
static INLINE bool bcm_ring_is_full(bcm_ring_t *ring, const int ring_size);
|
||||
|
||||
static INLINE void bcm_ring_prod_done(bcm_ring_t *ring, int write);
|
||||
static INLINE int bcm_ring_prod_pend(bcm_ring_t *ring, int *pend_write,
|
||||
const int ring_size);
|
||||
static INLINE int bcm_ring_prod(bcm_ring_t *ring, const int ring_size);
|
||||
|
||||
static INLINE void bcm_ring_cons_done(bcm_ring_t *ring, int read);
|
||||
static INLINE int bcm_ring_cons_pend(bcm_ring_t *ring, int *pend_read,
|
||||
const int ring_size);
|
||||
static INLINE int bcm_ring_cons(bcm_ring_t *ring, const int ring_size);
|
||||
|
||||
static INLINE void bcm_ring_sync_read(bcm_ring_t *peer, const bcm_ring_t *self);
|
||||
static INLINE void bcm_ring_sync_write(bcm_ring_t *peer, const bcm_ring_t *self);
|
||||
|
||||
static INLINE int bcm_ring_prod_avail(const bcm_ring_t *ring,
|
||||
const int ring_size);
|
||||
static INLINE int bcm_ring_cons_avail(const bcm_ring_t *ring,
|
||||
const int ring_size);
|
||||
static INLINE void bcm_ring_cons_all(bcm_ring_t *ring);
|
||||
|
||||
/**
|
||||
* bcm_ring_init - initialize a ring context.
|
||||
* @ring: pointer to a ring context
|
||||
*/
|
||||
static INLINE void
|
||||
bcm_ring_init(bcm_ring_t *ring)
|
||||
{
|
||||
ASSERT(ring != (bcm_ring_t *)NULL);
|
||||
#if defined(BCM_RING_DEBUG)
|
||||
ring->self = ring;
|
||||
#endif /* BCM_RING_DEBUG */
|
||||
ring->write = 0;
|
||||
ring->read = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* bcm_ring_copy - copy construct a ring
|
||||
* @to: pointer to the new ring context
|
||||
* @from: pointer to orig ring context
|
||||
*/
|
||||
static INLINE void
|
||||
bcm_ring_copy(bcm_ring_t *to, bcm_ring_t *from)
|
||||
{
|
||||
bcm_ring_init(to);
|
||||
|
||||
to->write = from->write;
|
||||
to->read = from->read;
|
||||
}
|
||||
|
||||
/**
|
||||
* bcm_ring_is_empty - "Boolean" test whether ring is empty.
|
||||
* @ring: pointer to a ring context
|
||||
*
|
||||
* PS. does not return BCM_RING_EMPTY value.
|
||||
*/
|
||||
static INLINE bool
|
||||
bcm_ring_is_empty(bcm_ring_t *ring)
|
||||
{
|
||||
RING_ASSERT(BCM_RING_IS_VALID(ring));
|
||||
return (ring->read == ring->write);
|
||||
}
|
||||
|
||||
/**
|
||||
* __bcm_ring_next_write - determine the index where the next write may occur
|
||||
* (with wrap-around).
|
||||
* @ring: pointer to a ring context
|
||||
* @ring_size: size of the ring
|
||||
*
|
||||
* PRIVATE INTERNAL USE ONLY.
|
||||
*/
|
||||
static INLINE int
|
||||
__bcm_ring_next_write(bcm_ring_t *ring, const int ring_size)
|
||||
{
|
||||
RING_ASSERT(BCM_RING_IS_VALID(ring) && BCM_RING_SIZE_IS_VALID(ring_size));
|
||||
return ((ring->write + 1) % ring_size);
|
||||
}
|
||||
|
||||
/**
|
||||
* __bcm_ring_full - support function for ring full test.
|
||||
* @ring: pointer to a ring context
|
||||
* @next_write: next location in ring where an element is to be produced
|
||||
*
|
||||
* PRIVATE INTERNAL USE ONLY.
|
||||
*/
|
||||
static INLINE bool
|
||||
__bcm_ring_full(bcm_ring_t *ring, int next_write)
|
||||
{
|
||||
return (next_write == ring->read);
|
||||
}
|
||||
|
||||
/**
|
||||
* bcm_ring_is_full - "Boolean" test whether a ring is full.
|
||||
* @ring: pointer to a ring context
|
||||
* @ring_size: size of the ring
|
||||
*
|
||||
* PS. does not return BCM_RING_FULL value.
|
||||
*/
|
||||
static INLINE bool
|
||||
bcm_ring_is_full(bcm_ring_t *ring, const int ring_size)
|
||||
{
|
||||
int next_write;
|
||||
RING_ASSERT(BCM_RING_IS_VALID(ring) && BCM_RING_SIZE_IS_VALID(ring_size));
|
||||
next_write = __bcm_ring_next_write(ring, ring_size);
|
||||
return __bcm_ring_full(ring, next_write);
|
||||
}
|
||||
|
||||
/**
|
||||
* bcm_ring_prod_done - commit a previously pending index where production
|
||||
* was requested.
|
||||
* @ring: pointer to a ring context
|
||||
* @write: index into ring upto where production was done.
|
||||
* +----------------------------------------------------------------------------
|
||||
*/
|
||||
static INLINE void
|
||||
bcm_ring_prod_done(bcm_ring_t *ring, int write)
|
||||
{
|
||||
RING_ASSERT(BCM_RING_IS_VALID(ring));
|
||||
ring->write = write;
|
||||
}
|
||||
|
||||
/**
|
||||
* bcm_ring_prod_pend - Fetch in "pend" mode, the index where an element may be
|
||||
* produced.
|
||||
* @ring: pointer to a ring context
|
||||
* @pend_write: next index, after the returned index
|
||||
* @ring_size: size of the ring
|
||||
*/
|
||||
static INLINE int
|
||||
bcm_ring_prod_pend(bcm_ring_t *ring, int *pend_write, const int ring_size)
|
||||
{
|
||||
int rtn;
|
||||
RING_ASSERT(BCM_RING_IS_VALID(ring) && BCM_RING_SIZE_IS_VALID(ring_size));
|
||||
*pend_write = __bcm_ring_next_write(ring, ring_size);
|
||||
if (__bcm_ring_full(ring, *pend_write)) {
|
||||
*pend_write = BCM_RING_FULL;
|
||||
rtn = BCM_RING_FULL;
|
||||
} else {
|
||||
/* production is not committed, caller needs to explicitly commit */
|
||||
rtn = ring->write;
|
||||
}
|
||||
return rtn;
|
||||
}
|
||||
|
||||
/**
|
||||
* bcm_ring_prod - Fetch and "commit" the next index where a ring element may
|
||||
* be produced.
|
||||
* @ring: pointer to a ring context
|
||||
* @ring_size: size of the ring
|
||||
*/
|
||||
static INLINE int
|
||||
bcm_ring_prod(bcm_ring_t *ring, const int ring_size)
|
||||
{
|
||||
int next_write, prod_write;
|
||||
RING_ASSERT(BCM_RING_IS_VALID(ring) && BCM_RING_SIZE_IS_VALID(ring_size));
|
||||
|
||||
next_write = __bcm_ring_next_write(ring, ring_size);
|
||||
if (__bcm_ring_full(ring, next_write)) {
|
||||
prod_write = BCM_RING_FULL;
|
||||
} else {
|
||||
prod_write = ring->write;
|
||||
bcm_ring_prod_done(ring, next_write); /* "commit" production */
|
||||
}
|
||||
return prod_write;
|
||||
}
|
||||
|
||||
/**
|
||||
* bcm_ring_cons_done - commit a previously pending read
|
||||
* @ring: pointer to a ring context
|
||||
* @read: index upto which elements have been consumed.
|
||||
*/
|
||||
static INLINE void
|
||||
bcm_ring_cons_done(bcm_ring_t *ring, int read)
|
||||
{
|
||||
RING_ASSERT(BCM_RING_IS_VALID(ring));
|
||||
ring->read = read;
|
||||
}
|
||||
|
||||
/**
|
||||
* bcm_ring_cons_pend - fetch in "pend" mode, the next index where a ring
|
||||
* element may be consumed.
|
||||
* @ring: pointer to a ring context
|
||||
* @pend_read: index into ring upto which elements may be consumed.
|
||||
* @ring_size: size of the ring
|
||||
*/
|
||||
static INLINE int
|
||||
bcm_ring_cons_pend(bcm_ring_t *ring, int *pend_read, const int ring_size)
|
||||
{
|
||||
int rtn;
|
||||
RING_ASSERT(BCM_RING_IS_VALID(ring) && BCM_RING_SIZE_IS_VALID(ring_size));
|
||||
if (bcm_ring_is_empty(ring)) {
|
||||
*pend_read = BCM_RING_EMPTY;
|
||||
rtn = BCM_RING_EMPTY;
|
||||
} else {
|
||||
*pend_read = (ring->read + 1) % ring_size;
|
||||
/* production is not committed, caller needs to explicitly commit */
|
||||
rtn = ring->read;
|
||||
}
|
||||
return rtn;
|
||||
}
|
||||
|
||||
/**
|
||||
* bcm_ring_cons - fetch and "commit" the next index where a ring element may
|
||||
* be consumed.
|
||||
* @ring: pointer to a ring context
|
||||
* @ring_size: size of the ring
|
||||
*/
|
||||
static INLINE int
|
||||
bcm_ring_cons(bcm_ring_t *ring, const int ring_size)
|
||||
{
|
||||
int cons_read;
|
||||
RING_ASSERT(BCM_RING_IS_VALID(ring) && BCM_RING_SIZE_IS_VALID(ring_size));
|
||||
if (bcm_ring_is_empty(ring)) {
|
||||
cons_read = BCM_RING_EMPTY;
|
||||
} else {
|
||||
cons_read = ring->read;
|
||||
ring->read = (ring->read + 1) % ring_size; /* read is committed */
|
||||
}
|
||||
return cons_read;
|
||||
}
|
||||
|
||||
/**
|
||||
* bcm_ring_sync_read - on consumption, update peer's read index.
|
||||
* @peer: pointer to peer's producer ring context
|
||||
* @self: pointer to consumer's ring context
|
||||
*/
|
||||
static INLINE void
|
||||
bcm_ring_sync_read(bcm_ring_t *peer, const bcm_ring_t *self)
|
||||
{
|
||||
RING_ASSERT(BCM_RING_IS_VALID(peer));
|
||||
RING_ASSERT(BCM_RING_IS_VALID(self));
|
||||
peer->read = self->read; /* flush read update to peer producer */
|
||||
}
|
||||
|
||||
/**
|
||||
* bcm_ring_sync_write - on consumption, update peer's write index.
|
||||
* @peer: pointer to peer's consumer ring context
|
||||
* @self: pointer to producer's ring context
|
||||
*/
|
||||
static INLINE void
|
||||
bcm_ring_sync_write(bcm_ring_t *peer, const bcm_ring_t *self)
|
||||
{
|
||||
RING_ASSERT(BCM_RING_IS_VALID(peer));
|
||||
RING_ASSERT(BCM_RING_IS_VALID(self));
|
||||
peer->write = self->write; /* flush write update to peer consumer */
|
||||
}
|
||||
|
||||
/**
|
||||
* bcm_ring_prod_avail - fetch total number of available empty slots in the
|
||||
* ring for production.
|
||||
* @ring: pointer to a ring context
|
||||
* @ring_size: size of the ring
|
||||
*/
|
||||
static INLINE int
|
||||
bcm_ring_prod_avail(const bcm_ring_t *ring, const int ring_size)
|
||||
{
|
||||
int prod_avail;
|
||||
RING_ASSERT(BCM_RING_IS_VALID(ring) && BCM_RING_SIZE_IS_VALID(ring_size));
|
||||
if (ring->write >= ring->read) {
|
||||
prod_avail = (ring_size - (ring->write - ring->read) - 1);
|
||||
} else {
|
||||
prod_avail = (ring->read - (ring->write + 1));
|
||||
}
|
||||
ASSERT(prod_avail < ring_size);
|
||||
return prod_avail;
|
||||
}
|
||||
|
||||
/**
|
||||
* bcm_ring_cons_avail - fetch total number of available elements for consumption.
|
||||
* @ring: pointer to a ring context
|
||||
* @ring_size: size of the ring
|
||||
*/
|
||||
static INLINE int
|
||||
bcm_ring_cons_avail(const bcm_ring_t *ring, const int ring_size)
|
||||
{
|
||||
int cons_avail;
|
||||
RING_ASSERT(BCM_RING_IS_VALID(ring) && BCM_RING_SIZE_IS_VALID(ring_size));
|
||||
if (ring->read == ring->write) {
|
||||
cons_avail = 0;
|
||||
} else if (ring->read > ring->write) {
|
||||
cons_avail = ((ring_size - ring->read) + ring->write);
|
||||
} else {
|
||||
cons_avail = ring->write - ring->read;
|
||||
}
|
||||
ASSERT(cons_avail < ring_size);
|
||||
return cons_avail;
|
||||
}
|
||||
|
||||
/**
|
||||
* bcm_ring_cons_all - set ring in state where all elements are consumed.
|
||||
* @ring: pointer to a ring context
|
||||
*/
|
||||
static INLINE void
|
||||
bcm_ring_cons_all(bcm_ring_t *ring)
|
||||
{
|
||||
ring->read = ring->write;
|
||||
}
|
||||
|
||||
/**
|
||||
* Work Queue
|
||||
* A work Queue is composed of a ring of work items, of a specified depth.
|
||||
* It HAS-A bcm_ring object, comprising of a RD and WR offset, to implement a
|
||||
* producer/consumer circular ring.
|
||||
*/
|
||||
|
||||
struct bcm_workq {
|
||||
bcm_ring_t ring; /* Ring context abstraction */
|
||||
struct bcm_workq *peer; /* Peer workq context */
|
||||
void *buffer; /* Buffer storage for work items in workQ */
|
||||
int ring_size; /* Depth of workQ */
|
||||
} __ring_aligned;
|
||||
|
||||
typedef struct bcm_workq bcm_workq_t;
|
||||
|
||||
/* #define BCM_WORKQ_DEBUG */
|
||||
#if defined(BCM_WORKQ_DEBUG)
|
||||
#define WORKQ_ASSERT(exp) ASSERT(exp)
|
||||
#else /* ! BCM_WORKQ_DEBUG */
|
||||
#define WORKQ_ASSERT(exp) do {} while (0)
|
||||
#endif /* ! BCM_WORKQ_DEBUG */
|
||||
|
||||
#define WORKQ_AUDIT(workq) \
|
||||
WORKQ_ASSERT((workq) != BCM_WORKQ_NULL); \
|
||||
WORKQ_ASSERT(WORKQ_PEER(workq) != BCM_WORKQ_NULL); \
|
||||
WORKQ_ASSERT((workq)->buffer == WORKQ_PEER(workq)->buffer); \
|
||||
WORKQ_ASSERT((workq)->ring_size == WORKQ_PEER(workq)->ring_size);
|
||||
|
||||
#define BCM_WORKQ_NULL ((bcm_workq_t *)NULL)
|
||||
|
||||
#define WORKQ_PEER(workq) ((workq)->peer)
|
||||
#define WORKQ_RING(workq) (&((workq)->ring))
|
||||
#define WORKQ_PEER_RING(workq) (&((workq)->peer->ring))
|
||||
|
||||
#define WORKQ_ELEMENT(__elem_type, __workq, __index) ({ \
|
||||
WORKQ_ASSERT((__workq) != BCM_WORKQ_NULL); \
|
||||
WORKQ_ASSERT((__index) < ((__workq)->ring_size)); \
|
||||
((__elem_type *)((__workq)->buffer)) + (__index); \
|
||||
})
|
||||
|
||||
static INLINE void bcm_workq_init(bcm_workq_t *workq, bcm_workq_t *workq_peer,
|
||||
void *buffer, int ring_size);
|
||||
|
||||
static INLINE bool bcm_workq_is_empty(bcm_workq_t *workq_prod);
|
||||
|
||||
static INLINE void bcm_workq_prod_sync(bcm_workq_t *workq_prod);
|
||||
static INLINE void bcm_workq_cons_sync(bcm_workq_t *workq_cons);
|
||||
|
||||
static INLINE void bcm_workq_prod_refresh(bcm_workq_t *workq_prod);
|
||||
static INLINE void bcm_workq_cons_refresh(bcm_workq_t *workq_cons);
|
||||
|
||||
/**
|
||||
* bcm_workq_init - initialize a workq
|
||||
* @workq: pointer to a workq context
|
||||
* @buffer: pointer to a pre-allocated circular buffer to serve as a ring
|
||||
* @ring_size: size of the ring in terms of max number of elements.
|
||||
*/
|
||||
static INLINE void
|
||||
bcm_workq_init(bcm_workq_t *workq, bcm_workq_t *workq_peer,
|
||||
void *buffer, int ring_size)
|
||||
{
|
||||
ASSERT(workq != BCM_WORKQ_NULL);
|
||||
ASSERT(workq_peer != BCM_WORKQ_NULL);
|
||||
ASSERT(buffer != NULL);
|
||||
ASSERT(ring_size > 0);
|
||||
|
||||
WORKQ_PEER(workq) = workq_peer;
|
||||
WORKQ_PEER(workq_peer) = workq;
|
||||
|
||||
bcm_ring_init(WORKQ_RING(workq));
|
||||
bcm_ring_init(WORKQ_RING(workq_peer));
|
||||
|
||||
workq->buffer = workq_peer->buffer = buffer;
|
||||
workq->ring_size = workq_peer->ring_size = ring_size;
|
||||
}
|
||||
|
||||
/**
|
||||
* bcm_workq_empty - test whether there is work
|
||||
* @workq_prod: producer's workq
|
||||
*/
|
||||
static INLINE bool
|
||||
bcm_workq_is_empty(bcm_workq_t *workq_prod)
|
||||
{
|
||||
return bcm_ring_is_empty(WORKQ_RING(workq_prod));
|
||||
}
|
||||
|
||||
/**
|
||||
* bcm_workq_prod_sync - Commit the producer write index to peer workq's ring
|
||||
* @workq_prod: producer's workq whose write index must be synced to peer
|
||||
*/
|
||||
static INLINE void
|
||||
bcm_workq_prod_sync(bcm_workq_t *workq_prod)
|
||||
{
|
||||
WORKQ_AUDIT(workq_prod);
|
||||
|
||||
/* cons::write <--- prod::write */
|
||||
bcm_ring_sync_write(WORKQ_PEER_RING(workq_prod), WORKQ_RING(workq_prod));
|
||||
}
|
||||
|
||||
/**
|
||||
* bcm_workq_cons_sync - Commit the consumer read index to the peer workq's ring
|
||||
* @workq_cons: consumer's workq whose read index must be synced to peer
|
||||
*/
|
||||
static INLINE void
|
||||
bcm_workq_cons_sync(bcm_workq_t *workq_cons)
|
||||
{
|
||||
WORKQ_AUDIT(workq_cons);
|
||||
|
||||
/* prod::read <--- cons::read */
|
||||
bcm_ring_sync_read(WORKQ_PEER_RING(workq_cons), WORKQ_RING(workq_cons));
|
||||
}
|
||||
|
||||
/**
|
||||
* bcm_workq_prod_refresh - Fetch the updated consumer's read index
|
||||
* @workq_prod: producer's workq whose read index must be refreshed from peer
|
||||
*/
|
||||
static INLINE void
|
||||
bcm_workq_prod_refresh(bcm_workq_t *workq_prod)
|
||||
{
|
||||
WORKQ_AUDIT(workq_prod);
|
||||
|
||||
/* prod::read <--- cons::read */
|
||||
bcm_ring_sync_read(WORKQ_RING(workq_prod), WORKQ_PEER_RING(workq_prod));
|
||||
}
|
||||
|
||||
/**
|
||||
* bcm_workq_cons_refresh - Fetch the updated producer's write index
|
||||
* @workq_cons: consumer's workq whose write index must be refreshed from peer
|
||||
*/
|
||||
static INLINE void
|
||||
bcm_workq_cons_refresh(bcm_workq_t *workq_cons)
|
||||
{
|
||||
WORKQ_AUDIT(workq_cons);
|
||||
|
||||
/* cons::write <--- prod::write */
|
||||
bcm_ring_sync_write(WORKQ_RING(workq_cons), WORKQ_PEER_RING(workq_cons));
|
||||
}
|
||||
|
||||
#endif /* ! __bcm_ring_h_included__ */
|
||||
@@ -0,0 +1,91 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Fundamental constants relating to ARP Protocol
|
||||
*
|
||||
* Copyright (C) 1999-2019, 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.
|
||||
*
|
||||
* 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: bcmarp.h 701633 2017-05-25 23:07:17Z $
|
||||
*/
|
||||
|
||||
#ifndef _bcmarp_h_
|
||||
#define _bcmarp_h_
|
||||
|
||||
#ifndef _TYPEDEFS_H_
|
||||
#include <typedefs.h>
|
||||
#endif // endif
|
||||
#include <bcmip.h>
|
||||
|
||||
/* This marks the start of a packed structure section. */
|
||||
#include <packed_section_start.h>
|
||||
|
||||
#define ARP_OPC_OFFSET 6 /* option code offset */
|
||||
#define ARP_SRC_ETH_OFFSET 8 /* src h/w address offset */
|
||||
#define ARP_SRC_IP_OFFSET 14 /* src IP address offset */
|
||||
#define ARP_TGT_ETH_OFFSET 18 /* target h/w address offset */
|
||||
#define ARP_TGT_IP_OFFSET 24 /* target IP address offset */
|
||||
|
||||
#define ARP_OPC_REQUEST 1 /* ARP request */
|
||||
#define ARP_OPC_REPLY 2 /* ARP reply */
|
||||
|
||||
#define ARP_DATA_LEN 28 /* ARP data length */
|
||||
|
||||
#define HTYPE_ETHERNET 1 /* htype for ethernet */
|
||||
BWL_PRE_PACKED_STRUCT struct bcmarp {
|
||||
uint16 htype; /* Header type (1 = ethernet) */
|
||||
uint16 ptype; /* Protocol type (0x800 = IP) */
|
||||
uint8 hlen; /* Hardware address length (Eth = 6) */
|
||||
uint8 plen; /* Protocol address length (IP = 4) */
|
||||
uint16 oper; /* ARP_OPC_... */
|
||||
uint8 src_eth[ETHER_ADDR_LEN]; /* Source hardware address */
|
||||
uint8 src_ip[IPV4_ADDR_LEN]; /* Source protocol address (not aligned) */
|
||||
uint8 dst_eth[ETHER_ADDR_LEN]; /* Destination hardware address */
|
||||
uint8 dst_ip[IPV4_ADDR_LEN]; /* Destination protocol address */
|
||||
} BWL_POST_PACKED_STRUCT;
|
||||
|
||||
/* Ethernet header + Arp message */
|
||||
BWL_PRE_PACKED_STRUCT struct bcmetharp {
|
||||
struct ether_header eh;
|
||||
struct bcmarp arp;
|
||||
} BWL_POST_PACKED_STRUCT;
|
||||
|
||||
/* IPv6 Neighbor Advertisement */
|
||||
#define NEIGHBOR_ADVERTISE_SRC_IPV6_OFFSET 8 /* src IPv6 address offset */
|
||||
#define NEIGHBOR_ADVERTISE_TYPE_OFFSET 40 /* type offset */
|
||||
#define NEIGHBOR_ADVERTISE_CHECKSUM_OFFSET 42 /* check sum offset */
|
||||
#define NEIGHBOR_ADVERTISE_FLAGS_OFFSET 44 /* R,S and O flags offset */
|
||||
#define NEIGHBOR_ADVERTISE_TGT_IPV6_OFFSET 48 /* target IPv6 address offset */
|
||||
#define NEIGHBOR_ADVERTISE_OPTION_OFFSET 64 /* options offset */
|
||||
#define NEIGHBOR_ADVERTISE_TYPE 136
|
||||
#define NEIGHBOR_SOLICITATION_TYPE 135
|
||||
|
||||
#define OPT_TYPE_SRC_LINK_ADDR 1
|
||||
#define OPT_TYPE_TGT_LINK_ADDR 2
|
||||
|
||||
#define NEIGHBOR_ADVERTISE_DATA_LEN 72 /* neighbor advertisement data length */
|
||||
#define NEIGHBOR_ADVERTISE_FLAGS_VALUE 0x60 /* R=0, S=1 and O=1 */
|
||||
|
||||
/* This marks the end of a packed structure section. */
|
||||
#include <packed_section_end.h>
|
||||
|
||||
#endif /* !defined(_bcmarp_h_) */
|
||||
@@ -0,0 +1,80 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Bloom filter support
|
||||
*
|
||||
* Copyright (C) 1999-2019, 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.
|
||||
*
|
||||
* 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: bcmbloom.h 714397 2017-08-04 08:24:38Z $
|
||||
*/
|
||||
|
||||
#ifndef _bcmbloom_h_
|
||||
#define _bcmbloom_h_
|
||||
|
||||
#include <typedefs.h>
|
||||
#ifdef BCMDRIVER
|
||||
#include <osl.h>
|
||||
#else
|
||||
#include <stddef.h> /* For size_t */
|
||||
#endif // endif
|
||||
|
||||
struct bcm_bloom_filter;
|
||||
typedef struct bcm_bloom_filter bcm_bloom_filter_t;
|
||||
|
||||
typedef void* (*bcm_bloom_alloc_t)(void *ctx, uint size);
|
||||
typedef void (*bcm_bloom_free_t)(void *ctx, void *buf, uint size);
|
||||
typedef uint (*bcm_bloom_hash_t)(void* ctx, uint idx, const uint8 *tag, uint len);
|
||||
|
||||
/* create/allocate a bloom filter. filter size can be 0 for validate only filters */
|
||||
int bcm_bloom_create(bcm_bloom_alloc_t alloc_cb,
|
||||
bcm_bloom_free_t free_cb, void *callback_ctx, uint max_hash,
|
||||
uint filter_size /* bytes */, bcm_bloom_filter_t **bloom);
|
||||
|
||||
/* destroy bloom filter */
|
||||
int bcm_bloom_destroy(bcm_bloom_filter_t **bloom, bcm_bloom_free_t free_cb);
|
||||
|
||||
/* add a hash function to filter, return an index */
|
||||
int bcm_bloom_add_hash(bcm_bloom_filter_t *filter, bcm_bloom_hash_t hash, uint *idx);
|
||||
|
||||
/* remove the hash function at index from filter */
|
||||
int bcm_bloom_remove_hash(bcm_bloom_filter_t *filter, uint idx);
|
||||
|
||||
/* check if given tag is member of the filter. If buf is NULL and/or buf_len is 0
|
||||
* then use the internal state. BCME_OK if member, BCME_NOTFOUND if not,
|
||||
* or other error (e.g. BADARG)
|
||||
*/
|
||||
bool bcm_bloom_is_member(bcm_bloom_filter_t *filter,
|
||||
const uint8 *tag, uint tag_len, const uint8 *buf, uint buf_len);
|
||||
|
||||
/* add a member to the filter. invalid for validate_only filters */
|
||||
int bcm_bloom_add_member(bcm_bloom_filter_t *filter, const uint8 *tag, uint tag_len);
|
||||
|
||||
/* no support for remove member */
|
||||
|
||||
/* get the filter data from state. BCME_BUFTOOSHORT w/ required length in buf_len
|
||||
* if supplied size is insufficient
|
||||
*/
|
||||
int bcm_bloom_get_filter_data(bcm_bloom_filter_t *filter,
|
||||
uint buf_size, uint8 *buf, uint *buf_len);
|
||||
|
||||
#endif /* _bcmbloom_h_ */
|
||||
@@ -0,0 +1,122 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* CDC network driver ioctl/indication encoding
|
||||
* Broadcom 802.11abg Networking Device Driver
|
||||
*
|
||||
* Definitions subject to change without notice.
|
||||
*
|
||||
* Copyright (C) 1999-2019, 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.
|
||||
*
|
||||
* 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: bcmcdc.h 700076 2017-05-17 14:42:22Z $
|
||||
*/
|
||||
#ifndef _bcmcdc_h_
|
||||
#define _bcmcdc_h_
|
||||
#include <ethernet.h>
|
||||
|
||||
typedef struct cdc_ioctl {
|
||||
uint32 cmd; /* ioctl command value */
|
||||
uint32 len; /* lower 16: output buflen; upper 16: input buflen (excludes header) */
|
||||
uint32 flags; /* flag defns given below */
|
||||
uint32 status; /* status code returned from the device */
|
||||
} cdc_ioctl_t;
|
||||
|
||||
/* Max valid buffer size that can be sent to the dongle */
|
||||
#define CDC_MAX_MSG_SIZE ETHER_MAX_LEN
|
||||
|
||||
/* len field is divided into input and output buffer lengths */
|
||||
#define CDCL_IOC_OUTLEN_MASK 0x0000FFFF /* maximum or expected response length, */
|
||||
/* excluding IOCTL header */
|
||||
#define CDCL_IOC_OUTLEN_SHIFT 0
|
||||
#define CDCL_IOC_INLEN_MASK 0xFFFF0000 /* input buffer length, excluding IOCTL header */
|
||||
#define CDCL_IOC_INLEN_SHIFT 16
|
||||
|
||||
/* CDC flag definitions */
|
||||
#define CDCF_IOC_ERROR 0x01 /* 0=success, 1=ioctl cmd failed */
|
||||
#define CDCF_IOC_SET 0x02 /* 0=get, 1=set cmd */
|
||||
#define CDCF_IOC_OVL_IDX_MASK 0x3c /* overlay region index mask */
|
||||
#define CDCF_IOC_OVL_RSV 0x40 /* 1=reserve this overlay region */
|
||||
#define CDCF_IOC_OVL 0x80 /* 1=this ioctl corresponds to an overlay */
|
||||
#define CDCF_IOC_ACTION_MASK 0xfe /* SET/GET, OVL_IDX, OVL_RSV, OVL mask */
|
||||
#define CDCF_IOC_ACTION_SHIFT 1 /* SET/GET, OVL_IDX, OVL_RSV, OVL shift */
|
||||
#define CDCF_IOC_IF_MASK 0xF000 /* I/F index */
|
||||
#define CDCF_IOC_IF_SHIFT 12
|
||||
#define CDCF_IOC_ID_MASK 0xFFFF0000 /* used to uniquely id an ioctl req/resp pairing */
|
||||
#define CDCF_IOC_ID_SHIFT 16 /* # of bits of shift for ID Mask */
|
||||
|
||||
#define CDC_IOC_IF_IDX(flags) (((flags) & CDCF_IOC_IF_MASK) >> CDCF_IOC_IF_SHIFT)
|
||||
#define CDC_IOC_ID(flags) (((flags) & CDCF_IOC_ID_MASK) >> CDCF_IOC_ID_SHIFT)
|
||||
|
||||
#define CDC_GET_IF_IDX(hdr) \
|
||||
((int)((((hdr)->flags) & CDCF_IOC_IF_MASK) >> CDCF_IOC_IF_SHIFT))
|
||||
#define CDC_SET_IF_IDX(hdr, idx) \
|
||||
((hdr)->flags = (((hdr)->flags & ~CDCF_IOC_IF_MASK) | ((idx) << CDCF_IOC_IF_SHIFT)))
|
||||
|
||||
/*
|
||||
* BDC header
|
||||
*
|
||||
* The BDC header is used on data packets to convey priority across USB.
|
||||
*/
|
||||
|
||||
struct bdc_header {
|
||||
uint8 flags; /* Flags */
|
||||
uint8 priority; /* 802.1d Priority 0:2 bits, 4:7 USB flow control info */
|
||||
uint8 flags2;
|
||||
uint8 dataOffset; /* Offset from end of BDC header to packet data, in
|
||||
* 4-byte words. Leaves room for optional headers.
|
||||
*/
|
||||
};
|
||||
|
||||
#define BDC_HEADER_LEN 4
|
||||
|
||||
/* flags field bitmap */
|
||||
#define BDC_FLAG_EXEMPT 0x03 /* EXT_STA: encryption exemption (host -> dongle?) */
|
||||
#define BDC_FLAG_80211_PKT 0x01 /* Packet is in 802.11 format (dongle -> host) */
|
||||
#define BDC_FLAG_SUM_GOOD 0x04 /* Dongle has verified good RX checksums */
|
||||
#define BDC_FLAG_SUM_NEEDED 0x08 /* Dongle needs to do TX checksums: host->device */
|
||||
#define BDC_FLAG_EVENT_MSG 0x08 /* Payload contains an event msg: device->host */
|
||||
#define BDC_FLAG_VER_MASK 0xf0 /* Protocol version mask */
|
||||
#define BDC_FLAG_VER_SHIFT 4 /* Protocol version shift */
|
||||
|
||||
/* priority field bitmap */
|
||||
#define BDC_PRIORITY_MASK 0x07
|
||||
#define BDC_PRIORITY_FC_MASK 0xf0 /* flow control info mask */
|
||||
#define BDC_PRIORITY_FC_SHIFT 4 /* flow control info shift */
|
||||
|
||||
/* flags2 field bitmap */
|
||||
#define BDC_FLAG2_IF_MASK 0x0f /* interface index (host <-> dongle) */
|
||||
#define BDC_FLAG2_IF_SHIFT 0
|
||||
#define BDC_FLAG2_FC_FLAG 0x10 /* flag to indicate if pkt contains */
|
||||
/* FLOW CONTROL info only */
|
||||
|
||||
/* version numbers */
|
||||
#define BDC_PROTO_VER_1 1 /* Old Protocol version */
|
||||
#define BDC_PROTO_VER 2 /* Protocol version */
|
||||
|
||||
/* flags2.if field access macros */
|
||||
#define BDC_GET_IF_IDX(hdr) \
|
||||
((int)((((hdr)->flags2) & BDC_FLAG2_IF_MASK) >> BDC_FLAG2_IF_SHIFT))
|
||||
#define BDC_SET_IF_IDX(hdr, idx) \
|
||||
((hdr)->flags2 = (((hdr)->flags2 & ~BDC_FLAG2_IF_MASK) | ((idx) << BDC_FLAG2_IF_SHIFT)))
|
||||
|
||||
#endif /* _bcmcdc_h_ */
|
||||
@@ -0,0 +1,616 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Misc system wide definitions
|
||||
*
|
||||
* Copyright (C) 1999-2019, 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.
|
||||
*
|
||||
* 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: bcmdefs.h 788740 2018-11-13 21:45:01Z $
|
||||
*/
|
||||
|
||||
#ifndef _bcmdefs_h_
|
||||
#define _bcmdefs_h_
|
||||
|
||||
/*
|
||||
* One doesn't need to include this file explicitly, gets included automatically if
|
||||
* typedefs.h is included.
|
||||
*/
|
||||
|
||||
/* Use BCM_REFERENCE to suppress warnings about intentionally-unused function
|
||||
* arguments or local variables.
|
||||
*/
|
||||
#define BCM_REFERENCE(data) ((void)(data))
|
||||
|
||||
/* Allow for suppressing unused variable warnings. */
|
||||
#ifdef __GNUC__
|
||||
#define UNUSED_VAR __attribute__ ((unused))
|
||||
#else
|
||||
#define UNUSED_VAR
|
||||
#endif // endif
|
||||
|
||||
/* GNU GCC 4.6+ supports selectively turning off a warning.
|
||||
* Define these diagnostic macros to help suppress cast-qual warning
|
||||
* until all the work can be done to fix the casting issues.
|
||||
*/
|
||||
#if (defined(__GNUC__) && defined(STRICT_GCC_WARNINGS) && (__GNUC__ > 4 || (__GNUC__ == \
|
||||
4 && __GNUC_MINOR__ >= 6)))
|
||||
#define GCC_DIAGNOSTIC_PUSH_SUPPRESS_CAST() \
|
||||
_Pragma("GCC diagnostic push") \
|
||||
_Pragma("GCC diagnostic ignored \"-Wcast-qual\"")
|
||||
#define GCC_DIAGNOSTIC_POP() \
|
||||
_Pragma("GCC diagnostic pop")
|
||||
#else
|
||||
#define GCC_DIAGNOSTIC_PUSH_SUPPRESS_CAST()
|
||||
#define GCC_DIAGNOSTIC_POP()
|
||||
#endif /* Diagnostic macros not defined */
|
||||
|
||||
/* Support clang for MACOSX compiler */
|
||||
#ifdef __clang__
|
||||
#define CLANG_DIAGNOSTIC_PUSH_SUPPRESS_CAST() \
|
||||
_Pragma("clang diagnostic push") \
|
||||
_Pragma("clang diagnostic ignored \"-Wcast-qual\"")
|
||||
#define CLANG_DIAGNOSTIC_PUSH_SUPPRESS_FORMAT() \
|
||||
_Pragma("clang diagnostic push") \
|
||||
_Pragma("clang diagnostic ignored \"-Wformat-nonliteral\"")
|
||||
#define CLANG_DIAGNOSTIC_POP() \
|
||||
_Pragma("clang diagnostic pop")
|
||||
#else
|
||||
#define CLANG_DIAGNOSTIC_PUSH_SUPPRESS_CAST()
|
||||
#define CLANG_DIAGNOSTIC_PUSH_SUPPRESS_FORMAT()
|
||||
#define CLANG_DIAGNOSTIC_POP()
|
||||
#endif // endif
|
||||
/* Compile-time assert can be used in place of ASSERT if the expression evaluates
|
||||
* to a constant at compile time.
|
||||
*/
|
||||
#define STATIC_ASSERT(expr) { \
|
||||
/* Make sure the expression is constant. */ \
|
||||
typedef enum { _STATIC_ASSERT_NOT_CONSTANT = (expr) } _static_assert_e UNUSED_VAR; \
|
||||
/* Make sure the expression is true. */ \
|
||||
typedef char STATIC_ASSERT_FAIL[(expr) ? 1 : -1] UNUSED_VAR; \
|
||||
}
|
||||
|
||||
/* Reclaiming text and data :
|
||||
* The following macros specify special linker sections that can be reclaimed
|
||||
* after a system is considered 'up'.
|
||||
* BCMATTACHFN is also used for detach functions (it's not worth having a BCMDETACHFN,
|
||||
* as in most cases, the attach function calls the detach function to clean up on error).
|
||||
*/
|
||||
#if defined(BCM_RECLAIM)
|
||||
|
||||
extern bool bcm_reclaimed;
|
||||
extern bool bcm_attach_part_reclaimed;
|
||||
extern bool bcm_preattach_part_reclaimed;
|
||||
extern bool bcm_postattach_part_reclaimed;
|
||||
|
||||
#define RECLAIMED() (bcm_reclaimed)
|
||||
#define ATTACH_PART_RECLAIMED() (bcm_attach_part_reclaimed)
|
||||
#define PREATTACH_PART_RECLAIMED() (bcm_preattach_part_reclaimed)
|
||||
#define POSTATTACH_PART_RECLAIMED() (bcm_postattach_part_reclaimed)
|
||||
|
||||
#if defined(BCM_RECLAIM_ATTACH_FN_DATA)
|
||||
#define _data __attribute__ ((__section__ (".dataini2." #_data))) _data
|
||||
#define _fn __attribute__ ((__section__ (".textini2." #_fn), noinline)) _fn
|
||||
|
||||
/* Relocate attach symbols to save-restore region to increase pre-reclaim heap size. */
|
||||
#define BCM_SRM_ATTACH_DATA(_data) __attribute__ ((__section__ (".datasrm." #_data))) _data
|
||||
#define BCM_SRM_ATTACH_FN(_fn) __attribute__ ((__section__ (".textsrm." #_fn), noinline)) _fn
|
||||
|
||||
#ifndef PREATTACH_NORECLAIM
|
||||
#define BCMPREATTACHDATA(_data) __attribute__ ((__section__ (".dataini3." #_data))) _data
|
||||
#define BCMPREATTACHFN(_fn) __attribute__ ((__section__ (".textini3." #_fn), noinline)) _fn
|
||||
#else
|
||||
#define BCMPREATTACHDATA(_data) __attribute__ ((__section__ (".dataini2." #_data))) _data
|
||||
#define BCMPREATTACHFN(_fn) __attribute__ ((__section__ (".textini2." #_fn), noinline)) _fn
|
||||
#endif /* PREATTACH_NORECLAIM */
|
||||
#define BCMPOSTATTACHDATA(_data) __attribute__ ((__section__ (".dataini5." #_data))) _data
|
||||
#define BCMPOSTATTACHFN(_fn) __attribute__ ((__section__ (".textini5." #_fn), noinline)) _fn
|
||||
#else /* BCM_RECLAIM_ATTACH_FN_DATA */
|
||||
#define _data _data
|
||||
#define _fn _fn
|
||||
#define BCMPREATTACHDATA(_data) _data
|
||||
#define BCMPREATTACHFN(_fn) _fn
|
||||
#define BCMPOSTATTACHDATA(_data) _data
|
||||
#define BCMPOSTATTACHFN(_fn) _fn
|
||||
#endif /* BCM_RECLAIM_ATTACH_FN_DATA */
|
||||
|
||||
#ifdef BCMDBG_SR
|
||||
/*
|
||||
* Don't reclaim so we can compare SR ASM
|
||||
*/
|
||||
#define BCMPREATTACHDATASR(_data) _data
|
||||
#define BCMPREATTACHFNSR(_fn) _fn
|
||||
#define BCMATTACHDATASR(_data) _data
|
||||
#define BCMATTACHFNSR(_fn) _fn
|
||||
#else
|
||||
#define BCMPREATTACHDATASR(_data) BCMPREATTACHDATA(_data)
|
||||
#define BCMPREATTACHFNSR(_fn) BCMPREATTACHFN(_fn)
|
||||
#define BCMATTACHDATASR(_data) _data
|
||||
#define BCMATTACHFNSR(_fn) _fn
|
||||
#endif // endif
|
||||
|
||||
#if defined(BCM_RECLAIM_INIT_FN_DATA)
|
||||
#define _data __attribute__ ((__section__ (".dataini1." #_data))) _data
|
||||
#define _fn __attribute__ ((__section__ (".textini1." #_fn), noinline)) _fn
|
||||
#define CONST
|
||||
#else /* BCM_RECLAIM_INIT_FN_DATA */
|
||||
#define _data _data
|
||||
#define _fn _fn
|
||||
#ifndef CONST
|
||||
#define CONST const
|
||||
#endif // endif
|
||||
#endif /* BCM_RECLAIM_INIT_FN_DATA */
|
||||
|
||||
/* Non-manufacture or internal attach function/dat */
|
||||
#define BCMNMIATTACHFN(_fn) _fn
|
||||
#define BCMNMIATTACHDATA(_data) _data
|
||||
|
||||
#if defined(BCM_CISDUMP_NO_RECLAIM)
|
||||
#define BCMCISDUMPATTACHFN(_fn) _fn
|
||||
#define BCMCISDUMPATTACHDATA(_data) _data
|
||||
#else
|
||||
#define BCMCISDUMPATTACHFN(_fn) BCMNMIATTACHFN(_fn)
|
||||
#define BCMCISDUMPATTACHDATA(_data) BCMNMIATTACHDATA(_data)
|
||||
#endif // endif
|
||||
|
||||
/* SROM with OTP support */
|
||||
#if defined(BCMOTPSROM)
|
||||
#define BCMSROMATTACHFN(_fn) _fn
|
||||
#define BCMSROMATTACHDATA(_data) _data
|
||||
#else
|
||||
#define BCMSROMATTACHFN(_fn) BCMNMIATTACHFN(_fn)
|
||||
#define BCMSROMATTACHDATA(_data) BCMNMIATTACHFN(_data)
|
||||
#endif /* BCMOTPSROM */
|
||||
|
||||
#if defined(BCM_CISDUMP_NO_RECLAIM)
|
||||
#define BCMSROMCISDUMPATTACHFN(_fn) _fn
|
||||
#define BCMSROMCISDUMPATTACHDATA(_data) _data
|
||||
#else
|
||||
#define BCMSROMCISDUMPATTACHFN(_fn) BCMSROMATTACHFN(_fn)
|
||||
#define BCMSROMCISDUMPATTACHDATA(_data) BCMSROMATTACHDATA(_data)
|
||||
#endif /* BCM_CISDUMP_NO_RECLAIM */
|
||||
|
||||
#ifdef BCMNODOWN
|
||||
#define _fn _fn
|
||||
#else
|
||||
#define _fn _fn
|
||||
#endif // endif
|
||||
|
||||
#else /* BCM_RECLAIM */
|
||||
|
||||
#define bcm_reclaimed (1)
|
||||
#define bcm_attach_part_reclaimed (1)
|
||||
#define bcm_preattach_part_reclaimed (1)
|
||||
#define bcm_postattach_part_reclaimed (1)
|
||||
#define _data _data
|
||||
#define _fn _fn
|
||||
#define BCM_SRM_ATTACH_DATA(_data) _data
|
||||
#define BCM_SRM_ATTACH_FN(_fn) _fn
|
||||
#define BCMPREATTACHDATA(_data) _data
|
||||
#define BCMPREATTACHFN(_fn) _fn
|
||||
#define BCMPOSTATTACHDATA(_data) _data
|
||||
#define BCMPOSTATTACHFN(_fn) _fn
|
||||
#define _data _data
|
||||
#define _fn _fn
|
||||
#define _fn _fn
|
||||
#define BCMNMIATTACHFN(_fn) _fn
|
||||
#define BCMNMIATTACHDATA(_data) _data
|
||||
#define BCMSROMATTACHFN(_fn) _fn
|
||||
#define BCMSROMATTACHDATA(_data) _data
|
||||
#define BCMPREATTACHFNSR(_fn) _fn
|
||||
#define BCMPREATTACHDATASR(_data) _data
|
||||
#define BCMATTACHFNSR(_fn) _fn
|
||||
#define BCMATTACHDATASR(_data) _data
|
||||
#define BCMSROMATTACHFN(_fn) _fn
|
||||
#define BCMSROMATTACHDATA(_data) _data
|
||||
#define BCMCISDUMPATTACHFN(_fn) _fn
|
||||
#define BCMCISDUMPATTACHDATA(_data) _data
|
||||
#define BCMSROMCISDUMPATTACHFN(_fn) _fn
|
||||
#define BCMSROMCISDUMPATTACHDATA(_data) _data
|
||||
#define CONST const
|
||||
|
||||
#define RECLAIMED() (bcm_reclaimed)
|
||||
#define ATTACH_PART_RECLAIMED() (bcm_attach_part_reclaimed)
|
||||
#define PREATTACH_PART_RECLAIMED() (bcm_preattach_part_reclaimed)
|
||||
#define POSTATTACH_PART_RECLAIMED() (bcm_postattach_part_reclaimed)
|
||||
|
||||
#endif /* BCM_RECLAIM */
|
||||
|
||||
#define BCMUCODEDATA(_data) _data
|
||||
|
||||
#if defined(BCM_DMA_CT) && !defined(BCM_DMA_CT_DISABLED)
|
||||
#define BCMUCODEFN(_fn) _fn
|
||||
#else
|
||||
#define BCMUCODEFN(_fn) _fn
|
||||
#endif /* BCM_DMA_CT */
|
||||
|
||||
#if !defined STB
|
||||
#undef BCM47XX_CA9
|
||||
#endif /* STB */
|
||||
|
||||
/* BCMFASTPATH Related Macro defines
|
||||
*/
|
||||
#ifndef BCMFASTPATH
|
||||
#if defined(STB)
|
||||
#define BCMFASTPATH __attribute__ ((__section__ (".text.fastpath")))
|
||||
#define BCMFASTPATH_HOST __attribute__ ((__section__ (".text.fastpath_host")))
|
||||
#else /* mips || BCM47XX_CA9 || STB */
|
||||
#define BCMFASTPATH
|
||||
#define BCMFASTPATH_HOST
|
||||
#endif // endif
|
||||
#endif /* BCMFASTPATH */
|
||||
|
||||
/* Use the BCMRAMFN() macro to tag functions in source that must be included in RAM (excluded from
|
||||
* ROM). This should eliminate the need to manually specify these functions in the ROM config file.
|
||||
* It should only be used in special cases where the function must be in RAM for *all* ROM-based
|
||||
* chips.
|
||||
*/
|
||||
#define BCMRAMFN(_fn) _fn
|
||||
|
||||
/* Use BCMSPECSYM() macro to tag symbols going to a special output section in the binary. */
|
||||
#define BCMSPECSYM(_sym) __attribute__ ((__section__ (".special." #_sym))) _sym
|
||||
|
||||
#define STATIC static
|
||||
|
||||
/* Bus types */
|
||||
#define SI_BUS 0 /* SOC Interconnect */
|
||||
#define PCI_BUS 1 /* PCI target */
|
||||
#define PCMCIA_BUS 2 /* PCMCIA target */
|
||||
#define SDIO_BUS 3 /* SDIO target */
|
||||
#define JTAG_BUS 4 /* JTAG */
|
||||
#define USB_BUS 5 /* USB (does not support R/W REG) */
|
||||
#define SPI_BUS 6 /* gSPI target */
|
||||
#define RPC_BUS 7 /* RPC target */
|
||||
|
||||
/* Allows size optimization for single-bus image */
|
||||
#ifdef BCMBUSTYPE
|
||||
#define BUSTYPE(bus) (BCMBUSTYPE)
|
||||
#else
|
||||
#define BUSTYPE(bus) (bus)
|
||||
#endif // endif
|
||||
|
||||
#ifdef BCMBUSCORETYPE
|
||||
#define BUSCORETYPE(ct) (BCMBUSCORETYPE)
|
||||
#else
|
||||
#define BUSCORETYPE(ct) (ct)
|
||||
#endif // endif
|
||||
|
||||
/* Allows size optimization for single-backplane image */
|
||||
#ifdef BCMCHIPTYPE
|
||||
#define CHIPTYPE(bus) (BCMCHIPTYPE)
|
||||
#else
|
||||
#define CHIPTYPE(bus) (bus)
|
||||
#endif // endif
|
||||
|
||||
/* Allows size optimization for SPROM support */
|
||||
#if defined(BCMSPROMBUS)
|
||||
#define SPROMBUS (BCMSPROMBUS)
|
||||
#elif defined(SI_PCMCIA_SROM)
|
||||
#define SPROMBUS (PCMCIA_BUS)
|
||||
#else
|
||||
#define SPROMBUS (PCI_BUS)
|
||||
#endif // endif
|
||||
|
||||
/* Allows size optimization for single-chip image */
|
||||
#ifdef BCMCHIPID
|
||||
#define CHIPID(chip) (BCMCHIPID)
|
||||
#else
|
||||
#define CHIPID(chip) (chip)
|
||||
#endif // endif
|
||||
|
||||
#ifdef BCMCHIPREV
|
||||
#define CHIPREV(rev) (BCMCHIPREV)
|
||||
#else
|
||||
#define CHIPREV(rev) (rev)
|
||||
#endif // endif
|
||||
|
||||
#ifdef BCMPCIEREV
|
||||
#define PCIECOREREV(rev) (BCMPCIEREV)
|
||||
#else
|
||||
#define PCIECOREREV(rev) (rev)
|
||||
#endif // endif
|
||||
|
||||
#ifdef BCMPMUREV
|
||||
#define PMUREV(rev) (BCMPMUREV)
|
||||
#else
|
||||
#define PMUREV(rev) (rev)
|
||||
#endif // endif
|
||||
|
||||
#ifdef BCMCCREV
|
||||
#define CCREV(rev) (BCMCCREV)
|
||||
#else
|
||||
#define CCREV(rev) (rev)
|
||||
#endif // endif
|
||||
|
||||
#ifdef BCMGCIREV
|
||||
#define GCIREV(rev) (BCMGCIREV)
|
||||
#else
|
||||
#define GCIREV(rev) (rev)
|
||||
#endif // endif
|
||||
|
||||
#ifdef BCMCR4REV
|
||||
#define CR4REV (BCMCR4REV)
|
||||
#endif // endif
|
||||
|
||||
/* Defines for DMA Address Width - Shared between OSL and HNDDMA */
|
||||
#define DMADDR_MASK_32 0x0 /* Address mask for 32-bits */
|
||||
#define DMADDR_MASK_30 0xc0000000 /* Address mask for 30-bits */
|
||||
#define DMADDR_MASK_26 0xFC000000 /* Address maks for 26-bits */
|
||||
#define DMADDR_MASK_0 0xffffffff /* Address mask for 0-bits (hi-part) */
|
||||
|
||||
#define DMADDRWIDTH_26 26 /* 26-bit addressing capability */
|
||||
#define DMADDRWIDTH_30 30 /* 30-bit addressing capability */
|
||||
#define DMADDRWIDTH_32 32 /* 32-bit addressing capability */
|
||||
#define DMADDRWIDTH_63 63 /* 64-bit addressing capability */
|
||||
#define DMADDRWIDTH_64 64 /* 64-bit addressing capability */
|
||||
|
||||
typedef struct {
|
||||
uint32 loaddr;
|
||||
uint32 hiaddr;
|
||||
} dma64addr_t;
|
||||
|
||||
#define PHYSADDR64HI(_pa) ((_pa).hiaddr)
|
||||
#define PHYSADDR64HISET(_pa, _val) \
|
||||
do { \
|
||||
(_pa).hiaddr = (_val); \
|
||||
} while (0)
|
||||
#define PHYSADDR64LO(_pa) ((_pa).loaddr)
|
||||
#define PHYSADDR64LOSET(_pa, _val) \
|
||||
do { \
|
||||
(_pa).loaddr = (_val); \
|
||||
} while (0)
|
||||
|
||||
#ifdef BCMDMA64OSL
|
||||
typedef dma64addr_t dmaaddr_t;
|
||||
#define PHYSADDRHI(_pa) PHYSADDR64HI(_pa)
|
||||
#define PHYSADDRHISET(_pa, _val) PHYSADDR64HISET(_pa, _val)
|
||||
#define PHYSADDRLO(_pa) PHYSADDR64LO(_pa)
|
||||
#define PHYSADDRLOSET(_pa, _val) PHYSADDR64LOSET(_pa, _val)
|
||||
#define PHYSADDRTOULONG(_pa, _ulong) \
|
||||
do { \
|
||||
_ulong = ((unsigned long long)(_pa).hiaddr << 32) | ((_pa).loaddr); \
|
||||
} while (0)
|
||||
|
||||
#else
|
||||
typedef unsigned long dmaaddr_t;
|
||||
#define PHYSADDRHI(_pa) (0)
|
||||
#define PHYSADDRHISET(_pa, _val)
|
||||
#define PHYSADDRLO(_pa) ((_pa))
|
||||
#define PHYSADDRLOSET(_pa, _val) \
|
||||
do { \
|
||||
(_pa) = (_val); \
|
||||
} while (0)
|
||||
#endif /* BCMDMA64OSL */
|
||||
#define PHYSADDRISZERO(_pa) (PHYSADDRLO(_pa) == 0 && PHYSADDRHI(_pa) == 0)
|
||||
|
||||
/* One physical DMA segment */
|
||||
typedef struct {
|
||||
dmaaddr_t addr;
|
||||
uint32 length;
|
||||
} hnddma_seg_t;
|
||||
|
||||
#define MAX_DMA_SEGS 8
|
||||
|
||||
typedef struct {
|
||||
void *oshdmah; /* Opaque handle for OSL to store its information */
|
||||
uint origsize; /* Size of the virtual packet */
|
||||
uint nsegs;
|
||||
hnddma_seg_t segs[MAX_DMA_SEGS];
|
||||
} hnddma_seg_map_t;
|
||||
|
||||
/* packet headroom necessary to accommodate the largest header in the system, (i.e TXOFF).
|
||||
* By doing, we avoid the need to allocate an extra buffer for the header when bridging to WL.
|
||||
* There is a compile time check in wlc.c which ensure that this value is at least as big
|
||||
* as TXOFF. This value is used in dma_rxfill (hnddma.c).
|
||||
*/
|
||||
|
||||
#if defined(BCM_RPC_NOCOPY) || defined(BCM_RCP_TXNOCOPY)
|
||||
/* add 40 bytes to allow for extra RPC header and info */
|
||||
#define BCMEXTRAHDROOM 260
|
||||
#else /* BCM_RPC_NOCOPY || BCM_RPC_TXNOCOPY */
|
||||
#if defined(STB)
|
||||
#define BCMEXTRAHDROOM 224
|
||||
#else
|
||||
#define BCMEXTRAHDROOM 204
|
||||
#endif // endif
|
||||
#endif /* BCM_RPC_NOCOPY || BCM_RPC_TXNOCOPY */
|
||||
|
||||
/* Packet alignment for most efficient SDIO (can change based on platform) */
|
||||
#ifndef SDALIGN
|
||||
#define SDALIGN 32
|
||||
#endif // endif
|
||||
|
||||
/* Headroom required for dongle-to-host communication. Packets allocated
|
||||
* locally in the dongle (e.g. for CDC ioctls or RNDIS messages) should
|
||||
* leave this much room in front for low-level message headers which may
|
||||
* be needed to get across the dongle bus to the host. (These messages
|
||||
* don't go over the network, so room for the full WL header above would
|
||||
* be a waste.).
|
||||
*/
|
||||
#define BCMDONGLEHDRSZ 12
|
||||
#define BCMDONGLEPADSZ 16
|
||||
|
||||
#define BCMDONGLEOVERHEAD (BCMDONGLEHDRSZ + BCMDONGLEPADSZ)
|
||||
|
||||
#if defined(NO_BCMDBG_ASSERT)
|
||||
# undef BCMDBG_ASSERT
|
||||
# undef BCMASSERT_LOG
|
||||
#endif // endif
|
||||
|
||||
#if defined(BCMASSERT_LOG)
|
||||
#define BCMASSERT_SUPPORT
|
||||
#endif // endif
|
||||
|
||||
/* Macros for doing definition and get/set of bitfields
|
||||
* Usage example, e.g. a three-bit field (bits 4-6):
|
||||
* #define <NAME>_M BITFIELD_MASK(3)
|
||||
* #define <NAME>_S 4
|
||||
* ...
|
||||
* regval = R_REG(osh, ®s->regfoo);
|
||||
* field = GFIELD(regval, <NAME>);
|
||||
* regval = SFIELD(regval, <NAME>, 1);
|
||||
* W_REG(osh, ®s->regfoo, regval);
|
||||
*/
|
||||
#define BITFIELD_MASK(width) \
|
||||
(((unsigned)1 << (width)) - 1)
|
||||
#define GFIELD(val, field) \
|
||||
(((val) >> field ## _S) & field ## _M)
|
||||
#define SFIELD(val, field, bits) \
|
||||
(((val) & (~(field ## _M << field ## _S))) | \
|
||||
((unsigned)(bits) << field ## _S))
|
||||
|
||||
/* define BCMSMALL to remove misc features for memory-constrained environments */
|
||||
#ifdef BCMSMALL
|
||||
#undef BCMSPACE
|
||||
#define bcmspace FALSE /* if (bcmspace) code is discarded */
|
||||
#else
|
||||
#define BCMSPACE
|
||||
#define bcmspace TRUE /* if (bcmspace) code is retained */
|
||||
#endif // endif
|
||||
|
||||
/* Max. nvram variable table size */
|
||||
#ifndef MAXSZ_NVRAM_VARS
|
||||
#ifdef LARGE_NVRAM_MAXSZ
|
||||
#define MAXSZ_NVRAM_VARS (LARGE_NVRAM_MAXSZ * 2)
|
||||
#else
|
||||
#define LARGE_NVRAM_MAXSZ 8192
|
||||
#define MAXSZ_NVRAM_VARS (LARGE_NVRAM_MAXSZ * 2)
|
||||
#endif /* LARGE_NVRAM_MAXSZ */
|
||||
#endif /* !MAXSZ_NVRAM_VARS */
|
||||
|
||||
/* ROM_ENAB_RUNTIME_CHECK may be set based upon the #define below (for ROM builds). It may also
|
||||
* be defined via makefiles (e.g. ROM auto abandon unoptimized compiles).
|
||||
*/
|
||||
|
||||
#ifdef BCMLFRAG /* BCMLFRAG support enab macros */
|
||||
extern bool _bcmlfrag;
|
||||
#if defined(ROM_ENAB_RUNTIME_CHECK) || !defined(DONGLEBUILD)
|
||||
#define BCMLFRAG_ENAB() (_bcmlfrag)
|
||||
#elif defined(BCMLFRAG_DISABLED)
|
||||
#define BCMLFRAG_ENAB() (0)
|
||||
#else
|
||||
#define BCMLFRAG_ENAB() (1)
|
||||
#endif
|
||||
#else
|
||||
#define BCMLFRAG_ENAB() (0)
|
||||
#endif /* BCMLFRAG_ENAB */
|
||||
|
||||
#ifdef BCMPCIEDEV /* BCMPCIEDEV support enab macros */
|
||||
extern bool _pciedevenab;
|
||||
#if defined(ROM_ENAB_RUNTIME_CHECK)
|
||||
#define BCMPCIEDEV_ENAB() (_pciedevenab)
|
||||
#elif defined(BCMPCIEDEV_ENABLED)
|
||||
#define BCMPCIEDEV_ENAB() 1
|
||||
#else
|
||||
#define BCMPCIEDEV_ENAB() 0
|
||||
#endif
|
||||
#else
|
||||
#define BCMPCIEDEV_ENAB() 0
|
||||
#endif /* BCMPCIEDEV */
|
||||
|
||||
#ifdef BCMRESVFRAGPOOL /* BCMRESVFRAGPOOL support enab macros */
|
||||
extern bool _resvfragpool_enab;
|
||||
#if defined(ROM_ENAB_RUNTIME_CHECK) || !defined(DONGLEBUILD)
|
||||
#define BCMRESVFRAGPOOL_ENAB() (_resvfragpool_enab)
|
||||
#elif defined(BCMRESVFRAGPOOL_ENABLED)
|
||||
#define BCMRESVFRAGPOOL_ENAB() 1
|
||||
#else
|
||||
#define BCMRESVFRAGPOOL_ENAB() 0
|
||||
#endif
|
||||
#else
|
||||
#define BCMRESVFRAGPOOL_ENAB() 0
|
||||
#endif /* BCMPCIEDEV */
|
||||
|
||||
#define BCMSDIODEV_ENAB() 0
|
||||
|
||||
/* Max size for reclaimable NVRAM array */
|
||||
#ifdef DL_NVRAM
|
||||
#define NVRAM_ARRAY_MAXSIZE DL_NVRAM
|
||||
#else
|
||||
#define NVRAM_ARRAY_MAXSIZE MAXSZ_NVRAM_VARS
|
||||
#endif /* DL_NVRAM */
|
||||
|
||||
extern uint32 gFWID;
|
||||
|
||||
#ifdef BCMFRWDPOOLREORG /* BCMFRWDPOOLREORG support enab macros */
|
||||
extern bool _bcmfrwdpoolreorg;
|
||||
#if defined(ROM_ENAB_RUNTIME_CHECK) || !defined(DONGLEBUILD)
|
||||
#define BCMFRWDPOOLREORG_ENAB() (_bcmfrwdpoolreorg)
|
||||
#elif defined(BCMFRWDPOOLREORG_DISABLED)
|
||||
#define BCMFRWDPOOLREORG_ENAB() (0)
|
||||
#else
|
||||
#define BCMFRWDPOOLREORG_ENAB() (1)
|
||||
#endif
|
||||
#else
|
||||
#define BCMFRWDPOOLREORG_ENAB() (0)
|
||||
#endif /* BCMFRWDPOOLREORG */
|
||||
|
||||
#ifdef BCMPOOLRECLAIM /* BCMPOOLRECLAIM support enab macros */
|
||||
extern bool _bcmpoolreclaim;
|
||||
#if defined(ROM_ENAB_RUNTIME_CHECK) || !defined(DONGLEBUILD)
|
||||
#define BCMPOOLRECLAIM_ENAB() (_bcmpoolreclaim)
|
||||
#elif defined(BCMPOOLRECLAIM_DISABLED)
|
||||
#define BCMPOOLRECLAIM_ENAB() (0)
|
||||
#else
|
||||
#define BCMPOOLRECLAIM_ENAB() (1)
|
||||
#endif
|
||||
#else
|
||||
#define BCMPOOLRECLAIM_ENAB() (0)
|
||||
#endif /* BCMPOOLRECLAIM */
|
||||
|
||||
/* Chip related low power flags (lpflags) */
|
||||
|
||||
#ifndef PAD
|
||||
#define _PADLINE(line) pad ## line
|
||||
#define _XSTR(line) _PADLINE(line)
|
||||
#define PAD _XSTR(__LINE__)
|
||||
#endif // endif
|
||||
|
||||
#ifndef FRAG_HEADROOM
|
||||
#define FRAG_HEADROOM 224 /* In absence of SFD, use default headroom of 224 */
|
||||
#endif // endif
|
||||
|
||||
#define MODULE_DETACH(var, detach_func)\
|
||||
if (var) { \
|
||||
detach_func(var); \
|
||||
(var) = NULL; \
|
||||
}
|
||||
#define MODULE_DETACH_2(var1, var2, detach_func) detach_func(var1, var2)
|
||||
#define MODULE_DETACH_TYPECASTED(var, detach_func) detach_func(var)
|
||||
|
||||
/* When building ROML image use runtime conditional to cause the compiler
|
||||
* to compile everything but not to complain "defined but not used"
|
||||
* as #ifdef would cause at the callsites.
|
||||
* In the end functions called under if (0) {} will not be linked
|
||||
* into the final binary if they're not called from other places either.
|
||||
*/
|
||||
#define BCM_ATTACH_REF_DECL()
|
||||
#define BCM_ATTACH_REF() (1)
|
||||
|
||||
/* Const in ROM else normal data in RAM */
|
||||
#if defined(ROM_ENAB_RUNTIME_CHECK)
|
||||
#define ROMCONST CONST
|
||||
#else
|
||||
#define ROMCONST
|
||||
#endif // endif
|
||||
|
||||
#endif /* _bcmdefs_h_ */
|
||||
@@ -0,0 +1,945 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Broadcom device-specific manifest constants.
|
||||
*
|
||||
* Copyright (C) 1999-2019, 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.
|
||||
*
|
||||
* 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: bcmdevs.h 825481 2019-06-14 10:06:03Z $
|
||||
*/
|
||||
|
||||
#ifndef _BCMDEVS_H
|
||||
#define _BCMDEVS_H
|
||||
|
||||
/* PCI vendor IDs */
|
||||
#define VENDOR_EPIGRAM 0xfeda
|
||||
#define VENDOR_BROADCOM 0x14e4
|
||||
#define VENDOR_3COM 0x10b7
|
||||
#define VENDOR_NETGEAR 0x1385
|
||||
#define VENDOR_DIAMOND 0x1092
|
||||
#define VENDOR_INTEL 0x8086
|
||||
#define VENDOR_DELL 0x1028
|
||||
#define VENDOR_HP 0x103c
|
||||
#define VENDOR_HP_COMPAQ 0x0e11
|
||||
#define VENDOR_APPLE 0x106b
|
||||
#define VENDOR_SI_IMAGE 0x1095 /* Silicon Image, used by Arasan SDIO Host */
|
||||
#define VENDOR_BUFFALO 0x1154 /* Buffalo vendor id */
|
||||
#define VENDOR_TI 0x104c /* Texas Instruments */
|
||||
#define VENDOR_RICOH 0x1180 /* Ricoh */
|
||||
#define VENDOR_JMICRON 0x197b
|
||||
|
||||
/* PCMCIA vendor IDs */
|
||||
#define VENDOR_BROADCOM_PCMCIA 0x02d0
|
||||
|
||||
/* SDIO vendor IDs */
|
||||
#define VENDOR_BROADCOM_SDIO 0x00BF
|
||||
|
||||
/* DONGLE VID/PIDs */
|
||||
#define BCM_DNGL_VID 0x0a5c
|
||||
#define BCM_DNGL_BL_PID_4328 0xbd12
|
||||
#define BCM_DNGL_BL_PID_4322 0xbd13
|
||||
#define BCM_DNGL_BL_PID_4319 0xbd16
|
||||
#define BCM_DNGL_BL_PID_43236 0xbd17
|
||||
#define BCM_DNGL_BL_PID_4332 0xbd18
|
||||
#define BCM_DNGL_BL_PID_4360 0xbd1d
|
||||
#define BCM_DNGL_BL_PID_43143 0xbd1e
|
||||
#define BCM_DNGL_BL_PID_43242 0xbd1f
|
||||
#define BCM_DNGL_BL_PID_4335 0xbd20
|
||||
#define BCM_DNGL_BL_PID_4350 0xbd23
|
||||
#define BCM_DNGL_BL_PID_4345 0xbd24
|
||||
#define BCM_DNGL_BL_PID_4349 0xbd25
|
||||
#define BCM_DNGL_BL_PID_4354 0xbd26
|
||||
#define BCM_DNGL_BL_PID_43569 0xbd27
|
||||
#define BCM_DNGL_BL_PID_4373 0xbd29
|
||||
|
||||
#define BCM_DNGL_BDC_PID 0x0bdc
|
||||
#define BCM_DNGL_JTAG_PID 0x4a44
|
||||
|
||||
#ifdef DEPRECATED
|
||||
#define BCM_DNGL_BL_PID_43239 0xbd1b
|
||||
#define BCM_DNGL_BL_PID_4324 0xbd1c
|
||||
#define BCM_DNGL_BL_PID_43242 0xbd1f
|
||||
#define BCM_DNGL_BL_PID_43909 0xbd28
|
||||
#endif // endif
|
||||
|
||||
/* PCI Device IDs */
|
||||
#ifdef DEPRECATED /* These products have been deprecated */
|
||||
#define BCM4210_DEVICE_ID 0x1072 /* never used */
|
||||
#define BCM4230_DEVICE_ID 0x1086 /* never used */
|
||||
#define BCM4401_ENET_ID 0x170c /* 4401b0 production enet cards */
|
||||
#define BCM3352_DEVICE_ID 0x3352 /* bcm3352 device id */
|
||||
#define BCM3360_DEVICE_ID 0x3360 /* bcm3360 device id */
|
||||
#define BCM4211_DEVICE_ID 0x4211
|
||||
#define BCM4231_DEVICE_ID 0x4231
|
||||
#define BCM4303_D11B_ID 0x4303 /* 4303 802.11b */
|
||||
#define BCM4311_D11G_ID 0x4311 /* 4311 802.11b/g id */
|
||||
#define BCM4311_D11DUAL_ID 0x4312 /* 4311 802.11a/b/g id */
|
||||
#define BCM4311_D11A_ID 0x4313 /* 4311 802.11a id */
|
||||
#define BCM4328_D11DUAL_ID 0x4314 /* 4328/4312 802.11a/g id */
|
||||
#define BCM4328_D11G_ID 0x4315 /* 4328/4312 802.11g id */
|
||||
#define BCM4328_D11A_ID 0x4316 /* 4328/4312 802.11a id */
|
||||
#define BCM4318_D11A_ID 0x431a /* 4318 802.11a id */
|
||||
#define BCM4325_D11DUAL_ID 0x431b /* 4325 802.11a/g id */
|
||||
#define BCM4325_D11G_ID 0x431c /* 4325 802.11g id */
|
||||
#define BCM4325_D11A_ID 0x431d /* 4325 802.11a id */
|
||||
#define BCM4306_UART_ID 0x4322 /* 4306 uart */
|
||||
#define BCM4306_V90_ID 0x4323 /* 4306 v90 codec */
|
||||
#define BCM4306_D11G_ID2 0x4325 /* BCM4306_D11G_ID; INF w/loose binding war */
|
||||
#define BCM4321_D11N_ID 0x4328 /* 4321 802.11n dualband id */
|
||||
#define BCM4321_D11N2G_ID 0x4329 /* 4321 802.11n 2.4Ghz band id */
|
||||
#define BCM4321_D11N5G_ID 0x432a /* 4321 802.11n 5Ghz band id */
|
||||
#define BCM4322_D11N_ID 0x432b /* 4322 802.11n dualband device */
|
||||
#define BCM4322_D11N2G_ID 0x432c /* 4322 802.11n 2.4GHz device */
|
||||
#define BCM4322_D11N5G_ID 0x432d /* 4322 802.11n 5GHz device */
|
||||
#define BCM4329_D11N_ID 0x432e /* 4329 802.11n dualband device */
|
||||
#define BCM4329_D11N2G_ID 0x432f /* 4329 802.11n 2.4G device */
|
||||
#define BCM4329_D11N5G_ID 0x4330 /* 4329 802.11n 5G device */
|
||||
#define BCM4314_D11N2G_ID 0x4364 /* 4314 802.11n 2.4G device */
|
||||
#define BCM43143_D11N2G_ID 0x4366 /* 43143 802.11n 2.4G device */
|
||||
#define BCM4315_D11DUAL_ID 0x4334 /* 4315 802.11a/g id */
|
||||
#define BCM4315_D11G_ID 0x4335 /* 4315 802.11g id */
|
||||
#define BCM4315_D11A_ID 0x4336 /* 4315 802.11a id */
|
||||
#define BCM4319_D11N_ID 0x4337 /* 4319 802.11n dualband device */
|
||||
#define BCM4319_D11N2G_ID 0x4338 /* 4319 802.11n 2.4G device */
|
||||
#define BCM4319_D11N5G_ID 0x4339 /* 4319 802.11n 5G device */
|
||||
#define BCM43221_D11N2G_ID 0x4341 /* 43221 802.11n 2.4GHz device */
|
||||
#define BCM43222_D11N_ID 0x4350 /* 43222 802.11n dualband device */
|
||||
#define BCM43222_D11N2G_ID 0x4351 /* 43222 802.11n 2.4GHz device */
|
||||
#define BCM43222_D11N5G_ID 0x4352 /* 43222 802.11n 5GHz device */
|
||||
#define BCM43225_D11N2G_ID 0x4357 /* 43225 802.11n 2.4GHz device */
|
||||
#define BCM43226_D11N_ID 0x4354 /* 43226 802.11n dualband device */
|
||||
#define BCM43228_D11N5G_ID 0x435a /* 43228 802.11n 5GHz device */
|
||||
#define BCM43231_D11N2G_ID 0x4340 /* 43231 802.11n 2.4GHz device */
|
||||
#define BCM43237_D11N_ID 0x4355 /* 43237 802.11n dualband device */
|
||||
#define BCM43237_D11N5G_ID 0x4356 /* 43237 802.11n 5GHz device */
|
||||
#define BCM43239_D11N_ID 0x4370 /* 43239 802.11n dualband device */
|
||||
#define BCM4324_D11N_ID 0x4374 /* 4324 802.11n dualband device */
|
||||
#define BCM43242_D11N_ID 0x4367 /* 43242 802.11n dualband device */
|
||||
#define BCM43242_D11N2G_ID 0x4368 /* 43242 802.11n 2.4G device */
|
||||
#define BCM43242_D11N5G_ID 0x4369 /* 43242 802.11n 5G device */
|
||||
#define BCM4330_D11N_ID 0x4360 /* 4330 802.11n dualband device */
|
||||
#define BCM4330_D11N2G_ID 0x4361 /* 4330 802.11n 2.4G device */
|
||||
#define BCM4330_D11N5G_ID 0x4362 /* 4330 802.11n 5G device */
|
||||
#define BCM4334_D11N_ID 0x4380 /* 4334 802.11n dualband device */
|
||||
#define BCM4334_D11N2G_ID 0x4381 /* 4334 802.11n 2.4G device */
|
||||
#define BCM4334_D11N5G_ID 0x4382 /* 4334 802.11n 5G device */
|
||||
#define BCM43342_D11N_ID 0x4383 /* 43342 802.11n dualband device */
|
||||
#define BCM43342_D11N2G_ID 0x4384 /* 43342 802.11n 2.4G device */
|
||||
#define BCM43342_D11N5G_ID 0x4385 /* 43342 802.11n 5G device */
|
||||
#define BCM43341_D11N_ID 0x4386 /* 43341 802.11n dualband device */
|
||||
#define BCM43341_D11N2G_ID 0x4387 /* 43341 802.11n 2.4G device */
|
||||
#define BCM43341_D11N5G_ID 0x4388 /* 43341 802.11n 5G device */
|
||||
#define BCM4336_D11N_ID 0x4343 /* 4336 802.11n 2.4GHz device */
|
||||
#define BCM43362_D11N_ID 0x4363 /* 43362 802.11n 2.4GHz device */
|
||||
#define BCM43421_D11N_ID 0xA99D /* 43421 802.11n dualband device */
|
||||
#define BCM43909_D11AC_ID 0x43d0 /* 43909 802.11ac dualband device */
|
||||
#define BCM43909_D11AC2G_ID 0x43d1 /* 43909 802.11ac 2.4G device */
|
||||
#define BCM43909_D11AC5G_ID 0x43d2 /* 43909 802.11ac 5G device */
|
||||
#endif /* DEPRECATED */
|
||||
/* DEPRECATED but used */
|
||||
#define BCM4306_D11G_ID 0x4320 /* 4306 802.11g */
|
||||
#define BCM4306_D11A_ID 0x4321 /* 4306 802.11a */
|
||||
#define BCM4306_D11DUAL_ID 0x4324 /* 4306 dual A+B */
|
||||
#define BCM43142_D11N2G_ID 0x4365 /* 43142 802.11n 2.4G device */
|
||||
#define BCM4313_D11N2G_ID 0x4727 /* 4313 802.11n 2.4G device */
|
||||
#define BCM4318_D11G_ID 0x4318 /* 4318 802.11b/g id */
|
||||
#define BCM4318_D11DUAL_ID 0x4319 /* 4318 802.11a/b/g id */
|
||||
#define BCM43224_D11N_ID 0x4353 /* 43224 802.11n dualband device */
|
||||
#define BCM43224_D11N_ID_VEN1 0x0576 /* Vendor specific 43224 802.11n db device */
|
||||
#define BCM43227_D11N2G_ID 0x4358 /* 43228 802.11n 2.4GHz device */
|
||||
#define BCM43228_D11N_ID 0x4359 /* 43228 802.11n DualBand device */
|
||||
#define BCM4331_D11N_ID 0x4331 /* 4331 802.11n dualband id */
|
||||
#define BCM4331_D11N2G_ID 0x4332 /* 4331 802.11n 2.4Ghz band id */
|
||||
#define BCM4331_D11N5G_ID 0x4333 /* 4331 802.11n 5Ghz band id */
|
||||
/* DEPRECATED */
|
||||
|
||||
#define BCM43236_D11N_ID 0x4346 /* 43236 802.11n dualband device */
|
||||
#define BCM43236_D11N2G_ID 0x4347 /* 43236 802.11n 2.4GHz device */
|
||||
#define BCM43236_D11N5G_ID 0x4348 /* 43236 802.11n 5GHz device */
|
||||
#define BCM6362_D11N_ID 0x435f /* 6362 802.11n dualband device */
|
||||
#define BCM6362_D11N2G_ID 0x433f /* 6362 802.11n 2.4Ghz band id */
|
||||
#define BCM6362_D11N5G_ID 0x434f /* 6362 802.11n 5Ghz band id */
|
||||
#define BCM43217_D11N2G_ID 0x43a9 /* 43217 802.11n 2.4GHz device */
|
||||
#define BCM43131_D11N2G_ID 0x43aa /* 43131 802.11n 2.4GHz device */
|
||||
#define BCM4360_D11AC_ID 0x43a0
|
||||
#define BCM4360_D11AC2G_ID 0x43a1
|
||||
#define BCM4360_D11AC5G_ID 0x43a2
|
||||
#define BCM4345_D11AC_ID 0x43ab /* 4345 802.11ac dualband device */
|
||||
#define BCM4345_D11AC2G_ID 0x43ac /* 4345 802.11ac 2.4G device */
|
||||
#define BCM4345_D11AC5G_ID 0x43ad /* 4345 802.11ac 5G device */
|
||||
#define BCM43455_D11AC_ID 0x43e3 /* 43455 802.11ac dualband device */
|
||||
#define BCM43455_D11AC2G_ID 0x43e4 /* 43455 802.11ac 2.4G device */
|
||||
#define BCM43455_D11AC5G_ID 0x43e5 /* 43455 802.11ac 5G device */
|
||||
#define BCM4335_D11AC_ID 0x43ae
|
||||
#define BCM4335_D11AC2G_ID 0x43af
|
||||
#define BCM4335_D11AC5G_ID 0x43b0
|
||||
#define BCM4352_D11AC_ID 0x43b1 /* 4352 802.11ac dualband device */
|
||||
#define BCM4352_D11AC2G_ID 0x43b2 /* 4352 802.11ac 2.4G device */
|
||||
#define BCM4352_D11AC5G_ID 0x43b3 /* 4352 802.11ac 5G device */
|
||||
#define BCM43602_D11AC_ID 0x43ba /* ac dualband PCI devid SPROM programmed */
|
||||
#define BCM43602_D11AC2G_ID 0x43bb /* 43602 802.11ac 2.4G device */
|
||||
#define BCM43602_D11AC5G_ID 0x43bc /* 43602 802.11ac 5G device */
|
||||
#define BCM4349_D11AC_ID 0x4349 /* 4349 802.11ac dualband device */
|
||||
#define BCM4349_D11AC2G_ID 0x43dd /* 4349 802.11ac 2.4G device */
|
||||
#define BCM4349_D11AC5G_ID 0x43de /* 4349 802.11ac 5G device */
|
||||
#define BCM53573_D11AC_ID 0x43b4 /* 53573 802.11ac dualband device */
|
||||
#define BCM53573_D11AC2G_ID 0x43b5 /* 53573 802.11ac 2.4G device */
|
||||
#define BCM53573_D11AC5G_ID 0x43b6 /* 53573 802.11ac 5G device */
|
||||
#define BCM47189_D11AC_ID 0x43c6 /* 47189 802.11ac dualband device */
|
||||
#define BCM47189_D11AC2G_ID 0x43c7 /* 47189 802.11ac 2.4G device */
|
||||
#define BCM47189_D11AC5G_ID 0x43c8 /* 47189 802.11ac 5G device */
|
||||
#define BCM4355_D11AC_ID 0x43dc /* 4355 802.11ac dualband device */
|
||||
#define BCM4355_D11AC2G_ID 0x43fc /* 4355 802.11ac 2.4G device */
|
||||
#define BCM4355_D11AC5G_ID 0x43fd /* 4355 802.11ac 5G device */
|
||||
#define BCM4359_D11AC_ID 0x43ef /* 4359 802.11ac dualband device */
|
||||
#define BCM4359_D11AC2G_ID 0x43fe /* 4359 802.11ac 2.4G device */
|
||||
#define BCM4359_D11AC5G_ID 0x43ff /* 4359 802.11ac 5G device */
|
||||
#define BCM43596_D11AC_ID 0x4415 /* 43596 802.11ac dualband device */
|
||||
#define BCM43596_D11AC2G_ID 0x4416 /* 43596 802.11ac 2.4G device */
|
||||
#define BCM43596_D11AC5G_ID 0x4417 /* 43596 802.11ac 5G device */
|
||||
#define BCM43597_D11AC_ID 0x441c /* 43597 802.11ac dualband device */
|
||||
#define BCM43597_D11AC2G_ID 0x441d /* 43597 802.11ac 2.4G device */
|
||||
#define BCM43597_D11AC5G_ID 0x441e /* 43597 802.11ac 5G device */
|
||||
#define BCM43012_D11N_ID 0xA804 /* 43012 802.11n dualband device */
|
||||
#define BCM43012_D11N2G_ID 0xA805 /* 43012 802.11n 2.4G device */
|
||||
#define BCM43012_D11N5G_ID 0xA806 /* 43012 802.11n 5G device */
|
||||
#define BCM43014_D11N_ID 0x4495 /* 43014 802.11n dualband device */
|
||||
#define BCM43014_D11N2G_ID 0x4496 /* 43014 802.11n 2.4G device */
|
||||
#define BCM43014_D11N5G_ID 0x4497 /* 43014 802.11n 5G device */
|
||||
|
||||
/* PCI Subsystem ID */
|
||||
#define BCM94313HMGBL_SSID_VEN1 0x0608
|
||||
#define BCM94313HMG_SSID_VEN1 0x0609
|
||||
#define BCM943142HM_SSID_VEN1 0x0611
|
||||
|
||||
#define BCM4350_D11AC_ID 0x43a3
|
||||
#define BCM4350_D11AC2G_ID 0x43a4
|
||||
#define BCM4350_D11AC5G_ID 0x43a5
|
||||
|
||||
#define BCM43556_D11AC_ID 0x43b7
|
||||
#define BCM43556_D11AC2G_ID 0x43b8
|
||||
#define BCM43556_D11AC5G_ID 0x43b9
|
||||
|
||||
#define BCM43558_D11AC_ID 0x43c0
|
||||
#define BCM43558_D11AC2G_ID 0x43c1
|
||||
#define BCM43558_D11AC5G_ID 0x43c2
|
||||
|
||||
#define BCM43566_D11AC_ID 0x43d3
|
||||
#define BCM43566_D11AC2G_ID 0x43d4
|
||||
#define BCM43566_D11AC5G_ID 0x43d5
|
||||
|
||||
#define BCM43568_D11AC_ID 0x43d6
|
||||
#define BCM43568_D11AC2G_ID 0x43d7
|
||||
#define BCM43568_D11AC5G_ID 0x43d8
|
||||
|
||||
#define BCM43569_D11AC_ID 0x43d9
|
||||
#define BCM43569_D11AC2G_ID 0x43da
|
||||
#define BCM43569_D11AC5G_ID 0x43db
|
||||
|
||||
#define BCM43570_D11AC_ID 0x43d9
|
||||
#define BCM43570_D11AC2G_ID 0x43da
|
||||
#define BCM43570_D11AC5G_ID 0x43db
|
||||
|
||||
#define BCM4354_D11AC_ID 0x43df /* 4354 802.11ac dualband device */
|
||||
#define BCM4354_D11AC2G_ID 0x43e0 /* 4354 802.11ac 2.4G device */
|
||||
#define BCM4354_D11AC5G_ID 0x43e1 /* 4354 802.11ac 5G device */
|
||||
#define BCM43430_D11N2G_ID 0x43e2 /* 43430 802.11n 2.4G device */
|
||||
#define BCM43018_D11N2G_ID 0x441b /* 43018 802.11n 2.4G device */
|
||||
|
||||
#define BCM4347_D11AC_ID 0x440a /* 4347 802.11ac dualband device */
|
||||
#define BCM4347_D11AC2G_ID 0x440b /* 4347 802.11ac 2.4G device */
|
||||
#define BCM4347_D11AC5G_ID 0x440c /* 4347 802.11ac 5G device */
|
||||
|
||||
#define BCM4361_D11AC_ID 0x441f /* 4361 802.11ac dualband device */
|
||||
#define BCM4361_D11AC2G_ID 0x4420 /* 4361 802.11ac 2.4G device */
|
||||
#define BCM4361_D11AC5G_ID 0x4421 /* 4361 802.11ac 5G device */
|
||||
|
||||
#define BCM4362_D11AX_ID 0x4490 /* 4362 802.11ax dualband device */
|
||||
#define BCM4362_D11AX2G_ID 0x4491 /* 4362 802.11ax 2.4G device */
|
||||
#define BCM4362_D11AX5G_ID 0x4492 /* 4362 802.11ax 5G device */
|
||||
#define BCM43751_D11AX_ID 0x449a /* 43751 802.11ax dualband device */
|
||||
#define BCM43751_D11AX2G_ID 0x449b /* 43751 802.11ax 2.4G device */
|
||||
#define BCM43751_D11AX5G_ID 0x449c /* 43751 802.11ax 5G device */
|
||||
#define BCM43752_D11AX_ID 0x449d /* 43752 802.11ax dualband device */
|
||||
#define BCM43752_D11AX2G_ID 0x449e /* 43752 802.11ax 2.4G device */
|
||||
#define BCM43752_D11AX5G_ID 0x449f /* 43752 802.11ax 5G device */
|
||||
|
||||
#define BCM4364_D11AC_ID 0x4464 /* 4364 802.11ac dualband device */
|
||||
#define BCM4364_D11AC2G_ID 0x446a /* 4364 802.11ac 2.4G device */
|
||||
#define BCM4364_D11AC5G_ID 0x446b /* 4364 802.11ac 5G device */
|
||||
|
||||
#define BCM4365_D11AC_ID 0x43ca
|
||||
#define BCM4365_D11AC2G_ID 0x43cb
|
||||
#define BCM4365_D11AC5G_ID 0x43cc
|
||||
|
||||
#define BCM4366_D11AC_ID 0x43c3
|
||||
#define BCM4366_D11AC2G_ID 0x43c4
|
||||
#define BCM4366_D11AC5G_ID 0x43c5
|
||||
|
||||
/* TBD change below values */
|
||||
#define BCM4369_D11AX_ID 0x4470 /* 4369 802.11ax dualband device */
|
||||
#define BCM4369_D11AX2G_ID 0x4471 /* 4369 802.11ax 2.4G device */
|
||||
#define BCM4369_D11AX5G_ID 0x4472 /* 4369 802.11ax 5G device */
|
||||
|
||||
#define BCM4375_D11AX_ID 0x4475 /* 4375 802.11ax dualband device */
|
||||
#define BCM4375_D11AX2G_ID 0x4476 /* 4375 802.11ax 2.4G device */
|
||||
#define BCM4375_D11AX5G_ID 0x4477 /* 4375 802.11ax 5G device */
|
||||
|
||||
#define BCM43349_D11N_ID 0x43e6 /* 43349 802.11n dualband id */
|
||||
#define BCM43349_D11N2G_ID 0x43e7 /* 43349 802.11n 2.4Ghz band id */
|
||||
#define BCM43349_D11N5G_ID 0x43e8 /* 43349 802.11n 5Ghz band id */
|
||||
|
||||
#define BCM4358_D11AC_ID 0x43e9 /* 4358 802.11ac dualband device */
|
||||
#define BCM4358_D11AC2G_ID 0x43ea /* 4358 802.11ac 2.4G device */
|
||||
#define BCM4358_D11AC5G_ID 0x43eb /* 4358 802.11ac 5G device */
|
||||
|
||||
#define BCM4356_D11AC_ID 0x43ec /* 4356 802.11ac dualband device */
|
||||
#define BCM4356_D11AC2G_ID 0x43ed /* 4356 802.11ac 2.4G device */
|
||||
#define BCM4356_D11AC5G_ID 0x43ee /* 4356 802.11ac 5G device */
|
||||
|
||||
#define BCM4371_D11AC_ID 0x440d /* 4371 802.11ac dualband device */
|
||||
#define BCM4371_D11AC2G_ID 0x440e /* 4371 802.11ac 2.4G device */
|
||||
#define BCM4371_D11AC5G_ID 0x440f /* 4371 802.11ac 5G device */
|
||||
#define BCM7271_D11AC_ID 0x4410 /* 7271 802.11ac dualband device */
|
||||
#define BCM7271_D11AC2G_ID 0x4411 /* 7271 802.11ac 2.4G device */
|
||||
#define BCM7271_D11AC5G_ID 0x4412 /* 7271 802.11ac 5G device */
|
||||
|
||||
#define BCM4373_D11AC_ID 0x4418 /* 4373 802.11ac dualband device */
|
||||
#define BCM4373_D11AC2G_ID 0x4419 /* 4373 802.11ac 2.4G device */
|
||||
#define BCM4373_D11AC5G_ID 0x441a /* 4373 802.11ac 5G device */
|
||||
|
||||
#define BCMGPRS_UART_ID 0x4333 /* Uart id used by 4306/gprs card */
|
||||
#define BCMGPRS2_UART_ID 0x4344 /* Uart id used by 4306/gprs card */
|
||||
#define FPGA_JTAGM_ID 0x43f0 /* FPGA jtagm device id */
|
||||
#define BCM_JTAGM_ID 0x43f1 /* BCM jtagm device id */
|
||||
#define SDIOH_FPGA_ID 0x43f2 /* sdio host fpga */
|
||||
#define BCM_SDIOH_ID 0x43f3 /* BCM sdio host id */
|
||||
#define SDIOD_FPGA_ID 0x43f4 /* sdio device fpga */
|
||||
#define SPIH_FPGA_ID 0x43f5 /* PCI SPI Host Controller FPGA */
|
||||
#define BCM_SPIH_ID 0x43f6 /* Synopsis SPI Host Controller */
|
||||
#define MIMO_FPGA_ID 0x43f8 /* FPGA mimo minimacphy device id */
|
||||
#define BCM_JTAGM2_ID 0x43f9 /* BCM alternate jtagm device id */
|
||||
#define SDHCI_FPGA_ID 0x43fa /* Standard SDIO Host Controller FPGA */
|
||||
#define BCM4402_ENET_ID 0x4402 /* 4402 enet */
|
||||
#define BCM4402_V90_ID 0x4403 /* 4402 v90 codec */
|
||||
#define BCM4410_DEVICE_ID 0x4410 /* bcm44xx family pci iline */
|
||||
#define BCM4412_DEVICE_ID 0x4412 /* bcm44xx family pci enet */
|
||||
#define BCM4430_DEVICE_ID 0x4430 /* bcm44xx family cardbus iline */
|
||||
#define BCM4432_DEVICE_ID 0x4432 /* bcm44xx family cardbus enet */
|
||||
#define BCM4704_ENET_ID 0x4706 /* 4704 enet (Use 47XX_ENET_ID instead!) */
|
||||
#define BCM4710_DEVICE_ID 0x4710 /* 4710 primary function 0 */
|
||||
#define BCM47XX_AUDIO_ID 0x4711 /* 47xx audio codec */
|
||||
#define BCM47XX_V90_ID 0x4712 /* 47xx v90 codec */
|
||||
#define BCM47XX_ENET_ID 0x4713 /* 47xx enet */
|
||||
#define BCM47XX_EXT_ID 0x4714 /* 47xx external i/f */
|
||||
#define BCM47XX_GMAC_ID 0x4715 /* 47xx Unimac based GbE */
|
||||
#define BCM47XX_USBH_ID 0x4716 /* 47xx usb host */
|
||||
#define BCM47XX_USBD_ID 0x4717 /* 47xx usb device */
|
||||
#define BCM47XX_IPSEC_ID 0x4718 /* 47xx ipsec */
|
||||
#define BCM47XX_ROBO_ID 0x4719 /* 47xx/53xx roboswitch core */
|
||||
#define BCM47XX_USB20H_ID 0x471a /* 47xx usb 2.0 host */
|
||||
#define BCM47XX_USB20D_ID 0x471b /* 47xx usb 2.0 device */
|
||||
#define BCM47XX_ATA100_ID 0x471d /* 47xx parallel ATA */
|
||||
#define BCM47XX_SATAXOR_ID 0x471e /* 47xx serial ATA & XOR DMA */
|
||||
#define BCM47XX_GIGETH_ID 0x471f /* 47xx GbE (5700) */
|
||||
#ifdef DEPRECATED /* These products have been deprecated */
|
||||
#define BCM4712_MIPS_ID 0x4720 /* 4712 base devid */
|
||||
#define BCM4716_DEVICE_ID 0x4722 /* 4716 base devid */
|
||||
#endif /* DEPRECATED */
|
||||
#define BCM47XX_USB30H_ID 0x472a /* 47xx usb 3.0 host */
|
||||
#define BCM47XX_USB30D_ID 0x472b /* 47xx usb 3.0 device */
|
||||
#define BCM47XX_USBHUB_ID 0x472c /* 47xx usb hub */
|
||||
#define BCM47XX_SMBUS_EMU_ID 0x47fe /* 47xx emulated SMBus device */
|
||||
#define BCM47XX_XOR_EMU_ID 0x47ff /* 47xx emulated XOR engine */
|
||||
#define EPI41210_DEVICE_ID 0xa0fa /* bcm4210 */
|
||||
#define EPI41230_DEVICE_ID 0xa10e /* bcm4230 */
|
||||
#define JINVANI_SDIOH_ID 0x4743 /* Jinvani SDIO Gold Host */
|
||||
#define BCM27XX_SDIOH_ID 0x2702 /* BCM27xx Standard SDIO Host */
|
||||
#define PCIXX21_FLASHMEDIA_ID 0x803b /* TI PCI xx21 Standard Host Controller */
|
||||
#define PCIXX21_SDIOH_ID 0x803c /* TI PCI xx21 Standard Host Controller */
|
||||
#define R5C822_SDIOH_ID 0x0822 /* Ricoh Co Ltd R5C822 SD/SDIO/MMC/MS/MSPro Host */
|
||||
#define JMICRON_SDIOH_ID 0x2381 /* JMicron Standard SDIO Host Controller */
|
||||
|
||||
#define BCM43452_D11AC_ID 0x47ab /* 43452 802.11ac dualband device */
|
||||
#define BCM43452_D11AC2G_ID 0x47ac /* 43452 802.11ac 2.4G device */
|
||||
#define BCM43452_D11AC5G_ID 0x47ad /* 43452 802.11ac 5G device */
|
||||
|
||||
/* Chip IDs */
|
||||
#ifdef DEPRECATED /* These products have been deprecated */
|
||||
#define BCM4306_CHIP_ID 0x4306 /* 4306 chipcommon chipid */
|
||||
#define BCM4311_CHIP_ID 0x4311 /* 4311 PCIe 802.11a/b/g */
|
||||
#define BCM43111_CHIP_ID 43111 /* 43111 chipcommon chipid (OTP chipid) */
|
||||
#define BCM43112_CHIP_ID 43112 /* 43112 chipcommon chipid (OTP chipid) */
|
||||
#define BCM4312_CHIP_ID 0x4312 /* 4312 chipcommon chipid */
|
||||
#define BCM4314_CHIP_ID 0x4314 /* 4314 chipcommon chipid */
|
||||
#define BCM43142_CHIP_ID 43142 /* 43142 chipcommon chipid */
|
||||
#define BCM43143_CHIP_ID 43143 /* 43143 chipcommon chipid */
|
||||
#define BCM4313_CHIP_ID 0x4313 /* 4313 chip id */
|
||||
#define BCM4315_CHIP_ID 0x4315 /* 4315 chip id */
|
||||
#define BCM4318_CHIP_ID 0x4318 /* 4318 chipcommon chipid */
|
||||
#define BCM4319_CHIP_ID 0x4319 /* 4319 chip id */
|
||||
#define BCM4320_CHIP_ID 0x4320 /* 4320 chipcommon chipid */
|
||||
#define BCM4321_CHIP_ID 0x4321 /* 4321 chipcommon chipid */
|
||||
#define BCM4322_CHIP_ID 0x4322 /* 4322 chipcommon chipid */
|
||||
#define BCM43221_CHIP_ID 43221 /* 43221 chipcommon chipid (OTP chipid) */
|
||||
#define BCM43222_CHIP_ID 43222 /* 43222 chipcommon chipid */
|
||||
#define BCM43224_CHIP_ID 43224 /* 43224 chipcommon chipid */
|
||||
#define BCM43225_CHIP_ID 43225 /* 43225 chipcommon chipid */
|
||||
#define BCM43226_CHIP_ID 43226 /* 43226 chipcommon chipid */
|
||||
#define BCM43227_CHIP_ID 43227 /* 43227 chipcommon chipid */
|
||||
#define BCM43228_CHIP_ID 43228 /* 43228 chipcommon chipid */
|
||||
#define BCM43231_CHIP_ID 43231 /* 43231 chipcommon chipid (OTP chipid) */
|
||||
#define BCM43237_CHIP_ID 43237 /* 43237 chipcommon chipid */
|
||||
#define BCM43239_CHIP_ID 43239 /* 43239 chipcommon chipid */
|
||||
#define BCM4324_CHIP_ID 0x4324 /* 4324 chipcommon chipid */
|
||||
#define BCM43242_CHIP_ID 43242 /* 43242 chipcommon chipid */
|
||||
#define BCM43243_CHIP_ID 43243 /* 43243 chipcommon chipid */
|
||||
#define BCM4325_CHIP_ID 0x4325 /* 4325 chip id */
|
||||
#define BCM4328_CHIP_ID 0x4328 /* 4328 chip id */
|
||||
#define BCM4329_CHIP_ID 0x4329 /* 4329 chipcommon chipid */
|
||||
#define BCM4331_CHIP_ID 0x4331 /* 4331 chipcommon chipid */
|
||||
#define BCM4334_CHIP_ID 0x4334 /* 4334 chipcommon chipid */
|
||||
#define BCM43349_CHIP_ID 43349 /* 43349(0xA955) chipcommon chipid */
|
||||
#define BCM43340_CHIP_ID 43340 /* 43340 chipcommon chipid */
|
||||
#define BCM43341_CHIP_ID 43341 /* 43341 chipcommon chipid */
|
||||
#define BCM43342_CHIP_ID 43342 /* 43342 chipcommon chipid */
|
||||
#define BCM4342_CHIP_ID 4342 /* 4342 chipcommon chipid (OTP, RBBU) */
|
||||
#define BCM43420_CHIP_ID 43420 /* 43420 chipcommon chipid (OTP, RBBU) */
|
||||
#define BCM43421_CHIP_ID 43421 /* 43224 chipcommon chipid (OTP, RBBU) */
|
||||
#define BCM43431_CHIP_ID 43431 /* 4331 chipcommon chipid (OTP, RBBU) */
|
||||
#define BCM43909_CHIP_ID 0xab85 /* 43909 chipcommon chipid */
|
||||
#define BCM4712_CHIP_ID 0x4712 /* 4712 chipcommon chipid */
|
||||
#define BCM4716_CHIP_ID 0x4716 /* 4716 chipcommon chipid */
|
||||
#define BCM4748_CHIP_ID 0x4748 /* 4716 chipcommon chipid (OTP, RBBU) */
|
||||
#endif /* DEPRECATED */
|
||||
|
||||
/* DEPRECATED but still referenced in components - start */
|
||||
#define BCM47162_CHIP_ID 47162 /* 47162 chipcommon chipid */
|
||||
#define BCM5354_CHIP_ID 0x5354 /* 5354 chipcommon chipid */
|
||||
/* DEPRECATED but still referenced in components - end */
|
||||
|
||||
#define BCM43217_CHIP_ID 43217 /* 43217 chip id (OTP chipid) */
|
||||
#define BCM43131_CHIP_ID 43131 /* 43131 chip id (OTP chipid) */
|
||||
#define BCM43234_CHIP_ID 43234 /* 43234 chipcommon chipid */
|
||||
#define BCM43235_CHIP_ID 43235 /* 43235 chipcommon chipid */
|
||||
#define BCM43236_CHIP_ID 43236 /* 43236 chipcommon chipid */
|
||||
#define BCM43238_CHIP_ID 43238 /* 43238 chipcommon chipid */
|
||||
#define BCM43428_CHIP_ID 43428 /* 43228 chipcommon chipid (OTP, RBBU) */
|
||||
#define BCM43460_CHIP_ID 43460 /* 4360 chipcommon chipid (OTP, RBBU) */
|
||||
#define BCM43362_CHIP_ID 43362 /* 43362 chipcommon chipid */
|
||||
#define BCM4330_CHIP_ID 0x4330 /* 4330 chipcommon chipid */
|
||||
#define BCM43465_CHIP_ID 43465 /* 4366 chipcommon chipid (OTP, RBBU) */
|
||||
#define BCM43525_CHIP_ID 43525 /* 4365 chipcommon chipid (OTP, RBBU) */
|
||||
#define BCM47452_CHIP_ID 47452 /* 53573 chipcommon chipid (OTP, RBBU) */
|
||||
#define BCM6362_CHIP_ID 0x6362 /* 6362 chipcommon chipid */
|
||||
#define BCM43143_CHIP_ID 43143 /* 43143 chipcommon chipid */
|
||||
#define BCM4324_CHIP_ID 0x4324 /* 4324 chipcommon chipid */
|
||||
#define BCM43242_CHIP_ID 43242 /* 43242 chipcommon chipid */
|
||||
#define BCM4334_CHIP_ID 0x4334 /* 4334 chipcommon chipid */
|
||||
#define BCM4335_CHIP_ID 0x4335 /* 4335 chipcommon chipid */
|
||||
#define BCM4339_CHIP_ID 0x4339 /* 4339 chipcommon chipid */
|
||||
#define BCM4360_CHIP_ID 0x4360 /* 4360 chipcommon chipid */
|
||||
#define BCM4364_CHIP_ID 0x4364 /* 4364 chipcommon chipid */
|
||||
#define BCM4352_CHIP_ID 0x4352 /* 4352 chipcommon chipid */
|
||||
#define BCM43526_CHIP_ID 0xAA06
|
||||
#define BCM43340_CHIP_ID 43340 /* 43340 chipcommon chipid */
|
||||
#define BCM43341_CHIP_ID 43341 /* 43341 chipcommon chipid */
|
||||
#define BCM4350_CHIP_ID 0x4350 /* 4350 chipcommon chipid */
|
||||
#define BCM4354_CHIP_ID 0x4354 /* 4354 chipcommon chipid */
|
||||
#define BCM4356_CHIP_ID 0x4356 /* 4356 chipcommon chipid */
|
||||
#define BCM4371_CHIP_ID 0x4371 /* 4371 chipcommon chipid */
|
||||
#define BCM43556_CHIP_ID 0xAA24 /* 43556 chipcommon chipid */
|
||||
#define BCM43558_CHIP_ID 0xAA26 /* 43558 chipcommon chipid */
|
||||
#define BCM43562_CHIP_ID 0xAA2A /* 43562 chipcommon chipid */
|
||||
#define BCM43566_CHIP_ID 0xAA2E /* 43566 chipcommon chipid */
|
||||
#define BCM43567_CHIP_ID 0xAA2F /* 43567 chipcommon chipid */
|
||||
#define BCM43568_CHIP_ID 0xAA30 /* 43568 chipcommon chipid */
|
||||
#define BCM43569_CHIP_ID 0xAA31 /* 43569 chipcommon chipid */
|
||||
#define BCM43570_CHIP_ID 0xAA32 /* 43570 chipcommon chipid */
|
||||
#define BCM4358_CHIP_ID 0x4358 /* 4358 chipcommon chipid */
|
||||
#define BCM43012_CHIP_ID 0xA804 /* 43012 chipcommon chipid */
|
||||
#define BCM43014_CHIP_ID 0xA806 /* 43014 chipcommon chipid */
|
||||
#define BCM4369_CHIP_ID 0x4369 /* 4369 chipcommon chipid */
|
||||
|
||||
#define BCM4350_CHIP(chipid) ((CHIPID(chipid) == BCM4350_CHIP_ID) || \
|
||||
(CHIPID(chipid) == BCM4354_CHIP_ID) || \
|
||||
(CHIPID(chipid) == BCM43556_CHIP_ID) || \
|
||||
(CHIPID(chipid) == BCM43558_CHIP_ID) || \
|
||||
(CHIPID(chipid) == BCM43566_CHIP_ID) || \
|
||||
(CHIPID(chipid) == BCM43567_CHIP_ID) || \
|
||||
(CHIPID(chipid) == BCM43568_CHIP_ID) || \
|
||||
(CHIPID(chipid) == BCM43569_CHIP_ID) || \
|
||||
(CHIPID(chipid) == BCM43570_CHIP_ID) || \
|
||||
(CHIPID(chipid) == BCM4358_CHIP_ID)) /* 4350 variations */
|
||||
|
||||
#define BCM4345_CHIP_ID 0x4345 /* 4345 chipcommon chipid */
|
||||
#define BCM43454_CHIP_ID 43454 /* 43454 chipcommon chipid */
|
||||
#define BCM43455_CHIP_ID 43455 /* 43455 chipcommon chipid */
|
||||
#define BCM43457_CHIP_ID 43457 /* 43457 chipcommon chipid */
|
||||
#define BCM43458_CHIP_ID 43458 /* 43458 chipcommon chipid */
|
||||
|
||||
#define BCM4345_CHIP(chipid) (CHIPID(chipid) == BCM4345_CHIP_ID || \
|
||||
CHIPID(chipid) == BCM43454_CHIP_ID || \
|
||||
CHIPID(chipid) == BCM43455_CHIP_ID || \
|
||||
CHIPID(chipid) == BCM43457_CHIP_ID || \
|
||||
CHIPID(chipid) == BCM43458_CHIP_ID)
|
||||
|
||||
#define CASE_BCM4345_CHIP case BCM4345_CHIP_ID: /* fallthrough */ \
|
||||
case BCM43454_CHIP_ID: /* fallthrough */ \
|
||||
case BCM43455_CHIP_ID: /* fallthrough */ \
|
||||
case BCM43457_CHIP_ID: /* fallthrough */ \
|
||||
case BCM43458_CHIP_ID
|
||||
|
||||
#define BCM43430_CHIP_ID 43430 /* 43430 chipcommon chipid */
|
||||
#define BCM43018_CHIP_ID 43018 /* 43018 chipcommon chipid */
|
||||
#define BCM4349_CHIP_ID 0x4349 /* 4349 chipcommon chipid */
|
||||
#define BCM4355_CHIP_ID 0x4355 /* 4355 chipcommon chipid */
|
||||
#define BCM4359_CHIP_ID 0x4359 /* 4359 chipcommon chipid */
|
||||
#define BCM4349_CHIP(chipid) ((CHIPID(chipid) == BCM4349_CHIP_ID) || \
|
||||
(CHIPID(chipid) == BCM4355_CHIP_ID) || \
|
||||
(CHIPID(chipid) == BCM4359_CHIP_ID))
|
||||
|
||||
#define BCM4355_CHIP(chipid) (CHIPID(chipid) == BCM4355_CHIP_ID)
|
||||
|
||||
#define BCM4349_CHIP_GRPID BCM4349_CHIP_ID: \
|
||||
case BCM4355_CHIP_ID: \
|
||||
case BCM4359_CHIP_ID
|
||||
#define BCM43596_CHIP_ID 43596 /* 43596 chipcommon chipid */
|
||||
|
||||
#define BCM4347_CHIP_ID 0x4347 /* 4347 chipcommon chipid */
|
||||
#define BCM4357_CHIP_ID 0x4357 /* 4357 chipcommon chipid */
|
||||
#define BCM4361_CHIP_ID 0x4361 /* 4361 chipcommon chipid */
|
||||
#define BCM4369_CHIP_ID 0x4369 /* 4369/ chipcommon chipid */
|
||||
#define BCM4375_CHIP_ID 0x4375 /* 4375/ chipcommon chipid */
|
||||
#define BCM4377_CHIP_ID 0x4377 /* 4377/ chipcommon chipid */
|
||||
#define BCM4362_CHIP_ID 0x4362 /* 4362 chipcommon chipid */
|
||||
#define BCM43751_CHIP_ID 0xAAE7 /* 43751 chipcommon chipid */
|
||||
#define BCM43752_CHIP_ID 0xAAE8 /* 43752 chipcommon chipid */
|
||||
|
||||
#define BCM4347_CHIP(chipid) ((CHIPID(chipid) == BCM4347_CHIP_ID) || \
|
||||
(CHIPID(chipid) == BCM4357_CHIP_ID) || \
|
||||
(CHIPID(chipid) == BCM4361_CHIP_ID))
|
||||
#define BCM4347_CHIP_GRPID BCM4347_CHIP_ID: \
|
||||
case BCM4357_CHIP_ID: \
|
||||
case BCM4361_CHIP_ID
|
||||
|
||||
#define BCM4369_CHIP(chipid) ((CHIPID(chipid) == BCM4369_CHIP_ID) || \
|
||||
(CHIPID(chipid) == BCM4377_CHIP_ID))
|
||||
#define BCM4369_CHIP_GRPID BCM4369_CHIP_ID: \
|
||||
case BCM4377_CHIP_ID
|
||||
|
||||
#define BCM4362_CHIP(chipid) ((CHIPID(chipid) == BCM4362_CHIP_ID) || \
|
||||
(CHIPID(chipid) == BCM43751_CHIP_ID) || \
|
||||
(CHIPID(chipid) == BCM43752_CHIP_ID))
|
||||
#define BCM4362_CHIP_GRPID BCM4362_CHIP_ID: \
|
||||
case BCM43751_CHIP_ID: \
|
||||
case BCM43752_CHIP_ID
|
||||
|
||||
#define BCM4365_CHIP_ID 0x4365 /* 4365 chipcommon chipid */
|
||||
#define BCM4366_CHIP_ID 0x4366 /* 4366 chipcommon chipid */
|
||||
#define BCM43664_CHIP_ID 43664 /* 4366E chipcommon chipid */
|
||||
#define BCM43666_CHIP_ID 43666 /* 4365E chipcommon chipid */
|
||||
#define BCM4365_CHIP(chipid) ((CHIPID(chipid) == BCM4365_CHIP_ID) || \
|
||||
(CHIPID(chipid) == BCM4366_CHIP_ID) || \
|
||||
(CHIPID(chipid) == BCM43664_CHIP_ID) || \
|
||||
(CHIPID(chipid) == BCM43666_CHIP_ID))
|
||||
#define CASE_BCM4365_CHIP case BCM4365_CHIP_ID: /* fallthrough */ \
|
||||
case BCM4366_CHIP_ID: /* fallthrough */ \
|
||||
case BCM43664_CHIP_ID: /* fallthrough */ \
|
||||
case BCM43666_CHIP_ID
|
||||
|
||||
#define BCM43602_CHIP_ID 0xaa52 /* 43602 chipcommon chipid */
|
||||
#define BCM43462_CHIP_ID 0xa9c6 /* 43462 chipcommon chipid */
|
||||
#define BCM43522_CHIP_ID 0xaa02 /* 43522 chipcommon chipid */
|
||||
#define BCM43602_CHIP(chipid) ((CHIPID(chipid) == BCM43602_CHIP_ID) || \
|
||||
(CHIPID(chipid) == BCM43462_CHIP_ID) || \
|
||||
(CHIPID(chipid) == BCM43522_CHIP_ID)) /* 43602 variations */
|
||||
#define BCM43012_CHIP(chipid) (CHIPID(chipid) == BCM43012_CHIP_ID)
|
||||
#define CASE_BCM43602_CHIP case BCM43602_CHIP_ID: /* fallthrough */ \
|
||||
case BCM43462_CHIP_ID: /* fallthrough */ \
|
||||
case BCM43522_CHIP_ID
|
||||
|
||||
#define BCM4402_CHIP_ID 0x4402 /* 4402 chipid */
|
||||
#define BCM4704_CHIP_ID 0x4704 /* 4704 chipcommon chipid */
|
||||
#define BCM4707_CHIP_ID 53010 /* 4707 chipcommon chipid */
|
||||
#define BCM47094_CHIP_ID 53030 /* 47094 chipcommon chipid */
|
||||
#define BCM53018_CHIP_ID 53018 /* 53018 chipcommon chipid */
|
||||
#define BCM4707_CHIP(chipid) (((chipid) == BCM4707_CHIP_ID) || \
|
||||
((chipid) == BCM53018_CHIP_ID) || \
|
||||
((chipid) == BCM47094_CHIP_ID))
|
||||
#define BCM4710_CHIP_ID 0x4710 /* 4710 chipid */
|
||||
#define BCM4785_CHIP_ID 0x4785 /* 4785 chipcommon chipid */
|
||||
#define BCM5350_CHIP_ID 0x5350 /* 5350 chipcommon chipid */
|
||||
#define BCM5352_CHIP_ID 0x5352 /* 5352 chipcommon chipid */
|
||||
#define BCM5365_CHIP_ID 0x5365 /* 5365 chipcommon chipid */
|
||||
#define BCM53573_CHIP_ID 53573 /* 53573 chipcommon chipid */
|
||||
#define BCM53574_CHIP_ID 53574 /* 53574 chipcommon chipid */
|
||||
#define BCM53573_CHIP(chipid) ((CHIPID(chipid) == BCM53573_CHIP_ID) || \
|
||||
(CHIPID(chipid) == BCM53574_CHIP_ID) || \
|
||||
(CHIPID(chipid) == BCM47452_CHIP_ID))
|
||||
#define BCM53573_CHIP_GRPID BCM53573_CHIP_ID : \
|
||||
case BCM53574_CHIP_ID : \
|
||||
case BCM47452_CHIP_ID
|
||||
#define BCM53573_DEVICE(devid) (((devid) == BCM53573_D11AC_ID) || \
|
||||
((devid) == BCM53573_D11AC2G_ID) || \
|
||||
((devid) == BCM53573_D11AC5G_ID) || \
|
||||
((devid) == BCM47189_D11AC_ID) || \
|
||||
((devid) == BCM47189_D11AC2G_ID) || \
|
||||
((devid) == BCM47189_D11AC5G_ID))
|
||||
|
||||
#define BCM7271_CHIP_ID 0x05c9 /* 7271 chipcommon chipid */
|
||||
#define BCM7271_CHIP(chipid) ((CHIPID(chipid) == BCM7271_CHIP_ID))
|
||||
|
||||
#define BCM4373_CHIP_ID 0x4373 /* 4373 chipcommon chipid */
|
||||
|
||||
/* Package IDs */
|
||||
#ifdef DEPRECATED /* These products have been deprecated */
|
||||
#define BCM4303_PKG_ID 2 /* 4303 package id */
|
||||
#define BCM4309_PKG_ID 1 /* 4309 package id */
|
||||
#define BCM4712LARGE_PKG_ID 0 /* 340pin 4712 package id */
|
||||
#define BCM4712SMALL_PKG_ID 1 /* 200pin 4712 package id */
|
||||
#define BCM4712MID_PKG_ID 2 /* 225pin 4712 package id */
|
||||
#define BCM4328USBD11G_PKG_ID 2 /* 4328 802.11g USB package id */
|
||||
#define BCM4328USBDUAL_PKG_ID 3 /* 4328 802.11a/g USB package id */
|
||||
#define BCM4328SDIOD11G_PKG_ID 4 /* 4328 802.11g SDIO package id */
|
||||
#define BCM4328SDIODUAL_PKG_ID 5 /* 4328 802.11a/g SDIO package id */
|
||||
#define BCM4329_289PIN_PKG_ID 0 /* 4329 289-pin package id */
|
||||
#define BCM4329_182PIN_PKG_ID 1 /* 4329N 182-pin package id */
|
||||
#define BCM5354E_PKG_ID 1 /* 5354E package id */
|
||||
#define BCM4716_PKG_ID 8 /* 4716 package id */
|
||||
#define BCM4717_PKG_ID 9 /* 4717 package id */
|
||||
#define BCM4718_PKG_ID 10 /* 4718 package id */
|
||||
#define BCM4331TT_PKG_ID 8 /* 4331 12x12 package id */
|
||||
#define BCM4331TN_PKG_ID 9 /* 4331 12x9 package id */
|
||||
#define BCM4331TNA0_PKG_ID 0xb /* 4331 12x9 package id */
|
||||
#endif /* DEPRECATED */
|
||||
#define BCM47189_PKG_ID 1 /* 47189 package id */
|
||||
#define BCM53573_PKG_ID 0 /* 53573 package id */
|
||||
|
||||
#define HDLSIM5350_PKG_ID 1 /* HDL simulator package id for a 5350 */
|
||||
#define HDLSIM_PKG_ID 14 /* HDL simulator package id */
|
||||
#define HWSIM_PKG_ID 15 /* Hardware simulator package id */
|
||||
|
||||
#define BCM4707_PKG_ID 1 /* 4707 package id */
|
||||
#define BCM4708_PKG_ID 2 /* 4708 package id */
|
||||
#define BCM4709_PKG_ID 0 /* 4709 package id */
|
||||
|
||||
#define PCIXX21_FLASHMEDIA0_ID 0x8033 /* TI PCI xx21 Standard Host Controller */
|
||||
#define PCIXX21_SDIOH0_ID 0x8034 /* TI PCI xx21 Standard Host Controller */
|
||||
|
||||
#define BCM4335_WLCSP_PKG_ID (0x0) /* WLCSP Module/Mobile SDIO/HSIC. */
|
||||
#define BCM4335_FCBGA_PKG_ID (0x1) /* FCBGA PC/Embeded/Media PCIE/SDIO */
|
||||
#define BCM4335_WLBGA_PKG_ID (0x2) /* WLBGA COB/Mobile SDIO/HSIC. */
|
||||
#define BCM4335_FCBGAD_PKG_ID (0x3) /* FCBGA Debug Debug/Dev All if's. */
|
||||
#define BCM4335_PKG_MASK (0x3)
|
||||
#define BCM43602_12x12_PKG_ID (0x1) /* 12x12 pins package, used for e.g. router designs */
|
||||
|
||||
/* boardflags */
|
||||
#define BFL_BTC2WIRE 0x00000001 /* old 2wire Bluetooth coexistence, OBSOLETE */
|
||||
#define BFL_BTCOEX 0x00000001 /* Board supports BTCOEX */
|
||||
#define BFL_PACTRL 0x00000002 /* Board has gpio 9 controlling the PA */
|
||||
#define BFL_AIRLINEMODE 0x00000004 /* Board implements gpio radio disable indication */
|
||||
#define BFL_ADCDIV 0x00000008 /* Board has the rssi ADC divider */
|
||||
#define BFL_DIS_256QAM 0x00000008
|
||||
#define BFL_ENETROBO 0x00000010 /* Board has robo switch or core */
|
||||
#define BFL_TSSIAVG 0x00000010 /* TSSI averaging for ACPHY chips */
|
||||
#define BFL_NOPLLDOWN 0x00000020 /* Not ok to power down the chip pll and oscillator */
|
||||
#define BFL_CCKHIPWR 0x00000040 /* Can do high-power CCK transmission */
|
||||
#define BFL_ENETADM 0x00000080 /* Board has ADMtek switch */
|
||||
#define BFL_ENETVLAN 0x00000100 /* Board has VLAN capability */
|
||||
#define BFL_LTECOEX 0x00000200 /* LTE Coex enabled */
|
||||
#define BFL_NOPCI 0x00000400 /* Board leaves PCI floating */
|
||||
#define BFL_FEM 0x00000800 /* Board supports the Front End Module */
|
||||
#define BFL_EXTLNA 0x00001000 /* Board has an external LNA in 2.4GHz band */
|
||||
#define BFL_HGPA 0x00002000 /* Board has a high gain PA */
|
||||
#define BFL_BTC2WIRE_ALTGPIO 0x00004000 /* Board's BTC 2wire is in the alternate gpios */
|
||||
#define BFL_ALTIQ 0x00008000 /* Alternate I/Q settings */
|
||||
#define BFL_NOPA 0x00010000 /* Board has no PA */
|
||||
#define BFL_RSSIINV 0x00020000 /* Board's RSSI uses positive slope(not TSSI) */
|
||||
#define BFL_PAREF 0x00040000 /* Board uses the PARef LDO */
|
||||
#define BFL_3TSWITCH 0x00080000 /* Board uses a triple throw switch shared with BT */
|
||||
#define BFL_PHASESHIFT 0x00100000 /* Board can support phase shifter */
|
||||
#define BFL_BUCKBOOST 0x00200000 /* Power topology uses BUCKBOOST */
|
||||
#define BFL_FEM_BT 0x00400000 /* Board has FEM and switch to share antenna w/ BT */
|
||||
#define BFL_NOCBUCK 0x00800000 /* Power topology doesn't use CBUCK */
|
||||
#define BFL_CCKFAVOREVM 0x01000000 /* Favor CCK EVM over spectral mask */
|
||||
#define BFL_PALDO 0x02000000 /* Power topology uses PALDO */
|
||||
#define BFL_LNLDO2_2P5 0x04000000 /* Select 2.5V as LNLDO2 output voltage */
|
||||
#define BFL_FASTPWR 0x08000000
|
||||
#define BFL_UCPWRCTL_MININDX 0x08000000 /* Enforce min power index to avoid FEM damage */
|
||||
#define BFL_EXTLNA_5GHz 0x10000000 /* Board has an external LNA in 5GHz band */
|
||||
#define BFL_TRSW_1by2 0x20000000 /* Board has 2 TRSW's in 1by2 designs */
|
||||
#define BFL_GAINBOOSTA01 0x20000000 /* 5g Gainboost for core0 and core1 */
|
||||
#define BFL_LO_TRSW_R_5GHz 0x40000000 /* In 5G do not throw TRSW to T for clipLO gain */
|
||||
#define BFL_ELNA_GAINDEF 0x80000000 /* Backoff InitGain based on elna_2g/5g field
|
||||
* when this flag is set
|
||||
*/
|
||||
#define BFL_EXTLNA_TX 0x20000000 /* Temp boardflag to indicate to */
|
||||
|
||||
/* boardflags2 */
|
||||
#define BFL2_RXBB_INT_REG_DIS 0x00000001 /* Board has an external rxbb regulator */
|
||||
#define BFL2_APLL_WAR 0x00000002 /* Flag to implement alternative A-band PLL settings */
|
||||
#define BFL2_TXPWRCTRL_EN 0x00000004 /* Board permits enabling TX Power Control */
|
||||
#define BFL2_2X4_DIV 0x00000008 /* Board supports the 2X4 diversity switch */
|
||||
#define BFL2_5G_PWRGAIN 0x00000010 /* Board supports 5G band power gain */
|
||||
#define BFL2_PCIEWAR_OVR 0x00000020 /* Board overrides ASPM and Clkreq settings */
|
||||
#define BFL2_CAESERS_BRD 0x00000040 /* Board is Caesers brd (unused by sw) */
|
||||
#define BFL2_WLCX_ATLAS 0x00000040 /* Board flag to initialize ECI for WLCX on FL-ATLAS */
|
||||
#define BFL2_BTC3WIRE 0x00000080 /* Board support legacy 3 wire or 4 wire */
|
||||
#define BFL2_BTCLEGACY 0x00000080 /* Board support legacy 3/4 wire, to replace
|
||||
* BFL2_BTC3WIRE
|
||||
*/
|
||||
#define BFL2_SKWRKFEM_BRD 0x00000100 /* 4321mcm93 board uses Skyworks FEM */
|
||||
#define BFL2_SPUR_WAR 0x00000200 /* Board has a WAR for clock-harmonic spurs */
|
||||
#define BFL2_GPLL_WAR 0x00000400 /* Flag to narrow G-band PLL loop b/w */
|
||||
#define BFL2_TRISTATE_LED 0x00000800 /* Tri-state the LED */
|
||||
#define BFL2_SINGLEANT_CCK 0x00001000 /* Tx CCK pkts on Ant 0 only */
|
||||
#define BFL2_2G_SPUR_WAR 0x00002000 /* WAR to reduce and avoid clock-harmonic spurs in 2G */
|
||||
#define BFL2_BPHY_ALL_TXCORES 0x00004000 /* Transmit bphy frames using all tx cores */
|
||||
#define BFL2_FCC_BANDEDGE_WAR 0x00008000 /* Activates WAR to improve FCC bandedge performance */
|
||||
#define BFL2_DAC_SPUR_IMPROVEMENT 0x00008000 /* Reducing DAC Spurs */
|
||||
#define BFL2_GPLL_WAR2 0x00010000 /* Flag to widen G-band PLL loop b/w */
|
||||
#define BFL2_REDUCED_PA_TURNONTIME 0x00010000 /* Flag to reduce PA turn on Time */
|
||||
#define BFL2_IPALVLSHIFT_3P3 0x00020000
|
||||
#define BFL2_INTERNDET_TXIQCAL 0x00040000 /* Use internal envelope detector for TX IQCAL */
|
||||
#define BFL2_XTALBUFOUTEN 0x00080000 /* Keep the buffered Xtal output from radio on */
|
||||
/* Most drivers will turn it off without this flag */
|
||||
/* to save power. */
|
||||
|
||||
#define BFL2_ANAPACTRL_2G 0x00100000 /* 2G ext PAs are controlled by analog PA ctrl lines */
|
||||
#define BFL2_ANAPACTRL_5G 0x00200000 /* 5G ext PAs are controlled by analog PA ctrl lines */
|
||||
#define BFL2_ELNACTRL_TRSW_2G 0x00400000 /* AZW4329: 2G gmode_elna_gain controls TR Switch */
|
||||
#define BFL2_BT_SHARE_ANT0 0x00800000 /* share core0 antenna with BT */
|
||||
#define BFL2_TEMPSENSE_HIGHER 0x01000000 /* The tempsense threshold can sustain higher value
|
||||
* than programmed. The exact delta is decided by
|
||||
* driver per chip/boardtype. This can be used
|
||||
* when tempsense qualification happens after shipment
|
||||
*/
|
||||
#define BFL2_BTC3WIREONLY 0x02000000 /* standard 3 wire btc only. 4 wire not supported */
|
||||
#define BFL2_PWR_NOMINAL 0x04000000 /* 0: power reduction on, 1: no power reduction */
|
||||
#define BFL2_EXTLNA_PWRSAVE 0x08000000 /* boardflag to enable ucode to apply power save */
|
||||
/* ucode control of eLNA during Tx */
|
||||
#define BFL2_SDR_EN 0x20000000 /* SDR enabled or disabled */
|
||||
#define BFL2_DYNAMIC_VMID 0x10000000 /* boardflag to enable dynamic Vmid idle TSSI CAL */
|
||||
#define BFL2_LNA1BYPFORTR2G 0x40000000 /* acphy, enable lna1 bypass for clip gain, 2g */
|
||||
#define BFL2_LNA1BYPFORTR5G 0x80000000 /* acphy, enable lna1 bypass for clip gain, 5g */
|
||||
|
||||
/* SROM 11 - 11ac boardflag definitions */
|
||||
#define BFL_SROM11_BTCOEX 0x00000001 /* Board supports BTCOEX */
|
||||
#define BFL_SROM11_WLAN_BT_SH_XTL 0x00000002 /* bluetooth and wlan share same crystal */
|
||||
#define BFL_SROM11_EXTLNA 0x00001000 /* Board has an external LNA in 2.4GHz band */
|
||||
#define BFL_SROM11_EPA_TURNON_TIME 0x00018000 /* 2 bits for different PA turn on times */
|
||||
#define BFL_SROM11_EPA_TURNON_TIME_SHIFT 15
|
||||
#define BFL_SROM11_PRECAL_TX_IDX 0x00040000 /* Dedicated TX IQLOCAL IDX values */
|
||||
/* per subband, as derived from 43602A1 MCH5 */
|
||||
#define BFL_SROM11_EXTLNA_5GHz 0x10000000 /* Board has an external LNA in 5GHz band */
|
||||
#define BFL_SROM11_GAINBOOSTA01 0x20000000 /* 5g Gainboost for core0 and core1 */
|
||||
#define BFL2_SROM11_APLL_WAR 0x00000002 /* Flag to implement alternative A-band PLL settings */
|
||||
#define BFL2_SROM11_ANAPACTRL_2G 0x00100000 /* 2G ext PAs are ctrl-ed by analog PA ctrl lines */
|
||||
#define BFL2_SROM11_ANAPACTRL_5G 0x00200000 /* 5G ext PAs are ctrl-ed by analog PA ctrl lines */
|
||||
#define BFL2_SROM11_SINGLEANT_CCK 0x00001000 /* Tx CCK pkts on Ant 0 only */
|
||||
#define BFL2_SROM11_EPA_ON_DURING_TXIQLOCAL 0x00020000 /* Keep ext. PA's on in TX IQLO CAL */
|
||||
|
||||
/* boardflags3 */
|
||||
#define BFL3_FEMCTRL_SUB 0x00000007 /* acphy, subrevs of femctrl on top of srom_femctrl */
|
||||
#define BFL3_RCAL_WAR 0x00000008 /* acphy, rcal war active on this board (4335a0) */
|
||||
#define BFL3_TXGAINTBLID 0x00000070 /* acphy, txgain table id */
|
||||
#define BFL3_TXGAINTBLID_SHIFT 0x4 /* acphy, txgain table id shift bit */
|
||||
#define BFL3_TSSI_DIV_WAR 0x00000080 /* acphy, Seperate paparam for 20/40/80 */
|
||||
#define BFL3_TSSI_DIV_WAR_SHIFT 0x7 /* acphy, Seperate paparam for 20/40/80 shift bit */
|
||||
#define BFL3_FEMTBL_FROM_NVRAM 0x00000100 /* acphy, femctrl table is read from nvram */
|
||||
#define BFL3_FEMTBL_FROM_NVRAM_SHIFT 0x8 /* acphy, femctrl table is read from nvram */
|
||||
#define BFL3_AGC_CFG_2G 0x00000200 /* acphy, gain control configuration for 2G */
|
||||
#define BFL3_AGC_CFG_5G 0x00000400 /* acphy, gain control configuration for 5G */
|
||||
#define BFL3_PPR_BIT_EXT 0x00000800 /* acphy, bit position for 1bit extension for ppr */
|
||||
#define BFL3_PPR_BIT_EXT_SHIFT 11 /* acphy, bit shift for 1bit extension for ppr */
|
||||
#define BFL3_BBPLL_SPR_MODE_DIS 0x00001000 /* acphy, disables bbpll spur modes */
|
||||
#define BFL3_RCAL_OTP_VAL_EN 0x00002000 /* acphy, to read rcal_trim value from otp */
|
||||
#define BFL3_2GTXGAINTBL_BLANK 0x00004000 /* acphy, blank the first X ticks of 2g gaintbl */
|
||||
#define BFL3_2GTXGAINTBL_BLANK_SHIFT 14 /* acphy, blank the first X ticks of 2g gaintbl */
|
||||
#define BFL3_5GTXGAINTBL_BLANK 0x00008000 /* acphy, blank the first X ticks of 5g gaintbl */
|
||||
#define BFL3_5GTXGAINTBL_BLANK_SHIFT 15 /* acphy, blank the first X ticks of 5g gaintbl */
|
||||
#define BFL3_PHASETRACK_MAX_ALPHABETA 0x00010000 /* acphy, to max out alpha,beta to 511 */
|
||||
#define BFL3_PHASETRACK_MAX_ALPHABETA_SHIFT 16 /* acphy, to max out alpha,beta to 511 */
|
||||
/* acphy, to use backed off gaintbl for lte-coex */
|
||||
#define BFL3_LTECOEX_GAINTBL_EN 0x00060000
|
||||
/* acphy, to use backed off gaintbl for lte-coex */
|
||||
#define BFL3_LTECOEX_GAINTBL_EN_SHIFT 17
|
||||
#define BFL3_5G_SPUR_WAR 0x00080000 /* acphy, enable spur WAR in 5G band */
|
||||
#define BFL3_1X1_RSDB_ANT 0x01000000 /* to find if 2-ant RSDB board or 1-ant RSDB board */
|
||||
#define BFL3_1X1_RSDB_ANT_SHIFT 24
|
||||
|
||||
/* acphy: lpmode2g and lpmode_5g related boardflags */
|
||||
#define BFL3_ACPHY_LPMODE_2G 0x00300000 /* bits 20:21 for lpmode_2g choice */
|
||||
#define BFL3_ACPHY_LPMODE_2G_SHIFT 20
|
||||
|
||||
#define BFL3_ACPHY_LPMODE_5G 0x00C00000 /* bits 22:23 for lpmode_5g choice */
|
||||
#define BFL3_ACPHY_LPMODE_5G_SHIFT 22
|
||||
|
||||
#define BFL3_EXT_LPO_ISCLOCK 0x02000000 /* External LPO is clock, not x-tal */
|
||||
#define BFL3_FORCE_INT_LPO_SEL 0x04000000 /* Force internal lpo */
|
||||
#define BFL3_FORCE_EXT_LPO_SEL 0x08000000 /* Force external lpo */
|
||||
|
||||
#define BFL3_EN_BRCM_IMPBF 0x10000000 /* acphy, Allow BRCM Implicit TxBF */
|
||||
#define BFL3_AVVMID_FROM_NVRAM 0x40000000 /* Read Av Vmid from NVRAM */
|
||||
#define BFL3_VLIN_EN_FROM_NVRAM 0x80000000 /* Read Vlin En from NVRAM */
|
||||
|
||||
#define BFL3_AVVMID_FROM_NVRAM_SHIFT 30 /* Read Av Vmid from NVRAM */
|
||||
#define BFL3_VLIN_EN_FROM_NVRAM_SHIFT 31 /* Enable Vlin from NVRAM */
|
||||
|
||||
/* boardflags4 for SROM12/SROM13 */
|
||||
#define BFL4_SROM12_4dBPAD (1 << 0) /* To distinguigh between normal and 4dB pad board */
|
||||
#define BFL4_SROM12_2G_DETTYPE (1 << 1) /* Determine power detector type for 2G */
|
||||
#define BFL4_SROM12_5G_DETTYPE (1 << 2) /* Determine power detector type for 5G */
|
||||
#define BFL4_SROM13_DETTYPE_EN (1 << 3) /* using pa_dettype from SROM13 flags */
|
||||
#define BFL4_SROM13_CCK_SPUR_EN (1 << 4) /* using cck spur reduction setting in 4366 */
|
||||
#define BFL4_SROM13_1P5V_CBUCK (1 << 7) /* using 1.5V cbuck board in 4366 */
|
||||
#define BFL4_SROM13_EN_SW_TXRXCHAIN_MASK (1 << 8) /* Enable/disable bit for sw chain mask */
|
||||
|
||||
#define BFL4_4364_HARPOON 0x0100 /* Harpoon module 4364 */
|
||||
#define BFL4_4364_GODZILLA 0x0200 /* Godzilla module 4364 */
|
||||
#define BFL4_BTCOEX_OVER_SECI 0x00000400 /* Enable btcoex over gci seci */
|
||||
|
||||
/* papd params */
|
||||
#define PAPD_TX_ATTN_2G 0xFF
|
||||
#define PAPD_TX_ATTN_5G 0xFF00
|
||||
#define PAPD_TX_ATTN_5G_SHIFT 8
|
||||
#define PAPD_RX_ATTN_2G 0xFF
|
||||
#define PAPD_RX_ATTN_5G 0xFF00
|
||||
#define PAPD_RX_ATTN_5G_SHIFT 8
|
||||
#define PAPD_CAL_IDX_2G 0xFF
|
||||
#define PAPD_CAL_IDX_5G 0xFF00
|
||||
#define PAPD_CAL_IDX_5G_SHIFT 8
|
||||
#define PAPD_BBMULT_2G 0xFF
|
||||
#define PAPD_BBMULT_5G 0xFF00
|
||||
#define PAPD_BBMULT_5G_SHIFT 8
|
||||
#define TIA_GAIN_MODE_2G 0xFF
|
||||
#define TIA_GAIN_MODE_5G 0xFF00
|
||||
#define TIA_GAIN_MODE_5G_SHIFT 8
|
||||
#define PAPD_EPS_OFFSET_2G 0xFFFF
|
||||
#define PAPD_EPS_OFFSET_5G 0xFFFF0000
|
||||
#define PAPD_EPS_OFFSET_5G_SHIFT 16
|
||||
#define PAPD_CALREF_DB_2G 0xFF
|
||||
#define PAPD_CALREF_DB_5G 0xFF00
|
||||
#define PAPD_CALREF_DB_5G_SHIFT 8
|
||||
|
||||
/* board specific GPIO assignment, gpio 0-3 are also customer-configurable led */
|
||||
#define BOARD_GPIO_BTC3W_IN 0x850 /* bit 4 is RF_ACTIVE, bit 6 is STATUS, bit 11 is PRI */
|
||||
#define BOARD_GPIO_BTC3W_OUT 0x020 /* bit 5 is TX_CONF */
|
||||
#define BOARD_GPIO_BTCMOD_IN 0x010 /* bit 4 is the alternate BT Coexistence Input */
|
||||
#define BOARD_GPIO_BTCMOD_OUT 0x020 /* bit 5 is the alternate BT Coexistence Out */
|
||||
#define BOARD_GPIO_BTC_IN 0x080 /* bit 7 is BT Coexistence Input */
|
||||
#define BOARD_GPIO_BTC_OUT 0x100 /* bit 8 is BT Coexistence Out */
|
||||
#define BOARD_GPIO_PACTRL 0x200 /* bit 9 controls the PA on new 4306 boards */
|
||||
#define BOARD_GPIO_12 0x1000 /* gpio 12 */
|
||||
#define BOARD_GPIO_13 0x2000 /* gpio 13 */
|
||||
#define BOARD_GPIO_BTC4_IN 0x0800 /* gpio 11, coex4, in */
|
||||
#define BOARD_GPIO_BTC4_BT 0x2000 /* gpio 12, coex4, bt active */
|
||||
#define BOARD_GPIO_BTC4_STAT 0x4000 /* gpio 14, coex4, status */
|
||||
#define BOARD_GPIO_BTC4_WLAN 0x8000 /* gpio 15, coex4, wlan active */
|
||||
#define BOARD_GPIO_1_WLAN_PWR 0x02 /* throttle WLAN power on X21 board */
|
||||
#define BOARD_GPIO_2_WLAN_PWR 0x04 /* throttle WLAN power on X29C board */
|
||||
#define BOARD_GPIO_3_WLAN_PWR 0x08 /* throttle WLAN power on X28 board */
|
||||
#define BOARD_GPIO_4_WLAN_PWR 0x10 /* throttle WLAN power on X19 board */
|
||||
#define BOARD_GPIO_13_WLAN_PWR 0x2000 /* throttle WLAN power on X14 board */
|
||||
|
||||
#define GPIO_BTC4W_OUT_4312 0x010 /* bit 4 is BT_IODISABLE */
|
||||
|
||||
#define PCI_CFG_GPIO_SCS 0x10 /* PCI config space bit 4 for 4306c0 slow clock source */
|
||||
#define PCI_CFG_GPIO_HWRAD 0x20 /* PCI config space GPIO 13 for hw radio disable */
|
||||
#define PCI_CFG_GPIO_XTAL 0x40 /* PCI config space GPIO 14 for Xtal power-up */
|
||||
#define PCI_CFG_GPIO_PLL 0x80 /* PCI config space GPIO 15 for PLL power-down */
|
||||
|
||||
/* power control defines */
|
||||
#define PLL_DELAY 150 /* us pll on delay */
|
||||
#define FREF_DELAY 200 /* us fref change delay */
|
||||
#define MIN_SLOW_CLK 32 /* us Slow clock period */
|
||||
#define XTAL_ON_DELAY 1000 /* us crystal power-on delay */
|
||||
|
||||
/* 43012 wlbga Board */
|
||||
#define BCM943012WLREF_SSID 0x07d7
|
||||
|
||||
/* 43012 fcbga Board */
|
||||
#define BCM943012FCREF_SSID 0x07d4
|
||||
|
||||
/* 43602 Boards, unclear yet what boards will be created. */
|
||||
#define BCM943602RSVD1_SSID 0x06a5
|
||||
#define BCM943602RSVD2_SSID 0x06a6
|
||||
#define BCM943602X87 0X0133
|
||||
#define BCM943602X87P2 0X0152
|
||||
#define BCM943602X87P3 0X0153
|
||||
#define BCM943602X238 0X0132
|
||||
#define BCM943602X238D 0X014A
|
||||
#define BCM943602X238DP2 0X0155
|
||||
#define BCM943602X238DP3 0X0156
|
||||
#define BCM943602X100 0x0761
|
||||
#define BCM943602X100GS 0x0157
|
||||
#define BCM943602X100P2 0x015A
|
||||
|
||||
/* # of GPIO pins */
|
||||
#define GPIO_NUMPINS 32
|
||||
|
||||
/* These values are used by dhd host driver. */
|
||||
#define RDL_RAM_BASE_4319 0x60000000
|
||||
#define RDL_RAM_BASE_4329 0x60000000
|
||||
#define RDL_RAM_SIZE_4319 0x48000
|
||||
#define RDL_RAM_SIZE_4329 0x48000
|
||||
#define RDL_RAM_SIZE_43236 0x70000
|
||||
#define RDL_RAM_BASE_43236 0x60000000
|
||||
#define RDL_RAM_SIZE_4328 0x60000
|
||||
#define RDL_RAM_BASE_4328 0x80000000
|
||||
#define RDL_RAM_SIZE_4322 0x60000
|
||||
#define RDL_RAM_BASE_4322 0x60000000
|
||||
#define RDL_RAM_SIZE_4360 0xA0000
|
||||
#define RDL_RAM_BASE_4360 0x60000000
|
||||
#define RDL_RAM_SIZE_43242 0x90000
|
||||
#define RDL_RAM_BASE_43242 0x60000000
|
||||
#define RDL_RAM_SIZE_43143 0x70000
|
||||
#define RDL_RAM_BASE_43143 0x60000000
|
||||
#define RDL_RAM_SIZE_4350 0xC0000
|
||||
#define RDL_RAM_BASE_4350 0x180800
|
||||
|
||||
/* generic defs for nvram "muxenab" bits
|
||||
* Note: these differ for 4335a0. refer bcmchipc.h for specific mux options.
|
||||
*/
|
||||
#define MUXENAB_UART 0x00000001
|
||||
#define MUXENAB_GPIO 0x00000002
|
||||
#define MUXENAB_ERCX 0x00000004 /* External Radio BT coex */
|
||||
#define MUXENAB_JTAG 0x00000008
|
||||
#define MUXENAB_HOST_WAKE 0x00000010 /* configure GPIO for SDIO host_wake */
|
||||
#define MUXENAB_I2S_EN 0x00000020
|
||||
#define MUXENAB_I2S_MASTER 0x00000040
|
||||
#define MUXENAB_I2S_FULL 0x00000080
|
||||
#define MUXENAB_SFLASH 0x00000100
|
||||
#define MUXENAB_RFSWCTRL0 0x00000200
|
||||
#define MUXENAB_RFSWCTRL1 0x00000400
|
||||
#define MUXENAB_RFSWCTRL2 0x00000800
|
||||
#define MUXENAB_SECI 0x00001000
|
||||
#define MUXENAB_BT_LEGACY 0x00002000
|
||||
#define MUXENAB_HOST_WAKE1 0x00004000 /* configure alternative GPIO for SDIO host_wake */
|
||||
|
||||
/* Boot flags */
|
||||
#define FLASH_KERNEL_NFLASH 0x00000001
|
||||
#define FLASH_BOOT_NFLASH 0x00000002
|
||||
|
||||
#endif /* _BCMDEVS_H */
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user