hopes and dreams
This commit is contained in:
commit
772a90e391
147 changed files with 80636 additions and 0 deletions
BIN
AX900 Deb驱动安装教程_Linux_V3.0.pdf
Normal file
BIN
AX900 Deb驱动安装教程_Linux_V3.0.pdf
Normal file
Binary file not shown.
BIN
aic8800d80fdrvpackage.deb
Normal file
BIN
aic8800d80fdrvpackage.deb
Normal file
Binary file not shown.
BIN
control.tar.gz
Normal file
BIN
control.tar.gz
Normal file
Binary file not shown.
BIN
data.tar.gz
Normal file
BIN
data.tar.gz
Normal file
Binary file not shown.
1
debian-binary
Normal file
1
debian-binary
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
2.0
|
||||||
4
usr/src/AIC8800/aic.rules
Normal file
4
usr/src/AIC8800/aic.rules
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
KERNEL=="sd*", ATTRS{idVendor}=="a69c", ATTRS{idProduct}=="5721", SYMLINK+="aicudisk", RUN+="/usr/bin/eject /dev/%k"
|
||||||
|
KERNEL=="sd*", ATTRS{idVendor}=="a69c", ATTRS{idProduct}=="5723", SYMLINK+="tendaudisk", RUN+="/usr/bin/eject /dev/%k"
|
||||||
|
KERNEL=="sd*", ATTRS{idVendor}=="a69c", ATTRS{idProduct}=="5724", SYMLINK+="ugreenudisk", RUN+="/usr/bin/eject /dev/%k"
|
||||||
|
|
||||||
10
usr/src/AIC8800/drivers/aic8800/Kconfig
Normal file
10
usr/src/AIC8800/drivers/aic8800/Kconfig
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
config AIC_WLAN_SUPPORT
|
||||||
|
bool "AIC wireless Support"
|
||||||
|
default n
|
||||||
|
help
|
||||||
|
This is support for aic wireless chip.
|
||||||
|
|
||||||
|
if AIC_WLAN_SUPPORT
|
||||||
|
source "drivers/net/wireless/aic8800/aic8800_fdrv/Kconfig"
|
||||||
|
source "drivers/net/wireless/aic8800/aic_load_fw/Kconfig"
|
||||||
|
endif
|
||||||
80
usr/src/AIC8800/drivers/aic8800/Makefile
Normal file
80
usr/src/AIC8800/drivers/aic8800/Makefile
Normal file
|
|
@ -0,0 +1,80 @@
|
||||||
|
CONFIG_AIC_LOADFW_SUPPORT := m
|
||||||
|
CONFIG_AIC8800_WLAN_SUPPORT := m
|
||||||
|
|
||||||
|
obj-$(CONFIG_AIC_LOADFW_SUPPORT) += aic_load_fw/
|
||||||
|
obj-$(CONFIG_AIC8800_WLAN_SUPPORT) += aic8800_fdrv/
|
||||||
|
|
||||||
|
########## config option ##########
|
||||||
|
export CONFIG_USE_FW_REQUEST = n
|
||||||
|
export CONFIG_PREALLOC_RX_SKB = y
|
||||||
|
export CONFIG_PREALLOC_TXQ = y
|
||||||
|
###################################
|
||||||
|
|
||||||
|
########## platform support list ##########
|
||||||
|
export CONFIG_PLATFORM_ROCKCHIP = n
|
||||||
|
export CONFIG_PLATFORM_ALLWINNER = n
|
||||||
|
export CONFIG_PLATFORM_AMLOGIC = n
|
||||||
|
export CONFIG_PLATFORM_HI = n
|
||||||
|
export CONFIG_PLATFORM_UBUNTU = y
|
||||||
|
|
||||||
|
ifeq ($(CONFIG_PLATFORM_ROCKCHIP), y)
|
||||||
|
ARCH = arm64
|
||||||
|
KDIR = /home/yaya/E/Rockchip/3566/firefly/Android11.0/Firefly-RK356X_Android11.0_git_20210824/RK356X_Android11.0/kernel
|
||||||
|
CROSS_COMPILE = /home/yaya/E/Rockchip/3566/firefly/Android11.0/Firefly-RK356X_Android11.0_git_20210824/RK356X_Android11.0/prebuilts/gcc/linux-x86/aarch64/gcc-linaro-6.3.1-2017.05-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-
|
||||||
|
ccflags-y += -DANDROID_PLATFORM
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq ($(CONFIG_PLATFORM_ALLWINNER), y)
|
||||||
|
KDIR = /home/yaya/E/Allwinner/R818/R818/AndroidQ/lichee/kernel/linux-4.9
|
||||||
|
ARCH = arm64
|
||||||
|
CROSS_COMPILE = /home/yaya/E/Allwinner/R818/R818/AndroidQ/lichee/out/gcc-linaro-5.3.1-2016.05-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-
|
||||||
|
ccflags-y += -DANDROID_PLATFORM
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq ($(CONFIG_PLATFORM_AMLOGIC), y)
|
||||||
|
ccflags-y += -DANDROID_PLATFORM
|
||||||
|
ARCH = arm
|
||||||
|
CROSS_COMPILE = /home/yaya/D/Workspace/CyberQuantum/JinHaoYue/amls905x3/SDK/20191101-0tt-asop/android9.0/prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.9/bin/arm-linux-androidkernel-
|
||||||
|
KDIR = /home/yaya/D/Workspace/CyberQuantum/JinHaoYue/amls905x3/SDK/20191101-0tt-asop/android9.0/out/target/product/u202/obj/KERNEL_OBJ/
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq ($(CONFIG_PLATFORM_HI), y)
|
||||||
|
ccflags-y += -DANDROID_PLATFORM
|
||||||
|
ARCH = arm
|
||||||
|
CROSS_COMPILE = /home/yaya/D/Workspace/CyberQuantum/JinHaoYue/amls905x3/SDK/20191101-0tt-asop/android9.0/prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.9/bin/arm-linux-androidkernel-
|
||||||
|
KDIR = /home/yaya/D/Workspace/CyberQuantum/JinHaoYue/amls905x3/SDK/20191101-0tt-asop/android9.0/out/target/product/u202/obj/KERNEL_OBJ/
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq ($(CONFIG_PLATFORM_UBUNTU), y)
|
||||||
|
KDIR = /lib/modules/$(shell uname -r)/build
|
||||||
|
PWD = $(shell pwd)
|
||||||
|
KVER = $(shell uname -r)
|
||||||
|
MODDESTDIR = /lib/modules/$(KVER)/kernel/drivers/net/wireless/aic8800
|
||||||
|
SUBARCH = $(shell uname -m | sed -e s/i.86/i386/ -e s/armv.l/arm/ -e s/aarch64/arm64/ -e s/loongarch64/loongarch/ -e s/loong64/loongarch/)
|
||||||
|
ARCH ?= $(SUBARCH)
|
||||||
|
CROSS_COMPILE ?=
|
||||||
|
endif
|
||||||
|
|
||||||
|
###########################################
|
||||||
|
|
||||||
|
MAKEFLAGS +=-j$(shell nproc)
|
||||||
|
|
||||||
|
all: modules
|
||||||
|
modules:
|
||||||
|
make -C $(KDIR) M=$(PWD) ARCH=$(ARCH) CROSS_COMPILE=$(CROSS_COMPILE) modules
|
||||||
|
|
||||||
|
install:
|
||||||
|
mkdir -p $(MODDESTDIR)
|
||||||
|
install -p -m 644 aic_load_fw/aic_load_fw.ko $(MODDESTDIR)/
|
||||||
|
install -p -m 644 aic8800_fdrv/aic8800_fdrv.ko $(MODDESTDIR)/
|
||||||
|
/sbin/depmod -a ${KVER}
|
||||||
|
|
||||||
|
uninstall:
|
||||||
|
rm -rfv $(MODDESTDIR)/aic_load_fw.ko
|
||||||
|
rm -rfv $(MODDESTDIR)/aic8800_fdrv.ko
|
||||||
|
/sbin/depmod -a ${KVER}
|
||||||
|
|
||||||
|
clean:
|
||||||
|
cd aic_load_fw/;make clean;cd ..
|
||||||
|
cd aic8800_fdrv/;make clean;cd ..
|
||||||
|
rm -rf modules.order Module.symvers .modules.order.cmd .Module.symvers.cmd .tmp_versions/
|
||||||
36
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/Kconfig
Normal file
36
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/Kconfig
Normal file
|
|
@ -0,0 +1,36 @@
|
||||||
|
config AIC8800_WLAN_SUPPORT
|
||||||
|
tristate "AIC8800 wlan Support"
|
||||||
|
help
|
||||||
|
This is support for aic wifi driver.
|
||||||
|
|
||||||
|
#choice
|
||||||
|
# depends on AIC8800_WLAN_SUPPORT
|
||||||
|
# prompt "Select 8800 support platform"
|
||||||
|
#
|
||||||
|
# config PLATFORM_ROCHCHIP
|
||||||
|
# bool "PLATFORM_ROCHCHIP"
|
||||||
|
# depends on AIC8800_WLAN_SUPPORT
|
||||||
|
#
|
||||||
|
# config PLATFORM_ALLWINNER
|
||||||
|
# bool "PLATFORM_ALLWINNER"
|
||||||
|
# depends on AIC8800_WLAN_SUPPORT
|
||||||
|
#
|
||||||
|
# config PLATFORM_AMLOGIC
|
||||||
|
# bool "PLATFORM_AMLOGIC"
|
||||||
|
# depends on AIC8800_WLAN_SUPPORT
|
||||||
|
#
|
||||||
|
# config PLATFORM_UBUNTU
|
||||||
|
# bool "PLATFORM_UBUNTU"
|
||||||
|
# depends on AIC8800_WLAN_SUPPORT
|
||||||
|
#
|
||||||
|
#endchoice
|
||||||
|
#
|
||||||
|
#config USE_5G
|
||||||
|
# bool "AIC8800 force enable 5G"
|
||||||
|
# ---help---
|
||||||
|
# This is parameter that force enable 5G.
|
||||||
|
#
|
||||||
|
#config HE_FOR_OLD_KERNEL
|
||||||
|
# bool "AIC8800 support AX for old kernel"
|
||||||
|
# ---help---
|
||||||
|
# This is parameter that enable AX for old kernel.
|
||||||
412
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/Makefile
Normal file
412
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/Makefile
Normal file
|
|
@ -0,0 +1,412 @@
|
||||||
|
EXTRA_CFLAGS += $(USER_EXTRA_CFLAGS)
|
||||||
|
EXTRA_CFLAGS += -Wno-implicit-fallthrough
|
||||||
|
#EXTRA_CFLAGS += -Wno-unused-variable
|
||||||
|
|
||||||
|
RWNX_VERS_NUM := 6.4.3.0
|
||||||
|
|
||||||
|
CONFIG_AIC8800_WLAN_SUPPORT = m
|
||||||
|
MODULE_NAME = aic8800_fdrv
|
||||||
|
CONFIG_COUNTRY_CODE = "00"
|
||||||
|
|
||||||
|
# Support of bootrom start
|
||||||
|
CONFIG_START_FROM_BOOTROM = y
|
||||||
|
|
||||||
|
# Support of pmic setting, new version bootrom avaliable
|
||||||
|
CONFIG_PMIC_SETTING ?=n
|
||||||
|
|
||||||
|
# Select 8800DC/DW DCDC_VRF mode, check your board
|
||||||
|
CONFIG_VRF_DCDC_MODE = y
|
||||||
|
|
||||||
|
# ROM patch enabled option
|
||||||
|
CONFIG_ROM_PATCH_EN ?=y
|
||||||
|
|
||||||
|
#
|
||||||
|
# WAITING FOR KCONFIG {
|
||||||
|
#
|
||||||
|
CONFIG_RWNX_SOFTMAC ?= n
|
||||||
|
CONFIG_RWNX_FULLMAC ?= y
|
||||||
|
CONFIG_RWNX_FHOST ?= n
|
||||||
|
|
||||||
|
#
|
||||||
|
# DEBUG OPTIONS
|
||||||
|
CONFIG_RWNX_UM_HELPER_DFLT ?= "/dini/dini_bin/rwnx_umh.sh"
|
||||||
|
CONFIG_AIC_FW_PATH = "/vendor/etc/firmware"
|
||||||
|
export CONFIG_AIC_FW_PATH
|
||||||
|
|
||||||
|
#
|
||||||
|
# FW ARCH:
|
||||||
|
CONFIG_RWNX_SDM ?= n
|
||||||
|
CONFIG_RWNX_TL4 ?= n
|
||||||
|
|
||||||
|
# IPC version
|
||||||
|
CONFIG_RWNX_OLD_IPC ?= n
|
||||||
|
|
||||||
|
# Support of P2P DebugFS for enabling/disabling NoA and OppPS
|
||||||
|
CONFIG_RWNX_P2P_DEBUGFS ?= y
|
||||||
|
|
||||||
|
#
|
||||||
|
# } // WAITING FOR KCONFIG
|
||||||
|
#
|
||||||
|
|
||||||
|
# Enable A-MSDU support (need FW support)
|
||||||
|
## Select this if FW is compiled with AMSDU support
|
||||||
|
CONFIG_RWNX_SPLIT_TX_BUF ?= n
|
||||||
|
## Select this TO send AMSDU
|
||||||
|
CONFIG_RWNX_AMSDUS_TX ?= n
|
||||||
|
|
||||||
|
# Enable BFMER support (need FW support)
|
||||||
|
CONFIG_RWNX_BFMER ?= n
|
||||||
|
|
||||||
|
CONFIG_SDIO_SUPPORT =n
|
||||||
|
CONFIG_USB_SUPPORT =y
|
||||||
|
CONFIG_RX_REORDER =y
|
||||||
|
CONFIG_ARP_OFFLOAD =y
|
||||||
|
CONFIG_USE_5G = y
|
||||||
|
CONFIG_RADAR_OR_IR_DETECT =n
|
||||||
|
CONFIG_DOWNLOAD_FW =n
|
||||||
|
CONFIG_RFTEST=y
|
||||||
|
CONFIG_USB_BT=y
|
||||||
|
CONFIG_MAC_RANDOM_IF_NO_MAC_IN_EFUSE = y
|
||||||
|
CONFIG_WPA3_FOR_OLD_KERNEL = n
|
||||||
|
CONFIG_HE_FOR_OLD_KERNEL = n
|
||||||
|
CONFIG_VHT_FOR_OLD_KERNEL = n
|
||||||
|
# CONFIG_COEX = n for BT_ONLY, CONFIG_COEX =y for combo and sw
|
||||||
|
CONFIG_COEX = y
|
||||||
|
CONFIG_ALIGN_8BYTES = y
|
||||||
|
CONFIG_TXRX_THREAD_PRIO = y
|
||||||
|
CONFIG_USB_ALIGN_DATA = y
|
||||||
|
CONFIG_RX_TASKLET = n
|
||||||
|
CONFIG_TX_TASKLET = n
|
||||||
|
CONFIG_RX_NETIF_RECV_SKB = y
|
||||||
|
CONFIG_BR_SUPPORT = n
|
||||||
|
CONFIG_USB_MSG_OUT_EP = y
|
||||||
|
CONFIG_USB_MSG_IN_EP = y
|
||||||
|
CONFIG_USB_RX_REASSEMBLE = n
|
||||||
|
CONFIG_WOWLAN = n
|
||||||
|
|
||||||
|
#DCDW support tx aggr, D80 support both
|
||||||
|
CONFIG_USB_RX_AGGR = n
|
||||||
|
CONFIG_USB_TX_AGGR = n
|
||||||
|
|
||||||
|
CONFIG_USB_NO_TRANS_DMA_MAP = n
|
||||||
|
CONFIG_GPIO_WAKEUP = n
|
||||||
|
CONFIG_CREATE_TRACE_POINTS = n
|
||||||
|
CONFIG_SUPPORT_REALTIME_CHANGE_MAC = y
|
||||||
|
CONFIG_USE_USB_ZERO_PACKET = y
|
||||||
|
CONFIG_DEBUG_FS = n
|
||||||
|
CONFIG_STA_SCAN_WHEN_P2P_WORKING = y
|
||||||
|
CONFIG_SET_VENDOR_EXTENSION_IE = n
|
||||||
|
CONFIG_VENDOR_GPIO = n
|
||||||
|
CONFIG_FWLOG_EN = n
|
||||||
|
CONFIG_FOR_IPCAM = n
|
||||||
|
CONFIG_5M10M = n
|
||||||
|
# Need to set fw path in BOARD_KERNEL_CMDLINE
|
||||||
|
CONFIG_USE_FW_REQUEST ?= n
|
||||||
|
CONFIG_USE_P2P0 = n
|
||||||
|
CONFIG_ONE_TXQ = n
|
||||||
|
CONFIG_PER_STA_FC = n
|
||||||
|
CONFIG_PREALLOC_RX_SKB ?= n
|
||||||
|
CONFIG_PREALLOC_TXQ ?= y
|
||||||
|
CONFIG_USE_WIRELESS_EXT = y
|
||||||
|
CONFIG_DPD = y
|
||||||
|
CONFIG_FORCE_DPD_CALIB = y
|
||||||
|
CONFIG_LOFT_CALIB = n
|
||||||
|
CONFIG_GKI = n
|
||||||
|
CONFIG_SCHED_SCAN = n
|
||||||
|
CONFIG_TEMP_COMP = n
|
||||||
|
CONFIG_POWER_LIMIT = n
|
||||||
|
CONFIG_EXT_FEM_8800DCDW = n
|
||||||
|
# CONFIG_MCC = n for sta and p2p concurrent in same channel.
|
||||||
|
CONFIG_MCC = y
|
||||||
|
CONFIG_LOAD_BT_PATCH_IN_FDRV = n
|
||||||
|
CONFIG_DYNAMIC_PWR = n
|
||||||
|
CONFIG_DYNAMIC_PERPWR = n
|
||||||
|
CONFIG_BAND_STEERING = n
|
||||||
|
CONFIG_PRBREQ_REPORT = n
|
||||||
|
|
||||||
|
#support D80X2 can write rf result to file
|
||||||
|
CONFIG_WRITE_FILE_D80X2 = n
|
||||||
|
|
||||||
|
ifneq ($(CONFIG_WIRELESS_EXT), y)
|
||||||
|
CONFIG_USE_WIRELESS_EXT = n
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq ($(CONFIG_EXT_FEM_8800DCDW), y)
|
||||||
|
CONFIG_DPD = n
|
||||||
|
CONFIG_FORCE_DPD_CALIB = n
|
||||||
|
CONFIG_LOFT_CALIB = y
|
||||||
|
endif
|
||||||
|
|
||||||
|
# Support of MU-MIMO transmission (need FW support)
|
||||||
|
ifeq ($(CONFIG_RWNX_BFMER), y)
|
||||||
|
CONFIG_RWNX_MUMIMO_TX ?= n
|
||||||
|
else
|
||||||
|
CONFIG_RWNX_MUMIMO_TX = n
|
||||||
|
endif
|
||||||
|
|
||||||
|
# Enable handling of radar event
|
||||||
|
CONFIG_RWNX_RADAR ?= y
|
||||||
|
|
||||||
|
# Enable HW queue for Broadcast/Multicast traffic (need FW support)
|
||||||
|
CONFIG_RWNX_BCMC ?= y
|
||||||
|
|
||||||
|
# Enable Monitor+Data interface support (need FW support)
|
||||||
|
CONFIG_RWNX_MON_DATA =n
|
||||||
|
CONFIG_RWNX_MON_XMIT ?= n
|
||||||
|
CONFIG_RWNX_MON_RXFILTER ?= n
|
||||||
|
|
||||||
|
CONFIG_FILTER_TCP_ACK =y
|
||||||
|
|
||||||
|
# extra DEBUG config
|
||||||
|
CONFIG_RWNX_SW_PROFILING ?= n
|
||||||
|
CONFIG_RWNX_DBG ?= y
|
||||||
|
BR_NAME = br0
|
||||||
|
|
||||||
|
obj-$(CONFIG_AIC8800_WLAN_SUPPORT) := $(MODULE_NAME).o
|
||||||
|
$(MODULE_NAME)-y := \
|
||||||
|
rwnx_wakelock.o \
|
||||||
|
rwnx_msg_tx.o \
|
||||||
|
rwnx_msg_rx.o \
|
||||||
|
rwnx_utils.o \
|
||||||
|
rwnx_cmds.o \
|
||||||
|
rwnx_irqs.o \
|
||||||
|
rwnx_cfgfile.o \
|
||||||
|
rwnx_strs.o \
|
||||||
|
rwnx_rx.o \
|
||||||
|
rwnx_tx.o \
|
||||||
|
rwnx_txq.o \
|
||||||
|
rwnx_main.o \
|
||||||
|
rwnx_mod_params.o \
|
||||||
|
rwnx_mesh.o \
|
||||||
|
rwnx_platform.o \
|
||||||
|
rwnx_pci.o \
|
||||||
|
rwnx_dini.o \
|
||||||
|
rwnx_v7.o \
|
||||||
|
ipc_host.o \
|
||||||
|
rwnx_tdls.o \
|
||||||
|
regdb.o \
|
||||||
|
md5.o \
|
||||||
|
aic_vendor.o \
|
||||||
|
aic_priv_cmd.o \
|
||||||
|
aicwf_compat_8800dc.o \
|
||||||
|
aicwf_compat_8800d80.o \
|
||||||
|
aicwf_compat_8800d80x2.o
|
||||||
|
|
||||||
|
$(MODULE_NAME)-$(CONFIG_BAND_STEERING) += aicwf_manager.o \
|
||||||
|
aicwf_steering.o
|
||||||
|
$(MODULE_NAME)-$(CONFIG_BR_SUPPORT) += aic_br_ext.o
|
||||||
|
$(MODULE_NAME)-$(CONFIG_RWNX_RADAR) += rwnx_radar.o
|
||||||
|
$(MODULE_NAME)-$(CONFIG_DEBUG_FS) += rwnx_debugfs.o
|
||||||
|
$(MODULE_NAME)-$(CONFIG_DEBUG_FS) += rwnx_fw_trace.o
|
||||||
|
$(MODULE_NAME)-$(CONFIG_NL80211_TESTMODE) += rwnx_testmode.o
|
||||||
|
$(MODULE_NAME)-$(CONFIG_RWNX_BFMER) += rwnx_bfmer.o
|
||||||
|
$(MODULE_NAME)-$(CONFIG_RWNX_MUMIMO_TX) += rwnx_mu_group.o
|
||||||
|
$(MODULE_NAME)-$(CONFIG_SDIO_SUPPORT) += sdio_host.o
|
||||||
|
$(MODULE_NAME)-$(CONFIG_SDIO_SUPPORT) += aicwf_txrxif.o
|
||||||
|
$(MODULE_NAME)-$(CONFIG_SDIO_SUPPORT) += aicwf_sdio.o
|
||||||
|
$(MODULE_NAME)-$(CONFIG_FILTER_TCP_ACK) += aicwf_tcp_ack.o
|
||||||
|
|
||||||
|
$(MODULE_NAME)-$(CONFIG_USB_SUPPORT) += usb_host.o
|
||||||
|
$(MODULE_NAME)-$(CONFIG_USB_SUPPORT) += aicwf_txrxif.o
|
||||||
|
$(MODULE_NAME)-$(CONFIG_USB_SUPPORT) += aicwf_usb.o
|
||||||
|
$(MODULE_NAME)-$(CONFIG_USE_WIRELESS_EXT) += aicwf_wext_linux.o
|
||||||
|
$(MODULE_NAME)-$(CONFIG_GKI) += rwnx_gki.o
|
||||||
|
|
||||||
|
ccflags-$(CONFIG_DEBUG_FS) += -DCONFIG_RWNX_DEBUGFS
|
||||||
|
ccflags-$(CONFIG_DEBUG_FS) += -DCONFIG_RWNX_UM_HELPER_DFLT=\"$(CONFIG_RWNX_UM_HELPER_DFLT)\"
|
||||||
|
ccflags-$(CONFIG_RWNX_P2P_DEBUGFS) += -DCONFIG_RWNX_P2P_DEBUGFS
|
||||||
|
|
||||||
|
# FW VARS
|
||||||
|
ccflags-y += -DNX_VIRT_DEV_MAX=4
|
||||||
|
|
||||||
|
#for 8800D and DCDW u01
|
||||||
|
#ccflags-y += -DNX_REMOTE_STA_MAX=8
|
||||||
|
|
||||||
|
#for 8800DCDW u02
|
||||||
|
ccflags-y += -DNX_REMOTE_STA_MAX_FOR_OLD_IC=8
|
||||||
|
ccflags-y += -DNX_REMOTE_STA_MAX=32
|
||||||
|
|
||||||
|
ccflags-y += -DNX_MU_GROUP_MAX=62
|
||||||
|
ccflags-y += -DNX_TXDESC_CNT=64
|
||||||
|
ccflags-y += -DNX_TX_MAX_RATES=4
|
||||||
|
ccflags-y += -DNX_CHAN_CTXT_CNT=3
|
||||||
|
|
||||||
|
# FW ARCH:
|
||||||
|
ccflags-$(CONFIG_RWNX_SDM) += -DCONFIG_RWNX_SDM
|
||||||
|
ccflags-$(CONFIG_RWNX_TL4) += -DCONFIG_RWNX_TL4
|
||||||
|
ccflags-$(CONFIG_RWNX_OLD_IPC) += -DCONFIG_RWNX_OLD_IPC
|
||||||
|
ccflags-$(CONFIG_START_FROM_BOOTROM) += -DCONFIG_START_FROM_BOOTROM
|
||||||
|
ccflags-$(CONFIG_PMIC_SETTING) += -DCONFIG_PMIC_SETTING
|
||||||
|
ccflags-$(CONFIG_VRF_DCDC_MODE) += -DCONFIG_VRF_DCDC_MODE
|
||||||
|
ccflags-$(CONFIG_ROM_PATCH_EN) += -DCONFIG_ROM_PATCH_EN
|
||||||
|
ccflags-$(CONFIG_WPA3_FOR_OLD_KERNEL) += -DCONFIG_WPA3_FOR_OLD_KERNEL
|
||||||
|
ccflags-$(CONFIG_HE_FOR_OLD_KERNEL) += -DCONFIG_HE_FOR_OLD_KERNEL
|
||||||
|
ccflags-$(CONFIG_VHT_FOR_OLD_KERNEL) += -DCONFIG_VHT_FOR_OLD_KERNEL
|
||||||
|
ccflags-$(CONFIG_COEX) += -DCONFIG_COEX
|
||||||
|
|
||||||
|
ccflags-y += -DCONFIG_RWNX_FULLMAC
|
||||||
|
ccflags-y += -I$(src)/.
|
||||||
|
ccflags-$(CONFIG_RWNX_RADAR) += -DCONFIG_RWNX_RADAR
|
||||||
|
ccflags-$(CONFIG_RWNX_MON_DATA) += -DCONFIG_RWNX_MON_DATA
|
||||||
|
ccflags-$(CONFIG_RWNX_MON_XMIT) += -DCONFIG_RWNX_MON_XMIT
|
||||||
|
ccflags-$(CONFIG_RWNX_MON_RXFILTER) += -DCONFIG_RWNX_MON_RXFILTER
|
||||||
|
ccflags-$(CONFIG_RWNX_BFMER) += -DCONFIG_RWNX_BFMER
|
||||||
|
ccflags-$(CONFIG_RWNX_SPLIT_TX_BUF) += -DCONFIG_RWNX_SPLIT_TX_BUF
|
||||||
|
ifeq ($(CONFIG_RWNX_SPLIT_TX_BUF), y)
|
||||||
|
ccflags-$(CONFIG_RWNX_AMSDUS_TX) += -DCONFIG_RWNX_AMSDUS_TX
|
||||||
|
endif
|
||||||
|
ccflags-$(CONFIG_RWNX_DBG) += -DCONFIG_RWNX_DBG
|
||||||
|
ccflags-$(CONFIG_RWNX_SW_PROFILING) += -DCONFIG_RWNX_SW_PROFILING
|
||||||
|
ccflags-$(CONFIG_RWNX_MUMIMO_TX) += -DCONFIG_RWNX_MUMIMO_TX
|
||||||
|
ccflags-$(CONFIG_RFTEST) += -DCONFIG_RFTEST
|
||||||
|
ccflags-$(CONFIG_MCC) += -DCONFIG_MCC
|
||||||
|
ccflags-$(CONFIG_LOAD_BT_PATCH_IN_FDRV) += -DCONFIG_LOAD_BT_PATCH_IN_FDRV
|
||||||
|
ccflags-$(CONFIG_DYNAMIC_PWR) += -DCONFIG_DYNAMIC_PWR
|
||||||
|
ccflags-$(CONFIG_DYNAMIC_PERPWR) += -DCONFIG_DYNAMIC_PERPWR
|
||||||
|
ccflags-$(CONFIG_BAND_STEERING) += -DCONFIG_BAND_STEERING
|
||||||
|
ccflags-$(CONFIG_PRBREQ_REPORT) += -DCONFIG_PRBREQ_REPORT
|
||||||
|
ccflags-$(CONFIG_WRITE_FILE_D80X2) += -DRF_WRITE_FILE
|
||||||
|
|
||||||
|
ifeq ($(CONFIG_SDIO_SUPPORT), y)
|
||||||
|
ccflags-y += -DAICWF_SDIO_SUPPORT
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq ($(CONFIG_USB_SUPPORT), y)
|
||||||
|
ccflags-y += -DAICWF_USB_SUPPORT
|
||||||
|
endif
|
||||||
|
ifeq ($(CONFIG_BR_SUPPORT), y)
|
||||||
|
ccflags-y += -DCONFIG_BR_SUPPORT
|
||||||
|
ccflags-y += '-DCONFIG_BR_SUPPORT_BRNAME="'$(BR_NAME)'"'
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq ($(CONFIG_RWNX_MUMIMO_TX), y)
|
||||||
|
ccflags-y += -DCONFIG_USER_MAX=2
|
||||||
|
else
|
||||||
|
ccflags-y += -DCONFIG_USER_MAX=1
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq ($(CONFIG_RWNX_BCMC), y)
|
||||||
|
ccflags-y += -DNX_TXQ_CNT=5
|
||||||
|
else
|
||||||
|
ccflags-y += -DNX_TXQ_CNT=4
|
||||||
|
endif
|
||||||
|
|
||||||
|
# For old kernel (<=3.19)
|
||||||
|
ifeq ($(shell test $(VERSION) -lt 4 -a "$(CONFIG_VENDOR_RWNX)" = y ; echo $$?),0)
|
||||||
|
ccflags-y += -DCONFIG_VENDOR_RWNX_VHT_NO80
|
||||||
|
endif
|
||||||
|
|
||||||
|
ccflags-$(CONFIG_RX_REORDER) += -DAICWF_RX_REORDER
|
||||||
|
ccflags-$(CONFIG_ARP_OFFLOAD) += -DAICWF_ARP_OFFLOAD
|
||||||
|
ccflags-$(CONFIG_USE_5G) += -DUSE_5G
|
||||||
|
ccflags-$(CONFIG_RADAR_OR_IR_DETECT) += -DCONFIG_RADAR_OR_IR_DETECT
|
||||||
|
ccflags-$(CONFIG_DOWNLOAD_FW) += -DCONFIG_DOWNLOAD_FW
|
||||||
|
ccflags-$(CONFIG_USB_BT) += -DCONFIG_USB_BT
|
||||||
|
ccflags-$(CONFIG_ALIGN_8BYTES) += -DCONFIG_ALIGN_8BYTES
|
||||||
|
ccflags-$(CONFIG_TXRX_THREAD_PRIO) += -DCONFIG_TXRX_THREAD_PRIO
|
||||||
|
ccflags-$(CONFIG_USB_ALIGN_DATA) += -DCONFIG_USB_ALIGN_DATA
|
||||||
|
ccflags-$(CONFIG_MAC_RANDOM_IF_NO_MAC_IN_EFUSE) += -DCONFIG_MAC_RANDOM_IF_NO_MAC_IN_EFUSE
|
||||||
|
ccflags-$(CONFIG_VENDOR_GPIO) += -DCONFIG_VENDOR_GPIO
|
||||||
|
ccflags-y += -DDEFAULT_COUNTRY_CODE=""\$(CONFIG_COUNTRY_CODE)"\"
|
||||||
|
ccflags-$(CONFIG_RX_NETIF_RECV_SKB) += -DCONFIG_RX_NETIF_RECV_SKB
|
||||||
|
ccflags-$(CONFIG_USB_MSG_OUT_EP) += -DCONFIG_USB_MSG_OUT_EP
|
||||||
|
ccflags-$(CONFIG_USB_MSG_IN_EP) += -DCONFIG_USB_MSG_IN_EP
|
||||||
|
ccflags-$(CONFIG_USB_RX_REASSEMBLE) += -DCONFIG_USB_RX_REASSEMBLE
|
||||||
|
ccflags-$(CONFIG_USB_RX_AGGR) += -DCONFIG_USB_RX_AGGR
|
||||||
|
ccflags-$(CONFIG_USB_TX_AGGR) += -DCONFIG_USB_TX_AGGR
|
||||||
|
ccflags-$(CONFIG_USB_NO_TRANS_DMA_MAP) += -DCONFIG_USB_NO_TRANS_DMA_MAP
|
||||||
|
ccflags-$(CONFIG_GPIO_WAKEUP) += -DCONFIG_GPIO_WAKEUP
|
||||||
|
ccflags-$(CONFIG_CREATE_TRACE_POINTS) += -DCREATE_TRACE_POINTS
|
||||||
|
ccflags-$(CONFIG_RX_TASKLET) += -DCONFIG_RX_TASKLET
|
||||||
|
ccflags-$(CONFIG_TX_TASKLET) += -DCONFIG_TX_TASKLET
|
||||||
|
ccflags-$(CONFIG_USE_USB_ZERO_PACKET) += -DCONFIG_USE_USB_ZERO_PACKET
|
||||||
|
ccflags-$(CONFIG_STA_SCAN_WHEN_P2P_WORKING) += -DCONFIG_STA_SCAN_WHEN_P2P_WORKING
|
||||||
|
ccflags-$(CONFIG_SUPPORT_REALTIME_CHANGE_MAC) += -DCONFIG_SUPPORT_REALTIME_CHANGE_MAC
|
||||||
|
ccflags-$(CONFIG_SET_VENDOR_EXTENSION_IE) += -DCONFIG_SET_VENDOR_EXTENSION_IE
|
||||||
|
ccflags-$(CONFIG_FWLOG_EN) += -DCONFIG_FWLOG_EN
|
||||||
|
ccflags-$(CONFIG_FOR_IPCAM) += -DCONFIG_FOR_IPCAM -DCONFIG_ONE_TXQ
|
||||||
|
ccflags-$(CONFIG_5M10M) += -DCONFIG_5M10M
|
||||||
|
ccflags-$(CONFIG_USE_FW_REQUEST) += -DCONFIG_USE_FW_REQUEST
|
||||||
|
ccflags-$(CONFIG_USE_P2P0) += -DCONFIG_USE_P2P0
|
||||||
|
ccflags-$(CONFIG_ONE_TXQ) += -DCONFIG_ONE_TXQ
|
||||||
|
ccflags-$(CONFIG_PER_STA_FC) += -DCONFIG_PER_STA_FC
|
||||||
|
ccflags-$(CONFIG_PREALLOC_RX_SKB) += -DCONFIG_PREALLOC_RX_SKB
|
||||||
|
ccflags-$(CONFIG_PREALLOC_TXQ) += -DCONFIG_PREALLOC_TXQ
|
||||||
|
ccflags-$(CONFIG_USE_WIRELESS_EXT) += -DCONFIG_USE_WIRELESS_EXT
|
||||||
|
ccflags-$(CONFIG_DPD) += -DCONFIG_DPD
|
||||||
|
ccflags-$(CONFIG_FORCE_DPD_CALIB) += -DCONFIG_FORCE_DPD_CALIB -DCONFIG_DPD
|
||||||
|
ccflags-$(CONFIG_LOFT_CALIB) += -DCONFIG_LOFT_CALIB
|
||||||
|
ccflags-$(CONFIG_GKI) += -DCONFIG_GKI
|
||||||
|
ccflags-$(CONFIG_SCHED_SCAN) += -DCONFIG_SCHED_SCAN
|
||||||
|
ccflags-$(CONFIG_FILTER_TCP_ACK) += -DCONFIG_FILTER_TCP_ACK
|
||||||
|
ccflags-$(CONFIG_TEMP_COMP) += -DCONFIG_TEMP_COMP
|
||||||
|
ccflags-$(CONFIG_POWER_LIMIT) += -DCONFIG_POWER_LIMIT
|
||||||
|
ccflags-$(CONFIG_EXT_FEM_8800DCDW) += -DCONFIG_EXT_FEM_8800DCDW
|
||||||
|
ccflags-$(CONFIG_WOWLAN) += -DCONFIG_WOWLAN
|
||||||
|
MAKEFLAGS +=-j$(shell nproc)
|
||||||
|
|
||||||
|
# Platform support list
|
||||||
|
CONFIG_PLATFORM_ROCKCHIP ?= n
|
||||||
|
CONFIG_PLATFORM_ALLWINNER ?= n
|
||||||
|
CONFIG_PLATFORM_AMLOGIC ?= n
|
||||||
|
CONFIG_PLATFORM_HI ?= n
|
||||||
|
CONFIG_PLATFORM_UBUNTU ?= y
|
||||||
|
|
||||||
|
ifeq ($(CONFIG_PLATFORM_ROCKCHIP), y)
|
||||||
|
ARCH := arm64
|
||||||
|
KDIR ?= /home/yaya/E/Rockchip/3566/firefly/Android11.0/Firefly-RK356X_Android11.0_git_20210824/RK356X_Android11.0/kernel
|
||||||
|
CROSS_COMPILE := /home/yaya/E/Rockchip/3566/firefly/Android11.0/Firefly-RK356X_Android11.0_git_20210824/RK356X_Android11.0/prebuilts/gcc/linux-x86/aarch64/gcc-linaro-6.3.1-2017.05-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-
|
||||||
|
ccflags-y += -DANDROID_PLATFORM
|
||||||
|
ccflags-y += -DCONFIG_PLATFORM_ROCKCHIP
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq ($(CONFIG_PLATFORM_ALLWINNER), y)
|
||||||
|
KDIR ?= /home/yaya/E/Allwinner/R818/R818/AndroidQ/lichee/kernel/linux-4.9
|
||||||
|
ARCH ?= arm64
|
||||||
|
CROSS_COMPILE ?= /home/yaya/E/Allwinner/R818/R818/AndroidQ/lichee/out/gcc-linaro-5.3.1-2016.05-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-
|
||||||
|
ccflags-y += -DANDROID_PLATFORM
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq ($(CONFIG_PLATFORM_AMLOGIC), y)
|
||||||
|
ccflags-y += -DANDROID_PLATFORM
|
||||||
|
ARCH ?= arm
|
||||||
|
CROSS_COMPILE ?= /home/yaya/D/Workspace/CyberQuantum/JinHaoYue/amls905x3/SDK/20191101-0tt-asop/android9.0/prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.9/bin/arm-linux-androidkernel-
|
||||||
|
KDIR ?= /home/yaya/D/Workspace/CyberQuantum/JinHaoYue/amls905x3/SDK/20191101-0tt-asop/android9.0/out/target/product/u202/obj/KERNEL_OBJ/
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq ($(CONFIG_PLATFORM_HI), y)
|
||||||
|
ccflags-y += -DANDROID_PLATFORM
|
||||||
|
ccflags-y += -DCONFIG_PLATFORM_HI
|
||||||
|
ARCH ?= arm
|
||||||
|
CROSS_COMPILE ?= /home/yaya/D/Workspace/CyberQuantum/JinHaoYue/amls905x3/SDK/20191101-0tt-asop/android9.0/prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.9/bin/arm-linux-androidkernel-
|
||||||
|
KDIR ?= /home/yaya/D/Workspace/CyberQuantum/JinHaoYue/amls905x3/SDK/20191101-0tt-asop/android9.0/out/target/product/u202/obj/KERNEL_OBJ/
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq ($(CONFIG_PLATFORM_UBUNTU), y)
|
||||||
|
KDIR ?= /lib/modules/$(shell uname -r)/build
|
||||||
|
#KDIR ?= ~/D/Workspace/CyberQuantum/Linux/linux-4.15/
|
||||||
|
PWD ?= $(shell pwd)
|
||||||
|
KVER ?= $(shell uname -r)
|
||||||
|
MODDESTDIR ?= /lib/modules/$(KVER)/kernel/drivers/net/wireless/aic8800
|
||||||
|
SUBARCH = $(shell uname -m | sed -e s/i.86/i386/ -e s/armv.l/arm/ -e s/aarch64/arm64/)
|
||||||
|
ARCH ?= $(SUBARCH)
|
||||||
|
CROSS_COMPILE ?=
|
||||||
|
endif
|
||||||
|
|
||||||
|
|
||||||
|
all: modules
|
||||||
|
modules:
|
||||||
|
# make -C $(KDIR) M=$(PWD) ARCH=$(ARCH) CROSS_COMPILE=$(CROSS_COMPILE) LLVM=1 LLVM_IAS=1 modules
|
||||||
|
make -C $(KDIR) M=$(PWD) ARCH=$(ARCH) CROSS_COMPILE=$(CROSS_COMPILE) modules
|
||||||
|
install:
|
||||||
|
mkdir -p $(MODDESTDIR)
|
||||||
|
install -p -m 644 $(MODULE_NAME).ko $(MODDESTDIR)
|
||||||
|
/sbin/depmod -a ${KVER}
|
||||||
|
|
||||||
|
uninstall:
|
||||||
|
rm -rfv $(MODDESTDIR)/$(MODULE_NAME).ko
|
||||||
|
/sbin/depmod -a ${KVER}
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -rf *.o *.ko *.o.* *.mod.* modules.* Module.* .a* .o* .*.o.* *.mod .tmp* .cache.mk .modules.order.cmd .Module.symvers.cmd
|
||||||
|
|
||||||
1569
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/aic_br_ext.c
Normal file
1569
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/aic_br_ext.c
Normal file
File diff suppressed because it is too large
Load diff
73
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/aic_br_ext.h
Normal file
73
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/aic_br_ext.h
Normal file
|
|
@ -0,0 +1,73 @@
|
||||||
|
/******************************************************************************
|
||||||
|
*
|
||||||
|
* Copyright(c) 2007 - 2017 Realtek Corporation.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of version 2 of the GNU General Public License as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
* more details.
|
||||||
|
*
|
||||||
|
*****************************************************************************/
|
||||||
|
#ifndef _AIC_BR_EXT_H_
|
||||||
|
#define _AIC_BR_EXT_H_
|
||||||
|
|
||||||
|
#define CL_IPV6_PASS 1
|
||||||
|
#define MACADDRLEN 6
|
||||||
|
#define WLAN_ETHHDR_LEN 14
|
||||||
|
|
||||||
|
#define NAT25_HASH_BITS 4
|
||||||
|
#define NAT25_HASH_SIZE (1 << NAT25_HASH_BITS)
|
||||||
|
#define NAT25_AGEING_TIME 300
|
||||||
|
|
||||||
|
#define NDEV_FMT "%s"
|
||||||
|
#define NDEV_ARG(ndev) ndev->name
|
||||||
|
#define ADPT_FMT "%s"
|
||||||
|
//#define ADPT_ARG(adapter) (adapter->pnetdev ? adapter->pnetdev->name : NULL)
|
||||||
|
#define FUNC_NDEV_FMT "%s(%s)"
|
||||||
|
#define FUNC_NDEV_ARG(ndev) __func__, ndev->name
|
||||||
|
#define FUNC_ADPT_FMT "%s(%s)"
|
||||||
|
//#define FUNC_ADPT_ARG(adapter) __func__, (adapter->pnetdev ? adapter->pnetdev->name : NULL)
|
||||||
|
#define MAC_FMT "%02x:%02x:%02x:%02x:%02x:%02x"
|
||||||
|
#define MAC_ARG(x) ((u8 *)(x))[0], ((u8 *)(x))[1], ((u8 *)(x))[2], ((u8 *)(x))[3], ((u8 *)(x))[4], ((u8 *)(x))[5]
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef CL_IPV6_PASS
|
||||||
|
#define MAX_NETWORK_ADDR_LEN 17
|
||||||
|
#else
|
||||||
|
#define MAX_NETWORK_ADDR_LEN 11
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct nat25_network_db_entry {
|
||||||
|
struct nat25_network_db_entry *next_hash;
|
||||||
|
struct nat25_network_db_entry **pprev_hash;
|
||||||
|
atomic_t use_count;
|
||||||
|
unsigned char macAddr[6];
|
||||||
|
unsigned long ageing_timer;
|
||||||
|
unsigned char networkAddr[MAX_NETWORK_ADDR_LEN];
|
||||||
|
};
|
||||||
|
|
||||||
|
enum NAT25_METHOD {
|
||||||
|
NAT25_MIN,
|
||||||
|
NAT25_CHECK,
|
||||||
|
NAT25_INSERT,
|
||||||
|
NAT25_LOOKUP,
|
||||||
|
NAT25_PARSE,
|
||||||
|
NAT25_MAX
|
||||||
|
};
|
||||||
|
|
||||||
|
struct br_ext_info {
|
||||||
|
unsigned int nat25_disable;
|
||||||
|
unsigned int macclone_enable;
|
||||||
|
unsigned int dhcp_bcst_disable;
|
||||||
|
int addPPPoETag; /* 1: Add PPPoE relay-SID, 0: disable */
|
||||||
|
unsigned char nat25_dmzMac[MACADDRLEN];
|
||||||
|
unsigned int nat25sc_disable;
|
||||||
|
};
|
||||||
|
|
||||||
|
void nat25_db_cleanup(struct rwnx_vif *vif);
|
||||||
|
|
||||||
|
#endif /* _AIC_BR_EXT_H_ */
|
||||||
2074
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/aic_priv_cmd.c
Normal file
2074
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/aic_priv_cmd.c
Normal file
File diff suppressed because it is too large
Load diff
64
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/aic_priv_cmd.h
Normal file
64
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/aic_priv_cmd.h
Normal file
|
|
@ -0,0 +1,64 @@
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
*
|
||||||
|
* @file private_cmd.h
|
||||||
|
*
|
||||||
|
* Copyright (C) Aicsemi 2018-2024
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _AIC_PRIV_CMD_H_
|
||||||
|
#define _AIC_PRIV_CMD_H_
|
||||||
|
|
||||||
|
#include "rwnx_defs.h"
|
||||||
|
|
||||||
|
typedef struct _android_wifi_priv_cmd {
|
||||||
|
char *buf;
|
||||||
|
int used_len;
|
||||||
|
int total_len;
|
||||||
|
} android_wifi_priv_cmd;
|
||||||
|
|
||||||
|
struct aicwf_cs_info {
|
||||||
|
u8_l phymode;
|
||||||
|
u8_l bandwidth;
|
||||||
|
u16_l freq;
|
||||||
|
|
||||||
|
s8_l rssi;
|
||||||
|
s8_l snr;
|
||||||
|
s8_l noise;
|
||||||
|
u8_l txpwr;
|
||||||
|
|
||||||
|
//chanutil
|
||||||
|
u16_l chan_time_ms;
|
||||||
|
u16_l chan_time_busy_ms;
|
||||||
|
|
||||||
|
char countrycode[4];
|
||||||
|
u8_l rxnss;
|
||||||
|
u8_l rxmcs;
|
||||||
|
u8_l txnss;
|
||||||
|
u8_l txmcs;
|
||||||
|
|
||||||
|
u32_l tx_phyrate;
|
||||||
|
u32_l rx_phyrate;
|
||||||
|
|
||||||
|
u32_l tx_ack_succ_stat;
|
||||||
|
u32_l tx_ack_fail_stat;
|
||||||
|
|
||||||
|
u16_l chan_tx_busy_time;
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef CONFIG_COMPAT
|
||||||
|
typedef struct _compat_android_wifi_priv_cmd {
|
||||||
|
compat_caddr_t buf;
|
||||||
|
int used_len;
|
||||||
|
int total_len;
|
||||||
|
} compat_android_wifi_priv_cmd;
|
||||||
|
#endif /* CONFIG_COMPAT */
|
||||||
|
|
||||||
|
int android_priv_cmd(struct net_device *net, struct ifreq *ifr, int cmd);
|
||||||
|
int get_cs_info(struct rwnx_vif *vif, u8 *mac_addr, u8 *val);
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* _AIC_PRIV_CMD_H_ */
|
||||||
|
|
||||||
1073
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/aic_vendor.c
Normal file
1073
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/aic_vendor.c
Normal file
File diff suppressed because it is too large
Load diff
346
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/aic_vendor.h
Normal file
346
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/aic_vendor.h
Normal file
|
|
@ -0,0 +1,346 @@
|
||||||
|
#ifndef _AIC_VENDOR_H
|
||||||
|
#define _AIC_VENDOR_H
|
||||||
|
|
||||||
|
#include <linux/types.h>
|
||||||
|
|
||||||
|
#define GOOGLE_OUI 0x001A11
|
||||||
|
#define BRCM_OUI 0x001018
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
START_MKEEP_ALIVE,
|
||||||
|
STOP_MKEEP_ALIVE,
|
||||||
|
} GetCmdType;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
/* don't use 0 as a valid subcommand */
|
||||||
|
VENDOR_NL80211_SUBCMD_UNSPECIFIED,
|
||||||
|
|
||||||
|
/* define all vendor startup commands between 0x0 and 0x0FFF */
|
||||||
|
VENDOR_NL80211_SUBCMD_RANGE_START = 0x0001,
|
||||||
|
VENDOR_NL80211_SUBCMD_RANGE_END = 0x0FFF,
|
||||||
|
|
||||||
|
/* define all GScan related commands between 0x1000 and 0x10FF */
|
||||||
|
ANDROID_NL80211_SUBCMD_GSCAN_RANGE_START = 0x1000,
|
||||||
|
ANDROID_NL80211_SUBCMD_GSCAN_RANGE_END = 0x10FF,
|
||||||
|
|
||||||
|
/* define all NearbyDiscovery related commands between 0x1100 and 0x11FF */
|
||||||
|
ANDROID_NL80211_SUBCMD_NBD_RANGE_START = 0x1100,
|
||||||
|
ANDROID_NL80211_SUBCMD_NBD_RANGE_END = 0x11FF,
|
||||||
|
|
||||||
|
/* define all RTT related commands between 0x1100 and 0x11FF */
|
||||||
|
ANDROID_NL80211_SUBCMD_RTT_RANGE_START = 0x1100,
|
||||||
|
ANDROID_NL80211_SUBCMD_RTT_RANGE_END = 0x11FF,
|
||||||
|
|
||||||
|
ANDROID_NL80211_SUBCMD_LSTATS_RANGE_START = 0x1200,
|
||||||
|
ANDROID_NL80211_SUBCMD_LSTATS_RANGE_END = 0x12FF,
|
||||||
|
|
||||||
|
/* define all Logger related commands between 0x1400 and 0x14FF */
|
||||||
|
ANDROID_NL80211_SUBCMD_DEBUG_RANGE_START = 0x1400,
|
||||||
|
ANDROID_NL80211_SUBCMD_DEBUG_RANGE_END = 0x14FF,
|
||||||
|
|
||||||
|
/* define all wifi offload related commands between 0x1600 and 0x16FF */
|
||||||
|
ANDROID_NL80211_SUBCMD_WIFI_OFFLOAD_RANGE_START = 0x1600,
|
||||||
|
ANDROID_NL80211_SUBCMD_WIFI_OFFLOAD_RANGE_END = 0x16FF,
|
||||||
|
|
||||||
|
/* define all NAN related commands between 0x1700 and 0x17FF */
|
||||||
|
ANDROID_NL80211_SUBCMD_NAN_RANGE_START = 0x1700,
|
||||||
|
ANDROID_NL80211_SUBCMD_NAN_RANGE_END = 0x17FF,
|
||||||
|
|
||||||
|
/* define all Android Packet Filter related commands between 0x1800 and 0x18FF */
|
||||||
|
ANDROID_NL80211_SUBCMD_PKT_FILTER_RANGE_START = 0x1800,
|
||||||
|
ANDROID_NL80211_SUBCMD_PKT_FILTER_RANGE_END = 0x18FF,
|
||||||
|
|
||||||
|
/* This is reserved for future usage */
|
||||||
|
|
||||||
|
} ANDROID_VENDOR_SUB_COMMAND;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
WIFI_OFFLOAD_SUBCMD_START_MKEEP_ALIVE = ANDROID_NL80211_SUBCMD_WIFI_OFFLOAD_RANGE_START,
|
||||||
|
WIFI_OFFLOAD_SUBCMD_STOP_MKEEP_ALIVE,
|
||||||
|
} WIFI_OFFLOAD_SUB_COMMAND;
|
||||||
|
|
||||||
|
|
||||||
|
enum mkeep_alive_attributes {
|
||||||
|
MKEEP_ALIVE_ATTRIBUTE_ID = 0x1,
|
||||||
|
MKEEP_ALIVE_ATTRIBUTE_IP_PKT,
|
||||||
|
MKEEP_ALIVE_ATTRIBUTE_IP_PKT_LEN,
|
||||||
|
MKEEP_ALIVE_ATTRIBUTE_SRC_MAC_ADDR,
|
||||||
|
MKEEP_ALIVE_ATTRIBUTE_DST_MAC_ADDR,
|
||||||
|
MKEEP_ALIVE_ATTRIBUTE_PERIOD_MSEC,
|
||||||
|
MKEEP_ALIVE_ATTRIBUTE_AFTER_LAST,
|
||||||
|
MKEEP_ALIVE_ATTRIBUTE_MAX = MKEEP_ALIVE_ATTRIBUTE_AFTER_LAST - 1
|
||||||
|
};
|
||||||
|
|
||||||
|
enum debug_sub_command {
|
||||||
|
LOGGER_START_LOGGING = ANDROID_NL80211_SUBCMD_DEBUG_RANGE_START,
|
||||||
|
LOGGER_TRIGGER_MEM_DUMP,
|
||||||
|
LOGGER_GET_MEM_DUMP,
|
||||||
|
LOGGER_GET_VER,
|
||||||
|
LOGGER_GET_RING_STATUS,
|
||||||
|
LOGGER_GET_RING_DATA,
|
||||||
|
LOGGER_GET_FEATURE,
|
||||||
|
LOGGER_RESET_LOGGING,
|
||||||
|
LOGGER_TRIGGER_DRIVER_MEM_DUMP,
|
||||||
|
LOGGER_GET_DRIVER_MEM_DUMP,
|
||||||
|
LOGGER_START_PKT_FATE_MONITORING,
|
||||||
|
LOGGER_GET_TX_PKT_FATES,
|
||||||
|
LOGGER_GET_RX_PKT_FATES,
|
||||||
|
LOGGER_GET_WAKE_REASON_STATS,
|
||||||
|
LOGGER_DEBUG_GET_DUMP,
|
||||||
|
LOGGER_FILE_DUMP_DONE_IND,
|
||||||
|
LOGGER_SET_HAL_START,
|
||||||
|
LOGGER_HAL_STOP,
|
||||||
|
LOGGER_SET_HAL_PID,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum logger_attributes {
|
||||||
|
LOGGER_ATTRIBUTE_INVALID = 0,
|
||||||
|
LOGGER_ATTRIBUTE_DRIVER_VER,
|
||||||
|
LOGGER_ATTRIBUTE_FW_VER,
|
||||||
|
LOGGER_ATTRIBUTE_RING_ID,
|
||||||
|
LOGGER_ATTRIBUTE_RING_NAME,
|
||||||
|
LOGGER_ATTRIBUTE_RING_FLAGS,
|
||||||
|
LOGGER_ATTRIBUTE_LOG_LEVEL,
|
||||||
|
LOGGER_ATTRIBUTE_LOG_TIME_INTVAL,
|
||||||
|
LOGGER_ATTRIBUTE_LOG_MIN_DATA_SIZE,
|
||||||
|
LOGGER_ATTRIBUTE_FW_DUMP_LEN,
|
||||||
|
LOGGER_ATTRIBUTE_FW_DUMP_DATA,
|
||||||
|
// LOGGER_ATTRIBUTE_FW_ERR_CODE,
|
||||||
|
LOGGER_ATTRIBUTE_RING_DATA,
|
||||||
|
LOGGER_ATTRIBUTE_RING_STATUS,
|
||||||
|
LOGGER_ATTRIBUTE_RING_NUM,
|
||||||
|
LOGGER_ATTRIBUTE_DRIVER_DUMP_LEN,
|
||||||
|
LOGGER_ATTRIBUTE_DRIVER_DUMP_DATA,
|
||||||
|
LOGGER_ATTRIBUTE_PKT_FATE_NUM,
|
||||||
|
LOGGER_ATTRIBUTE_PKT_FATE_DATA,
|
||||||
|
LOGGER_ATTRIBUTE_AFTER_LAST,
|
||||||
|
LOGGER_ATTRIBUTE_MAX = LOGGER_ATTRIBUTE_AFTER_LAST - 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum wifi_sub_command {
|
||||||
|
GSCAN_SUBCMD_GET_CAPABILITIES = ANDROID_NL80211_SUBCMD_GSCAN_RANGE_START,
|
||||||
|
GSCAN_SUBCMD_SET_CONFIG, /* 0x1001 */
|
||||||
|
GSCAN_SUBCMD_SET_SCAN_CONFIG, /* 0x1002 */
|
||||||
|
GSCAN_SUBCMD_ENABLE_GSCAN, /* 0x1003 */
|
||||||
|
GSCAN_SUBCMD_GET_SCAN_RESULTS, /* 0x1004 */
|
||||||
|
GSCAN_SUBCMD_SCAN_RESULTS, /* 0x1005 */
|
||||||
|
GSCAN_SUBCMD_SET_HOTLIST, /* 0x1006 */
|
||||||
|
GSCAN_SUBCMD_SET_SIGNIFICANT_CHANGE_CONFIG, /* 0x1007 */
|
||||||
|
GSCAN_SUBCMD_ENABLE_FULL_SCAN_RESULTS, /* 0x1008 */
|
||||||
|
GSCAN_SUBCMD_GET_CHANNEL_LIST, /* 0x1009 */
|
||||||
|
WIFI_SUBCMD_GET_FEATURE_SET, /* 0x100A */
|
||||||
|
WIFI_SUBCMD_GET_FEATURE_SET_MATRIX, /* 0x100B */
|
||||||
|
WIFI_SUBCMD_SET_PNO_RANDOM_MAC_OUI, /* 0x100C */
|
||||||
|
WIFI_SUBCMD_NODFS_SET, /* 0x100D */
|
||||||
|
WIFI_SUBCMD_SET_COUNTRY_CODE, /* 0x100E */
|
||||||
|
/* Add more sub commands here */
|
||||||
|
GSCAN_SUBCMD_SET_EPNO_SSID, /* 0x100F */
|
||||||
|
WIFI_SUBCMD_SET_SSID_WHITE_LIST, /* 0x1010 */
|
||||||
|
WIFI_SUBCMD_SET_ROAM_PARAMS, /* 0x1011 */
|
||||||
|
WIFI_SUBCMD_ENABLE_LAZY_ROAM, /* 0x1012 */
|
||||||
|
WIFI_SUBCMD_SET_BSSID_PREF, /* 0x1013 */
|
||||||
|
WIFI_SUBCMD_SET_BSSID_BLACKLIST, /* 0x1014 */
|
||||||
|
GSCAN_SUBCMD_ANQPO_CONFIG, /* 0x1015 */
|
||||||
|
WIFI_SUBCMD_SET_RSSI_MONITOR, /* 0x1016 */
|
||||||
|
WIFI_SUBCMD_CONFIG_ND_OFFLOAD, /* 0x1017 */
|
||||||
|
/* Add more sub commands here */
|
||||||
|
GSCAN_SUBCMD_MAX,
|
||||||
|
APF_SUBCMD_GET_CAPABILITIES = ANDROID_NL80211_SUBCMD_PKT_FILTER_RANGE_START,
|
||||||
|
APF_SUBCMD_SET_FILTER,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum gscan_attributes {
|
||||||
|
GSCAN_ATTRIBUTE_NUM_BUCKETS = 10,
|
||||||
|
GSCAN_ATTRIBUTE_BASE_PERIOD,
|
||||||
|
GSCAN_ATTRIBUTE_BUCKETS_BAND,
|
||||||
|
GSCAN_ATTRIBUTE_BUCKET_ID,
|
||||||
|
GSCAN_ATTRIBUTE_BUCKET_PERIOD,
|
||||||
|
GSCAN_ATTRIBUTE_BUCKET_NUM_CHANNELS,
|
||||||
|
GSCAN_ATTRIBUTE_BUCKET_CHANNELS,
|
||||||
|
GSCAN_ATTRIBUTE_NUM_AP_PER_SCAN,
|
||||||
|
GSCAN_ATTRIBUTE_REPORT_THRESHOLD,
|
||||||
|
GSCAN_ATTRIBUTE_NUM_SCANS_TO_CACHE,
|
||||||
|
GSCAN_ATTRIBUTE_BAND = GSCAN_ATTRIBUTE_BUCKETS_BAND,
|
||||||
|
|
||||||
|
GSCAN_ATTRIBUTE_ENABLE_FEATURE = 20,
|
||||||
|
GSCAN_ATTRIBUTE_SCAN_RESULTS_COMPLETE, /* indicates no more results */
|
||||||
|
GSCAN_ATTRIBUTE_FLUSH_FEATURE, /* Flush all the configs */
|
||||||
|
GSCAN_ENABLE_FULL_SCAN_RESULTS,
|
||||||
|
GSCAN_ATTRIBUTE_REPORT_EVENTS,
|
||||||
|
|
||||||
|
/* remaining reserved for additional attributes */
|
||||||
|
GSCAN_ATTRIBUTE_NUM_OF_RESULTS = 30,
|
||||||
|
GSCAN_ATTRIBUTE_FLUSH_RESULTS,
|
||||||
|
GSCAN_ATTRIBUTE_SCAN_RESULTS, /* flat array of wifi_scan_result */
|
||||||
|
GSCAN_ATTRIBUTE_SCAN_ID, /* indicates scan number */
|
||||||
|
GSCAN_ATTRIBUTE_SCAN_FLAGS, /* indicates if scan was aborted */
|
||||||
|
GSCAN_ATTRIBUTE_AP_FLAGS, /* flags on significant change event */
|
||||||
|
GSCAN_ATTRIBUTE_NUM_CHANNELS,
|
||||||
|
GSCAN_ATTRIBUTE_CHANNEL_LIST,
|
||||||
|
GSCAN_ATTRIBUTE_CH_BUCKET_BITMASK,
|
||||||
|
|
||||||
|
GSCAN_ATTRIBUTE_AFTER_LAST,
|
||||||
|
GSCAN_ATTRIBUTE_MAX = GSCAN_ATTRIBUTE_AFTER_LAST - 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum andr_wifi_attributes {
|
||||||
|
ANDR_WIFI_ATTRIBUTE_NUM_FEATURE_SET,
|
||||||
|
ANDR_WIFI_ATTRIBUTE_FEATURE_SET,
|
||||||
|
ANDR_WIFI_ATTRIBUTE_PNO_RANDOM_MAC_OUI,
|
||||||
|
ANDR_WIFI_ATTRIBUTE_NODFS_SET,
|
||||||
|
ANDR_WIFI_ATTRIBUTE_COUNTRY,
|
||||||
|
ANDR_WIFI_ATTRIBUTE_ND_OFFLOAD_VALUE,
|
||||||
|
// Add more attribute here
|
||||||
|
ANDR_WIFI_ATTRIBUTE_AFTER_LAST,
|
||||||
|
ANDR_WIFI_ATTRIBUTE_MAX = ANDR_WIFI_ATTRIBUTE_AFTER_LAST - 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum wifi_support_feature {
|
||||||
|
/* Feature enums */
|
||||||
|
WIFI_FEATURE_INFRA = 0x0001, /* Basic infrastructure mode */
|
||||||
|
WIFI_FEATURE_INFRA_5G = 0x0002, /* Support for 5, GHz Band */
|
||||||
|
WIFI_FEATURE_HOTSPOT = 0x0004, /* Support for GAS/ANQP */
|
||||||
|
WIFI_FEATURE_P2P = 0x0008, /* Wifi-Direct */
|
||||||
|
WIFI_FEATURE_SOFT_AP = 0x0010, /* Soft AP */
|
||||||
|
WIFI_FEATURE_GSCAN = 0x0020, /* Google-Scan APIs */
|
||||||
|
WIFI_FEATURE_NAN = 0x0040, /* Neighbor Awareness Networking */
|
||||||
|
WIFI_FEATURE_D2D_RTT = 0x0080, /* Device-to-device RTT */
|
||||||
|
WIFI_FEATURE_D2AP_RTT = 0x0100, /* Device-to-AP RTT */
|
||||||
|
WIFI_FEATURE_BATCH_SCAN = 0x0200, /* Batched Scan (legacy) */
|
||||||
|
WIFI_FEATURE_PNO = 0x0400, /* Preferred network offload */
|
||||||
|
WIFI_FEATURE_ADDITIONAL_STA = 0x0800, /* Support for two STAs */
|
||||||
|
WIFI_FEATURE_TDLS = 0x1000, /* Tunnel directed link setup */
|
||||||
|
WIFI_FEATURE_TDLS_OFFCHANNEL = 0x2000, /* Support for TDLS off channel */
|
||||||
|
WIFI_FEATURE_EPR = 0x4000, /* Enhanced power reporting */
|
||||||
|
WIFI_FEATURE_AP_STA = 0x8000, /* Support for AP STA Concurrency */
|
||||||
|
WIFI_FEATURE_LINK_LAYER_STATS = 0x10000, /* Support for Linkstats */
|
||||||
|
WIFI_FEATURE_LOGGER = 0x20000, /* WiFi Logger */
|
||||||
|
WIFI_FEATURE_HAL_EPNO = 0x40000, /* WiFi PNO enhanced */
|
||||||
|
WIFI_FEATURE_RSSI_MONITOR = 0x80000, /* RSSI Monitor */
|
||||||
|
WIFI_FEATURE_MKEEP_ALIVE = 0x100000, /* WiFi mkeep_alive */
|
||||||
|
WIFI_FEATURE_CONFIG_NDO = 0x200000, /* ND offload configure */
|
||||||
|
WIFI_FEATURE_TX_TRANSMIT_POWER = 0x400000, /* Capture Tx transmit power levels */
|
||||||
|
WIFI_FEATURE_CONTROL_ROAMING = 0x800000, /* Enable/Disable firmware roaming */
|
||||||
|
WIFI_FEATURE_IE_WHITELIST = 0x1000000, /* Support Probe IE white listing */
|
||||||
|
WIFI_FEATURE_SCAN_RAND = 0x2000000, /* Support MAC & Probe Sequence Number randomization */
|
||||||
|
WIFI_FEATURE_INVALID = 0xFFFFFFFF, /* Invalid Feature */
|
||||||
|
};
|
||||||
|
|
||||||
|
enum wifi_logger_feature {
|
||||||
|
WIFI_LOGGER_MEMORY_DUMP_SUPPORTED = (1 << (0)), // Memory dump of FW
|
||||||
|
WIFI_LOGGER_PER_PACKET_TX_RX_STATUS_SUPPORTED = (1 << (1)), // PKT status
|
||||||
|
WIFI_LOGGER_CONNECT_EVENT_SUPPORTED = (1 << (2)), // Connectivity event
|
||||||
|
WIFI_LOGGER_POWER_EVENT_SUPPORTED = (1 << (3)), // POWER of Driver
|
||||||
|
WIFI_LOGGER_WAKE_LOCK_SUPPORTED = (1 << (4)), // WAKE LOCK of Driver
|
||||||
|
WIFI_LOGGER_VERBOSE_SUPPORTED = (1 << (5)), // verbose log of FW
|
||||||
|
WIFI_LOGGER_WATCHDOG_TIMER_SUPPORTED = (1 << (6)), // monitor the health of FW
|
||||||
|
WIFI_LOGGER_DRIVER_DUMP_SUPPORTED = (1 << (7)), // dumps driver state
|
||||||
|
WIFI_LOGGER_PACKET_FATE_SUPPORTED = (1 << (8)), // tracks connection packets' fate
|
||||||
|
};
|
||||||
|
|
||||||
|
enum wake_stats_attributes {
|
||||||
|
WAKE_STAT_ATTRIBUTE_TOTAL_CMD_EVENT,
|
||||||
|
WAKE_STAT_ATTRIBUTE_CMD_EVENT_WAKE,
|
||||||
|
WAKE_STAT_ATTRIBUTE_CMD_EVENT_COUNT,
|
||||||
|
WAKE_STAT_ATTRIBUTE_CMD_COUNT_USED,
|
||||||
|
WAKE_STAT_ATTRIBUTE_TOTAL_DRIVER_FW,
|
||||||
|
WAKE_STAT_ATTRIBUTE_DRIVER_FW_WAKE,
|
||||||
|
WAKE_STAT_ATTRIBUTE_DRIVER_FW_COUNT,
|
||||||
|
WAKE_STAT_ATTRIBUTE_DRIVER_FW_COUNT_USED,
|
||||||
|
WAKE_STAT_ATTRIBUTE_TOTAL_RX_DATA_WAKE,
|
||||||
|
WAKE_STAT_ATTRIBUTE_RX_UNICAST_COUNT,
|
||||||
|
WAKE_STAT_ATTRIBUTE_RX_MULTICAST_COUNT,
|
||||||
|
WAKE_STAT_ATTRIBUTE_RX_BROADCAST_COUNT,
|
||||||
|
WAKE_STAT_ATTRIBUTE_RX_ICMP_PKT,
|
||||||
|
WAKE_STAT_ATTRIBUTE_RX_ICMP6_PKT,
|
||||||
|
WAKE_STAT_ATTRIBUTE_RX_ICMP6_RA,
|
||||||
|
WAKE_STAT_ATTRIBUTE_RX_ICMP6_NA,
|
||||||
|
WAKE_STAT_ATTRIBUTE_RX_ICMP6_NS,
|
||||||
|
WAKE_STAT_ATTRIBUTE_IPV4_RX_MULTICAST_ADD_CNT,
|
||||||
|
WAKE_STAT_ATTRIBUTE_IPV6_RX_MULTICAST_ADD_CNT,
|
||||||
|
WAKE_STAT_ATTRIBUTE_OTHER__RX_MULTICAST_ADD_CNT,
|
||||||
|
WAKE_STAT_ATTRIBUTE_RX_MULTICAST_PKT_INFO,
|
||||||
|
WAKE_STAT_ATTRIBUTE_AFTER_LAST,
|
||||||
|
WAKE_STAT_ATTRIBUTE_MAX = WAKE_STAT_ATTRIBUTE_AFTER_LAST - 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum vendor_nl80211_subcmd {
|
||||||
|
/* copied from wpa_supplicant brcm definations */
|
||||||
|
VENDOR_NL80211_SUBCMD_UNSPEC = 0,
|
||||||
|
VENDOR_NL80211_SUBCMD_SET_PMK = 4,
|
||||||
|
VENDOR_NL80211_SUBCMD_SET_MAC = 6,
|
||||||
|
VENDOR_NL80211_SCMD_ACS = 9,
|
||||||
|
VENDOR_NL80211_SCMD_MAX = 10,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum nl80211_vendor_subcmd_attributes {
|
||||||
|
WIFI_VENDOR_ATTR_DRIVER_CMD = 0,
|
||||||
|
WIFI_VENDOR_ATTR_DRIVER_KEY_PMK = 1,
|
||||||
|
WIFI_VENDOR_ATTR_DRIVER_MAC_ADDR = 3,
|
||||||
|
WIFI_VENDOR_ATTR_DRIVER_AFTER_LAST = 5,
|
||||||
|
WIFI_VENDOR_ATTR_DRIVER_MAX =
|
||||||
|
WIFI_VENDOR_ATTR_DRIVER_AFTER_LAST - 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef int wifi_ring_buffer_id;
|
||||||
|
|
||||||
|
struct wifi_ring_buffer_status {
|
||||||
|
u8 name[32];
|
||||||
|
u32 flags;
|
||||||
|
wifi_ring_buffer_id ring_id;
|
||||||
|
u32 ring_buffer_byte_size;
|
||||||
|
u32 verbose_level;
|
||||||
|
u32 written_bytes;
|
||||||
|
u32 read_bytes;
|
||||||
|
u32 written_records;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct rx_data_cnt_details_t {
|
||||||
|
int rx_unicast_cnt; /*Total rx unicast packet which woke up host */
|
||||||
|
int rx_multicast_cnt; /*Total rx multicast packet which woke up host */
|
||||||
|
int rx_broadcast_cnt; /*Total rx broadcast packet which woke up host */
|
||||||
|
};
|
||||||
|
|
||||||
|
struct rx_wake_pkt_type_classification_t {
|
||||||
|
int icmp_pkt; /*wake icmp packet count */
|
||||||
|
int icmp6_pkt; /*wake icmp6 packet count */
|
||||||
|
int icmp6_ra; /*wake icmp6 RA packet count */
|
||||||
|
int icmp6_na; /*wake icmp6 NA packet count */
|
||||||
|
int icmp6_ns; /*wake icmp6 NS packet count */
|
||||||
|
//ToDo: Any more interesting classification to add?
|
||||||
|
};
|
||||||
|
|
||||||
|
struct rx_multicast_cnt_t{
|
||||||
|
int ipv4_rx_multicast_addr_cnt; /*Rx wake packet was ipv4 multicast */
|
||||||
|
int ipv6_rx_multicast_addr_cnt; /*Rx wake packet was ipv6 multicast */
|
||||||
|
int other_rx_multicast_addr_cnt;/*Rx wake packet was non-ipv4 and non-ipv6*/
|
||||||
|
};
|
||||||
|
|
||||||
|
struct wlan_driver_wake_reason_cnt_t {
|
||||||
|
int total_cmd_event_wake; /* Total count of cmd event wakes */
|
||||||
|
int *cmd_event_wake_cnt; /* Individual wake count array, each index a reason */
|
||||||
|
int cmd_event_wake_cnt_sz; /* Max number of cmd event wake reasons */
|
||||||
|
int cmd_event_wake_cnt_used; /* Number of cmd event wake reasons specific to the driver */
|
||||||
|
|
||||||
|
int total_driver_fw_local_wake; /* Total count of drive/fw wakes, for local reasons */
|
||||||
|
int *driver_fw_local_wake_cnt; /* Individual wake count array, each index a reason */
|
||||||
|
int driver_fw_local_wake_cnt_sz; /* Max number of local driver/fw wake reasons */
|
||||||
|
int driver_fw_local_wake_cnt_used; /* Number of local driver/fw wake reasons specific to the driver */
|
||||||
|
|
||||||
|
int total_rx_data_wake; /* total data rx packets, that woke up host */
|
||||||
|
struct rx_data_cnt_details_t rx_wake_details;
|
||||||
|
struct rx_wake_pkt_type_classification_t rx_wake_pkt_classification_info;
|
||||||
|
struct rx_multicast_cnt_t rx_multicast_wake_pkt_info;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct wl_mkeep_alive_pkt {
|
||||||
|
u16 version; /* Version for mkeep_alive */
|
||||||
|
u16 length; /* length of fixed parameters in the structure */
|
||||||
|
u32 period_msec; /* high bit on means immediate send */
|
||||||
|
u16 len_bytes;
|
||||||
|
u8 keep_alive_id; /* 0 - 3 for N = 4 */
|
||||||
|
u8 data[1];
|
||||||
|
} wl_mkeep_alive_pkt_t;
|
||||||
|
|
||||||
|
#endif /* _AIC_VENDOR_H */
|
||||||
|
|
||||||
|
|
@ -0,0 +1,96 @@
|
||||||
|
#include "rwnx_main.h"
|
||||||
|
#include "rwnx_msg_tx.h"
|
||||||
|
#include "reg_access.h"
|
||||||
|
|
||||||
|
#define FW_USERCONFIG_NAME_8800D80 "aic_userconfig_8800d80.txt"
|
||||||
|
#define FW_POWERLIMIT_NAME_8800D80 "aic_powerlimit_8800d80.txt"
|
||||||
|
|
||||||
|
extern char aic_fw_path[200];
|
||||||
|
|
||||||
|
int rwnx_request_firmware_common(struct rwnx_hw *rwnx_hw,
|
||||||
|
u32** buffer, const char *filename);
|
||||||
|
void rwnx_plat_userconfig_parsing(char *buffer, int size);
|
||||||
|
void rwnx_release_firmware_common(u32** buffer);
|
||||||
|
|
||||||
|
|
||||||
|
int aicwf_set_rf_config_8800d80(struct rwnx_hw *rwnx_hw, struct mm_set_rf_calib_cfm *cfm)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
if ((ret = rwnx_send_txpwr_lvl_v3_req(rwnx_hw))) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if ((ret = rwnx_send_txpwr_lvl_adj_req(rwnx_hw))) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if ((ret = rwnx_send_txpwr_ofst2x_req(rwnx_hw))) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if ((ret = rwnx_send_rf_calib_req(rwnx_hw, cfm))) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0 ;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int rwnx_plat_userconfig_load_8800d80(struct rwnx_hw *rwnx_hw){
|
||||||
|
int size;
|
||||||
|
u32 *dst=NULL;
|
||||||
|
char *filename = FW_USERCONFIG_NAME_8800D80;
|
||||||
|
|
||||||
|
#ifndef ANDROID_PLATFORM
|
||||||
|
sprintf(aic_fw_path, "%s/%s", aic_fw_path, "aic8800D80");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
AICWFDBG(LOGINFO, "userconfig file path:%s \r\n", filename);
|
||||||
|
|
||||||
|
/* load file */
|
||||||
|
size = rwnx_request_firmware_common(rwnx_hw, &dst, filename);
|
||||||
|
if (size <= 0) {
|
||||||
|
AICWFDBG(LOGERROR, "wrong size of firmware file\n");
|
||||||
|
dst = NULL;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Copy the file on the Embedded side */
|
||||||
|
AICWFDBG(LOGINFO, "### Load file done: %s, size=%d\n", filename, size);
|
||||||
|
|
||||||
|
rwnx_plat_userconfig_parsing((char *)dst, size);
|
||||||
|
|
||||||
|
rwnx_release_firmware_common(&dst);
|
||||||
|
|
||||||
|
AICWFDBG(LOGINFO, "userconfig download complete\n\n");
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_POWER_LIMIT
|
||||||
|
extern char country_code[];
|
||||||
|
int rwnx_plat_powerlimit_load_8800d80(struct rwnx_hw *rwnx_hw)
|
||||||
|
{
|
||||||
|
int size;
|
||||||
|
u32 *dst=NULL;
|
||||||
|
char *filename = FW_POWERLIMIT_NAME_8800D80;
|
||||||
|
|
||||||
|
AICWFDBG(LOGINFO, "powerlimit file path:%s \r\n", filename);
|
||||||
|
|
||||||
|
/* load file */
|
||||||
|
size = rwnx_request_firmware_common(rwnx_hw, &dst, filename);
|
||||||
|
if (size <= 0) {
|
||||||
|
AICWFDBG(LOGERROR, "wrong size of cfg file\n");
|
||||||
|
dst = NULL;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
AICWFDBG(LOGINFO, "### Load file done: %s, size=%d\n", filename, size);
|
||||||
|
|
||||||
|
/* parsing the file */
|
||||||
|
rwnx_plat_powerlimit_parsing((char *)dst, size, country_code);
|
||||||
|
|
||||||
|
rwnx_release_firmware_common(&dst);
|
||||||
|
|
||||||
|
AICWFDBG(LOGINFO, "powerlimit download complete\n\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
#include <linux/types.h>
|
||||||
|
|
||||||
|
int rwnx_plat_userconfig_load_8800d80(struct rwnx_hw *rwnx_hw);
|
||||||
|
#ifdef CONFIG_POWER_LIMIT
|
||||||
|
int rwnx_plat_powerlimit_load_8800d80(struct rwnx_hw *rwnx_hw);
|
||||||
|
#endif
|
||||||
|
int aicwf_set_rf_config_8800d80(struct rwnx_hw *rwnx_hw, struct mm_set_rf_calib_cfm *cfm);
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -0,0 +1,97 @@
|
||||||
|
#include "rwnx_main.h"
|
||||||
|
#include "rwnx_msg_tx.h"
|
||||||
|
#include "reg_access.h"
|
||||||
|
|
||||||
|
#define FW_USERCONFIG_NAME_8800D80X2 "aic_userconfig_8800d80x2.txt"
|
||||||
|
#define FW_POWERLIMIT_NAME_8800D80X2 "aic_powerlimit_8800d80x2.txt"
|
||||||
|
|
||||||
|
extern char aic_fw_path[200];
|
||||||
|
|
||||||
|
int rwnx_request_firmware_common(struct rwnx_hw *rwnx_hw,
|
||||||
|
u32** buffer, const char *filename);
|
||||||
|
void rwnx_plat_userconfig_parsing_8800d80x2(char *buffer, int size);
|
||||||
|
void rwnx_plat_userconfig_parsing(char *buffer, int size);
|
||||||
|
void rwnx_release_firmware_common(u32** buffer);
|
||||||
|
|
||||||
|
|
||||||
|
int aicwf_set_rf_config_8800d80x2(struct rwnx_hw *rwnx_hw, struct mm_set_rf_calib_cfm *cfm)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
if ((ret = rwnx_send_txpwr_lvl_v4_req(rwnx_hw))) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if ((ret = rwnx_send_txpwr_lvl_adj_req(rwnx_hw))) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if ((ret = rwnx_send_txpwr_ofst2x_v2_req(rwnx_hw))) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if ((ret = rwnx_send_rf_calib_req(rwnx_hw, cfm))) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0 ;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int rwnx_plat_userconfig_load_8800d80x2(struct rwnx_hw *rwnx_hw){
|
||||||
|
int size;
|
||||||
|
u32 *dst=NULL;
|
||||||
|
char *filename = FW_USERCONFIG_NAME_8800D80X2;
|
||||||
|
|
||||||
|
#ifndef ANDROID_PLATFORM
|
||||||
|
sprintf(aic_fw_path, "%s/%s", aic_fw_path, "aic8800D80X2");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
AICWFDBG(LOGINFO, "userconfig file path:%s \r\n", filename);
|
||||||
|
|
||||||
|
/* load file */
|
||||||
|
size = rwnx_request_firmware_common(rwnx_hw, &dst, filename);
|
||||||
|
if (size <= 0) {
|
||||||
|
AICWFDBG(LOGERROR, "wrong size of firmware file\n");
|
||||||
|
dst = NULL;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Copy the file on the Embedded side */
|
||||||
|
AICWFDBG(LOGINFO, "### Load file done: %s, size=%d\n", filename, size);
|
||||||
|
|
||||||
|
rwnx_plat_userconfig_parsing_8800d80x2((char *)dst, size);
|
||||||
|
|
||||||
|
rwnx_release_firmware_common(&dst);
|
||||||
|
|
||||||
|
AICWFDBG(LOGINFO, "userconfig download complete\n\n");
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_POWER_LIMIT
|
||||||
|
extern char country_code[];
|
||||||
|
int rwnx_plat_powerlimit_load_8800d80x2(struct rwnx_hw *rwnx_hw)
|
||||||
|
{
|
||||||
|
int size;
|
||||||
|
u32 *dst=NULL;
|
||||||
|
char *filename = FW_POWERLIMIT_NAME_8800D80X2;
|
||||||
|
|
||||||
|
AICWFDBG(LOGINFO, "powerlimit file path:%s \r\n", filename);
|
||||||
|
|
||||||
|
/* load file */
|
||||||
|
size = rwnx_request_firmware_common(rwnx_hw, &dst, filename);
|
||||||
|
if (size <= 0) {
|
||||||
|
AICWFDBG(LOGERROR, "wrong size of cfg file\n");
|
||||||
|
dst = NULL;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
AICWFDBG(LOGINFO, "### Load file done: %s, size=%d\n", filename, size);
|
||||||
|
|
||||||
|
/* parsing the file */
|
||||||
|
rwnx_plat_powerlimit_parsing((char *)dst, size, country_code);
|
||||||
|
|
||||||
|
rwnx_release_firmware_common(&dst);
|
||||||
|
|
||||||
|
AICWFDBG(LOGINFO, "powerlimit download complete\n\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
#include <linux/types.h>
|
||||||
|
|
||||||
|
int rwnx_plat_userconfig_load_8800d80x2(struct rwnx_hw *rwnx_hw);
|
||||||
|
#ifdef CONFIG_POWER_LIMIT
|
||||||
|
int rwnx_plat_powerlimit_load_8800d80x2(struct rwnx_hw *rwnx_hw);
|
||||||
|
#endif
|
||||||
|
int aicwf_set_rf_config_8800d80x2(struct rwnx_hw *rwnx_hw, struct mm_set_rf_calib_cfm *cfm);
|
||||||
|
|
||||||
|
|
||||||
3685
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/aicwf_compat_8800dc.c
Normal file
3685
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/aicwf_compat_8800dc.c
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -0,0 +1,62 @@
|
||||||
|
#include <linux/types.h>
|
||||||
|
|
||||||
|
#if defined(CONFIG_DPD) || defined(CONFIG_LOFT_CALIB)
|
||||||
|
typedef struct {
|
||||||
|
uint32_t bit_mask[3];
|
||||||
|
uint32_t reserved;
|
||||||
|
uint32_t dpd_high[96];
|
||||||
|
uint32_t dpd_11b[96];
|
||||||
|
uint32_t dpd_low[96];
|
||||||
|
uint32_t idac_11b[48];
|
||||||
|
uint32_t idac_high[48];
|
||||||
|
uint32_t idac_low[48];
|
||||||
|
uint32_t loft_res[18];
|
||||||
|
uint32_t rx_iqim_res[16];
|
||||||
|
} rf_misc_ram_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint32_t bit_mask[4];
|
||||||
|
uint32_t dpd_high[96];
|
||||||
|
uint32_t loft_res[18];
|
||||||
|
} rf_misc_ram_lite_t;
|
||||||
|
|
||||||
|
#define MEMBER_SIZE(type, member) sizeof(((type *)0)->member)
|
||||||
|
#define DPD_RESULT_SIZE_8800DC sizeof(rf_misc_ram_lite_t)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_DPD
|
||||||
|
extern rf_misc_ram_lite_t dpd_res;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_LOFT_CALIB
|
||||||
|
extern rf_misc_ram_lite_t loft_res_local;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int aicwf_patch_table_load(struct rwnx_hw *rwnx_hw, char *filename);
|
||||||
|
void aicwf_patch_config_8800dc(struct rwnx_hw *rwnx_hw);
|
||||||
|
int aicwf_set_rf_config_8800dc(struct rwnx_hw *rwnx_hw, struct mm_set_rf_calib_cfm *cfm);
|
||||||
|
int aicwf_misc_ram_init_8800dc(struct rwnx_hw *rwnx_hw);
|
||||||
|
#if defined(CONFIG_DPD) || defined(CONFIG_LOFT_CALIB)
|
||||||
|
int aicwf_misc_ram_valid_check_8800dc(struct rwnx_hw *rwnx_hw, int *valid_out);
|
||||||
|
int aicwf_plat_calib_load_8800dc(struct rwnx_hw *rwnx_hw);
|
||||||
|
#endif
|
||||||
|
#ifdef CONFIG_DPD
|
||||||
|
int aicwf_dpd_calib_8800dc(struct rwnx_hw *rwnx_hw, rf_misc_ram_lite_t *dpd_res);
|
||||||
|
int aicwf_dpd_result_apply_8800dc(struct rwnx_hw *rwnx_hw, rf_misc_ram_lite_t *dpd_res);
|
||||||
|
#ifndef CONFIG_FORCE_DPD_CALIB
|
||||||
|
int aicwf_dpd_result_load_8800dc(struct rwnx_hw *rwnx_hw, rf_misc_ram_lite_t *dpd_res);
|
||||||
|
int aicwf_dpd_result_write_8800dc(void *buf, int buf_len);
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#ifdef CONFIG_LOFT_CALIB
|
||||||
|
int aicwf_loft_calib_8800dc(struct rwnx_hw *rwnx_hw, rf_misc_ram_lite_t *loft_res);
|
||||||
|
int aicwf_loft_result_apply_8800dc(struct rwnx_hw *rwnx_hw, rf_misc_ram_lite_t *loft_res);
|
||||||
|
#endif
|
||||||
|
int aicwf_plat_patch_load_8800dc(struct rwnx_hw *rwnx_hw);
|
||||||
|
int aicwf_plat_rftest_load_8800dc(struct rwnx_hw *rwnx_hw);
|
||||||
|
int rwnx_plat_userconfig_load_8800dc(struct rwnx_hw *rwnx_hw);
|
||||||
|
int rwnx_plat_userconfig_load_8800dw(struct rwnx_hw *rwnx_hw);
|
||||||
|
#ifdef CONFIG_POWER_LIMIT
|
||||||
|
int rwnx_plat_powerlimit_load_8800dcdw(struct rwnx_hw *rwnx_hw, uint16_t chip_id);
|
||||||
|
#endif
|
||||||
|
void system_config_8800dc(struct rwnx_hw *rwnx_hw);
|
||||||
53
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/aicwf_debug.h
Normal file
53
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/aicwf_debug.h
Normal file
|
|
@ -0,0 +1,53 @@
|
||||||
|
|
||||||
|
|
||||||
|
#define RWNX_FN_ENTRY_STR ">>> %s()\n", __func__
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* message levels */
|
||||||
|
#define LOGERROR 0x0001
|
||||||
|
#define LOGINFO 0x0002
|
||||||
|
#define LOGTRACE 0x0004
|
||||||
|
#define LOGDEBUG 0x0008
|
||||||
|
#define LOGDATA 0x0010
|
||||||
|
#define LOGSTEER 0x0020
|
||||||
|
|
||||||
|
extern int aicwf_dbg_level;
|
||||||
|
void rwnx_data_dump(char* tag, void* data, unsigned long len);
|
||||||
|
|
||||||
|
#define AICWF_LOG "AICWFDBG("
|
||||||
|
|
||||||
|
#define AICWFDBG(level, args, arg...) \
|
||||||
|
do { \
|
||||||
|
if (aicwf_dbg_level & level) { \
|
||||||
|
printk(AICWF_LOG#level")\t" args, ##arg); \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define RWNX_DBG(fmt, ...) \
|
||||||
|
do { \
|
||||||
|
if (aicwf_dbg_level & LOGTRACE) { \
|
||||||
|
printk(AICWF_LOG"LOGTRACE)\t"fmt , ##__VA_ARGS__); \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
#define RWNX_DBG(fmt, ...) \
|
||||||
|
do { \
|
||||||
|
if (aicwf_dbg_level & LOGTRACE) { \
|
||||||
|
printk(AICWF_LOG"LOGTRACE"")\t" fmt, ##__VA_ARGS__); \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
#define AICWFDBG(args, level) \
|
||||||
|
do { \
|
||||||
|
if (aicwf_dbg_level & level) { \
|
||||||
|
printk(AICWF_LOG"(%s)\t" ,#level); \
|
||||||
|
printf args; \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
601
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/aicwf_manager.c
Normal file
601
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/aicwf_manager.c
Normal file
|
|
@ -0,0 +1,601 @@
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
*
|
||||||
|
* Copyright (C) 2020 AIC semiconductor.
|
||||||
|
*
|
||||||
|
* @file aicwf_manager.c
|
||||||
|
*
|
||||||
|
* @brief netlink msg definitions
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <linux/module.h>
|
||||||
|
#include <linux/netlink.h>
|
||||||
|
#include <net/sock.h>
|
||||||
|
#include "aicwf_manager.h"
|
||||||
|
#include "lmac_mac.h"
|
||||||
|
#include "aicwf_debug.h"
|
||||||
|
|
||||||
|
#define MAC_FMT "%02x:%02x:%02x:%02x:%02x:%02x"
|
||||||
|
#define MAC_ARG(x) ((u8_l *)(x))[0], ((u8_l *)(x))[1], ((u8_l *)(x))[2], ((u8_l *)(x))[3], ((u8_l *)(x))[4], ((u8_l *)(x))[5]
|
||||||
|
#define MANAGER_STR "[MANAGER] USB "
|
||||||
|
|
||||||
|
|
||||||
|
static struct sock *nl_sock = NULL;
|
||||||
|
|
||||||
|
static struct rwnx_vif *nl_rwnx_vif[PHY_BAND_MAX][CONFIG_IFACE_NUMBER] = {{NULL}};
|
||||||
|
static u8_l nl_hook[PHY_BAND_MAX][CONFIG_IFACE_NUMBER] = {{0}};
|
||||||
|
|
||||||
|
static u8_l nl_daemon_on = 0;
|
||||||
|
|
||||||
|
#define FREQ_2G_MIN 2412
|
||||||
|
#define FREQ_2G_MAX 2484
|
||||||
|
#define FREQ_5G_MIN 5170
|
||||||
|
#define FREQ_5G_MAX 5825
|
||||||
|
#define FREQ_6G_MIN 5925
|
||||||
|
#define FREQ_6G_MAX 7125
|
||||||
|
|
||||||
|
static int freq_to_channel(int freq)
|
||||||
|
{
|
||||||
|
if (freq >= FREQ_2G_MIN && freq <= FREQ_2G_MAX) {
|
||||||
|
if (freq == 2484) {
|
||||||
|
return 14;
|
||||||
|
} else {
|
||||||
|
return (freq - 2412) / 5 + 1;
|
||||||
|
}
|
||||||
|
} else if (freq >= FREQ_5G_MIN && freq <= FREQ_5G_MAX) {
|
||||||
|
return (freq - 5000) / 5;
|
||||||
|
} else if (freq >= FREQ_6G_MIN && freq <= FREQ_6G_MAX) {
|
||||||
|
return (freq - 5950) / 5;
|
||||||
|
} else {
|
||||||
|
AICWFDBG(LOGERROR, MANAGER_STR"aic Unsupported frequency: %d MHz\n", freq);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void aicwf_nl_recv_msg(struct sk_buff *skb)
|
||||||
|
{
|
||||||
|
struct rwnx_vif *rwnx_vif;
|
||||||
|
struct rwnx_sta *sta = NULL;
|
||||||
|
u8_l rwnx_hook = 0;
|
||||||
|
u8_l band;
|
||||||
|
u8_l ssid;
|
||||||
|
struct nlmsghdr *nlh = NULL;
|
||||||
|
struct b_nl_message *msg = NULL;
|
||||||
|
struct b_elm_header *hdr = NULL;
|
||||||
|
struct b_elm_intf *intf = NULL;
|
||||||
|
struct b_elm_sta_info *sta_info = NULL;
|
||||||
|
struct b_elm_roam_info *roam_info = NULL;
|
||||||
|
u32 offset = 0;
|
||||||
|
|
||||||
|
if (skb == NULL) {
|
||||||
|
AICWFDBG(LOGERROR, MANAGER_STR"skb is null.\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
nlh = (struct nlmsghdr *)skb->data;
|
||||||
|
msg = (struct b_nl_message *)NLMSG_DATA(nlh);
|
||||||
|
|
||||||
|
AICWFDBG(LOGSTEER, MANAGER_STR"%s, %d\n", __func__, msg->type);
|
||||||
|
|
||||||
|
/* message type */
|
||||||
|
switch(msg->type) {
|
||||||
|
case AIC_NL_DAEMON_ON_TYPE:
|
||||||
|
nl_daemon_on = 1;
|
||||||
|
AICWFDBG(LOGSTEER, MANAGER_STR"AIC_NL_DAEMON_ON_TYPE\n");
|
||||||
|
for (band = 0; band < PHY_BAND_MAX; band++) {
|
||||||
|
for (ssid = 0; ssid < CONFIG_IFACE_NUMBER; ssid++) {
|
||||||
|
rwnx_vif = nl_rwnx_vif[band][ssid];
|
||||||
|
rwnx_hook = nl_hook[band][ssid];
|
||||||
|
|
||||||
|
if (!rwnx_hook) {
|
||||||
|
AICWFDBG(LOGSTEER, MANAGER_STR"%s, !rwnx_hook, %d,%d\n", __func__, band, ssid);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (rwnx_vif == NULL || rwnx_vif->up == false) {
|
||||||
|
AICWFDBG(LOGSTEER, MANAGER_STR"%s, !rwnx_vif, %d,%d\n", __func__, band, ssid);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_BAND_STEERING
|
||||||
|
aicwf_band_steering_init(rwnx_vif);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
spin_lock_bh(&rwnx_vif->rwnx_hw->cb_lock);
|
||||||
|
list_for_each_entry(sta, &rwnx_vif->ap.sta_list, list){
|
||||||
|
if (sta->valid)
|
||||||
|
aicwf_nl_send_new_sta_msg(rwnx_vif, sta->mac_addr);
|
||||||
|
}
|
||||||
|
spin_unlock_bh(&rwnx_vif->rwnx_hw->cb_lock);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case AIC_NL_DAEMON_OFF_TYPE:
|
||||||
|
nl_daemon_on = 0;
|
||||||
|
break;
|
||||||
|
#ifdef CONFIG_BAND_STEERING
|
||||||
|
case AIC_NL_B_STEER_BLOCK_ADD_TYPE:
|
||||||
|
case AIC_NL_B_STEER_BLOCK_DEL_TYPE:
|
||||||
|
while (offset < msg->len) {
|
||||||
|
hdr = (struct b_elm_header *)(msg->content + offset);
|
||||||
|
offset += ELM_HEADER_LEN;
|
||||||
|
|
||||||
|
switch(hdr->id) {
|
||||||
|
case AIC_ELM_INTF_ID:
|
||||||
|
intf = (struct b_elm_intf *)(msg->content + offset);
|
||||||
|
break;
|
||||||
|
case AIC_ELM_STA_INFO_ID:
|
||||||
|
sta_info = (struct b_elm_sta_info *)(msg->content + offset);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
AICWFDBG(LOGERROR, MANAGER_STR"unknown element id.\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
offset += hdr->len;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (intf && sta_info) {
|
||||||
|
band = intf->band;
|
||||||
|
ssid = intf->ssid;
|
||||||
|
AICWFDBG(LOGSTEER, MANAGER_STR"STEER_BLOCK band: %d, ssid: %d\n", band, ssid);
|
||||||
|
rwnx_vif = nl_rwnx_vif[band][ssid];
|
||||||
|
rwnx_hook = nl_hook[band][ssid];
|
||||||
|
|
||||||
|
if (!rwnx_hook) {
|
||||||
|
AICWFDBG(LOGSTEER, MANAGER_STR"rwnx_hook is null p1.\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (rwnx_vif == NULL || rwnx_vif->up == false) {
|
||||||
|
AICWFDBG(LOGSTEER, MANAGER_STR"rwnx_vif is null/down p1.\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (msg->type == AIC_NL_B_STEER_BLOCK_ADD_TYPE)
|
||||||
|
aicwf_band_steering_block_entry_add(rwnx_vif, sta_info->mac);
|
||||||
|
else if (msg->type == AIC_NL_B_STEER_BLOCK_DEL_TYPE)
|
||||||
|
aicwf_band_steering_block_entry_del(rwnx_vif, sta_info->mac);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case AIC_NL_B_STEER_ROAM_TYPE:
|
||||||
|
while (offset < msg->len) {
|
||||||
|
hdr = (struct b_elm_header *)(msg->content + offset);
|
||||||
|
offset += ELM_HEADER_LEN;
|
||||||
|
|
||||||
|
/* element type: should handle wrong length */
|
||||||
|
switch(hdr->id) {
|
||||||
|
case AIC_ELM_INTF_ID:
|
||||||
|
intf = (struct b_elm_intf *)(msg->content + offset);
|
||||||
|
break;
|
||||||
|
case AIC_ELM_ROAM_INFO_ID:
|
||||||
|
roam_info = (struct b_elm_roam_info *)(msg->content + offset);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
AICWFDBG(LOGERROR, MANAGER_STR"unknown element id.\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
offset += hdr->len;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (intf && roam_info) {
|
||||||
|
band = intf->band;
|
||||||
|
ssid = intf->ssid;
|
||||||
|
rwnx_vif = nl_rwnx_vif[band][ssid];
|
||||||
|
rwnx_hook = nl_hook[band][ssid];
|
||||||
|
|
||||||
|
if (!rwnx_hook) {
|
||||||
|
AICWFDBG(LOGERROR, MANAGER_STR"rwnx_hook is null p2.\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (rwnx_vif == NULL || rwnx_vif->up == false) {
|
||||||
|
AICWFDBG(LOGERROR, MANAGER_STR"rwnx_vif is null/down p2.\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
AICWFDBG(LOGSTEER, MANAGER_STR"AIC_NL_B_STEER_ROAM_TYPE (hostapd_cli)!\n");
|
||||||
|
AICWFDBG(LOGSTEER, MANAGER_STR"sta_mac="MAC_FMT"\n", MAC_ARG(roam_info->sta_mac));
|
||||||
|
AICWFDBG(LOGSTEER, MANAGER_STR"bss_mac="MAC_FMT" bss_ch=%u method=%s\n",
|
||||||
|
MAC_ARG(roam_info->bss_mac),
|
||||||
|
roam_info->bss_ch,
|
||||||
|
roam_info->method == 0 ? "11V" : "Deauth");
|
||||||
|
|
||||||
|
if (roam_info->method == 1)
|
||||||
|
aicwf_band_steering_roam_block_entry_add(rwnx_vif, roam_info->sta_mac);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
default:
|
||||||
|
AICWFDBG(LOGERROR, MANAGER_STR"unknown message type.\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void aicwf_nl_send_msg(void *msg, u32 msg_len)
|
||||||
|
{
|
||||||
|
struct nlmsghdr *nlh = NULL;
|
||||||
|
struct sk_buff *skb = NULL;
|
||||||
|
u32 skb_len;
|
||||||
|
s32 err;
|
||||||
|
|
||||||
|
skb_len = NLMSG_SPACE(NL_MAX_MSG_SIZE);
|
||||||
|
skb = __dev_alloc_skb(skb_len, GFP_ATOMIC);
|
||||||
|
if (!skb) {
|
||||||
|
AICWFDBG(LOGERROR, MANAGER_STR"allocate skb failed.\n");
|
||||||
|
goto func_return;
|
||||||
|
}
|
||||||
|
|
||||||
|
nlh = nlmsg_put(skb, 0, 0, 0, NL_MAX_MSG_SIZE, 0);
|
||||||
|
if (!nlh) {
|
||||||
|
AICWFDBG(LOGERROR, MANAGER_STR"put netlink header failed.\n");
|
||||||
|
kfree_skb(skb);
|
||||||
|
goto func_return;
|
||||||
|
}
|
||||||
|
|
||||||
|
NETLINK_CB(skb).portid = 0;
|
||||||
|
NETLINK_CB(skb).dst_group = 0;
|
||||||
|
memset(NLMSG_DATA(nlh), 0, msg_len);
|
||||||
|
memcpy(NLMSG_DATA(nlh), (u8_l *)msg, msg_len);
|
||||||
|
|
||||||
|
if (!nl_sock) {
|
||||||
|
AICWFDBG(LOGERROR, MANAGER_STR"[%s %u] nl_sock is NULL\n", __FUNCTION__, __LINE__);
|
||||||
|
goto msg_fail_skb;
|
||||||
|
}
|
||||||
|
|
||||||
|
err = netlink_unicast(nl_sock, skb, NL_AIC_MANAGER_PID, MSG_DONTWAIT);
|
||||||
|
|
||||||
|
if (err < 0) {
|
||||||
|
/* netlink_unicast() already kfree_skb */
|
||||||
|
AICWFDBG(LOGSTEER, MANAGER_STR"send netlink unicast failed.\n");
|
||||||
|
goto func_return;
|
||||||
|
}
|
||||||
|
|
||||||
|
func_return:
|
||||||
|
return;
|
||||||
|
|
||||||
|
msg_fail_skb:
|
||||||
|
kfree_skb(skb);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void aicwf_netlink_set_msg(
|
||||||
|
struct b_nl_message *msg, u32 *msg_len, void *elm, u32 elm_len)
|
||||||
|
{
|
||||||
|
memcpy(msg->content + (*msg_len), elm, elm_len);
|
||||||
|
(*msg_len) += elm_len;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void aicwf_nl_send_del_sta_msg(struct rwnx_vif *rwnx_vif, u8_l *mac)
|
||||||
|
{
|
||||||
|
u32 msg_len = 0;
|
||||||
|
struct b_nl_message msg = {0};
|
||||||
|
struct b_elm_header hdr = {0};
|
||||||
|
struct b_elm_intf intf = {{0}};
|
||||||
|
struct b_elm_sta_info sta_info = {{0}};
|
||||||
|
|
||||||
|
if (!nl_daemon_on)
|
||||||
|
return;
|
||||||
|
|
||||||
|
AICWFDBG(LOGSTEER, MANAGER_STR"%s, "MAC_FMT"\n", __func__, MAC_ARG(mac));
|
||||||
|
|
||||||
|
/* element header */
|
||||||
|
hdr.id = AIC_ELM_INTF_ID;
|
||||||
|
hdr.len = ELM_INTF_LEN;
|
||||||
|
aicwf_netlink_set_msg(&msg, &msg_len, (void *)&hdr, ELM_HEADER_LEN);
|
||||||
|
|
||||||
|
/* element: AIC_ELM_INTF_ID */
|
||||||
|
intf.root = 0; /* TBD */
|
||||||
|
intf.band = rwnx_vif->ap.band;
|
||||||
|
intf.ssid = rwnx_vif->rwnx_hw->iface_idx;
|
||||||
|
aicwf_netlink_set_msg(&msg, &msg_len, (void *)&intf, ELM_INTF_LEN);
|
||||||
|
|
||||||
|
/* element header */
|
||||||
|
hdr.id = AIC_ELM_STA_INFO_ID;
|
||||||
|
hdr.len = ELM_STA_INFO_LEN;
|
||||||
|
aicwf_netlink_set_msg(&msg, &msg_len, (void *)&hdr, ELM_HEADER_LEN);
|
||||||
|
|
||||||
|
/* element: AIC_ELM_STA_INFO_ID */
|
||||||
|
memcpy(sta_info.mac, mac, 6);
|
||||||
|
aicwf_netlink_set_msg(&msg, &msg_len, (void *)&sta_info, ELM_STA_INFO_LEN);
|
||||||
|
|
||||||
|
/* finish message */
|
||||||
|
msg.type = AIC_NL_DEL_STA_TYPE;
|
||||||
|
msg.len = msg_len;
|
||||||
|
|
||||||
|
/* length += (type + len) */
|
||||||
|
msg_len += 8;
|
||||||
|
aicwf_nl_send_msg((void *)&msg, msg_len);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void aicwf_nl_send_new_sta_msg(struct rwnx_vif *rwnx_vif, u8_l *mac)
|
||||||
|
{
|
||||||
|
u32 msg_len = 0;
|
||||||
|
struct b_nl_message msg = {0};
|
||||||
|
struct b_elm_header hdr = {0};
|
||||||
|
struct b_elm_intf intf = {{0}};
|
||||||
|
struct b_elm_sta_info sta_info = {{0}};
|
||||||
|
|
||||||
|
if (!nl_daemon_on)
|
||||||
|
return;
|
||||||
|
|
||||||
|
AICWFDBG(LOGSTEER, MANAGER_STR"%s, "MAC_FMT"\n", __func__, MAC_ARG(mac));
|
||||||
|
|
||||||
|
/* element header */
|
||||||
|
hdr.id = AIC_ELM_INTF_ID;
|
||||||
|
hdr.len = ELM_INTF_LEN;
|
||||||
|
aicwf_netlink_set_msg(&msg, &msg_len, (void *)&hdr, ELM_HEADER_LEN);
|
||||||
|
|
||||||
|
/* element: AIC_ELM_INTF_ID */
|
||||||
|
intf.root = 0; /* TBD */
|
||||||
|
intf.band = rwnx_vif->ap.band;
|
||||||
|
intf.ssid = rwnx_vif->rwnx_hw->iface_idx;
|
||||||
|
aicwf_netlink_set_msg(&msg, &msg_len, (void *)&intf, ELM_INTF_LEN);
|
||||||
|
|
||||||
|
/* element header */
|
||||||
|
hdr.id = AIC_ELM_STA_INFO_ID;
|
||||||
|
hdr.len = ELM_STA_INFO_LEN;
|
||||||
|
aicwf_netlink_set_msg(&msg, &msg_len, (void *)&hdr, ELM_HEADER_LEN);
|
||||||
|
|
||||||
|
/* element: AIC_ELM_STA_INFO_ID */
|
||||||
|
memcpy(sta_info.mac, mac, 6);
|
||||||
|
aicwf_netlink_set_msg(&msg, &msg_len, (void *)&sta_info, ELM_STA_INFO_LEN);
|
||||||
|
|
||||||
|
/* finish message */
|
||||||
|
msg.type = AIC_NL_NEW_STA_TYPE;
|
||||||
|
msg.len = msg_len;
|
||||||
|
|
||||||
|
/* length += (type + len) */
|
||||||
|
msg_len += 8;
|
||||||
|
aicwf_nl_send_msg((void *)&msg, msg_len);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void aicwf_nl_send_intf_rpt_msg(struct rwnx_vif *rwnx_vif)
|
||||||
|
{
|
||||||
|
u32 msg_len = 0;
|
||||||
|
struct b_nl_message msg = {0};
|
||||||
|
struct b_elm_header hdr = {0};
|
||||||
|
struct b_elm_intf intf = {{0}};
|
||||||
|
struct b_elm_intf_info intf_info = {0};
|
||||||
|
|
||||||
|
if (!nl_daemon_on)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* element header */
|
||||||
|
hdr.id = AIC_ELM_INTF_ID;
|
||||||
|
hdr.len = ELM_INTF_LEN;
|
||||||
|
aicwf_netlink_set_msg(&msg, &msg_len, (void *)&hdr, ELM_HEADER_LEN);
|
||||||
|
|
||||||
|
/* element: AIC_ELM_INTF_ID */
|
||||||
|
memcpy(intf.mac, rwnx_vif->ndev->dev_addr, 6);
|
||||||
|
intf.root = 0; /* TBD */
|
||||||
|
intf.band = rwnx_vif->ap.band;
|
||||||
|
intf.ssid = rwnx_vif->rwnx_hw->iface_idx;
|
||||||
|
memcpy(intf.name, rwnx_vif->ndev->name, 16);
|
||||||
|
aicwf_netlink_set_msg(&msg, &msg_len, (void *)&intf, ELM_INTF_LEN);
|
||||||
|
|
||||||
|
/* element header */
|
||||||
|
hdr.id = AIC_ELM_INTF_INFO_ID;
|
||||||
|
hdr.len = ELM_INTF_INFO_LEN;
|
||||||
|
aicwf_netlink_set_msg(&msg, &msg_len, (void *)&hdr, ELM_HEADER_LEN);
|
||||||
|
|
||||||
|
/* element: AIC_ELM_INTF_INFO_ID */
|
||||||
|
intf_info.ch = freq_to_channel(rwnx_vif->ap.freq);
|
||||||
|
intf_info.tx_tp = 0; /* TBD */
|
||||||
|
intf_info.rx_tp = 0; /* TBD */
|
||||||
|
|
||||||
|
intf_info.bss_info = 0;
|
||||||
|
intf_info.reg_class = (rwnx_vif->ap.band == 0) ? 81 : 128;
|
||||||
|
intf_info.phy_type = 7;
|
||||||
|
|
||||||
|
aicwf_netlink_set_msg(&msg, &msg_len, (void *)&intf_info, ELM_INTF_INFO_LEN);
|
||||||
|
|
||||||
|
/* finish message */
|
||||||
|
msg.type = AIC_NL_INTF_RPT_TYPE;
|
||||||
|
msg.len = msg_len;
|
||||||
|
|
||||||
|
/* length += (type + len) */
|
||||||
|
msg_len += 8;
|
||||||
|
aicwf_nl_send_msg((void *)&msg, msg_len);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void aicwf_nl_send_sta_rpt_msg(struct rwnx_vif *rwnx_vif, struct rwnx_sta *sta)
|
||||||
|
{
|
||||||
|
u32 msg_len = 0;
|
||||||
|
struct b_nl_message msg = {0};
|
||||||
|
struct b_elm_header hdr = {0};
|
||||||
|
struct b_elm_intf intf = {{0}};
|
||||||
|
struct b_elm_sta_info sta_info = {{0}};
|
||||||
|
struct b_elm_sta_info_ext sta_info_ext = {{0}};
|
||||||
|
|
||||||
|
if (!nl_daemon_on)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* element header */
|
||||||
|
hdr.id = AIC_ELM_INTF_ID;
|
||||||
|
hdr.len = ELM_INTF_LEN;
|
||||||
|
aicwf_netlink_set_msg(&msg, &msg_len, (void *)&hdr, ELM_HEADER_LEN);
|
||||||
|
|
||||||
|
/* element: AIC_ELM_INTF_ID */
|
||||||
|
memcpy(intf.mac, rwnx_vif->ndev->dev_addr, 6);
|
||||||
|
intf.root = 0; /* TBD */
|
||||||
|
intf.band = rwnx_vif->ap.band;
|
||||||
|
intf.ssid = rwnx_vif->rwnx_hw->iface_idx;
|
||||||
|
memcpy(intf.name, rwnx_vif->ndev->name, 16);
|
||||||
|
aicwf_netlink_set_msg(&msg, &msg_len, (void *)&intf, ELM_INTF_LEN);
|
||||||
|
|
||||||
|
/* element header */
|
||||||
|
hdr.id = AIC_ELM_STA_INFO_ID;
|
||||||
|
hdr.len = ELM_STA_INFO_LEN;
|
||||||
|
aicwf_netlink_set_msg(&msg, &msg_len, (void *)&hdr, ELM_HEADER_LEN);
|
||||||
|
|
||||||
|
/* element: AIC_ELM_STA_INFO_ID */
|
||||||
|
memcpy(sta_info.mac, sta->mac_addr, 6);
|
||||||
|
sta_info.rssi = sta->rssi;
|
||||||
|
sta_info.link_time = sta->link_time;
|
||||||
|
aicwf_netlink_set_msg(&msg, &msg_len, (void *)&sta_info, ELM_STA_INFO_LEN);
|
||||||
|
|
||||||
|
/* element header */
|
||||||
|
hdr.id = AIC_ELM_STA_INFO_EXT_ID;
|
||||||
|
hdr.len = ELM_STA_INFO_EXT_LEN;
|
||||||
|
aicwf_netlink_set_msg(&msg, &msg_len, (void *)&hdr, ELM_HEADER_LEN);
|
||||||
|
|
||||||
|
/* element: AIC_ELM_STA_INFO_EXT_ID */
|
||||||
|
memcpy(sta_info_ext.mac, sta->mac_addr, 6);
|
||||||
|
sta_info_ext.supported_band = sta->support_band;
|
||||||
|
aicwf_netlink_set_msg(&msg, &msg_len, (void *)&sta_info_ext, ELM_STA_INFO_EXT_LEN);
|
||||||
|
|
||||||
|
/* finish message */
|
||||||
|
msg.type = AIC_NL_STA_RPT_TYPE;
|
||||||
|
msg.len = msg_len;
|
||||||
|
|
||||||
|
/* length += (type + len) */
|
||||||
|
msg_len += 8;
|
||||||
|
aicwf_nl_send_msg((void *)&msg, msg_len);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void aicwf_nl_send_frame_rpt_msg(struct rwnx_vif *rwnx_vif, u16_l frame_type, u8_l *sa, s8_l rssi)
|
||||||
|
{
|
||||||
|
u32 msg_len = 0;
|
||||||
|
struct b_nl_message msg = {0};
|
||||||
|
struct b_elm_header hdr = {0};
|
||||||
|
struct b_elm_frame_info frame_info = {0};
|
||||||
|
struct b_elm_intf intf = {{0}};
|
||||||
|
|
||||||
|
if (!nl_daemon_on)
|
||||||
|
return;
|
||||||
|
|
||||||
|
//AICWFDBG(LOGSTEER, "[NETLINK] %s, sta: "MAC_FMT"\n", __func__, MAC_ARG(sa));
|
||||||
|
|
||||||
|
/* TBD */
|
||||||
|
if (frame_type == WIFI_PROBEREQ && rssi <= LOW_RSSI_IGNORE) {
|
||||||
|
AICWFDBG(LOGSTEER, MANAGER_STR"WIFI_PROBEREQ <= %d, ignore\n", LOW_RSSI_IGNORE);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* element header */
|
||||||
|
hdr.id = AIC_ELM_INTF_ID;
|
||||||
|
hdr.len = ELM_INTF_LEN;
|
||||||
|
aicwf_netlink_set_msg(&msg, &msg_len, (void *)&hdr, ELM_HEADER_LEN);
|
||||||
|
|
||||||
|
/* element: AIC_ELM_INTF_ID */
|
||||||
|
intf.root = 0; /* TBD */
|
||||||
|
intf.band = rwnx_vif->ap.band;
|
||||||
|
intf.ssid = rwnx_vif->rwnx_hw->iface_idx;
|
||||||
|
aicwf_netlink_set_msg(&msg, &msg_len, (void *)&intf, ELM_INTF_LEN);
|
||||||
|
|
||||||
|
/* element header */
|
||||||
|
hdr.id = AIC_ELM_FRAME_INFO_ID;
|
||||||
|
hdr.len = ELM_FRAME_INFO_LEN;
|
||||||
|
aicwf_netlink_set_msg(&msg, &msg_len, (void *)&hdr, ELM_HEADER_LEN);
|
||||||
|
|
||||||
|
/* element: AIC_ELM_FRAME_INFO_ID */
|
||||||
|
frame_info.frame_type = frame_type;
|
||||||
|
memcpy(frame_info.sa, sa, 6);
|
||||||
|
frame_info.rssi = rssi;
|
||||||
|
aicwf_netlink_set_msg(&msg, &msg_len, (void *)&frame_info, ELM_FRAME_INFO_LEN);
|
||||||
|
|
||||||
|
/* finish message */
|
||||||
|
msg.type = AIC_NL_FRAME_RPT_TYPE;
|
||||||
|
msg.len = msg_len;
|
||||||
|
|
||||||
|
/* length += (type + len) */
|
||||||
|
msg_len += 8;
|
||||||
|
aicwf_nl_send_msg((void *)&msg, msg_len);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void aicwf_nl_send_time_tick_msg(struct rwnx_vif *rwnx_vif)
|
||||||
|
{
|
||||||
|
u32 msg_len = 0;
|
||||||
|
struct b_nl_message msg = {0};
|
||||||
|
struct b_elm_header hdr = {0};
|
||||||
|
struct b_elm_intf intf = {{0}};
|
||||||
|
|
||||||
|
if (!nl_daemon_on)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* element header */
|
||||||
|
hdr.id = AIC_ELM_INTF_ID;
|
||||||
|
hdr.len = ELM_INTF_LEN;
|
||||||
|
aicwf_netlink_set_msg(&msg, &msg_len, (void *)&hdr, ELM_HEADER_LEN);
|
||||||
|
|
||||||
|
/* element: AIC_ELM_INTF_ID */
|
||||||
|
intf.root = 0; /* TBD */
|
||||||
|
intf.band = rwnx_vif->ap.band;
|
||||||
|
intf.ssid = rwnx_vif->rwnx_hw->iface_idx;
|
||||||
|
aicwf_netlink_set_msg(&msg, &msg_len, (void *)&intf, ELM_INTF_LEN);
|
||||||
|
|
||||||
|
/* finish message */
|
||||||
|
msg.type = AIC_NL_TIME_TICK_TYPE;
|
||||||
|
msg.len = msg_len;
|
||||||
|
|
||||||
|
/* length += (type + len) */
|
||||||
|
msg_len += 8;
|
||||||
|
aicwf_nl_send_msg((void *)&msg, msg_len);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void aicwf_nl_hook(struct rwnx_vif *rwnx_vif, u8_l band, u8_l ssid)
|
||||||
|
{
|
||||||
|
AICWFDBG(LOGSTEER, MANAGER_STR"%s band:%d, ssid:%d\n", __func__, band, ssid);
|
||||||
|
|
||||||
|
nl_hook[band][ssid] = 1;
|
||||||
|
nl_rwnx_vif[band][ssid] = rwnx_vif;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void aicwf_nl_hook_deinit(u8_l band, u8_l ssid)
|
||||||
|
{
|
||||||
|
|
||||||
|
AICWFDBG(LOGSTEER, MANAGER_STR"%s band:%d, ssid:%d\n", __func__, band, ssid);
|
||||||
|
|
||||||
|
nl_hook[band][ssid] = 0;
|
||||||
|
nl_rwnx_vif[band][ssid] = NULL;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void aicwf_nl_init(void)
|
||||||
|
{
|
||||||
|
if (nl_sock) {
|
||||||
|
AICWFDBG(LOGSTEER, MANAGER_STR"netlink already init.\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
struct netlink_kernel_cfg cfg = {
|
||||||
|
.input = aicwf_nl_recv_msg,
|
||||||
|
};
|
||||||
|
|
||||||
|
nl_sock = netlink_kernel_create(&init_net, NL_AIC_PROTOCOL, &cfg);
|
||||||
|
if (!nl_sock)
|
||||||
|
AICWFDBG(LOGERROR, MANAGER_STR"create netlink falied.\n");
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void aicwf_nl_deinit(void)
|
||||||
|
{
|
||||||
|
if(nl_sock)
|
||||||
|
{
|
||||||
|
netlink_kernel_release(nl_sock);
|
||||||
|
nl_sock = NULL;
|
||||||
|
}
|
||||||
|
AICWFDBG(LOGSTEER, MANAGER_STR"[aicwf_nl_deinit] delete nl_sock netlink succeed.\n");
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
146
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/aicwf_manager.h
Normal file
146
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/aicwf_manager.h
Normal file
|
|
@ -0,0 +1,146 @@
|
||||||
|
#ifndef _AICWF_MANAGER_H_
|
||||||
|
#define _AICWF_MANAGER_H_
|
||||||
|
|
||||||
|
#include "lmac_types.h"
|
||||||
|
#include "rwnx_defs.h"
|
||||||
|
|
||||||
|
#define DRV_WLAN_MANAGER_VER "v1.0"
|
||||||
|
|
||||||
|
|
||||||
|
/* TBD */
|
||||||
|
#define CONFIG_IFACE_NUMBER 1
|
||||||
|
|
||||||
|
#define NL_AIC_PROTOCOL_FRT_DRV 28
|
||||||
|
#define NL_AIC_PROTOCOL_SEC_DRV 29
|
||||||
|
#define NL_AIC_PROTOCOL NL_AIC_PROTOCOL_SEC_DRV
|
||||||
|
|
||||||
|
#define NL_AIC_MANAGER_PID 5185
|
||||||
|
|
||||||
|
#define NL_MAX_MSG_SIZE 768
|
||||||
|
|
||||||
|
/* Netlink Message Type List */
|
||||||
|
#define AIC_NL_DAEMON_ON_TYPE 1
|
||||||
|
#define AIC_NL_DAEMON_OFF_TYPE 2
|
||||||
|
#define AIC_NL_DAEMON_ALIVE_TYPE 3
|
||||||
|
#define AIC_NL_DEL_STA_TYPE 4
|
||||||
|
#define AIC_NL_NEW_STA_TYPE 5
|
||||||
|
#define AIC_NL_INTF_RPT_TYPE 6
|
||||||
|
#define AIC_NL_STA_RPT_TYPE 7
|
||||||
|
#define AIC_NL_FRAME_RPT_TYPE 8
|
||||||
|
#define AIC_NL_TIME_TICK_TYPE 9
|
||||||
|
#define AIC_NL_PRIV_INFO_CMD_TYPE 10
|
||||||
|
#ifdef CONFIG_BAND_STEERING
|
||||||
|
#define AIC_NL_B_STEER_CMD_TYPE 11
|
||||||
|
#define AIC_NL_B_STEER_BLOCK_ADD_TYPE 12
|
||||||
|
#define AIC_NL_B_STEER_BLOCK_DEL_TYPE 13
|
||||||
|
#define AIC_NL_B_STEER_ROAM_TYPE 14
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define AIC_NL_GENERAL_CMD_TYPE 100
|
||||||
|
#define AIC_NL_CUSTOMER_TYPE 101
|
||||||
|
#define AIC_NL_CONFIG_UPDATE_TYPE 102
|
||||||
|
|
||||||
|
/* Element ID */
|
||||||
|
#define AIC_ELM_INTF_ID 1
|
||||||
|
#define AIC_ELM_INTF_INFO_ID 2
|
||||||
|
#define AIC_ELM_FRAME_INFO_ID 3
|
||||||
|
#define AIC_ELM_STA_INFO_ID 4
|
||||||
|
#define AIC_ELM_ROAM_INFO_ID 5
|
||||||
|
#define AIC_ELM_BUFFER_ID 6
|
||||||
|
#define AIC_ELM_STA_INFO_EXT_ID 7
|
||||||
|
|
||||||
|
#define LOW_RSSI_IGNORE (-85)
|
||||||
|
|
||||||
|
struct b_nl_message {
|
||||||
|
u32_l type;
|
||||||
|
u32_l len;
|
||||||
|
u8_l content[NL_MAX_MSG_SIZE];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct b_elm_header {
|
||||||
|
u8_l id;
|
||||||
|
u8_l len;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct b_elm_intf {
|
||||||
|
u8_l mac[6];
|
||||||
|
u8_l root;
|
||||||
|
u8_l band;
|
||||||
|
u8_l ssid;
|
||||||
|
s8_l name[16];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct b_elm_intf_info {
|
||||||
|
u16_l ch;
|
||||||
|
u8_l ch_clm;
|
||||||
|
u8_l ch_noise;
|
||||||
|
u32_l tx_tp;
|
||||||
|
u32_l rx_tp;
|
||||||
|
u32_l assoc_sta_num;
|
||||||
|
/* self neighbor report info */
|
||||||
|
u32_l bss_info;
|
||||||
|
u8_l reg_class;
|
||||||
|
u8_l phy_type;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct b_elm_frame_info {
|
||||||
|
u16_l frame_type;
|
||||||
|
u8_l sa[6];
|
||||||
|
s8_l rssi;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct b_elm_sta_info {
|
||||||
|
u8_l mac[6];
|
||||||
|
s8_l rssi;
|
||||||
|
u32_l link_time;
|
||||||
|
u32_l tx_tp; /* kbits */
|
||||||
|
u32_l rx_tp; /* kbits */
|
||||||
|
};
|
||||||
|
|
||||||
|
struct b_elm_roam_info {
|
||||||
|
u8_l sta_mac[6]; /* station mac */
|
||||||
|
u8_l bss_mac[6]; /* target bss mac */
|
||||||
|
u16_l bss_ch; /* target bss channel */
|
||||||
|
u8_l method; /* 0: 11V, 1: Deauth */
|
||||||
|
};
|
||||||
|
|
||||||
|
struct b_elm_buffer {
|
||||||
|
u8_l buf[255];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct b_elm_sta_info_ext {
|
||||||
|
u8_l mac[6];
|
||||||
|
u8_l supported_band; /* bit0:2g bit1:5g */
|
||||||
|
u8_l empty[119]; /* for future use */
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/* Element Size List */
|
||||||
|
#define ELM_HEADER_LEN (sizeof(struct b_elm_header))
|
||||||
|
#define ELM_INTF_LEN (sizeof(struct b_elm_intf))
|
||||||
|
#define ELM_INTF_INFO_LEN (sizeof(struct b_elm_intf_info))
|
||||||
|
#define ELM_FRAME_INFO_LEN (sizeof(struct b_elm_frame_info))
|
||||||
|
#define ELM_STA_INFO_LEN (sizeof(struct b_elm_sta_info))
|
||||||
|
#define ELM_ROAM_INFO_LEN (sizeof(struct b_elm_roam_info))
|
||||||
|
#define ELM_BUFFER_LEN (sizeof(struct b_elm_buffer))
|
||||||
|
#define ELM_STA_INFO_EXT_LEN (sizeof(struct b_elm_sta_info_ext))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void aicwf_nl_send_del_sta_msg(struct rwnx_vif *rwnx_vif, u8_l *mac);
|
||||||
|
void aicwf_nl_send_new_sta_msg(struct rwnx_vif *rwnx_vif, u8_l *mac);
|
||||||
|
void aicwf_nl_send_intf_rpt_msg(struct rwnx_vif *rwnx_vif);
|
||||||
|
void aicwf_nl_send_sta_rpt_msg(struct rwnx_vif *rwnx_vif, struct rwnx_sta *sta);
|
||||||
|
void aicwf_nl_send_frame_rpt_msg(struct rwnx_vif *rwnx_vif, u16_l frame_type, u8_l *sa, s8_l rssi);
|
||||||
|
void aicwf_nl_send_time_tick_msg(struct rwnx_vif *rwnx_vif);
|
||||||
|
void aicwf_nl_hook(struct rwnx_vif *rwnx_vif, u8_l band, u8_l iface_id);
|
||||||
|
void aicwf_nl_hook_deinit(u8_l band, u8_l ssid);
|
||||||
|
void aicwf_nl_init(void);
|
||||||
|
void aicwf_nl_deinit(void);
|
||||||
|
void aicwf_wlan_manager_recv_msg(struct b_nl_message *msg);
|
||||||
|
void aicwf_nl_recv_msg(struct sk_buff *skb);
|
||||||
|
void aicwf_nl_send_msg(void *msg, u32_l msg_len);
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
27
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/aicwf_rx_prealloc.h
Executable file
27
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/aicwf_rx_prealloc.h
Executable file
|
|
@ -0,0 +1,27 @@
|
||||||
|
|
||||||
|
#ifndef _AICWF_RX_PREALLOC_H_
|
||||||
|
#define _AICWF_RX_PREALLOC_H_
|
||||||
|
|
||||||
|
#ifdef CONFIG_PREALLOC_RX_SKB
|
||||||
|
|
||||||
|
struct rx_buff {
|
||||||
|
struct list_head queue;
|
||||||
|
unsigned char *data;
|
||||||
|
u32 len;
|
||||||
|
uint8_t *start;
|
||||||
|
uint8_t *end;
|
||||||
|
uint8_t *read;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct aicwf_rx_buff_list {
|
||||||
|
struct list_head rxbuff_list;
|
||||||
|
atomic_t rxbuff_list_len;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern struct rx_buff *aicwf_prealloc_rxbuff_alloc(spinlock_t *lock);
|
||||||
|
extern void aicwf_prealloc_rxbuff_free(struct rx_buff *rxbuff, spinlock_t *lock);
|
||||||
|
extern int aicwf_prealloc_init(void);
|
||||||
|
extern void aicwf_prealloc_exit(void);
|
||||||
|
extern int aicwf_rxbuff_size_get(void);
|
||||||
|
#endif
|
||||||
|
#endif /* _AICWF_RX_PREALLOC_H_ */
|
||||||
1250
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/aicwf_sdio.c
Normal file
1250
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/aicwf_sdio.c
Normal file
File diff suppressed because it is too large
Load diff
99
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/aicwf_sdio.h
Normal file
99
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/aicwf_sdio.h
Normal file
|
|
@ -0,0 +1,99 @@
|
||||||
|
/**
|
||||||
|
* aicwf_sdio.h
|
||||||
|
*
|
||||||
|
* SDIO function declarations
|
||||||
|
*
|
||||||
|
* Copyright (C) AICSemi 2018-2020
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _AICWF_SDMMC_H_
|
||||||
|
#define _AICWF_SDMMC_H_
|
||||||
|
|
||||||
|
#ifdef AICWF_SDIO_SUPPORT
|
||||||
|
#include <linux/skbuff.h>
|
||||||
|
#include <linux/if_ether.h>
|
||||||
|
#include <linux/ieee80211.h>
|
||||||
|
#include <linux/semaphore.h>
|
||||||
|
#include "rwnx_cmds.h"
|
||||||
|
#define AICWF_SDIO_NAME "aicwf_sdio"
|
||||||
|
#define SDIOWIFI_FUNC_BLOCKSIZE 512
|
||||||
|
|
||||||
|
#define SDIO_VENDOR_ID_AIC 0x8800
|
||||||
|
#define SDIO_DEVICE_ID_AIC 0x0001
|
||||||
|
#define SDIOWIFI_BYTEMODE_LEN_REG 0x02
|
||||||
|
#define SDIOWIFI_INTR_CONFIG_REG 0x04
|
||||||
|
#define SDIOWIFI_SLEEP_REG 0x05
|
||||||
|
#define SDIOWIFI_WAKEUP_REG 0x09
|
||||||
|
#define SDIOWIFI_FLOW_CTRL_REG 0x0A
|
||||||
|
#define SDIOWIFI_REGISTER_BLOCK 0x0B
|
||||||
|
#define SDIOWIFI_BYTEMODE_ENABLE_REG 0x11
|
||||||
|
#define SDIOWIFI_BLOCK_CNT_REG 0x12
|
||||||
|
#define SDIOWIFI_FLOWCTRL_MASK_REG 0x7F
|
||||||
|
|
||||||
|
#define SDIOWIFI_PWR_CTRL_INTERVAL 30
|
||||||
|
#define FLOW_CTRL_RETRY_COUNT 50
|
||||||
|
#define BUFFER_SIZE 1536
|
||||||
|
#define TAIL_LEN 4
|
||||||
|
#define TXQLEN (2048*4)
|
||||||
|
|
||||||
|
#define SDIO_SLEEP_ST 0
|
||||||
|
#define SDIO_ACTIVE_ST 1
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
SDIO_TYPE_DATA = 0X00,
|
||||||
|
SDIO_TYPE_CFG = 0X10,
|
||||||
|
SDIO_TYPE_CFG_CMD_RSP = 0X11,
|
||||||
|
SDIO_TYPE_CFG_DATA_CFM = 0X12
|
||||||
|
} sdio_type;
|
||||||
|
|
||||||
|
struct rwnx_hw;
|
||||||
|
|
||||||
|
|
||||||
|
struct aic_sdio_dev {
|
||||||
|
struct rwnx_hw *rwnx_hw;
|
||||||
|
struct sdio_func *func;
|
||||||
|
struct device *dev;
|
||||||
|
struct aicwf_bus *bus_if;
|
||||||
|
struct rwnx_cmd_mgr cmd_mgr;
|
||||||
|
|
||||||
|
struct aicwf_rx_priv *rx_priv;
|
||||||
|
struct aicwf_tx_priv *tx_priv;
|
||||||
|
u32 state;
|
||||||
|
|
||||||
|
//for sdio pwr ctrl
|
||||||
|
struct timer_list timer;
|
||||||
|
uint active_duration;
|
||||||
|
struct completion pwrctrl_trgg;
|
||||||
|
struct task_struct *pwrctl_tsk;
|
||||||
|
spinlock_t pwrctl_lock;
|
||||||
|
struct semaphore pwrctl_wakeup_sema;
|
||||||
|
};
|
||||||
|
int aicwf_sdio_writeb(struct aic_sdio_dev *sdiodev, uint regaddr, u8 val);
|
||||||
|
void aicwf_sdio_hal_irqhandler(struct sdio_func *func);
|
||||||
|
void aicwf_sdio_pwrctl_timer(struct aic_sdio_dev *sdiodev, uint duration);
|
||||||
|
int aicwf_sdio_pwr_stctl(struct aic_sdio_dev *sdiodev, uint target);
|
||||||
|
int aicwf_sdio_func_init(struct aic_sdio_dev *sdiodev);
|
||||||
|
void aicwf_sdio_func_deinit(struct aic_sdio_dev *sdiodev);
|
||||||
|
int aicwf_sdio_flow_ctrl(struct aic_sdio_dev *sdiodev);
|
||||||
|
int aicwf_sdio_recv_pkt(struct aic_sdio_dev *sdiodev, struct sk_buff *skbbuf, u32 size);
|
||||||
|
int aicwf_sdio_send_pkt(struct aic_sdio_dev *sdiodev, u8 *buf, uint count);
|
||||||
|
void *aicwf_sdio_bus_init(struct aic_sdio_dev *sdiodev);
|
||||||
|
void aicwf_sdio_release(struct aic_sdio_dev *sdiodev);
|
||||||
|
void aicwf_sdio_exit(void);
|
||||||
|
void aicwf_sdio_register(void);
|
||||||
|
int aicwf_sdio_txpkt(struct aic_sdio_dev *sdiodev, struct sk_buff *pkt);
|
||||||
|
int sdio_bustx_thread(void *data);
|
||||||
|
int sdio_busrx_thread(void *data);
|
||||||
|
int aicwf_sdio_aggr(struct aicwf_tx_priv *tx_priv, struct sk_buff *pkt);
|
||||||
|
int aicwf_sdio_send(struct aicwf_tx_priv *tx_priv);
|
||||||
|
void aicwf_sdio_aggr_send(struct aicwf_tx_priv *tx_priv);
|
||||||
|
void aicwf_sdio_aggrbuf_reset(struct aicwf_tx_priv* tx_priv);
|
||||||
|
extern void aicwf_hostif_ready(void);
|
||||||
|
#ifdef CONFIG_PLATFORM_NANOPI
|
||||||
|
extern void extern_wifi_set_enable(int is_on);
|
||||||
|
extern void sdio_reinit(void);
|
||||||
|
#endif /*CONFIG_PLATFORM_NANOPI*/
|
||||||
|
|
||||||
|
#endif /* AICWF_SDIO_SUPPORT */
|
||||||
|
|
||||||
|
#endif /*_AICWF_SDMMC_H_*/
|
||||||
217
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/aicwf_steering.c
Normal file
217
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/aicwf_steering.c
Normal file
|
|
@ -0,0 +1,217 @@
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
*
|
||||||
|
* Copyright (C) 2020 AIC semiconductor.
|
||||||
|
*
|
||||||
|
* @file aicwf_steering.c
|
||||||
|
*
|
||||||
|
* @brief band steering definitions
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "aicwf_steering.h"
|
||||||
|
#include "rwnx_defs.h"
|
||||||
|
|
||||||
|
#define MAC_FMT_B "%02x:%02x:%02x:%02x:%02x:%02x"
|
||||||
|
#define MAC_ARG_B(x) ((u8_l *)(x))[0], ((u8_l *)(x))[1], ((u8_l *)(x))[2], ((u8_l *)(x))[3], ((u8_l *)(x))[4], ((u8_l *)(x))[5]
|
||||||
|
#define STEEER_STR "[STEERING] USB "
|
||||||
|
|
||||||
|
#ifdef CONFIG_BAND_STEERING
|
||||||
|
|
||||||
|
static struct b_steer_block_entry *block_entry_lookup(struct rwnx_vif *rwnx_vif, u8_l *mac)
|
||||||
|
{
|
||||||
|
u8_l i;
|
||||||
|
struct b_steer_block_entry *ent = NULL;
|
||||||
|
|
||||||
|
for (i = 0; i < B_STEER_ENTRY_NUM; i++) {
|
||||||
|
ent = &(rwnx_vif->bsteerpriv.block_list[i]);
|
||||||
|
if (ent->used && (memcmp(ent->mac, mac, 6) == 0)) {
|
||||||
|
AICWFDBG(LOGSTEER, STEEER_STR"%s "MAC_FMT_B"\n", __func__, MAC_ARG_B(mac));
|
||||||
|
return ent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void aicwf_band_steering_expire(struct rwnx_vif *rwnx_vif)
|
||||||
|
{
|
||||||
|
u8_l i;
|
||||||
|
struct b_steer_block_entry *ent = NULL;
|
||||||
|
|
||||||
|
if (rwnx_vif->bsteerpriv.inited == false) {
|
||||||
|
AICWFDBG(LOGSTEER, STEEER_STR"%s bsteerpriv not inited\n", __func__);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
spin_lock_bh(&(rwnx_vif->bsteerpriv.lock));
|
||||||
|
|
||||||
|
/* block entry */
|
||||||
|
for (i = 0; i < B_STEER_ENTRY_NUM; i++) {
|
||||||
|
ent = &(rwnx_vif->bsteerpriv.block_list[i]);
|
||||||
|
if (!ent->used)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (ent->entry_expire) {
|
||||||
|
ent->entry_expire--;
|
||||||
|
if (ent->entry_expire == 0)
|
||||||
|
ent->used = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
spin_unlock_bh(&(rwnx_vif->bsteerpriv.lock));
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
s32_l aicwf_band_steering_block_chk(struct rwnx_vif *rwnx_vif, u8_l *mac)
|
||||||
|
{
|
||||||
|
s32 ret = 0;
|
||||||
|
struct b_steer_block_entry *ent = NULL;
|
||||||
|
|
||||||
|
if (rwnx_vif->bsteerpriv.inited == false) {
|
||||||
|
AICWFDBG(LOGSTEER, STEEER_STR"%s bsteerpriv not inited\n", __func__);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
spin_lock_bh(&(rwnx_vif->bsteerpriv.lock));
|
||||||
|
|
||||||
|
ent = block_entry_lookup(rwnx_vif, mac);
|
||||||
|
if (ent)
|
||||||
|
ret = 1;
|
||||||
|
|
||||||
|
spin_unlock_bh(&(rwnx_vif->bsteerpriv.lock));
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void aicwf_band_steering_block_entry_add(struct rwnx_vif *rwnx_vif, u8_l *mac)
|
||||||
|
{
|
||||||
|
u8_l i;
|
||||||
|
struct b_steer_block_entry *ent = NULL;
|
||||||
|
|
||||||
|
if (rwnx_vif->bsteerpriv.inited == false) {
|
||||||
|
AICWFDBG(LOGSTEER, STEEER_STR"%s bsteerpriv not inited\n", __func__);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
AICWFDBG(LOGSTEER, STEEER_STR"%s "MAC_FMT_B"\n", __func__, MAC_ARG_B(mac));
|
||||||
|
|
||||||
|
spin_lock_bh(&(rwnx_vif->bsteerpriv.lock));
|
||||||
|
|
||||||
|
ent = block_entry_lookup(rwnx_vif, mac);
|
||||||
|
|
||||||
|
/* already exist */
|
||||||
|
if (ent) {
|
||||||
|
AICWFDBG(LOGSTEER, STEEER_STR"%s already exist\n", __func__);
|
||||||
|
ent->entry_expire = B_STEER_BLOCK_ENTRY_EXPIRE;
|
||||||
|
goto func_return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* find an empty entry */
|
||||||
|
for (i = 0; i < B_STEER_ENTRY_NUM; i++) {
|
||||||
|
if (!rwnx_vif->bsteerpriv.block_list[i].used) {
|
||||||
|
ent = &(rwnx_vif->bsteerpriv.block_list[i]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* add the entry */
|
||||||
|
if (ent) {
|
||||||
|
AICWFDBG(LOGSTEER, STEEER_STR"%s "MAC_FMT_B"\n", __func__, MAC_ARG_B(mac));
|
||||||
|
ent->used = 1;
|
||||||
|
memcpy(ent->mac, mac, 6);
|
||||||
|
ent->entry_expire = B_STEER_BLOCK_ENTRY_EXPIRE;
|
||||||
|
}
|
||||||
|
|
||||||
|
func_return:
|
||||||
|
spin_unlock_bh(&(rwnx_vif->bsteerpriv.lock));
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void aicwf_band_steering_block_entry_del(struct rwnx_vif *rwnx_vif, u8_l *mac)
|
||||||
|
{
|
||||||
|
struct b_steer_block_entry *ent = NULL;
|
||||||
|
|
||||||
|
if (rwnx_vif->bsteerpriv.inited == false) {
|
||||||
|
AICWFDBG(LOGSTEER, STEEER_STR"%s bsteerpriv not inited\n", __func__);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
AICWFDBG(LOGSTEER, STEEER_STR"%s "MAC_FMT_B"\n", __func__, MAC_ARG_B(mac));
|
||||||
|
|
||||||
|
spin_lock_bh(&(rwnx_vif->bsteerpriv.lock));
|
||||||
|
|
||||||
|
ent = block_entry_lookup(rwnx_vif, mac);
|
||||||
|
if (ent)
|
||||||
|
ent->used = 0;
|
||||||
|
|
||||||
|
spin_unlock_bh(&(rwnx_vif->bsteerpriv.lock));
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void aicwf_band_steering_roam_block_entry_add(struct rwnx_vif *rwnx_vif, u8_l *mac)
|
||||||
|
{
|
||||||
|
u8_l i;
|
||||||
|
struct b_steer_block_entry *ent = NULL;
|
||||||
|
|
||||||
|
if (rwnx_vif->bsteerpriv.inited == false) {
|
||||||
|
AICWFDBG(LOGSTEER, STEEER_STR"%s bsteerpriv not inited\n", __func__);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
AICWFDBG(LOGSTEER, STEEER_STR"%s "MAC_FMT_B"\n", __func__, MAC_ARG_B(mac));
|
||||||
|
|
||||||
|
spin_lock_bh(&rwnx_vif->bsteerpriv.lock);
|
||||||
|
|
||||||
|
ent = block_entry_lookup(rwnx_vif, mac);
|
||||||
|
|
||||||
|
/* already exist */
|
||||||
|
if (ent)
|
||||||
|
goto func_return;
|
||||||
|
|
||||||
|
/* find an empty entry */
|
||||||
|
for (i = 0; i < B_STEER_ENTRY_NUM; i++) {
|
||||||
|
if (!rwnx_vif->bsteerpriv.block_list[i].used) {
|
||||||
|
ent = &(rwnx_vif->bsteerpriv.block_list[i]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* add the entry */
|
||||||
|
if (ent) {
|
||||||
|
ent->used = 1;
|
||||||
|
memcpy(ent->mac, mac, 6);
|
||||||
|
ent->entry_expire = B_STEER_ROAM_BLOCK_ENTRY_EXPIRE;
|
||||||
|
}
|
||||||
|
|
||||||
|
func_return:
|
||||||
|
spin_unlock_bh(&rwnx_vif->bsteerpriv.lock);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void aicwf_band_steering_init(struct rwnx_vif *rwnx_vif)
|
||||||
|
{
|
||||||
|
u8_l i;
|
||||||
|
|
||||||
|
AICWFDBG(LOGSTEER, STEEER_STR"%s\n", __func__);
|
||||||
|
spin_lock_init(&rwnx_vif->bsteerpriv.lock);
|
||||||
|
rwnx_vif->bsteerpriv.inited = true;
|
||||||
|
|
||||||
|
spin_lock_bh(&rwnx_vif->bsteerpriv.lock);
|
||||||
|
|
||||||
|
/* block entry */
|
||||||
|
for (i = 0; i < B_STEER_ENTRY_NUM; i++)
|
||||||
|
memset(&(rwnx_vif->bsteerpriv.block_list[i]), 0, sizeof(struct b_steer_block_entry));
|
||||||
|
|
||||||
|
spin_unlock_bh(&rwnx_vif->bsteerpriv.lock);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
@ -0,0 +1,40 @@
|
||||||
|
#ifndef _AICWF_STEERING_H_
|
||||||
|
#define _AICWF_STEERING_H_
|
||||||
|
|
||||||
|
#include <linux/spinlock.h>
|
||||||
|
#include "lmac_types.h"
|
||||||
|
|
||||||
|
#ifdef CONFIG_BAND_STEERING
|
||||||
|
|
||||||
|
#define B_STEER_ENTRY_NUM 64//32
|
||||||
|
|
||||||
|
#define B_STEER_BLOCK_ENTRY_EXPIRE 60
|
||||||
|
#define B_STEER_ROAM_BLOCK_ENTRY_EXPIRE 5
|
||||||
|
#define STEER_UPFATE_TIME 2000
|
||||||
|
|
||||||
|
struct rwnx_vif;
|
||||||
|
|
||||||
|
struct b_steer_block_entry {
|
||||||
|
u8_l used;
|
||||||
|
u8_l mac[6];
|
||||||
|
u32_l entry_expire;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct b_steer_priv {
|
||||||
|
struct b_steer_block_entry block_list[B_STEER_ENTRY_NUM];
|
||||||
|
spinlock_t lock;
|
||||||
|
bool inited;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
void aicwf_band_steering_expire(struct rwnx_vif *rwnx_vif);
|
||||||
|
s32_l aicwf_band_steering_block_chk(struct rwnx_vif *rwnx_vif, u8_l *mac);
|
||||||
|
void aicwf_band_steering_block_entry_add(struct rwnx_vif *rwnx_vif, u8_l *mac);
|
||||||
|
void aicwf_band_steering_block_entry_del(struct rwnx_vif *rwnx_vif, u8_l *mac);
|
||||||
|
void aicwf_band_steering_roam_block_entry_add(struct rwnx_vif *rwnx_vif, u8_l *mac);
|
||||||
|
void aicwf_band_steering_init(struct rwnx_vif *rwnx_vif);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
630
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/aicwf_tcp_ack.c
Normal file
630
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/aicwf_tcp_ack.c
Normal file
|
|
@ -0,0 +1,630 @@
|
||||||
|
#include"aicwf_tcp_ack.h"
|
||||||
|
//#include"rwnx_tx.h"
|
||||||
|
//#include "aicwf_tcp_ack.h"
|
||||||
|
#include"rwnx_defs.h"
|
||||||
|
extern int intf_tx(struct rwnx_hw *priv,struct msg_buf *msg);
|
||||||
|
struct msg_buf *intf_tcp_alloc_msg(struct msg_buf *msg)
|
||||||
|
{
|
||||||
|
//printk("%s \n",__func__);
|
||||||
|
int len=sizeof(struct msg_buf) ;
|
||||||
|
msg = kzalloc(len , GFP_ATOMIC);
|
||||||
|
if(!msg)
|
||||||
|
printk("%s: alloc failed \n", __func__);
|
||||||
|
memset(msg,0,len);
|
||||||
|
return msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
void intf_tcp_drop_msg(struct rwnx_hw *priv,
|
||||||
|
struct msg_buf *msg)
|
||||||
|
{
|
||||||
|
//printk("%s \n",__func__);
|
||||||
|
if (msg->skb)
|
||||||
|
dev_kfree_skb_any(msg->skb);
|
||||||
|
|
||||||
|
kfree(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 14, 0)
|
||||||
|
void tcp_ack_timeout(unsigned long data)
|
||||||
|
#else
|
||||||
|
void tcp_ack_timeout(struct timer_list *t)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
//printk("%s \n",__func__);
|
||||||
|
struct tcp_ack_info *ack_info;
|
||||||
|
struct msg_buf *msg;
|
||||||
|
struct tcp_ack_manage *ack_m = NULL;
|
||||||
|
|
||||||
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 14, 0)
|
||||||
|
ack_info = (struct tcp_ack_info *)data;
|
||||||
|
#else
|
||||||
|
ack_info = container_of(t,struct tcp_ack_info,timer);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
ack_m = container_of(ack_info, struct tcp_ack_manage,
|
||||||
|
ack_info[ack_info->ack_info_num]);
|
||||||
|
|
||||||
|
write_seqlock_bh(&ack_info->seqlock);
|
||||||
|
msg = ack_info->msgbuf;
|
||||||
|
if (ack_info->busy && msg && !ack_info->in_send_msg) {
|
||||||
|
ack_info->msgbuf = NULL;
|
||||||
|
ack_info->drop_cnt = 0;
|
||||||
|
ack_info->in_send_msg = msg;
|
||||||
|
write_sequnlock_bh(&ack_info->seqlock);
|
||||||
|
intf_tx(ack_m->priv, msg);//send skb
|
||||||
|
//ack_info->in_send_msg = NULL;//add by dwx
|
||||||
|
//write_sequnlock_bh(&ack_info->seqlock);
|
||||||
|
//intf_tx(ack_m->priv, msg);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
write_sequnlock_bh(&ack_info->seqlock);
|
||||||
|
}
|
||||||
|
|
||||||
|
void tcp_ack_init(struct rwnx_hw *priv)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
struct tcp_ack_info *ack_info;
|
||||||
|
struct tcp_ack_manage *ack_m = &priv->ack_m;
|
||||||
|
|
||||||
|
printk("========== tcp ack debug %s \n",__func__);
|
||||||
|
memset(ack_m, 0, sizeof(struct tcp_ack_manage));
|
||||||
|
ack_m->priv = priv;
|
||||||
|
spin_lock_init(&ack_m->lock);
|
||||||
|
atomic_set(&ack_m->max_drop_cnt, TCP_ACK_DROP_CNT);
|
||||||
|
ack_m->last_time = jiffies;
|
||||||
|
ack_m->timeout = msecs_to_jiffies(ACK_OLD_TIME);
|
||||||
|
|
||||||
|
for (i = 0; i < TCP_ACK_NUM; i++) {
|
||||||
|
ack_info = &ack_m->ack_info[i];
|
||||||
|
ack_info->ack_info_num = i;
|
||||||
|
seqlock_init(&ack_info->seqlock);
|
||||||
|
ack_info->last_time = jiffies;
|
||||||
|
ack_info->timeout = msecs_to_jiffies(ACK_OLD_TIME);
|
||||||
|
|
||||||
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 14, 0)
|
||||||
|
setup_timer(&ack_info->timer, tcp_ack_timeout,
|
||||||
|
(unsigned long)ack_info);
|
||||||
|
#else
|
||||||
|
timer_setup(&ack_info->timer,tcp_ack_timeout,0);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
atomic_set(&ack_m->enable, 1);
|
||||||
|
ack_m->ack_winsize = MIN_WIN;
|
||||||
|
}
|
||||||
|
|
||||||
|
void tcp_ack_deinit(struct rwnx_hw *priv)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
struct tcp_ack_manage *ack_m = &priv->ack_m;
|
||||||
|
struct msg_buf *drop_msg = NULL;
|
||||||
|
|
||||||
|
printk("%s \n",__func__);
|
||||||
|
atomic_set(&ack_m->enable, 0);
|
||||||
|
|
||||||
|
for (i = 0; i < TCP_ACK_NUM; i++) {
|
||||||
|
drop_msg = NULL;
|
||||||
|
|
||||||
|
write_seqlock_bh(&ack_m->ack_info[i].seqlock);
|
||||||
|
del_timer(&ack_m->ack_info[i].timer);
|
||||||
|
drop_msg = ack_m->ack_info[i].msgbuf;
|
||||||
|
ack_m->ack_info[i].msgbuf = NULL;
|
||||||
|
write_sequnlock_bh(&ack_m->ack_info[i].seqlock);
|
||||||
|
|
||||||
|
if (drop_msg)
|
||||||
|
intf_tcp_drop_msg(priv, drop_msg);//drop skb
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int tcp_check_quick_ack(unsigned char *buf,
|
||||||
|
struct tcp_ack_msg *msg)
|
||||||
|
{
|
||||||
|
int ip_hdr_len;
|
||||||
|
unsigned char *temp;
|
||||||
|
struct ethhdr *ethhdr;
|
||||||
|
struct iphdr *iphdr;
|
||||||
|
struct tcphdr *tcphdr;
|
||||||
|
|
||||||
|
ethhdr = (struct ethhdr *)buf;
|
||||||
|
if (ethhdr->h_proto != htons(ETH_P_IP))
|
||||||
|
return 0;
|
||||||
|
iphdr = (struct iphdr *)(ethhdr + 1);
|
||||||
|
if (iphdr->version != 4 || iphdr->protocol != IPPROTO_TCP)
|
||||||
|
return 0;
|
||||||
|
ip_hdr_len = iphdr->ihl * 4;
|
||||||
|
temp = (unsigned char *)(iphdr) + ip_hdr_len;
|
||||||
|
tcphdr = (struct tcphdr *)temp;
|
||||||
|
/* TCP_FLAG_ACK */
|
||||||
|
if (!(temp[13] & 0x10))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (temp[13] & 0x8) {
|
||||||
|
msg->saddr = iphdr->daddr;
|
||||||
|
msg->daddr = iphdr->saddr;
|
||||||
|
msg->source = tcphdr->dest;
|
||||||
|
msg->dest = tcphdr->source;
|
||||||
|
msg->seq = ntohl(tcphdr->seq);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int is_drop_tcp_ack(struct tcphdr *tcphdr, int tcp_tot_len,
|
||||||
|
unsigned short *win_scale)
|
||||||
|
{
|
||||||
|
//printk("%s \n",__func__);
|
||||||
|
int drop = 1;
|
||||||
|
int len = tcphdr->doff * 4;
|
||||||
|
unsigned char *ptr;
|
||||||
|
|
||||||
|
if(tcp_tot_len > len) {
|
||||||
|
drop = 0;
|
||||||
|
} else {
|
||||||
|
len -= sizeof(struct tcphdr);
|
||||||
|
ptr = (unsigned char *)(tcphdr + 1);
|
||||||
|
|
||||||
|
while ((len > 0) && drop) {
|
||||||
|
int opcode = *ptr++;
|
||||||
|
int opsize;
|
||||||
|
|
||||||
|
switch (opcode) {
|
||||||
|
case TCPOPT_EOL:
|
||||||
|
break;
|
||||||
|
case TCPOPT_NOP:
|
||||||
|
len--;
|
||||||
|
continue;
|
||||||
|
default:
|
||||||
|
opsize = *ptr++;
|
||||||
|
if (opsize < 2)
|
||||||
|
break;
|
||||||
|
if (opsize > len)
|
||||||
|
break;
|
||||||
|
|
||||||
|
switch (opcode) {
|
||||||
|
/* TODO: Add other ignore opt */
|
||||||
|
case TCPOPT_TIMESTAMP:
|
||||||
|
break;
|
||||||
|
case TCPOPT_WINDOW:
|
||||||
|
if (*ptr < 15)
|
||||||
|
*win_scale = (1 << (*ptr));
|
||||||
|
//printk("%d\n",*win_scale);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
drop = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
ptr += opsize - 2;
|
||||||
|
len -= opsize;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return drop;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* flag:0 for not tcp ack
|
||||||
|
* 1 for ack which can be drop
|
||||||
|
* 2 for other ack whith more info
|
||||||
|
*/
|
||||||
|
|
||||||
|
int tcp_check_ack(unsigned char *buf,
|
||||||
|
struct tcp_ack_msg *msg,
|
||||||
|
unsigned short *win_scale)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
int ip_hdr_len;
|
||||||
|
int tcp_tot_len;
|
||||||
|
unsigned char *temp;
|
||||||
|
struct ethhdr *ethhdr;
|
||||||
|
struct iphdr *iphdr;
|
||||||
|
struct tcphdr *tcphdr;
|
||||||
|
|
||||||
|
ethhdr =(struct ethhdr *)buf;
|
||||||
|
if (ethhdr->h_proto != htons(ETH_P_IP))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
iphdr = (struct iphdr *)(ethhdr + 1);
|
||||||
|
if (iphdr->version != 4 || iphdr->protocol != IPPROTO_TCP)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
ip_hdr_len = iphdr->ihl * 4;
|
||||||
|
temp = (unsigned char *)(iphdr) + ip_hdr_len;
|
||||||
|
tcphdr = (struct tcphdr *)temp;
|
||||||
|
/* TCP_FLAG_ACK */
|
||||||
|
if (!(temp[13] & 0x10))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
tcp_tot_len = ntohs(iphdr->tot_len) - ip_hdr_len;// tcp total len
|
||||||
|
ret = is_drop_tcp_ack(tcphdr, tcp_tot_len, win_scale);
|
||||||
|
//printk("is drop:%d \n",ret);
|
||||||
|
|
||||||
|
if (ret > 0) {
|
||||||
|
msg->saddr = iphdr->saddr;
|
||||||
|
msg->daddr = iphdr->daddr;
|
||||||
|
msg->source = tcphdr->source;
|
||||||
|
msg->dest = tcphdr->dest;
|
||||||
|
msg->seq = ntohl(tcphdr->ack_seq);
|
||||||
|
msg->win = ntohs(tcphdr->window);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* return val: -1 for not match, others for match */
|
||||||
|
int tcp_ack_match(struct tcp_ack_manage *ack_m,
|
||||||
|
struct tcp_ack_msg *ack_msg)
|
||||||
|
{
|
||||||
|
int i, ret = -1;
|
||||||
|
unsigned start;
|
||||||
|
struct tcp_ack_info *ack_info;
|
||||||
|
struct tcp_ack_msg *ack;
|
||||||
|
|
||||||
|
for (i = 0; ((ret < 0) && (i < TCP_ACK_NUM)); i++) {
|
||||||
|
ack_info = &ack_m->ack_info[i];
|
||||||
|
do {
|
||||||
|
start = read_seqbegin(&ack_info->seqlock);
|
||||||
|
ret = -1;
|
||||||
|
|
||||||
|
ack = &ack_info->ack_msg;
|
||||||
|
if (ack_info->busy &&
|
||||||
|
ack->dest == ack_msg->dest &&
|
||||||
|
ack->source == ack_msg->source &&
|
||||||
|
ack->saddr == ack_msg->saddr &&
|
||||||
|
ack->daddr == ack_msg->daddr)
|
||||||
|
ret = i;
|
||||||
|
} while(read_seqretry(&ack_info->seqlock, start));
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void tcp_ack_update(struct tcp_ack_manage *ack_m)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
struct tcp_ack_info *ack_info;
|
||||||
|
|
||||||
|
if (time_after(jiffies, ack_m->last_time + ack_m->timeout)) {
|
||||||
|
spin_lock_bh(&ack_m->lock);
|
||||||
|
ack_m->last_time = jiffies;
|
||||||
|
for (i = TCP_ACK_NUM - 1; i >= 0; i--) {
|
||||||
|
ack_info = &ack_m->ack_info[i];
|
||||||
|
write_seqlock_bh(&ack_info->seqlock);
|
||||||
|
if (ack_info->busy &&
|
||||||
|
time_after(jiffies, ack_info->last_time +
|
||||||
|
ack_info->timeout)) {
|
||||||
|
ack_m->free_index = i;
|
||||||
|
ack_m->max_num--;
|
||||||
|
ack_info->busy = 0;
|
||||||
|
}
|
||||||
|
write_sequnlock_bh(&ack_info->seqlock);
|
||||||
|
}
|
||||||
|
spin_unlock_bh(&ack_m->lock);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* return val: -1 for no index, others for index */
|
||||||
|
int tcp_ack_alloc_index(struct tcp_ack_manage *ack_m)
|
||||||
|
{
|
||||||
|
int i, ret = -1;
|
||||||
|
struct tcp_ack_info *ack_info;
|
||||||
|
unsigned start;
|
||||||
|
|
||||||
|
spin_lock_bh(&ack_m->lock);
|
||||||
|
if (ack_m->max_num == TCP_ACK_NUM) {
|
||||||
|
spin_unlock_bh(&ack_m->lock);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ack_m->free_index >= 0) {
|
||||||
|
i = ack_m->free_index;
|
||||||
|
ack_m->free_index = -1;
|
||||||
|
ack_m->max_num++;
|
||||||
|
spin_unlock_bh(&ack_m->lock);
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; ((ret < 0) && (i < TCP_ACK_NUM)); i++) {
|
||||||
|
ack_info = &ack_m->ack_info[i];
|
||||||
|
do {
|
||||||
|
start = read_seqbegin(&ack_info->seqlock);
|
||||||
|
ret = -1;
|
||||||
|
if (!ack_info->busy) {
|
||||||
|
ack_m->free_index = -1;
|
||||||
|
ack_m->max_num++;
|
||||||
|
ret = i;
|
||||||
|
}
|
||||||
|
} while(read_seqretry(&ack_info->seqlock, start));
|
||||||
|
}
|
||||||
|
spin_unlock_bh(&ack_m->lock);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* return val: 0 for not handle tx, 1 for handle tx */
|
||||||
|
int tcp_ack_handle(struct msg_buf *new_msgbuf,
|
||||||
|
struct tcp_ack_manage *ack_m,
|
||||||
|
struct tcp_ack_info *ack_info,
|
||||||
|
struct tcp_ack_msg *ack_msg,
|
||||||
|
int type)
|
||||||
|
{
|
||||||
|
int quick_ack = 0;
|
||||||
|
struct tcp_ack_msg *ack;
|
||||||
|
int ret = 0;
|
||||||
|
struct msg_buf *drop_msg = NULL;
|
||||||
|
|
||||||
|
//printk("%s %d",__func__,type);
|
||||||
|
write_seqlock_bh(&ack_info->seqlock);
|
||||||
|
|
||||||
|
ack_info->last_time = jiffies;
|
||||||
|
ack = &ack_info->ack_msg;
|
||||||
|
|
||||||
|
if (type == 2) {
|
||||||
|
if (U32_BEFORE(ack->seq, ack_msg->seq)) {
|
||||||
|
ack->seq = ack_msg->seq;
|
||||||
|
if (ack_info->psh_flag &&
|
||||||
|
!U32_BEFORE(ack_msg->seq,
|
||||||
|
ack_info->psh_seq)) {
|
||||||
|
ack_info->psh_flag = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ack_info->msgbuf) {
|
||||||
|
//printk("%lx \n",ack_info->msgbuf);
|
||||||
|
drop_msg = ack_info->msgbuf;
|
||||||
|
ack_info->msgbuf = NULL;
|
||||||
|
del_timer(&ack_info->timer);
|
||||||
|
}else{
|
||||||
|
//printk("msgbuf is NULL \n");
|
||||||
|
}
|
||||||
|
|
||||||
|
ack_info->in_send_msg = NULL;
|
||||||
|
ack_info->drop_cnt = atomic_read(&ack_m->max_drop_cnt);
|
||||||
|
} else {
|
||||||
|
printk("%s before abnormal ack: %d, %d\n",
|
||||||
|
__func__, ack->seq, ack_msg->seq);
|
||||||
|
drop_msg = new_msgbuf;
|
||||||
|
ret = 1;
|
||||||
|
}
|
||||||
|
} else if (U32_BEFORE(ack->seq, ack_msg->seq)) {
|
||||||
|
if (ack_info->msgbuf) {
|
||||||
|
drop_msg = ack_info->msgbuf;
|
||||||
|
ack_info->msgbuf = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ack_info->psh_flag &&
|
||||||
|
!U32_BEFORE(ack_msg->seq, ack_info->psh_seq)) {
|
||||||
|
ack_info->psh_flag = 0;
|
||||||
|
quick_ack = 1;
|
||||||
|
} else {
|
||||||
|
ack_info->drop_cnt++;
|
||||||
|
}
|
||||||
|
|
||||||
|
ack->seq = ack_msg->seq;
|
||||||
|
|
||||||
|
if (quick_ack || (!ack_info->in_send_msg &&
|
||||||
|
(ack_info->drop_cnt >=
|
||||||
|
atomic_read(&ack_m->max_drop_cnt)))) {
|
||||||
|
ack_info->drop_cnt = 0;
|
||||||
|
ack_info->in_send_msg = new_msgbuf;
|
||||||
|
del_timer(&ack_info->timer);
|
||||||
|
} else {
|
||||||
|
ret = 1;
|
||||||
|
ack_info->msgbuf = new_msgbuf;
|
||||||
|
if (!timer_pending(&ack_info->timer))
|
||||||
|
mod_timer(&ack_info->timer,
|
||||||
|
(jiffies + msecs_to_jiffies(5)));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
printk("%s before ack: %d, %d\n",
|
||||||
|
__func__, ack->seq, ack_msg->seq);
|
||||||
|
drop_msg = new_msgbuf;
|
||||||
|
ret = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
write_sequnlock_bh(&ack_info->seqlock);
|
||||||
|
|
||||||
|
if (drop_msg)
|
||||||
|
intf_tcp_drop_msg(ack_m->priv, drop_msg);// drop skb
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int tcp_ack_handle_new(struct msg_buf *new_msgbuf,
|
||||||
|
struct tcp_ack_manage *ack_m,
|
||||||
|
struct tcp_ack_info *ack_info,
|
||||||
|
struct tcp_ack_msg *ack_msg,
|
||||||
|
int type)
|
||||||
|
{
|
||||||
|
int quick_ack = 0;
|
||||||
|
struct tcp_ack_msg *ack;
|
||||||
|
int ret = 0;
|
||||||
|
struct msg_buf *drop_msg = NULL;
|
||||||
|
//struct msg_buf * send_msg = NULL;
|
||||||
|
//printk("",);
|
||||||
|
write_seqlock_bh(&ack_info->seqlock);
|
||||||
|
|
||||||
|
ack_info->last_time = jiffies;
|
||||||
|
ack = &ack_info->ack_msg;
|
||||||
|
|
||||||
|
if(U32_BEFORE(ack->seq, ack_msg->seq)){
|
||||||
|
if (ack_info->msgbuf) {
|
||||||
|
drop_msg = ack_info->msgbuf;
|
||||||
|
ack_info->msgbuf = NULL;
|
||||||
|
//ack_info->drop_cnt++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ack_info->psh_flag &&
|
||||||
|
!U32_BEFORE(ack_msg->seq, ack_info->psh_seq)) {
|
||||||
|
ack_info->psh_flag = 0;
|
||||||
|
quick_ack = 1;
|
||||||
|
} else {
|
||||||
|
ack_info->drop_cnt++;
|
||||||
|
}
|
||||||
|
|
||||||
|
ack->seq = ack_msg->seq;
|
||||||
|
|
||||||
|
if(quick_ack || (!ack_info->in_send_msg &&
|
||||||
|
(ack_info->drop_cnt >=
|
||||||
|
atomic_read(&ack_m->max_drop_cnt)))){
|
||||||
|
ack_info->drop_cnt = 0;
|
||||||
|
//send_msg = new_msgbuf;
|
||||||
|
ack_info->in_send_msg = new_msgbuf;
|
||||||
|
del_timer(&ack_info->timer);
|
||||||
|
}else{
|
||||||
|
ret = 1;
|
||||||
|
ack_info->msgbuf = new_msgbuf;
|
||||||
|
if (!timer_pending(&ack_info->timer))
|
||||||
|
mod_timer(&ack_info->timer,
|
||||||
|
(jiffies + msecs_to_jiffies(5)));
|
||||||
|
}
|
||||||
|
|
||||||
|
//ret = 1;
|
||||||
|
}else {
|
||||||
|
printk("%s before ack: %d, %d\n",
|
||||||
|
__func__, ack->seq, ack_msg->seq);
|
||||||
|
drop_msg = new_msgbuf;
|
||||||
|
ret = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*if(send_msg){
|
||||||
|
intf_tx(ack_m->priv,send_msg);
|
||||||
|
ack_info->in_send_msg=NULL;
|
||||||
|
}*/
|
||||||
|
|
||||||
|
//ack_info->in_send_msg=NULL;
|
||||||
|
|
||||||
|
write_sequnlock_bh(&ack_info->seqlock);
|
||||||
|
|
||||||
|
/*if(send_msg){
|
||||||
|
intf_tx(ack_m->priv,send_msg);
|
||||||
|
//ack_info->in_send_msg=NULL;
|
||||||
|
}*/
|
||||||
|
|
||||||
|
if (drop_msg)
|
||||||
|
intf_tcp_drop_msg(ack_m->priv, drop_msg);// drop skb
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void filter_rx_tcp_ack(struct rwnx_hw *priv,
|
||||||
|
unsigned char *buf, unsigned plen)
|
||||||
|
{
|
||||||
|
int index;
|
||||||
|
struct tcp_ack_msg ack_msg;
|
||||||
|
struct tcp_ack_info *ack_info;
|
||||||
|
struct tcp_ack_manage *ack_m = &priv->ack_m;
|
||||||
|
|
||||||
|
if (!atomic_read(&ack_m->enable))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if ((plen > MAX_TCP_ACK) ||
|
||||||
|
!tcp_check_quick_ack(buf, &ack_msg))
|
||||||
|
return;
|
||||||
|
|
||||||
|
index = tcp_ack_match(ack_m, &ack_msg);
|
||||||
|
if (index >= 0) {
|
||||||
|
ack_info = ack_m->ack_info + index;
|
||||||
|
write_seqlock_bh(&ack_info->seqlock);
|
||||||
|
ack_info->psh_flag = 1;
|
||||||
|
ack_info->psh_seq = ack_msg.seq;
|
||||||
|
write_sequnlock_bh(&ack_info->seqlock);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* return val: 0 for not filter, 1 for filter */
|
||||||
|
int filter_send_tcp_ack(struct rwnx_hw *priv,
|
||||||
|
struct msg_buf *msgbuf,
|
||||||
|
unsigned char *buf, unsigned int plen)
|
||||||
|
{
|
||||||
|
// printk("%s \n",__func__);
|
||||||
|
int ret = 0;
|
||||||
|
int index, drop;
|
||||||
|
unsigned short win_scale = 0;
|
||||||
|
unsigned int win = 0;
|
||||||
|
struct tcp_ack_msg ack_msg;
|
||||||
|
struct tcp_ack_msg *ack;
|
||||||
|
struct tcp_ack_info *ack_info;
|
||||||
|
struct tcp_ack_manage *ack_m = &priv->ack_m;
|
||||||
|
|
||||||
|
tcp_ack_update(ack_m);
|
||||||
|
drop = tcp_check_ack(buf, &ack_msg, &win_scale);
|
||||||
|
// printk("drop:%d win_scale:%d",drop,win_scale);
|
||||||
|
if (!drop && (0 == win_scale))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
index = tcp_ack_match(ack_m, &ack_msg);
|
||||||
|
if (index >= 0) {
|
||||||
|
ack_info = ack_m->ack_info + index;
|
||||||
|
if ((0 != win_scale) &&
|
||||||
|
(ack_info->win_scale != win_scale)) {
|
||||||
|
write_seqlock_bh(&ack_info->seqlock);
|
||||||
|
ack_info->win_scale = win_scale;
|
||||||
|
write_sequnlock_bh(&ack_info->seqlock);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (drop > 0 && atomic_read(&ack_m->enable)) {
|
||||||
|
win = ack_info->win_scale * ack_msg.win;
|
||||||
|
if ((win_scale!=0) && (win < (ack_m->ack_winsize * SIZE_KB)))
|
||||||
|
{
|
||||||
|
drop = 2;
|
||||||
|
printk("%d %d %d",win_scale,win,(ack_m->ack_winsize * SIZE_KB));
|
||||||
|
}
|
||||||
|
ret = tcp_ack_handle_new(msgbuf, ack_m, ack_info,
|
||||||
|
&ack_msg, drop);
|
||||||
|
}
|
||||||
|
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
index = tcp_ack_alloc_index(ack_m);
|
||||||
|
if (index >= 0) {
|
||||||
|
write_seqlock_bh(&ack_m->ack_info[index].seqlock);
|
||||||
|
ack_m->ack_info[index].busy = 1;
|
||||||
|
ack_m->ack_info[index].psh_flag = 0;
|
||||||
|
ack_m->ack_info[index].last_time = jiffies;
|
||||||
|
ack_m->ack_info[index].drop_cnt =
|
||||||
|
atomic_read(&ack_m->max_drop_cnt);
|
||||||
|
ack_m->ack_info[index].win_scale =
|
||||||
|
(win_scale != 0) ? win_scale : 1;
|
||||||
|
|
||||||
|
//ack_m->ack_info[index].msgbuf = NULL;
|
||||||
|
//ack_m->ack_info[index].in_send_msg = NULL;
|
||||||
|
ack = &ack_m->ack_info[index].ack_msg;
|
||||||
|
ack->dest = ack_msg.dest;
|
||||||
|
ack->source = ack_msg.source;
|
||||||
|
ack->saddr = ack_msg.saddr;
|
||||||
|
ack->daddr = ack_msg.daddr;
|
||||||
|
ack->seq = ack_msg.seq;
|
||||||
|
write_sequnlock_bh(&ack_m->ack_info[index].seqlock);
|
||||||
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void move_tcpack_msg(struct rwnx_hw *priv,
|
||||||
|
struct msg_buf *msg)
|
||||||
|
{
|
||||||
|
struct tcp_ack_info *ack_info;
|
||||||
|
struct tcp_ack_manage *ack_m = &priv->ack_m;
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
if (!atomic_read(&ack_m->enable))
|
||||||
|
return;
|
||||||
|
|
||||||
|
//if (msg->len > MAX_TCP_ACK)
|
||||||
|
// return;
|
||||||
|
|
||||||
|
for (i = 0; i < TCP_ACK_NUM; i++) {
|
||||||
|
ack_info = &ack_m->ack_info[i];
|
||||||
|
write_seqlock_bh(&ack_info->seqlock);
|
||||||
|
if (ack_info->busy && (ack_info->in_send_msg == msg))
|
||||||
|
ack_info->in_send_msg = NULL;
|
||||||
|
write_sequnlock_bh(&ack_info->seqlock);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
92
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/aicwf_tcp_ack.h
Normal file
92
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/aicwf_tcp_ack.h
Normal file
|
|
@ -0,0 +1,92 @@
|
||||||
|
#ifndef _AICWF_TCP_ACK_H_
|
||||||
|
#define _AICWF_TCP_ACK_H_
|
||||||
|
|
||||||
|
#include <uapi/linux/if_ether.h>
|
||||||
|
#include <uapi/linux/tcp.h>
|
||||||
|
#include <uapi/linux/ip.h>
|
||||||
|
#include <uapi/linux/in.h>
|
||||||
|
#include <linux/moduleparam.h>
|
||||||
|
#include <net/tcp.h>
|
||||||
|
#include <linux/timer.h>
|
||||||
|
|
||||||
|
|
||||||
|
#define TCP_ACK_NUM 32
|
||||||
|
#define TCP_ACK_EXIT_VAL 0x800
|
||||||
|
#define TCP_ACK_DROP_CNT 10
|
||||||
|
|
||||||
|
#define ACK_OLD_TIME 4000
|
||||||
|
#define U32_BEFORE(a, b) ((__s32)((__u32)a - (__u32)b) <= 0)
|
||||||
|
|
||||||
|
#define MAX_TCP_ACK 200
|
||||||
|
/*min window size in KB, it's 256KB*/
|
||||||
|
#define MIN_WIN 256
|
||||||
|
#define SIZE_KB 1024
|
||||||
|
|
||||||
|
|
||||||
|
struct msg_buf {
|
||||||
|
//struct list_head list;
|
||||||
|
struct sk_buff *skb;
|
||||||
|
struct rwnx_vif *rwnx_vif;
|
||||||
|
/* data just tx cmd use,not include the head */
|
||||||
|
};
|
||||||
|
|
||||||
|
struct tcp_ack_msg {
|
||||||
|
u16 source;
|
||||||
|
u16 dest;
|
||||||
|
s32 saddr;
|
||||||
|
s32 daddr;
|
||||||
|
u32 seq;
|
||||||
|
u16 win;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct tcp_ack_info {
|
||||||
|
int ack_info_num;
|
||||||
|
int busy;
|
||||||
|
int drop_cnt;
|
||||||
|
int psh_flag;
|
||||||
|
u32 psh_seq;
|
||||||
|
u16 win_scale;
|
||||||
|
/* seqlock for ack info */
|
||||||
|
seqlock_t seqlock;
|
||||||
|
unsigned long last_time;
|
||||||
|
unsigned long timeout;
|
||||||
|
struct timer_list timer;
|
||||||
|
struct msg_buf *msgbuf;
|
||||||
|
struct msg_buf *in_send_msg;
|
||||||
|
struct tcp_ack_msg ack_msg;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct tcp_ack_manage {
|
||||||
|
/* 1 filter */
|
||||||
|
atomic_t enable;
|
||||||
|
int max_num;
|
||||||
|
int free_index;
|
||||||
|
unsigned long last_time;
|
||||||
|
unsigned long timeout;
|
||||||
|
atomic_t max_drop_cnt;
|
||||||
|
/* lock for tcp ack alloc and free */
|
||||||
|
spinlock_t lock;
|
||||||
|
struct rwnx_hw *priv;
|
||||||
|
struct tcp_ack_info ack_info[TCP_ACK_NUM];
|
||||||
|
/*size in KB*/
|
||||||
|
unsigned int ack_winsize;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct msg_buf *intf_tcp_alloc_msg(struct msg_buf *msg);
|
||||||
|
|
||||||
|
void tcp_ack_init(struct rwnx_hw *priv);
|
||||||
|
|
||||||
|
void tcp_ack_deinit(struct rwnx_hw *priv);
|
||||||
|
|
||||||
|
|
||||||
|
int is_drop_tcp_ack(struct tcphdr *tcphdr, int tcp_tot_len, unsigned short *win_scale);
|
||||||
|
|
||||||
|
int is_tcp_ack(struct sk_buff *skb, unsigned short *win_scale);
|
||||||
|
|
||||||
|
int filter_send_tcp_ack(struct rwnx_hw *priv, struct msg_buf *msgbuf,unsigned char *buf, unsigned int plen);
|
||||||
|
|
||||||
|
void filter_rx_tcp_ack(struct rwnx_hw *priv,unsigned char *buf, unsigned plen);
|
||||||
|
|
||||||
|
void move_tcpack_msg(struct rwnx_hw *priv, struct msg_buf * msg);
|
||||||
|
#endif
|
||||||
1358
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/aicwf_txrxif.c
Executable file
1358
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/aicwf_txrxif.c
Executable file
File diff suppressed because it is too large
Load diff
313
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/aicwf_txrxif.h
Executable file
313
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/aicwf_txrxif.h
Executable file
|
|
@ -0,0 +1,313 @@
|
||||||
|
/**
|
||||||
|
* aicwf_txrxif.h
|
||||||
|
*
|
||||||
|
* bus function declarations
|
||||||
|
*
|
||||||
|
* Copyright (C) AICSemi 2018-2020
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _AICWF_TXRXIF_H_
|
||||||
|
#define _AICWF_TXRXIF_H_
|
||||||
|
|
||||||
|
#include <linux/skbuff.h>
|
||||||
|
#include <linux/sched.h>
|
||||||
|
#include "ipc_shared.h"
|
||||||
|
#include "aicwf_rx_prealloc.h"
|
||||||
|
#ifdef AICWF_SDIO_SUPPORT
|
||||||
|
#include "aicwf_sdio.h"
|
||||||
|
#else
|
||||||
|
#include "aicwf_usb.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define CMD_BUF_MAX 1536
|
||||||
|
#define DATA_BUF_MAX 2048
|
||||||
|
#define TXPKT_BLOCKSIZE 512
|
||||||
|
#define MAX_AGGR_TXPKT_LEN (1536*64)
|
||||||
|
#define CMD_TX_TIMEOUT 5000
|
||||||
|
#define TX_ALIGNMENT 4
|
||||||
|
|
||||||
|
#ifdef CONFIG_USB_TX_AGGR
|
||||||
|
#define MAX_USB_AGGR_TXPKT_LEN (1536*15)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define RX_HWHRD_LEN 60 //58->60 word allined
|
||||||
|
#define CCMP_OR_WEP_INFO 8
|
||||||
|
#define MAX_RXQLEN 2000
|
||||||
|
#define RX_ALIGNMENT 4
|
||||||
|
|
||||||
|
#define DEBUG_ERROR_LEVEL 0
|
||||||
|
#define DEBUG_DEBUG_LEVEL 1
|
||||||
|
#define DEBUG_INFO_LEVEL 2
|
||||||
|
|
||||||
|
#define DBG_LEVEL DEBUG_DEBUG_LEVEL
|
||||||
|
|
||||||
|
#define txrx_err(fmt, ...) pr_err("txrx_err:<%s,%d>: " fmt, __func__, __LINE__, ##__VA_ARGS__)
|
||||||
|
#define sdio_err(fmt, ...) pr_err("sdio_err:<%s,%d>: " fmt, __func__, __LINE__, ##__VA_ARGS__)
|
||||||
|
#define usb_err(fmt, ...) pr_err("usb_err:<%s,%d>: " fmt, __func__, __LINE__, ##__VA_ARGS__)
|
||||||
|
#if DBG_LEVEL >= DEBUG_DEBUG_LEVEL
|
||||||
|
#define txrx_dbg(fmt, ...) printk("txrx: " fmt, ##__VA_ARGS__)
|
||||||
|
#define sdio_dbg(fmt, ...) printk("aicsdio: " fmt, ##__VA_ARGS__)
|
||||||
|
#define usb_dbg(fmt, ...) printk("aicusb: " fmt, ##__VA_ARGS__)
|
||||||
|
#else
|
||||||
|
#define txrx_dbg(fmt, ...)
|
||||||
|
#define sdio_dbg(fmt, ...)
|
||||||
|
#define usb_dbg(fmt, ...)
|
||||||
|
#endif
|
||||||
|
#if DBG_LEVEL >= DEBUG_INFO_LEVEL
|
||||||
|
#define txrx_info(fmt, ...) printk("aicsdio: " fmt, ##__VA_ARGS__)
|
||||||
|
#define sdio_info(fmt, ...) printk("aicsdio: " fmt, ##__VA_ARGS__)
|
||||||
|
#define usb_info(fmt, ...) printk("aicusb: " fmt, ##__VA_ARGS__)
|
||||||
|
#else
|
||||||
|
#define txrx_info(fmt, ...)
|
||||||
|
#define sdio_info(fmt, ...)
|
||||||
|
#define usb_info(fmt, ...)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
enum aicwf_bus_state {
|
||||||
|
BUS_DOWN_ST,
|
||||||
|
BUS_UP_ST
|
||||||
|
};
|
||||||
|
|
||||||
|
struct aicwf_bus_ops {
|
||||||
|
int (*start) (struct device * dev);
|
||||||
|
void (*stop) (struct device * dev);
|
||||||
|
int (*txdata) (struct device * dev, struct sk_buff * skb);
|
||||||
|
int (*txmsg) (struct device * dev, u8 * msg, uint len);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct frame_queue {
|
||||||
|
u16 num_prio;
|
||||||
|
u16 hi_prio;
|
||||||
|
u16 qmax; /* max number of queued frames */
|
||||||
|
u16 qcnt;
|
||||||
|
struct sk_buff_head queuelist[8];
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef CONFIG_PREALLOC_RX_SKB
|
||||||
|
struct rx_frame_queue {
|
||||||
|
u16 qmax; /* max number of queued frames */
|
||||||
|
u16 qcnt;
|
||||||
|
struct list_head queuelist;
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct aicwf_bus {
|
||||||
|
union {
|
||||||
|
struct aic_sdio_dev *sdio;
|
||||||
|
struct aic_usb_dev *usb;
|
||||||
|
} bus_priv;
|
||||||
|
struct device *dev;
|
||||||
|
struct aicwf_bus_ops *ops;
|
||||||
|
enum aicwf_bus_state state;
|
||||||
|
u8 *cmd_buf;
|
||||||
|
struct completion bustx_trgg;
|
||||||
|
struct completion busrx_trgg;
|
||||||
|
#ifdef CONFIG_USB_MSG_IN_EP
|
||||||
|
struct completion msg_busrx_trgg;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct task_struct *bustx_thread;
|
||||||
|
struct task_struct *busrx_thread;
|
||||||
|
#ifdef CONFIG_USB_MSG_IN_EP
|
||||||
|
struct task_struct *msg_busrx_thread;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
struct aicwf_tx_priv {
|
||||||
|
#ifdef AICWF_SDIO_SUPPORT
|
||||||
|
struct aic_sdio_dev *sdiodev;
|
||||||
|
int fw_avail_bufcnt;
|
||||||
|
//for cmd tx
|
||||||
|
u8 *cmd_buf;
|
||||||
|
uint cmd_len;
|
||||||
|
bool cmd_txstate;
|
||||||
|
bool cmd_tx_succ;
|
||||||
|
struct semaphore cmd_txsema;
|
||||||
|
wait_queue_head_t cmd_txdone_wait;
|
||||||
|
//for data tx
|
||||||
|
atomic_t tx_pktcnt;
|
||||||
|
|
||||||
|
struct frame_queue txq;
|
||||||
|
spinlock_t txqlock;
|
||||||
|
struct semaphore txctl_sema;
|
||||||
|
#endif
|
||||||
|
#ifdef AICWF_USB_SUPPORT
|
||||||
|
struct aic_usb_dev *usbdev;
|
||||||
|
#ifdef CONFIG_USB_TX_AGGR
|
||||||
|
int fw_avail_bufcnt;
|
||||||
|
|
||||||
|
//for data tx
|
||||||
|
atomic_t tx_pktcnt;
|
||||||
|
|
||||||
|
struct frame_queue txq;
|
||||||
|
spinlock_t txqlock;
|
||||||
|
spinlock_t txdlock;
|
||||||
|
#endif
|
||||||
|
#endif//AICWF_USB_SUPPORT
|
||||||
|
struct sk_buff *aggr_buf;
|
||||||
|
atomic_t aggr_count;
|
||||||
|
u8 *head;
|
||||||
|
u8 *tail;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#define DEFRAG_MAX_WAIT 40 //100
|
||||||
|
#ifdef AICWF_RX_REORDER
|
||||||
|
#define MAX_REORD_RXFRAME 250
|
||||||
|
#define REORDER_UPDATE_TIME 500//50
|
||||||
|
#define AICWF_REORDER_WINSIZE 64
|
||||||
|
//SN_LESS(a, b) a-b<0 is ture
|
||||||
|
#define SN_LESS(a, b) (((a-b)&0x800)!=0)
|
||||||
|
#define SN_EQUAL(a, b) (a == b)
|
||||||
|
|
||||||
|
struct reord_ctrl {
|
||||||
|
struct aicwf_rx_priv *rx_priv;
|
||||||
|
u8 enable;
|
||||||
|
u16 ind_sn;
|
||||||
|
u8 wsize_b;
|
||||||
|
spinlock_t reord_list_lock;
|
||||||
|
struct list_head reord_list;
|
||||||
|
struct timer_list reord_timer;
|
||||||
|
struct work_struct reord_timer_work;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct reord_ctrl_info {
|
||||||
|
u8 mac_addr[6];
|
||||||
|
struct reord_ctrl preorder_ctrl[8];
|
||||||
|
struct list_head list;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct recv_msdu {
|
||||||
|
struct sk_buff *pkt;
|
||||||
|
u8 tid;
|
||||||
|
u8 forward;
|
||||||
|
u16 seq_num;
|
||||||
|
//uint len;
|
||||||
|
u8 is_amsdu;
|
||||||
|
u8 is_ap_reord;
|
||||||
|
u8 ap_fwd_cnt;
|
||||||
|
u8 ap_resend_cnt;
|
||||||
|
u8 *rx_data;
|
||||||
|
struct sk_buff *first_fwd_skb;
|
||||||
|
struct sk_buff *last_fwd_skb;
|
||||||
|
struct sk_buff *first_resend_skb;
|
||||||
|
struct sk_buff *last_resend_skb;
|
||||||
|
//for pending rx reorder list
|
||||||
|
struct list_head reord_pending_list;
|
||||||
|
//for total frame list, when rxframe from busif, dequeue, when submit frame to net, enqueue
|
||||||
|
struct list_head rxframe_list;
|
||||||
|
struct reord_ctrl *preorder_ctrl;
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct aicwf_rx_priv {
|
||||||
|
#ifdef AICWF_SDIO_SUPPORT
|
||||||
|
struct aic_sdio_dev *sdiodev;
|
||||||
|
#endif
|
||||||
|
#ifdef AICWF_USB_SUPPORT
|
||||||
|
struct aic_usb_dev *usbdev;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void *rwnx_vif;
|
||||||
|
atomic_t rx_cnt;
|
||||||
|
u32 data_len;
|
||||||
|
spinlock_t rxqlock;
|
||||||
|
#ifdef CONFIG_PREALLOC_RX_SKB
|
||||||
|
struct rx_frame_queue rxq;
|
||||||
|
#else
|
||||||
|
struct frame_queue rxq;
|
||||||
|
#endif
|
||||||
|
#ifdef CONFIG_USB_RX_REASSEMBLE
|
||||||
|
struct sk_buff *rx_reassemble_skb;
|
||||||
|
u32 rx_reassemble_total_len;
|
||||||
|
u32 rx_reassemble_cur_len;
|
||||||
|
u32 rx_reassemble_total_frags;
|
||||||
|
u32 rx_reassemble_cur_frags;
|
||||||
|
|
||||||
|
struct sk_buff *rx_msg_reassemble_skb;
|
||||||
|
u32 rx_msg_reassemble_total_len;
|
||||||
|
u32 rx_msg_reassemble_cur_len;
|
||||||
|
u32 rx_msg_reassemble_total_frags;
|
||||||
|
u32 rx_msg_reassemble_cur_frags;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_USB_MSG_IN_EP
|
||||||
|
atomic_t msg_rx_cnt;
|
||||||
|
spinlock_t msg_rxqlock;
|
||||||
|
struct frame_queue msg_rxq;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef AICWF_RX_REORDER
|
||||||
|
spinlock_t freeq_lock;
|
||||||
|
struct list_head rxframes_freequeue;
|
||||||
|
struct list_head stas_reord_list;
|
||||||
|
spinlock_t stas_reord_lock;
|
||||||
|
struct recv_msdu *recv_frames;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_PREALLOC_RX_SKB
|
||||||
|
spinlock_t rxbuff_lock;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
static inline int aicwf_bus_start(struct aicwf_bus *bus)
|
||||||
|
{
|
||||||
|
return bus->ops->start(bus->dev);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void aicwf_bus_stop(struct aicwf_bus *bus)
|
||||||
|
{
|
||||||
|
bus->ops->stop(bus->dev);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int aicwf_bus_txdata(struct aicwf_bus *bus, struct sk_buff *skb)
|
||||||
|
{
|
||||||
|
return bus->ops->txdata(bus->dev, skb);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int aicwf_bus_txmsg(struct aicwf_bus *bus, u8 *msg, uint len)
|
||||||
|
{
|
||||||
|
return bus->ops->txmsg(bus->dev, msg, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void aicwf_sched_timeout(u32 millisec)
|
||||||
|
{
|
||||||
|
ulong timeout = 0, expires = 0;
|
||||||
|
expires = jiffies + msecs_to_jiffies(millisec);
|
||||||
|
timeout = millisec;
|
||||||
|
|
||||||
|
while (timeout) {
|
||||||
|
timeout = schedule_timeout(timeout);
|
||||||
|
if (time_after(jiffies, expires))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int aicwf_bus_init(uint bus_hdrlen, struct device *dev);
|
||||||
|
void aicwf_bus_deinit(struct device *dev);
|
||||||
|
void aicwf_tx_deinit(struct aicwf_tx_priv* tx_priv);
|
||||||
|
void aicwf_rx_deinit(struct aicwf_rx_priv* rx_priv);
|
||||||
|
struct aicwf_tx_priv* aicwf_tx_init(void *arg);
|
||||||
|
struct aicwf_rx_priv* aicwf_rx_init(void *arg);
|
||||||
|
void aicwf_frame_queue_init(struct frame_queue *pq, int num_prio, int max_len);
|
||||||
|
void aicwf_frame_queue_flush(struct frame_queue *pq);
|
||||||
|
bool aicwf_frame_enq(struct device *dev, struct frame_queue *q, struct sk_buff *pkt, int prio);
|
||||||
|
bool aicwf_rxframe_enqueue(struct device *dev, struct frame_queue *q, struct sk_buff *pkt);
|
||||||
|
bool aicwf_is_framequeue_empty(struct frame_queue *pq);
|
||||||
|
void aicwf_frame_tx(void *dev, struct sk_buff *skb);
|
||||||
|
void aicwf_dev_skb_free(struct sk_buff *skb);
|
||||||
|
struct sk_buff *aicwf_frame_dequeue(struct frame_queue *pq);
|
||||||
|
struct sk_buff *aicwf_frame_queue_peek_tail(struct frame_queue *pq, int *prio_out);
|
||||||
|
#ifdef CONFIG_PREALLOC_RX_SKB
|
||||||
|
void rxbuff_queue_flush(struct aicwf_rx_priv* rx_priv);
|
||||||
|
void aicwf_rxframe_queue_init_2(struct rx_frame_queue *pq, int max_len);
|
||||||
|
void rxbuff_free(struct rx_buff *rxbuff);
|
||||||
|
struct rx_buff *rxbuff_dequeue(struct rx_frame_queue *pq);
|
||||||
|
bool aicwf_rxbuff_enqueue(struct device *dev, struct rx_frame_queue *rxq, struct rx_buff *pkt);
|
||||||
|
extern struct aicwf_rx_buff_list aic_rx_buff_list;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* _AICWF_TXRXIF_H_ */
|
||||||
2734
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/aicwf_usb.c
Normal file
2734
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/aicwf_usb.c
Normal file
File diff suppressed because it is too large
Load diff
208
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/aicwf_usb.h
Normal file
208
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/aicwf_usb.h
Normal file
|
|
@ -0,0 +1,208 @@
|
||||||
|
/**
|
||||||
|
* aicwf_usb.h
|
||||||
|
*
|
||||||
|
* USB function declarations
|
||||||
|
*
|
||||||
|
* Copyright (C) AICSemi 2018-2020
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _AICWF_USB_H_
|
||||||
|
#define _AICWF_USB_H_
|
||||||
|
|
||||||
|
#include <linux/usb.h>
|
||||||
|
#include "rwnx_cmds.h"
|
||||||
|
|
||||||
|
#ifdef AICWF_USB_SUPPORT
|
||||||
|
|
||||||
|
/* USB Device ID */
|
||||||
|
#define USB_VENDOR_ID_AIC 0xA69C
|
||||||
|
#define USB_VENDOR_ID_TP 0x2357
|
||||||
|
#define USB_VENDOR_ID_TENDA 0x2604
|
||||||
|
#define USB_VENDOR_ID_AIC_V2 0x368B
|
||||||
|
|
||||||
|
#define USB_PRODUCT_ID_TP 0x014e
|
||||||
|
#define USB_PRODUCT_ID_MERCURY 0x014b
|
||||||
|
#define USB_PRODUCT_ID_FAST 0x014f
|
||||||
|
|
||||||
|
#define USB_PRODUCT_ID_TENDA 0x001f
|
||||||
|
|
||||||
|
#ifndef CONFIG_USB_BT
|
||||||
|
#define USB_PRODUCT_ID_AIC8800 0x8800
|
||||||
|
#define USB_PRODUCT_ID_AIC8801 0x8801
|
||||||
|
#define USB_PRODUCT_ID_AIC8800DC 0x88dc
|
||||||
|
#define USB_PRODUCT_ID_AIC8800DW 0x88dd
|
||||||
|
#define USB_PRODUCT_ID_AIC8800D81 0x8d81
|
||||||
|
#define USB_PRODUCT_ID_AIC8800D81X2 0x8d91
|
||||||
|
#define USB_PRODUCT_ID_AIC8800D89X2 0x8d99
|
||||||
|
#else
|
||||||
|
#define USB_PRODUCT_ID_AIC8801 0x8801
|
||||||
|
#define USB_PRODUCT_ID_AIC8800DC 0x88dc
|
||||||
|
#define USB_PRODUCT_ID_AIC8800DW 0x88dd
|
||||||
|
#define USB_PRODUCT_ID_AIC8800D81 0x8d81
|
||||||
|
#define USB_PRODUCT_ID_AIC8800D41 0x8d41
|
||||||
|
#define USB_PRODUCT_ID_AIC8800D81X2 0x8d91
|
||||||
|
#define USB_PRODUCT_ID_AIC8800D89X2 0x8d99
|
||||||
|
#define USB_PRODUCT_ID_AIC8800D83 0x8d83
|
||||||
|
#define USB_PRODUCT_ID_AIC8800D84 0x8d84
|
||||||
|
#define USB_PRODUCT_ID_AIC8800D85 0x8d85
|
||||||
|
#define USB_PRODUCT_ID_AIC8800D88 0x8d88
|
||||||
|
#endif
|
||||||
|
|
||||||
|
enum AICWF_IC{
|
||||||
|
PRODUCT_ID_AIC8801 = 0,
|
||||||
|
PRODUCT_ID_AIC8800DC,
|
||||||
|
PRODUCT_ID_AIC8800DW,
|
||||||
|
PRODUCT_ID_AIC8800D81,
|
||||||
|
PRODUCT_ID_AIC8800D81X2,
|
||||||
|
PRODUCT_ID_AIC8800D89X2
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#define AICWF_USB_RX_URBS (20)//(200)
|
||||||
|
#ifdef CONFIG_USB_MSG_IN_EP
|
||||||
|
#define AICWF_USB_MSG_RX_URBS (100)
|
||||||
|
#endif
|
||||||
|
#ifdef CONFIG_USB_TX_AGGR
|
||||||
|
#define TXQLEN (2048*4)
|
||||||
|
#define AICWF_USB_TX_URBS (50)
|
||||||
|
#else
|
||||||
|
#define AICWF_USB_TX_URBS 200//(100)
|
||||||
|
#endif
|
||||||
|
#define AICWF_USB_TX_LOW_WATER (AICWF_USB_TX_URBS/4)//25%
|
||||||
|
#define AICWF_USB_TX_HIGH_WATER (AICWF_USB_TX_LOW_WATER*3)//75%
|
||||||
|
#ifdef CONFIG_PLATFORM_HI
|
||||||
|
#define AICWF_USB_AGGR_MAX_PKT_SIZE (2048*1)
|
||||||
|
#else
|
||||||
|
#define AICWF_USB_AGGR_MAX_PKT_SIZE (2048*10)
|
||||||
|
#endif
|
||||||
|
#define AICWF_USB_MSG_MAX_PKT_SIZE (2048)
|
||||||
|
#define AICWF_USB_MAX_PKT_SIZE (2048)
|
||||||
|
#define AICWF_USB_MAX_AMSDU_PKT_SIZE (2048*6)
|
||||||
|
#define AICWF_USB_FC_PERSTA_HIGH_WATER 64
|
||||||
|
#define AICWF_USB_FC_PERSTA_LOW_WATER 16
|
||||||
|
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
USB_TYPE_DATA = 0X00,
|
||||||
|
USB_TYPE_CFG = 0X10,
|
||||||
|
USB_TYPE_CFG_CMD_RSP = 0X11,
|
||||||
|
USB_TYPE_CFG_DATA_CFM = 0X12,
|
||||||
|
USB_TYPE_CFG_PRINT = 0X13
|
||||||
|
} usb_type;
|
||||||
|
|
||||||
|
enum aicwf_usb_state {
|
||||||
|
USB_DOWN_ST,
|
||||||
|
USB_UP_ST,
|
||||||
|
USB_SLEEP_ST
|
||||||
|
};
|
||||||
|
|
||||||
|
struct aicwf_usb_buf {
|
||||||
|
struct list_head list;
|
||||||
|
struct aic_usb_dev *usbdev;
|
||||||
|
struct urb *urb;
|
||||||
|
struct sk_buff *skb;
|
||||||
|
#ifdef CONFIG_PREALLOC_RX_SKB
|
||||||
|
struct rx_buff *rx_buff;
|
||||||
|
#endif
|
||||||
|
#ifdef CONFIG_USB_NO_TRANS_DMA_MAP
|
||||||
|
u8 *data_buf;
|
||||||
|
dma_addr_t data_dma_trans_addr;
|
||||||
|
#endif
|
||||||
|
bool cfm;
|
||||||
|
#ifdef CONFIG_USB_TX_AGGR
|
||||||
|
u8 aggr_cnt;
|
||||||
|
#endif
|
||||||
|
u8* usb_align_data;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct aic_usb_dev {
|
||||||
|
struct rwnx_hw *rwnx_hw;
|
||||||
|
struct aicwf_bus *bus_if;
|
||||||
|
struct usb_device *udev;
|
||||||
|
struct device *dev;
|
||||||
|
struct aicwf_rx_priv* rx_priv;
|
||||||
|
enum aicwf_usb_state state;
|
||||||
|
struct rwnx_cmd_mgr cmd_mgr;
|
||||||
|
|
||||||
|
#ifdef CONFIG_USB_TX_AGGR
|
||||||
|
struct aicwf_tx_priv *tx_priv;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct usb_anchor rx_submitted;
|
||||||
|
struct work_struct rx_urb_work;
|
||||||
|
#ifdef CONFIG_USB_MSG_IN_EP
|
||||||
|
struct usb_anchor msg_rx_submitted;
|
||||||
|
struct work_struct msg_rx_urb_work;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
spinlock_t rx_free_lock;
|
||||||
|
spinlock_t tx_free_lock;
|
||||||
|
spinlock_t tx_post_lock;
|
||||||
|
spinlock_t tx_flow_lock;
|
||||||
|
#ifdef CONFIG_USB_MSG_IN_EP
|
||||||
|
spinlock_t msg_rx_free_lock;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct list_head rx_free_list;
|
||||||
|
struct list_head tx_free_list;
|
||||||
|
struct list_head tx_post_list;
|
||||||
|
#ifdef CONFIG_USB_MSG_IN_EP
|
||||||
|
struct list_head msg_rx_free_list;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
uint bulk_in_pipe;
|
||||||
|
uint bulk_out_pipe;
|
||||||
|
#ifdef CONFIG_USB_MSG_OUT_EP
|
||||||
|
uint msg_out_pipe;
|
||||||
|
#endif
|
||||||
|
#ifdef CONFIG_USB_MSG_IN_EP
|
||||||
|
uint msg_in_pipe;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int tx_free_count;
|
||||||
|
int tx_post_count;
|
||||||
|
bool rx_prepare_ready;
|
||||||
|
#if 0
|
||||||
|
struct aicwf_usb_buf usb_tx_buf[AICWF_USB_TX_URBS];
|
||||||
|
struct aicwf_usb_buf usb_rx_buf[AICWF_USB_RX_URBS];
|
||||||
|
#else
|
||||||
|
struct aicwf_usb_buf *usb_tx_buf;
|
||||||
|
struct aicwf_usb_buf *usb_rx_buf;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_USB_MSG_IN_EP
|
||||||
|
struct aicwf_usb_buf usb_msg_rx_buf[AICWF_USB_MSG_RX_URBS];
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int msg_finished;
|
||||||
|
wait_queue_head_t msg_wait;
|
||||||
|
ulong msg_busy;
|
||||||
|
struct urb *msg_out_urb;
|
||||||
|
#ifdef CONFIG_USB_NO_TRANS_DMA_MAP
|
||||||
|
dma_addr_t cmd_dma_trans_addr;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_RX_TASKLET//AIDEN tasklet
|
||||||
|
struct tasklet_struct recv_tasklet;
|
||||||
|
#endif
|
||||||
|
#ifdef CONFIG_TX_TASKLET//AIDEN tasklet
|
||||||
|
struct tasklet_struct xmit_tasklet;
|
||||||
|
#endif
|
||||||
|
u16 chipid;
|
||||||
|
bool tbusy;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern void aicwf_usb_exit(void);
|
||||||
|
extern void aicwf_usb_register(void);
|
||||||
|
extern void aicwf_usb_tx_flowctrl(struct rwnx_hw *rwnx_hw, bool state);
|
||||||
|
#ifdef CONFIG_USB_MSG_IN_EP
|
||||||
|
int usb_msg_busrx_thread(void *data);
|
||||||
|
#endif
|
||||||
|
int usb_bustx_thread(void *data);
|
||||||
|
int usb_busrx_thread(void *data);
|
||||||
|
|
||||||
|
|
||||||
|
extern void aicwf_hostif_ready(void);
|
||||||
|
|
||||||
|
#endif /* AICWF_USB_SUPPORT */
|
||||||
|
#endif /* _AICWF_USB_H_ */
|
||||||
1224
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/aicwf_wext_linux.c
Normal file
1224
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/aicwf_wext_linux.c
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -0,0 +1,11 @@
|
||||||
|
|
||||||
|
struct scanu_result_wext{
|
||||||
|
struct list_head scanu_re_list;
|
||||||
|
struct cfg80211_bss *bss;
|
||||||
|
struct scanu_result_ind *ind;
|
||||||
|
u32_l *payload;
|
||||||
|
};
|
||||||
|
|
||||||
|
void aicwf_set_wireless_ext( struct net_device *ndev, struct rwnx_hw *rwnx_hw);
|
||||||
|
void aicwf_scan_complete_event(struct net_device *dev);
|
||||||
|
|
||||||
376
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/hal_desc.h
Normal file
376
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/hal_desc.h
Normal file
|
|
@ -0,0 +1,376 @@
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
*
|
||||||
|
* @file hal_desc.h
|
||||||
|
*
|
||||||
|
* @brief File containing the definition of HW descriptors.
|
||||||
|
*
|
||||||
|
* Contains the definition and structures used by HW
|
||||||
|
*
|
||||||
|
* Copyright (C) RivieraWaves 2011-2019
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _HAL_DESC_H_
|
||||||
|
#define _HAL_DESC_H_
|
||||||
|
|
||||||
|
#include "lmac_types.h"
|
||||||
|
|
||||||
|
/* Rate and policy table */
|
||||||
|
|
||||||
|
#define N_CCK 8
|
||||||
|
#define N_OFDM 8
|
||||||
|
#define N_HT (8 * 2 * 2 * 4)
|
||||||
|
#define N_VHT (10 * 4 * 2 * 8)
|
||||||
|
#define N_HE_SU (12 * 4 * 3 * 8)
|
||||||
|
#define N_HE_MU (12 * 6 * 3 * 8)
|
||||||
|
|
||||||
|
/* conversion table from NL80211 to MACHW enum */
|
||||||
|
extern const int chnl2bw[];
|
||||||
|
|
||||||
|
/* conversion table from MACHW to NL80211 enum */
|
||||||
|
extern const int bw2chnl[];
|
||||||
|
|
||||||
|
/* Rate cntrl info */
|
||||||
|
#define MCS_INDEX_TX_RCX_OFT 0
|
||||||
|
#define MCS_INDEX_TX_RCX_MASK (0x7F << MCS_INDEX_TX_RCX_OFT)
|
||||||
|
#define BW_TX_RCX_OFT 7
|
||||||
|
#define BW_TX_RCX_MASK (0x3 << BW_TX_RCX_OFT)
|
||||||
|
#define SHORT_GI_TX_RCX_OFT 9
|
||||||
|
#define SHORT_GI_TX_RCX_MASK (0x1 << SHORT_GI_TX_RCX_OFT)
|
||||||
|
#define PRE_TYPE_TX_RCX_OFT 10
|
||||||
|
#define PRE_TYPE_TX_RCX_MASK (0x1 << PRE_TYPE_TX_RCX_OFT)
|
||||||
|
#define FORMAT_MOD_TX_RCX_OFT 11
|
||||||
|
#define FORMAT_MOD_TX_RCX_MASK (0x7 << FORMAT_MOD_TX_RCX_OFT)
|
||||||
|
|
||||||
|
/* Values for formatModTx */
|
||||||
|
#define FORMATMOD_NON_HT 0
|
||||||
|
#define FORMATMOD_NON_HT_DUP_OFDM 1
|
||||||
|
#define FORMATMOD_HT_MF 2
|
||||||
|
#define FORMATMOD_HT_GF 3
|
||||||
|
#define FORMATMOD_VHT 4
|
||||||
|
#define FORMATMOD_HE_SU 5
|
||||||
|
#define FORMATMOD_HE_MU 6
|
||||||
|
#define FORMATMOD_HE_ER 7
|
||||||
|
|
||||||
|
/* Values for navProtFrmEx */
|
||||||
|
#define NAV_PROT_NO_PROT_BIT 0
|
||||||
|
#define NAV_PROT_SELF_CTS_BIT 1
|
||||||
|
#define NAV_PROT_RTS_CTS_BIT 2
|
||||||
|
#define NAV_PROT_RTS_CTS_WITH_QAP_BIT 3
|
||||||
|
#define NAV_PROT_STBC_BIT 4
|
||||||
|
|
||||||
|
/* THD MACCTRLINFO2 fields, used in struct umacdesc umac.flags */
|
||||||
|
/// WhichDescriptor definition - contains aMPDU bit and position value
|
||||||
|
/// Offset of WhichDescriptor field in the MAC CONTROL INFO 2 word
|
||||||
|
#define WHICHDESC_OFT 19
|
||||||
|
/// Mask of the WhichDescriptor field
|
||||||
|
#define WHICHDESC_MSK (0x07 << WHICHDESC_OFT)
|
||||||
|
/// Only 1 THD possible, describing an unfragmented MSDU
|
||||||
|
#define WHICHDESC_UNFRAGMENTED_MSDU (0x00 << WHICHDESC_OFT)
|
||||||
|
/// THD describing the first MPDU of a fragmented MSDU
|
||||||
|
#define WHICHDESC_FRAGMENTED_MSDU_FIRST (0x01 << WHICHDESC_OFT)
|
||||||
|
/// THD describing intermediate MPDUs of a fragmented MSDU
|
||||||
|
#define WHICHDESC_FRAGMENTED_MSDU_INT (0x02 << WHICHDESC_OFT)
|
||||||
|
/// THD describing the last MPDU of a fragmented MSDU
|
||||||
|
#define WHICHDESC_FRAGMENTED_MSDU_LAST (0x03 << WHICHDESC_OFT)
|
||||||
|
/// THD for extra descriptor starting an AMPDU
|
||||||
|
#define WHICHDESC_AMPDU_EXTRA (0x04 << WHICHDESC_OFT)
|
||||||
|
/// THD describing the first MPDU of an A-MPDU
|
||||||
|
#define WHICHDESC_AMPDU_FIRST (0x05 << WHICHDESC_OFT)
|
||||||
|
/// THD describing intermediate MPDUs of an A-MPDU
|
||||||
|
#define WHICHDESC_AMPDU_INT (0x06 << WHICHDESC_OFT)
|
||||||
|
/// THD describing the last MPDU of an A-MPDU
|
||||||
|
#define WHICHDESC_AMPDU_LAST (0x07 << WHICHDESC_OFT)
|
||||||
|
|
||||||
|
/// aMPDU bit offset
|
||||||
|
#define AMPDU_OFT 21
|
||||||
|
/// aMPDU bit
|
||||||
|
#define AMPDU_BIT CO_BIT(AMPDU_OFT)
|
||||||
|
|
||||||
|
enum {
|
||||||
|
HW_RATE_1MBPS = 0,
|
||||||
|
HW_RATE_2MBPS = 1,
|
||||||
|
HW_RATE_5_5MBPS = 2,
|
||||||
|
HW_RATE_11MBPS = 3,
|
||||||
|
HW_RATE_6MBPS = 4,
|
||||||
|
HW_RATE_9MBPS = 5,
|
||||||
|
HW_RATE_12MBPS = 6,
|
||||||
|
HW_RATE_18MBPS = 7,
|
||||||
|
HW_RATE_24MBPS = 8,
|
||||||
|
HW_RATE_36MBPS = 9,
|
||||||
|
HW_RATE_48MBPS = 10,
|
||||||
|
HW_RATE_54MBPS = 11,
|
||||||
|
HW_RATE_MAX
|
||||||
|
};
|
||||||
|
|
||||||
|
union rwnx_mcs_index {
|
||||||
|
struct {
|
||||||
|
u32 mcs : 3;
|
||||||
|
u32 nss : 2;
|
||||||
|
} ht;
|
||||||
|
struct {
|
||||||
|
u32 mcs : 4;
|
||||||
|
u32 nss : 3;
|
||||||
|
} vht;
|
||||||
|
struct {
|
||||||
|
u32 mcs : 4;
|
||||||
|
u32 nss : 3;
|
||||||
|
} he;
|
||||||
|
u32 legacy : 7;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* c.f RW-WLAN-nX-MAC-HW-UM */
|
||||||
|
union rwnx_rate_ctrl_info {
|
||||||
|
struct {
|
||||||
|
u32 mcsIndexTx : 7;
|
||||||
|
u32 bwTx : 2;
|
||||||
|
u32 giAndPreTypeTx : 2;
|
||||||
|
u32 formatModTx : 3;
|
||||||
|
u32 navProtFrmEx : 3;
|
||||||
|
u32 mcsIndexProtTx : 7;
|
||||||
|
u32 bwProtTx : 2;
|
||||||
|
u32 formatModProtTx : 3;
|
||||||
|
u32 nRetry : 3;
|
||||||
|
};
|
||||||
|
u32 value;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* c.f RW-WLAN-nX-MAC-HW-UM */
|
||||||
|
struct rwnx_power_ctrl_info {
|
||||||
|
u32 txPwrLevelPT : 8;
|
||||||
|
u32 txPwrLevelProtPT : 8;
|
||||||
|
u32 reserved :16;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* c.f RW-WLAN-nX-MAC-HW-UM */
|
||||||
|
union rwnx_pol_phy_ctrl_info_1 {
|
||||||
|
struct {
|
||||||
|
u32 rsvd1 : 3;
|
||||||
|
u32 bfFrmEx : 1;
|
||||||
|
u32 numExtnSS : 2;
|
||||||
|
u32 fecCoding : 1;
|
||||||
|
u32 stbc : 2;
|
||||||
|
u32 rsvd2 : 5;
|
||||||
|
u32 nTx : 3;
|
||||||
|
u32 nTxProt : 3;
|
||||||
|
};
|
||||||
|
u32 value;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* c.f RW-WLAN-nX-MAC-HW-UM */
|
||||||
|
union rwnx_pol_phy_ctrl_info_2 {
|
||||||
|
struct {
|
||||||
|
u32 antennaSet : 8;
|
||||||
|
u32 smmIndex : 8;
|
||||||
|
u32 beamFormed : 1;
|
||||||
|
};
|
||||||
|
u32 value;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* c.f RW-WLAN-nX-MAC-HW-UM */
|
||||||
|
union rwnx_pol_mac_ctrl_info_1 {
|
||||||
|
struct {
|
||||||
|
u32 keySRamIndex : 10;
|
||||||
|
u32 keySRamIndexRA : 10;
|
||||||
|
};
|
||||||
|
u32 value;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* c.f RW-WLAN-nX-MAC-HW-UM */
|
||||||
|
union rwnx_pol_mac_ctrl_info_2 {
|
||||||
|
struct {
|
||||||
|
u32 longRetryLimit : 8;
|
||||||
|
u32 shortRetryLimit : 8;
|
||||||
|
u32 rtsThreshold : 12;
|
||||||
|
};
|
||||||
|
u32 value;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define POLICY_TABLE_PATTERN 0xBADCAB1E
|
||||||
|
|
||||||
|
struct tx_policy_tbl {
|
||||||
|
/* Unique Pattern at the start of Policy Table */
|
||||||
|
u32 upatterntx;
|
||||||
|
/* PHY Control 1 Information used by MAC HW */
|
||||||
|
union rwnx_pol_phy_ctrl_info_1 phyctrlinfo_1;
|
||||||
|
/* PHY Control 2 Information used by MAC HW */
|
||||||
|
union rwnx_pol_phy_ctrl_info_2 phyctrlinfo_2;
|
||||||
|
/* MAC Control 1 Information used by MAC HW */
|
||||||
|
union rwnx_pol_mac_ctrl_info_1 macctrlinfo_1;
|
||||||
|
/* MAC Control 2 Information used by MAC HW */
|
||||||
|
union rwnx_pol_mac_ctrl_info_2 macctrlinfo_2;
|
||||||
|
|
||||||
|
union rwnx_rate_ctrl_info ratectrlinfos[NX_TX_MAX_RATES];
|
||||||
|
struct rwnx_power_ctrl_info powerctrlinfos[NX_TX_MAX_RATES];
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef CONFIG_RWNX_FULLMAC
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct rwnx_hw_txstatus - Bitfield of confirmation status
|
||||||
|
*
|
||||||
|
* @tx_done: packet has been processed by the firmware.
|
||||||
|
* @retry_required: packet has been transmitted but not acknoledged.
|
||||||
|
* Driver must repush it.
|
||||||
|
* @sw_retry_required: packet has not been transmitted (FW wasn't able to push
|
||||||
|
* it when it received it: not active channel ...). Driver must repush it.
|
||||||
|
* @acknowledged: packet has been acknowledged by peer
|
||||||
|
*/
|
||||||
|
union rwnx_hw_txstatus {
|
||||||
|
struct {
|
||||||
|
u32 tx_done : 1;
|
||||||
|
u32 retry_required : 1;
|
||||||
|
u32 sw_retry_required : 1;
|
||||||
|
u32 acknowledged : 1;
|
||||||
|
u32 reserved :28;
|
||||||
|
};
|
||||||
|
u32 value;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct tx_cfm_tag - Structure indicating the status and other
|
||||||
|
* information about the transmission
|
||||||
|
*
|
||||||
|
* @pn: PN that was used for the transmission
|
||||||
|
* @sn: Sequence number of the packet
|
||||||
|
* @timestamp: Timestamp of first transmission of this MPDU
|
||||||
|
* @credits: Number of credits to be reallocated for the txq that push this
|
||||||
|
* buffer (can be 0 or 1)
|
||||||
|
* @ampdu_size: Size of the ampdu in which the frame has been transmitted if
|
||||||
|
* this was the last frame of the a-mpdu, and 0 if the frame is not the last
|
||||||
|
* frame on a a-mdpu.
|
||||||
|
* 1 means that the frame has been transmitted as a singleton.
|
||||||
|
* @amsdu_size: Size, in bytes, allowed to create a-msdu.
|
||||||
|
* @status: transmission status
|
||||||
|
*/
|
||||||
|
struct tx_cfm_tag
|
||||||
|
{
|
||||||
|
u16_l pn[4];
|
||||||
|
u16_l sn;
|
||||||
|
u16_l timestamp;
|
||||||
|
s8_l credits;
|
||||||
|
u8_l ampdu_size;
|
||||||
|
#ifdef CONFIG_RWNX_SPLIT_TX_BUF
|
||||||
|
u16_l amsdu_size;
|
||||||
|
#endif
|
||||||
|
union rwnx_hw_txstatus status;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct rwnx_hw_txhdr - Hardware part of tx header
|
||||||
|
*
|
||||||
|
* @cfm: Information updated by fw/hardware after sending a frame
|
||||||
|
*/
|
||||||
|
struct rwnx_hw_txhdr {
|
||||||
|
struct tx_cfm_tag cfm;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* CONFIG_RWNX_FULLMAC */
|
||||||
|
|
||||||
|
/* Modem */
|
||||||
|
|
||||||
|
#define MDM_PHY_CONFIG_TRIDENT 0
|
||||||
|
#define MDM_PHY_CONFIG_ELMA 1
|
||||||
|
#define MDM_PHY_CONFIG_KARST 2
|
||||||
|
|
||||||
|
// MODEM features (from reg_mdm_stat.h)
|
||||||
|
/// MUMIMOTX field bit
|
||||||
|
#define MDM_MUMIMOTX_BIT ((u32)0x80000000)
|
||||||
|
/// MUMIMOTX field position
|
||||||
|
#define MDM_MUMIMOTX_POS 31
|
||||||
|
/// MUMIMORX field bit
|
||||||
|
#define MDM_MUMIMORX_BIT ((u32)0x40000000)
|
||||||
|
/// MUMIMORX field position
|
||||||
|
#define MDM_MUMIMORX_POS 30
|
||||||
|
/// BFMER field bit
|
||||||
|
#define MDM_BFMER_BIT ((u32)0x20000000)
|
||||||
|
/// BFMER field position
|
||||||
|
#define MDM_BFMER_POS 29
|
||||||
|
/// BFMEE field bit
|
||||||
|
#define MDM_BFMEE_BIT ((u32)0x10000000)
|
||||||
|
/// BFMEE field position
|
||||||
|
#define MDM_BFMEE_POS 28
|
||||||
|
/// LDPCDEC field bit
|
||||||
|
#define MDM_LDPCDEC_BIT ((u32)0x08000000)
|
||||||
|
/// LDPCDEC field position
|
||||||
|
#define MDM_LDPCDEC_POS 27
|
||||||
|
/// LDPCENC field bit
|
||||||
|
#define MDM_LDPCENC_BIT ((u32)0x04000000)
|
||||||
|
/// LDPCENC field position
|
||||||
|
#define MDM_LDPCENC_POS 26
|
||||||
|
/// CHBW field mask
|
||||||
|
#define MDM_CHBW_MASK ((u32)0x03000000)
|
||||||
|
/// CHBW field LSB position
|
||||||
|
#define MDM_CHBW_LSB 24
|
||||||
|
/// CHBW field width
|
||||||
|
#define MDM_CHBW_WIDTH ((u32)0x00000002)
|
||||||
|
/// DSSSCCK field bit
|
||||||
|
#define MDM_DSSSCCK_BIT ((u32)0x00800000)
|
||||||
|
/// DSSSCCK field position
|
||||||
|
#define MDM_DSSSCCK_POS 23
|
||||||
|
/// VHT field bit
|
||||||
|
#define MDM_VHT_BIT ((u32)0x00400000)
|
||||||
|
/// VHT field position
|
||||||
|
#define MDM_VHT_POS 22
|
||||||
|
/// HE field bit
|
||||||
|
#define MDM_HE_BIT ((u32)0x00200000)
|
||||||
|
/// HE field position
|
||||||
|
#define MDM_HE_POS 21
|
||||||
|
/// ESS field bit
|
||||||
|
#define MDM_ESS_BIT ((u32)0x00100000)
|
||||||
|
/// ESS field position
|
||||||
|
#define MDM_ESS_POS 20
|
||||||
|
/// RFMODE field mask
|
||||||
|
#define MDM_RFMODE_MASK ((u32)0x000F0000)
|
||||||
|
/// RFMODE field LSB position
|
||||||
|
#define MDM_RFMODE_LSB 16
|
||||||
|
/// RFMODE field width
|
||||||
|
#define MDM_RFMODE_WIDTH ((u32)0x00000004)
|
||||||
|
/// NSTS field mask
|
||||||
|
#define MDM_NSTS_MASK ((u32)0x0000F000)
|
||||||
|
/// NSTS field LSB position
|
||||||
|
#define MDM_NSTS_LSB 12
|
||||||
|
/// NSTS field width
|
||||||
|
#define MDM_NSTS_WIDTH ((u32)0x00000004)
|
||||||
|
/// NSS field mask
|
||||||
|
#define MDM_NSS_MASK ((u32)0x00000F00)
|
||||||
|
/// NSS field LSB position
|
||||||
|
#define MDM_NSS_LSB 8
|
||||||
|
/// NSS field width
|
||||||
|
#define MDM_NSS_WIDTH ((u32)0x00000004)
|
||||||
|
/// NTX field mask
|
||||||
|
#define MDM_NTX_MASK ((u32)0x000000F0)
|
||||||
|
/// NTX field LSB position
|
||||||
|
#define MDM_NTX_LSB 4
|
||||||
|
/// NTX field width
|
||||||
|
#define MDM_NTX_WIDTH ((u32)0x00000004)
|
||||||
|
/// NRX field mask
|
||||||
|
#define MDM_NRX_MASK ((u32)0x0000000F)
|
||||||
|
/// NRX field LSB position
|
||||||
|
#define MDM_NRX_LSB 0
|
||||||
|
/// NRX field width
|
||||||
|
#define MDM_NRX_WIDTH ((u32)0x00000004)
|
||||||
|
|
||||||
|
#define __MDM_PHYCFG_FROM_VERS(v) (((v) & MDM_RFMODE_MASK) >> MDM_RFMODE_LSB)
|
||||||
|
|
||||||
|
#define RIU_FCU_PRESENT_MASK ((u32)0xFF000000)
|
||||||
|
#define RIU_FCU_PRESENT_LSB 24
|
||||||
|
|
||||||
|
#define __RIU_FCU_PRESENT(v) (((v) & RIU_FCU_PRESENT_MASK) >> RIU_FCU_PRESENT_LSB == 5)
|
||||||
|
|
||||||
|
/// AGC load version field mask
|
||||||
|
#define RIU_AGC_LOAD_MASK ((u32)0x00C00000)
|
||||||
|
/// AGC load version field LSB position
|
||||||
|
#define RIU_AGC_LOAD_LSB 22
|
||||||
|
|
||||||
|
#define __RIU_AGCLOAD_FROM_VERS(v) (((v) & RIU_AGC_LOAD_MASK) >> RIU_AGC_LOAD_LSB)
|
||||||
|
|
||||||
|
#define __FPGA_TYPE(v) (((v) & 0xFFFF0000) >> 16)
|
||||||
|
|
||||||
|
#define __MDM_MAJOR_VERSION(v) (((v) & 0xFF000000) >> 24)
|
||||||
|
#define __MDM_MINOR_VERSION(v) (((v) & 0x00FF0000) >> 16)
|
||||||
|
|
||||||
|
|
||||||
|
#endif // _HAL_DESC_H_
|
||||||
25
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/ipc_compat.h
Normal file
25
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/ipc_compat.h
Normal file
|
|
@ -0,0 +1,25 @@
|
||||||
|
/**
|
||||||
|
****************************************************************************************
|
||||||
|
*
|
||||||
|
* @file ipc_compat.h
|
||||||
|
*
|
||||||
|
* Copyright (C) RivieraWaves 2011-2019
|
||||||
|
*
|
||||||
|
****************************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _IPC_H_
|
||||||
|
#define _IPC_H_
|
||||||
|
|
||||||
|
#define __INLINE static __attribute__((__always_inline__)) inline
|
||||||
|
|
||||||
|
#define __ALIGN4 __aligned(4)
|
||||||
|
|
||||||
|
#define ASSERT_ERR(condition) \
|
||||||
|
do { \
|
||||||
|
if (unlikely(!(condition))) { \
|
||||||
|
printk(KERN_ERR "%s:%d:ASSERT_ERR(" #condition ")\n", __FILE__, __LINE__); \
|
||||||
|
} \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
#endif /* _IPC_H_ */
|
||||||
771
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/ipc_host.c
Normal file
771
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/ipc_host.c
Normal file
|
|
@ -0,0 +1,771 @@
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
*
|
||||||
|
* @file ipc_host.c
|
||||||
|
*
|
||||||
|
* @brief IPC module.
|
||||||
|
*
|
||||||
|
* Copyright (C) RivieraWaves 2011-2019
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* INCLUDE FILES
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
#ifndef __KERNEL__
|
||||||
|
#include <stdio.h>
|
||||||
|
#define REG_SW_SET_PROFILING(env, value) do{ }while(0)
|
||||||
|
#define REG_SW_CLEAR_PROFILING(env, value) do{ }while(0)
|
||||||
|
#define REG_SW_CLEAR_HOSTBUF_IDX_PROFILING(env) do{ }while(0)
|
||||||
|
#define REG_SW_SET_HOSTBUF_IDX_PROFILING(env, val) do{ }while(0)
|
||||||
|
#else
|
||||||
|
#include <linux/spinlock.h>
|
||||||
|
#include "rwnx_defs.h"
|
||||||
|
#include "rwnx_prof.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "reg_ipc_app.h"
|
||||||
|
#include "ipc_host.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* TYPES DEFINITION
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
const int nx_txdesc_cnt[] =
|
||||||
|
{
|
||||||
|
NX_TXDESC_CNT0,
|
||||||
|
NX_TXDESC_CNT1,
|
||||||
|
NX_TXDESC_CNT2,
|
||||||
|
NX_TXDESC_CNT3,
|
||||||
|
#if NX_TXQ_CNT == 5
|
||||||
|
NX_TXDESC_CNT4,
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
const int nx_txdesc_cnt_msk[] =
|
||||||
|
{
|
||||||
|
NX_TXDESC_CNT0 - 1,
|
||||||
|
NX_TXDESC_CNT1 - 1,
|
||||||
|
NX_TXDESC_CNT2 - 1,
|
||||||
|
NX_TXDESC_CNT3 - 1,
|
||||||
|
#if NX_TXQ_CNT == 5
|
||||||
|
NX_TXDESC_CNT4 - 1,
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
const int nx_txuser_cnt[] =
|
||||||
|
{
|
||||||
|
CONFIG_USER_MAX,
|
||||||
|
CONFIG_USER_MAX,
|
||||||
|
CONFIG_USER_MAX,
|
||||||
|
CONFIG_USER_MAX,
|
||||||
|
#if NX_TXQ_CNT == 5
|
||||||
|
1,
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* FUNCTIONS DEFINITIONS
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* ipc_host_rxdesc_handler() - Handle the reception of a Rx Descriptor
|
||||||
|
*
|
||||||
|
* @env: pointer to the IPC Host environment
|
||||||
|
*
|
||||||
|
* Called from general IRQ handler when status %IPC_IRQ_E2A_RXDESC is set
|
||||||
|
*/
|
||||||
|
static void ipc_host_rxdesc_handler(struct ipc_host_env_tag *env)
|
||||||
|
{
|
||||||
|
// For profiling
|
||||||
|
REG_SW_SET_PROFILING(env->pthis, SW_PROF_IRQ_E2A_RXDESC);
|
||||||
|
|
||||||
|
// LMAC has triggered an IT saying that a reception has occurred.
|
||||||
|
// Then we first need to check the validity of the current hostbuf, and the validity
|
||||||
|
// of the next hostbufs too, because it is likely that several hostbufs have been
|
||||||
|
// filled within the time needed for this irq handling
|
||||||
|
do {
|
||||||
|
#ifdef CONFIG_RWNX_FULLMAC
|
||||||
|
// call the external function to indicate that a RX descriptor is received
|
||||||
|
if (env->cb.recv_data_ind(env->pthis,
|
||||||
|
env->ipc_host_rxdesc_array[env->ipc_host_rxdesc_idx].hostid) != 0)
|
||||||
|
#else
|
||||||
|
// call the external function to indicate that a RX packet is received
|
||||||
|
if (env->cb.recv_data_ind(env->pthis,
|
||||||
|
env->ipc_host_rxbuf_array[env->ipc_host_rxbuf_idx].hostid) != 0)
|
||||||
|
#endif //(CONFIG_RWNX_FULLMAC)
|
||||||
|
break;
|
||||||
|
|
||||||
|
}while(1);
|
||||||
|
|
||||||
|
// For profiling
|
||||||
|
REG_SW_CLEAR_PROFILING(env->pthis, SW_PROF_IRQ_E2A_RXDESC);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ipc_host_radar_handler() - Handle the reception of radar events
|
||||||
|
*
|
||||||
|
* @env: pointer to the IPC Host environment
|
||||||
|
*
|
||||||
|
* Called from general IRQ handler when status %IPC_IRQ_E2A_RADAR is set
|
||||||
|
*/
|
||||||
|
static void ipc_host_radar_handler(struct ipc_host_env_tag *env)
|
||||||
|
{
|
||||||
|
#ifdef CONFIG_RWNX_RADAR
|
||||||
|
// LMAC has triggered an IT saying that a radar event has been sent to upper layer.
|
||||||
|
// Then we first need to check the validity of the current msg buf, and the validity
|
||||||
|
// of the next buffers too, because it is likely that several buffers have been
|
||||||
|
// filled within the time needed for this irq handling
|
||||||
|
// call the external function to indicate that a RX packet is received
|
||||||
|
spin_lock_bh(&((struct rwnx_hw *)env->pthis)->radar.lock);
|
||||||
|
while (env->cb.recv_radar_ind(env->pthis,
|
||||||
|
env->ipc_host_radarbuf_array[env->ipc_host_radarbuf_idx].hostid) == 0)
|
||||||
|
;
|
||||||
|
spin_unlock_bh(&((struct rwnx_hw *)env->pthis)->radar.lock);
|
||||||
|
#endif /* CONFIG_RWNX_RADAR */
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ipc_host_unsup_rx_vec_handler() - Handle the reception of unsupported rx vector
|
||||||
|
*
|
||||||
|
* @env: pointer to the IPC Host environment
|
||||||
|
*
|
||||||
|
* Called from general IRQ handler when status %IPC_IRQ_E2A_UNSUP_RX_VEC is set
|
||||||
|
*/
|
||||||
|
static void ipc_host_unsup_rx_vec_handler(struct ipc_host_env_tag *env)
|
||||||
|
{
|
||||||
|
while (env->cb.recv_unsup_rx_vec_ind(env->pthis,
|
||||||
|
env->ipc_host_unsuprxvecbuf_array[env->ipc_host_unsuprxvecbuf_idx].hostid) == 0)
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ipc_host_msg_handler() - Handler for firmware message
|
||||||
|
*
|
||||||
|
* @env: pointer to the IPC Host environment
|
||||||
|
*
|
||||||
|
* Called from general IRQ handler when status %IPC_IRQ_E2A_MSG is set
|
||||||
|
*/
|
||||||
|
static void ipc_host_msg_handler(struct ipc_host_env_tag *env)
|
||||||
|
{
|
||||||
|
// For profiling
|
||||||
|
REG_SW_SET_PROFILING(env->pthis, SW_PROF_IRQ_E2A_MSG);
|
||||||
|
|
||||||
|
// LMAC has triggered an IT saying that a message has been sent to upper layer.
|
||||||
|
// Then we first need to check the validity of the current msg buf, and the validity
|
||||||
|
// of the next buffers too, because it is likely that several buffers have been
|
||||||
|
// filled within the time needed for this irq handling
|
||||||
|
// call the external function to indicate that a RX packet is received
|
||||||
|
while (env->cb.recv_msg_ind(env->pthis,
|
||||||
|
env->ipc_host_msgbuf_array[env->ipc_host_msge2a_idx].hostid) == 0)
|
||||||
|
;
|
||||||
|
|
||||||
|
|
||||||
|
// For profiling
|
||||||
|
REG_SW_CLEAR_PROFILING(env->pthis, SW_PROF_IRQ_E2A_MSG);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ipc_host_msgack_handler() - Handle the reception of message acknowledgement
|
||||||
|
*
|
||||||
|
* @env: pointer to the IPC Host environment
|
||||||
|
*
|
||||||
|
* Called from general IRQ handler when status %IPC_IRQ_E2A_MSG_ACK is set
|
||||||
|
*/
|
||||||
|
static void ipc_host_msgack_handler(struct ipc_host_env_tag *env)
|
||||||
|
{
|
||||||
|
void *hostid = env->msga2e_hostid;
|
||||||
|
|
||||||
|
ASSERT_ERR(hostid);
|
||||||
|
ASSERT_ERR(env->msga2e_cnt == (((struct lmac_msg *)(&env->shared->msg_a2e_buf.msg))->src_id & 0xFF));
|
||||||
|
|
||||||
|
env->msga2e_hostid = NULL;
|
||||||
|
env->msga2e_cnt++;
|
||||||
|
env->cb.recv_msgack_ind(env->pthis, hostid);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ipc_host_dbg_handler() - Handle the reception of Debug event
|
||||||
|
*
|
||||||
|
* @env: pointer to the IPC Host environment
|
||||||
|
*
|
||||||
|
* Called from general IRQ handler when status %IPC_IRQ_E2A_DBG is set
|
||||||
|
*/
|
||||||
|
static void ipc_host_dbg_handler(struct ipc_host_env_tag *env)
|
||||||
|
{
|
||||||
|
// For profiling
|
||||||
|
REG_SW_SET_PROFILING(env->pthis, SW_PROF_IRQ_E2A_DBG);
|
||||||
|
|
||||||
|
// LMAC has triggered an IT saying that a DBG message has been sent to upper layer.
|
||||||
|
// Then we first need to check the validity of the current buffer, and the validity
|
||||||
|
// of the next buffers too, because it is likely that several buffers have been
|
||||||
|
// filled within the time needed for this irq handling
|
||||||
|
// call the external function to indicate that a RX packet is received
|
||||||
|
while(env->cb.recv_dbg_ind(env->pthis,
|
||||||
|
env->ipc_host_dbgbuf_array[env->ipc_host_dbg_idx].hostid) == 0)
|
||||||
|
;
|
||||||
|
|
||||||
|
// For profiling
|
||||||
|
REG_SW_CLEAR_PROFILING(env->pthis, SW_PROF_IRQ_E2A_DBG);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ipc_host_tx_cfm_handler() - Handle the reception of TX confirmation
|
||||||
|
*
|
||||||
|
* @env: pointer to the IPC Host environment
|
||||||
|
* @queue_idx: index of the hardware on which the confirmation has been received
|
||||||
|
* @user_pos: index of the user position
|
||||||
|
*
|
||||||
|
* Called from general IRQ handler when status %IPC_IRQ_E2A_TXCFM is set
|
||||||
|
*/
|
||||||
|
static void ipc_host_tx_cfm_handler(struct ipc_host_env_tag *env,
|
||||||
|
const int queue_idx, const int user_pos)
|
||||||
|
{
|
||||||
|
// TX confirmation descriptors have been received
|
||||||
|
REG_SW_SET_PROFILING(env->pthis, SW_PROF_IRQ_E2A_TXCFM);
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
// Get the used index and increase it. We do the increase before knowing if the
|
||||||
|
// current buffer is confirmed because the callback function may call the
|
||||||
|
// ipc_host_txdesc_get() in case flow control was enabled and the index has to be
|
||||||
|
// already at the good value to ensure that the test of FIFO full is correct
|
||||||
|
uint32_t used_idx = env->txdesc_used_idx[queue_idx][user_pos]++;
|
||||||
|
uint32_t used_idx_mod = used_idx & nx_txdesc_cnt_msk[queue_idx];
|
||||||
|
void *host_id = env->tx_host_id[queue_idx][user_pos][used_idx_mod];
|
||||||
|
|
||||||
|
// Reset the host id in the array
|
||||||
|
env->tx_host_id[queue_idx][user_pos][used_idx_mod] = 0;
|
||||||
|
|
||||||
|
// call the external function to indicate that a TX packet is freed
|
||||||
|
if (host_id == 0)
|
||||||
|
{
|
||||||
|
// No more confirmations, so put back the used index at its initial value
|
||||||
|
env->txdesc_used_idx[queue_idx][user_pos] = used_idx;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (env->cb.send_data_cfm(env->pthis, host_id) != 0)
|
||||||
|
{
|
||||||
|
// No more confirmations, so put back the used index at its initial value
|
||||||
|
env->txdesc_used_idx[queue_idx][user_pos] = used_idx;
|
||||||
|
env->tx_host_id[queue_idx][user_pos][used_idx_mod] = host_id;
|
||||||
|
// and exit the loop
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
REG_SW_SET_PROFILING_CHAN(env->pthis, SW_PROF_CHAN_CTXT_CFM_HDL_BIT);
|
||||||
|
REG_SW_CLEAR_PROFILING_CHAN(env->pthis, SW_PROF_CHAN_CTXT_CFM_HDL_BIT);
|
||||||
|
}
|
||||||
|
|
||||||
|
REG_SW_CLEAR_PROFILING(env->pthis, SW_PROF_IRQ_E2A_TXCFM);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
bool ipc_host_tx_frames_pending(struct ipc_host_env_tag *env)
|
||||||
|
{
|
||||||
|
int i, j;
|
||||||
|
bool tx_frames_pending = false;
|
||||||
|
|
||||||
|
for (i = 0; (i < IPC_TXQUEUE_CNT) && !tx_frames_pending; i++)
|
||||||
|
{
|
||||||
|
for (j = 0; j < nx_txuser_cnt[i]; j++)
|
||||||
|
{
|
||||||
|
uint32_t used_idx = env->txdesc_used_idx[i][j];
|
||||||
|
uint32_t free_idx = env->txdesc_free_idx[i][j];
|
||||||
|
|
||||||
|
// Check if this queue is empty or not
|
||||||
|
if (used_idx != free_idx)
|
||||||
|
{
|
||||||
|
// The queue is not empty, update the flag and exit
|
||||||
|
tx_frames_pending = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (tx_frames_pending);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
void *ipc_host_tx_flush(struct ipc_host_env_tag *env, const int queue_idx, const int user_pos)
|
||||||
|
{
|
||||||
|
uint32_t used_idx = env->txdesc_used_idx[queue_idx][user_pos];
|
||||||
|
void *host_id = env->tx_host_id[queue_idx][user_pos][used_idx & nx_txdesc_cnt_msk[queue_idx]];
|
||||||
|
|
||||||
|
// call the external function to indicate that a TX packet is freed
|
||||||
|
if (host_id != 0)
|
||||||
|
{
|
||||||
|
// Reset the host id in the array
|
||||||
|
env->tx_host_id[queue_idx][user_pos][used_idx & nx_txdesc_cnt_msk[queue_idx]] = 0;
|
||||||
|
|
||||||
|
// Increment the used index
|
||||||
|
env->txdesc_used_idx[queue_idx][user_pos]++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (host_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
void ipc_host_init(struct ipc_host_env_tag *env,
|
||||||
|
struct ipc_host_cb_tag *cb,
|
||||||
|
struct ipc_shared_env_tag *shared_env_ptr,
|
||||||
|
void *pthis)
|
||||||
|
{
|
||||||
|
unsigned int i;
|
||||||
|
unsigned int size;
|
||||||
|
unsigned int * dst;
|
||||||
|
|
||||||
|
// Reset the environments
|
||||||
|
// Reset the IPC Shared memory
|
||||||
|
#if 0
|
||||||
|
/* check potential platform bug on multiple stores */
|
||||||
|
memset(shared_env_ptr, 0, sizeof(struct ipc_shared_env_tag));
|
||||||
|
#else
|
||||||
|
dst = (unsigned int *)shared_env_ptr;
|
||||||
|
size = (unsigned int)sizeof(struct ipc_shared_env_tag);
|
||||||
|
for (i=0; i < size; i+=4)
|
||||||
|
{
|
||||||
|
*dst++ = 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
// Reset the IPC Host environment
|
||||||
|
memset(env, 0, sizeof(struct ipc_host_env_tag));
|
||||||
|
|
||||||
|
// Initialize the shared environment pointer
|
||||||
|
env->shared = shared_env_ptr;
|
||||||
|
|
||||||
|
// Save the callbacks in our own environment
|
||||||
|
env->cb = *cb;
|
||||||
|
|
||||||
|
// Save the pointer to the register base
|
||||||
|
env->pthis = pthis;
|
||||||
|
|
||||||
|
// Initialize buffers numbers and buffers sizes needed for DMA Receptions
|
||||||
|
env->rx_bufnb = IPC_RXBUF_CNT;
|
||||||
|
#ifdef CONFIG_RWNX_FULLMAC
|
||||||
|
env->rxdesc_nb = IPC_RXDESC_CNT;
|
||||||
|
#endif //(CONFIG_RWNX_FULLMAC)
|
||||||
|
env->radar_bufnb = IPC_RADARBUF_CNT;
|
||||||
|
env->radar_bufsz = sizeof(struct radar_pulse_array_desc);
|
||||||
|
env->unsuprxvec_bufnb = IPC_UNSUPRXVECBUF_CNT;
|
||||||
|
env->unsuprxvec_bufsz = max(sizeof(struct rx_vector_desc), (size_t) RADIOTAP_HDR_MAX_LEN) +
|
||||||
|
RADIOTAP_HDR_VEND_MAX_LEN + UNSUP_RX_VEC_DATA_LEN;
|
||||||
|
env->ipc_e2amsg_bufnb = IPC_MSGE2A_BUF_CNT;
|
||||||
|
env->ipc_e2amsg_bufsz = sizeof(struct ipc_e2a_msg);
|
||||||
|
env->ipc_dbg_bufnb = IPC_DBGBUF_CNT;
|
||||||
|
env->ipc_dbg_bufsz = sizeof(struct ipc_dbg_msg);
|
||||||
|
|
||||||
|
for (i = 0; i < CONFIG_USER_MAX; i++)
|
||||||
|
{
|
||||||
|
// Initialize the pointers to the hostid arrays
|
||||||
|
env->tx_host_id[0][i] = env->tx_host_id0[i];
|
||||||
|
env->tx_host_id[1][i] = env->tx_host_id1[i];
|
||||||
|
env->tx_host_id[2][i] = env->tx_host_id2[i];
|
||||||
|
env->tx_host_id[3][i] = env->tx_host_id3[i];
|
||||||
|
#if NX_TXQ_CNT == 5
|
||||||
|
env->tx_host_id[4][i] = NULL;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Initialize the pointers to the TX descriptor arrays
|
||||||
|
env->txdesc[0][i] = shared_env_ptr->txdesc0[i];
|
||||||
|
env->txdesc[1][i] = shared_env_ptr->txdesc1[i];
|
||||||
|
env->txdesc[2][i] = shared_env_ptr->txdesc2[i];
|
||||||
|
env->txdesc[3][i] = shared_env_ptr->txdesc3[i];
|
||||||
|
#if NX_TXQ_CNT == 5
|
||||||
|
env->txdesc[4][i] = NULL;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#if NX_TXQ_CNT == 5
|
||||||
|
env->tx_host_id[4][0] = env->tx_host_id4[0];
|
||||||
|
env->txdesc[4][0] = shared_env_ptr->txdesc4[0];
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
void ipc_host_patt_addr_push(struct ipc_host_env_tag *env, uint32_t addr)
|
||||||
|
{
|
||||||
|
struct ipc_shared_env_tag *shared_env_ptr = env->shared;
|
||||||
|
|
||||||
|
// Copy the address
|
||||||
|
shared_env_ptr->pattern_addr = addr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
int ipc_host_rxbuf_push(struct ipc_host_env_tag *env,
|
||||||
|
#ifdef CONFIG_RWNX_FULLMAC
|
||||||
|
uint32_t hostid,
|
||||||
|
#endif
|
||||||
|
uint32_t hostbuf)
|
||||||
|
{
|
||||||
|
struct ipc_shared_env_tag *shared_env_ptr = env->shared;
|
||||||
|
|
||||||
|
REG_SW_CLEAR_HOSTBUF_IDX_PROFILING(env->pthis);
|
||||||
|
REG_SW_SET_HOSTBUF_IDX_PROFILING(env->pthis, env->ipc_host_rxbuf_idx);
|
||||||
|
|
||||||
|
#ifdef CONFIG_RWNX_FULLMAC
|
||||||
|
// Copy the hostbuf (DMA address) in the ipc shared memory
|
||||||
|
shared_env_ptr->host_rxbuf[env->ipc_host_rxbuf_idx].hostid = hostid;
|
||||||
|
shared_env_ptr->host_rxbuf[env->ipc_host_rxbuf_idx].dma_addr = hostbuf;
|
||||||
|
#else
|
||||||
|
// Save the hostid and the hostbuf in global array
|
||||||
|
env->ipc_host_rxbuf_array[env->ipc_host_rxbuf_idx].hostid = hostid;
|
||||||
|
env->ipc_host_rxbuf_array[env->ipc_host_rxbuf_idx].dma_addr = hostbuf;
|
||||||
|
|
||||||
|
shared_env_ptr->host_rxbuf[env->ipc_host_rxbuf_idx] = hostbuf;
|
||||||
|
#endif //(CONFIG_RWNX_FULLMAC)
|
||||||
|
|
||||||
|
// Signal to the embedded CPU that at least one buffer is available
|
||||||
|
ipc_app2emb_trigger_set(shared_env_ptr, IPC_IRQ_A2E_RXBUF_BACK);
|
||||||
|
|
||||||
|
// Increment the array index
|
||||||
|
env->ipc_host_rxbuf_idx = (env->ipc_host_rxbuf_idx +1)%IPC_RXBUF_CNT;
|
||||||
|
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_RWNX_FULLMAC
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
int ipc_host_rxdesc_push(struct ipc_host_env_tag *env, void *hostid,
|
||||||
|
uint32_t hostbuf)
|
||||||
|
{
|
||||||
|
struct ipc_shared_env_tag *shared_env_ptr = env->shared;
|
||||||
|
|
||||||
|
// Reset the RX Descriptor DMA Address and increment the counter
|
||||||
|
env->ipc_host_rxdesc_array[env->ipc_host_rxdesc_idx].dma_addr = hostbuf;
|
||||||
|
env->ipc_host_rxdesc_array[env->ipc_host_rxdesc_idx].hostid = hostid;
|
||||||
|
|
||||||
|
shared_env_ptr->host_rxdesc[env->ipc_host_rxdesc_idx].dma_addr = hostbuf;
|
||||||
|
|
||||||
|
// Signal to the embedded CPU that at least one descriptor is available
|
||||||
|
ipc_app2emb_trigger_set(shared_env_ptr, IPC_IRQ_A2E_RXDESC_BACK);
|
||||||
|
|
||||||
|
env->ipc_host_rxdesc_idx = (env->ipc_host_rxdesc_idx + 1) % IPC_RXDESC_CNT;
|
||||||
|
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_RWNX_FULLMAC */
|
||||||
|
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
int ipc_host_radarbuf_push(struct ipc_host_env_tag *env, void *hostid,
|
||||||
|
uint32_t hostbuf)
|
||||||
|
{
|
||||||
|
struct ipc_shared_env_tag *shared_env_ptr = env->shared;
|
||||||
|
|
||||||
|
// Save the hostid and the hostbuf in global array
|
||||||
|
env->ipc_host_radarbuf_array[env->ipc_host_radarbuf_idx].hostid = hostid;
|
||||||
|
env->ipc_host_radarbuf_array[env->ipc_host_radarbuf_idx].dma_addr = hostbuf;
|
||||||
|
|
||||||
|
// Copy the hostbuf (DMA address) in the ipc shared memory
|
||||||
|
shared_env_ptr->radarbuf_hostbuf[env->ipc_host_radarbuf_idx] = hostbuf;
|
||||||
|
|
||||||
|
// Increment the array index
|
||||||
|
env->ipc_host_radarbuf_idx = (env->ipc_host_radarbuf_idx +1)%IPC_RADARBUF_CNT;
|
||||||
|
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
int ipc_host_unsup_rx_vec_buf_push(struct ipc_host_env_tag *env,
|
||||||
|
void *hostid,
|
||||||
|
uint32_t hostbuf)
|
||||||
|
{
|
||||||
|
struct ipc_shared_env_tag *shared_env_ptr = env->shared;
|
||||||
|
|
||||||
|
env->ipc_host_unsuprxvecbuf_array[env->ipc_host_unsuprxvecbuf_idx].hostid = hostid;
|
||||||
|
env->ipc_host_unsuprxvecbuf_array[env->ipc_host_unsuprxvecbuf_idx].dma_addr = hostbuf;
|
||||||
|
|
||||||
|
// Copy the hostbuf (DMA address) in the ipc shared memory
|
||||||
|
shared_env_ptr->unsuprxvecbuf_hostbuf[env->ipc_host_unsuprxvecbuf_idx] = hostbuf;
|
||||||
|
|
||||||
|
// Increment the array index
|
||||||
|
env->ipc_host_unsuprxvecbuf_idx = (env->ipc_host_unsuprxvecbuf_idx + 1)%IPC_UNSUPRXVECBUF_CNT;
|
||||||
|
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
int ipc_host_msgbuf_push(struct ipc_host_env_tag *env, void *hostid,
|
||||||
|
uint32_t hostbuf)
|
||||||
|
{
|
||||||
|
struct ipc_shared_env_tag *shared_env_ptr = env->shared;
|
||||||
|
|
||||||
|
// Save the hostid and the hostbuf in global array
|
||||||
|
env->ipc_host_msgbuf_array[env->ipc_host_msge2a_idx].hostid = hostid;
|
||||||
|
env->ipc_host_msgbuf_array[env->ipc_host_msge2a_idx].dma_addr = hostbuf;
|
||||||
|
|
||||||
|
// Copy the hostbuf (DMA address) in the ipc shared memory
|
||||||
|
shared_env_ptr->msg_e2a_hostbuf_addr[env->ipc_host_msge2a_idx] = hostbuf;
|
||||||
|
|
||||||
|
// Increment the array index
|
||||||
|
env->ipc_host_msge2a_idx = (env->ipc_host_msge2a_idx +1)%IPC_MSGE2A_BUF_CNT;
|
||||||
|
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
int ipc_host_dbgbuf_push(struct ipc_host_env_tag *env, void *hostid,
|
||||||
|
uint32_t hostbuf)
|
||||||
|
{
|
||||||
|
struct ipc_shared_env_tag *shared_env_ptr = env->shared;
|
||||||
|
|
||||||
|
// Save the hostid and the hostbuf in global array
|
||||||
|
env->ipc_host_dbgbuf_array[env->ipc_host_dbg_idx].hostid = hostid;
|
||||||
|
env->ipc_host_dbgbuf_array[env->ipc_host_dbg_idx].dma_addr = hostbuf;
|
||||||
|
|
||||||
|
// Copy the hostbuf (DMA address) in the ipc shared memory
|
||||||
|
shared_env_ptr->dbg_hostbuf_addr[env->ipc_host_dbg_idx] = hostbuf;
|
||||||
|
|
||||||
|
// Increment the array index
|
||||||
|
env->ipc_host_dbg_idx = (env->ipc_host_dbg_idx +1)%IPC_DBGBUF_CNT;
|
||||||
|
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
void ipc_host_dbginfobuf_push(struct ipc_host_env_tag *env, uint32_t infobuf)
|
||||||
|
{
|
||||||
|
struct ipc_shared_env_tag *shared_env_ptr = env->shared;
|
||||||
|
|
||||||
|
// Copy the hostbuf (DMA address) in the ipc shared memory
|
||||||
|
shared_env_ptr->la_dbginfo_addr = infobuf;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
volatile struct txdesc_host *ipc_host_txdesc_get(struct ipc_host_env_tag *env, const int queue_idx, const int user_pos)
|
||||||
|
{
|
||||||
|
volatile struct txdesc_host *txdesc_free;
|
||||||
|
uint32_t used_idx = env->txdesc_used_idx[queue_idx][user_pos];
|
||||||
|
uint32_t free_idx = env->txdesc_free_idx[queue_idx][user_pos];
|
||||||
|
|
||||||
|
ASSERT_ERR(queue_idx < IPC_TXQUEUE_CNT);
|
||||||
|
ASSERT_ERR((free_idx - used_idx) <= nx_txdesc_cnt[queue_idx]);
|
||||||
|
|
||||||
|
// Check if a free descriptor is available
|
||||||
|
if (free_idx != (used_idx + nx_txdesc_cnt[queue_idx]))
|
||||||
|
{
|
||||||
|
// Get the pointer to the first free descriptor
|
||||||
|
txdesc_free = env->txdesc[queue_idx][user_pos] + (free_idx & nx_txdesc_cnt_msk[queue_idx]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
txdesc_free = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return txdesc_free;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
void ipc_host_txdesc_push(struct ipc_host_env_tag *env, const int queue_idx,
|
||||||
|
const int user_pos, void *host_id)
|
||||||
|
{
|
||||||
|
uint32_t free_idx = env->txdesc_free_idx[queue_idx][user_pos] & nx_txdesc_cnt_msk[queue_idx];
|
||||||
|
volatile struct txdesc_host *txdesc_pushed = env->txdesc[queue_idx][user_pos] + free_idx;
|
||||||
|
|
||||||
|
|
||||||
|
// Descriptor is now ready
|
||||||
|
txdesc_pushed->ready = 0xFFFFFFFF;
|
||||||
|
|
||||||
|
// Save the host id in the environment
|
||||||
|
env->tx_host_id[queue_idx][user_pos][free_idx] = host_id;
|
||||||
|
|
||||||
|
// Increment the index
|
||||||
|
env->txdesc_free_idx[queue_idx][user_pos]++;
|
||||||
|
|
||||||
|
// trigger interrupt!!!
|
||||||
|
//REG_SW_SET_PROFILING(env->pthis, CO_BIT(queue_idx+SW_PROF_IRQ_A2E_TXDESC_FIRSTBIT));
|
||||||
|
ipc_app2emb_trigger_setf(env->shared, CO_BIT(user_pos + queue_idx * CONFIG_USER_MAX +
|
||||||
|
IPC_IRQ_A2E_TXDESC_FIRSTBIT));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
void ipc_host_irq(struct ipc_host_env_tag *env, uint32_t status)
|
||||||
|
{
|
||||||
|
// Acknowledge the pending interrupts
|
||||||
|
ipc_emb2app_ack_clear(env->shared, status);
|
||||||
|
// And re-read the status, just to be sure that the acknowledgment is
|
||||||
|
// effective when we start the interrupt handling
|
||||||
|
ipc_emb2app_status_get(env->shared);
|
||||||
|
|
||||||
|
// Optimized for only one IRQ at a time
|
||||||
|
if (status & IPC_IRQ_E2A_RXDESC)
|
||||||
|
{
|
||||||
|
// handle the RX descriptor reception
|
||||||
|
ipc_host_rxdesc_handler(env);
|
||||||
|
}
|
||||||
|
if (status & IPC_IRQ_E2A_MSG_ACK)
|
||||||
|
{
|
||||||
|
ipc_host_msgack_handler(env);
|
||||||
|
}
|
||||||
|
if (status & IPC_IRQ_E2A_MSG)
|
||||||
|
{
|
||||||
|
ipc_host_msg_handler(env);
|
||||||
|
}
|
||||||
|
if (status & IPC_IRQ_E2A_TXCFM)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
#ifdef __KERNEL__
|
||||||
|
spin_lock_bh(&((struct rwnx_hw *)env->pthis)->tx_lock);
|
||||||
|
#endif
|
||||||
|
// handle the TX confirmation reception
|
||||||
|
for (i = 0; i < IPC_TXQUEUE_CNT; i++)
|
||||||
|
{
|
||||||
|
int j = 0;
|
||||||
|
#ifdef CONFIG_RWNX_MUMIMO_TX
|
||||||
|
for (; j < nx_txuser_cnt[i]; j++)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
uint32_t q_bit = CO_BIT(j + i * CONFIG_USER_MAX + IPC_IRQ_E2A_TXCFM_POS);
|
||||||
|
if (status & q_bit)
|
||||||
|
{
|
||||||
|
// handle the confirmation
|
||||||
|
ipc_host_tx_cfm_handler(env, i, j);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#ifdef __KERNEL__
|
||||||
|
spin_unlock_bh(&((struct rwnx_hw *)env->pthis)->tx_lock);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
if (status & IPC_IRQ_E2A_RADAR)
|
||||||
|
{
|
||||||
|
// handle the radar event reception
|
||||||
|
ipc_host_radar_handler(env);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (status & IPC_IRQ_E2A_UNSUP_RX_VEC)
|
||||||
|
{
|
||||||
|
// handle the unsupported rx vector reception
|
||||||
|
ipc_host_unsup_rx_vec_handler(env);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (status & IPC_IRQ_E2A_DBG)
|
||||||
|
{
|
||||||
|
ipc_host_dbg_handler(env);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (status & IPC_IRQ_E2A_TBTT_PRIM)
|
||||||
|
{
|
||||||
|
env->cb.prim_tbtt_ind(env->pthis);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (status & IPC_IRQ_E2A_TBTT_SEC)
|
||||||
|
{
|
||||||
|
env->cb.sec_tbtt_ind(env->pthis);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
int ipc_host_msg_push(struct ipc_host_env_tag *env, void *msg_buf, uint16_t len)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
uint32_t *src, *dst;
|
||||||
|
|
||||||
|
REG_SW_SET_PROFILING(env->pthis, SW_PROF_IPC_MSGPUSH);
|
||||||
|
|
||||||
|
ASSERT_ERR(!env->msga2e_hostid);
|
||||||
|
ASSERT_ERR(round_up(len, 4) <= sizeof(env->shared->msg_a2e_buf.msg));
|
||||||
|
|
||||||
|
// Copy the message into the IPC MSG buffer
|
||||||
|
#ifdef __KERNEL__
|
||||||
|
src = (uint32_t*)((struct rwnx_cmd *)msg_buf)->a2e_msg;
|
||||||
|
#else
|
||||||
|
src = (uint32_t*) msg_buf;
|
||||||
|
#endif
|
||||||
|
dst = (uint32_t*)&(env->shared->msg_a2e_buf.msg);
|
||||||
|
|
||||||
|
// Copy the message in the IPC queue
|
||||||
|
for (i=0; i<len; i+=4)
|
||||||
|
{
|
||||||
|
*dst++ = *src++;
|
||||||
|
}
|
||||||
|
|
||||||
|
env->msga2e_hostid = msg_buf;
|
||||||
|
|
||||||
|
// Trigger the irq to send the message to EMB
|
||||||
|
ipc_app2emb_trigger_set(env->shared, IPC_IRQ_A2E_MSG);
|
||||||
|
|
||||||
|
REG_SW_CLEAR_PROFILING(env->pthis, SW_PROF_IPC_MSGPUSH);
|
||||||
|
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
void ipc_host_enable_irq(struct ipc_host_env_tag *env, uint32_t value)
|
||||||
|
{
|
||||||
|
// Enable the handled interrupts
|
||||||
|
ipc_emb2app_unmask_set(env->shared, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
void ipc_host_disable_irq(struct ipc_host_env_tag *env, uint32_t value)
|
||||||
|
{
|
||||||
|
// Enable the handled interrupts
|
||||||
|
ipc_emb2app_unmask_clear(env->shared, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
uint32_t ipc_host_get_status(struct ipc_host_env_tag *env)
|
||||||
|
{
|
||||||
|
volatile uint32_t status;
|
||||||
|
|
||||||
|
status = ipc_emb2app_status_get(env->shared);
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
uint32_t ipc_host_get_rawstatus(struct ipc_host_env_tag *env)
|
||||||
|
{
|
||||||
|
volatile uint32_t rawstatus;
|
||||||
|
|
||||||
|
rawstatus = ipc_emb2app_rawstatus_get(env->shared);
|
||||||
|
|
||||||
|
return rawstatus;
|
||||||
|
}
|
||||||
|
|
||||||
508
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/ipc_host.h
Normal file
508
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/ipc_host.h
Normal file
|
|
@ -0,0 +1,508 @@
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
*
|
||||||
|
* @file ipc_host.h
|
||||||
|
*
|
||||||
|
* @brief IPC module.
|
||||||
|
*
|
||||||
|
* Copyright (C) RivieraWaves 2011-2019
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
#ifndef _IPC_HOST_H_
|
||||||
|
#define _IPC_HOST_H_
|
||||||
|
|
||||||
|
/*
|
||||||
|
* INCLUDE FILES
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
#include "ipc_shared.h"
|
||||||
|
#ifndef __KERNEL__
|
||||||
|
#include "arch.h"
|
||||||
|
#else
|
||||||
|
#include "ipc_compat.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ENUMERATION
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
enum ipc_host_desc_status
|
||||||
|
{
|
||||||
|
/// Descriptor is IDLE
|
||||||
|
IPC_HOST_DESC_IDLE = 0,
|
||||||
|
/// Data can be forwarded
|
||||||
|
IPC_HOST_DESC_FORWARD,
|
||||||
|
/// Data has to be kept in UMAC memory
|
||||||
|
IPC_HOST_DESC_KEEP,
|
||||||
|
/// Delete stored packet
|
||||||
|
IPC_HOST_DESC_DELETE,
|
||||||
|
/// Update Frame Length status
|
||||||
|
IPC_HOST_DESC_LEN_UPDATE,
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* @brief This structure is used to initialize the MAC SW
|
||||||
|
*
|
||||||
|
* The WLAN device driver provides functions call-back with this structure
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
struct ipc_host_cb_tag
|
||||||
|
{
|
||||||
|
/// WLAN driver call-back function: send_data_cfm
|
||||||
|
int (*send_data_cfm)(void *pthis, void *host_id);
|
||||||
|
|
||||||
|
/// WLAN driver call-back function: recv_data_ind
|
||||||
|
uint8_t (*recv_data_ind)(void *pthis, void *host_id);
|
||||||
|
|
||||||
|
/// WLAN driver call-back function: recv_radar_ind
|
||||||
|
uint8_t (*recv_radar_ind)(void *pthis, void *host_id);
|
||||||
|
|
||||||
|
/// WLAN driver call-back function: recv_unsup_rx_vec_ind
|
||||||
|
uint8_t (*recv_unsup_rx_vec_ind)(void *pthis, void *host_id);
|
||||||
|
|
||||||
|
/// WLAN driver call-back function: recv_msg_ind
|
||||||
|
uint8_t (*recv_msg_ind)(void *pthis, void *host_id);
|
||||||
|
|
||||||
|
/// WLAN driver call-back function: recv_msgack_ind
|
||||||
|
uint8_t (*recv_msgack_ind)(void *pthis, void *host_id);
|
||||||
|
|
||||||
|
/// WLAN driver call-back function: recv_dbg_ind
|
||||||
|
uint8_t (*recv_dbg_ind)(void *pthis, void *host_id);
|
||||||
|
|
||||||
|
/// WLAN driver call-back function: prim_tbtt_ind
|
||||||
|
void (*prim_tbtt_ind)(void *pthis);
|
||||||
|
|
||||||
|
/// WLAN driver call-back function: sec_tbtt_ind
|
||||||
|
void (*sec_tbtt_ind)(void *pthis);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Struct used to store information about host buffers (DMA Address and local pointer)
|
||||||
|
*/
|
||||||
|
struct ipc_hostbuf
|
||||||
|
{
|
||||||
|
void *hostid; ///< ptr to hostbuf client (ipc_host client) structure
|
||||||
|
uint32_t dma_addr; ///< ptr to real hostbuf dma address
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Definition of the IPC Host environment structure.
|
||||||
|
struct ipc_host_env_tag
|
||||||
|
{
|
||||||
|
/// Structure containing the callback pointers
|
||||||
|
struct ipc_host_cb_tag cb;
|
||||||
|
|
||||||
|
/// Pointer to the shared environment
|
||||||
|
struct ipc_shared_env_tag *shared;
|
||||||
|
|
||||||
|
#ifdef CONFIG_RWNX_FULLMAC
|
||||||
|
// Array used to store the descriptor addresses
|
||||||
|
struct ipc_hostbuf ipc_host_rxdesc_array[IPC_RXDESC_CNT];
|
||||||
|
// Index of the host RX descriptor array (ipc_shared environment)
|
||||||
|
uint8_t ipc_host_rxdesc_idx;
|
||||||
|
/// Store the number of RX Descriptors
|
||||||
|
uint8_t rxdesc_nb;
|
||||||
|
#endif //(CONFIG_RWNX_FULLMAC)
|
||||||
|
|
||||||
|
/// Fields for Data Rx handling
|
||||||
|
// Index used for ipc_host_rxbuf_array to point to current buffer
|
||||||
|
uint8_t ipc_host_rxbuf_idx;
|
||||||
|
// Store the number of Rx Data buffers
|
||||||
|
uint32_t rx_bufnb;
|
||||||
|
// Store the size of the Rx Data buffers
|
||||||
|
uint32_t rx_bufsz;
|
||||||
|
|
||||||
|
/// Fields for Radar events handling
|
||||||
|
// Global array used to store the hostid and hostbuf addresses
|
||||||
|
struct ipc_hostbuf ipc_host_radarbuf_array[IPC_RADARBUF_CNT];
|
||||||
|
// Index used for ipc_host_rxbuf_array to point to current buffer
|
||||||
|
uint8_t ipc_host_radarbuf_idx;
|
||||||
|
// Store the number of radar event buffers
|
||||||
|
uint32_t radar_bufnb;
|
||||||
|
// Store the size of the radar event buffers
|
||||||
|
uint32_t radar_bufsz;
|
||||||
|
|
||||||
|
///Fields for Unsupported frame handling
|
||||||
|
// Global array used to store the hostid and hostbuf addresses
|
||||||
|
struct ipc_hostbuf ipc_host_unsuprxvecbuf_array[IPC_UNSUPRXVECBUF_CNT];
|
||||||
|
// Index used for ipc_host_unsuprxvecbuf_array to point to current buffer
|
||||||
|
uint8_t ipc_host_unsuprxvecbuf_idx;
|
||||||
|
// Store the number of unsupported rx vector buffers
|
||||||
|
uint32_t unsuprxvec_bufnb;
|
||||||
|
// Store the size of unsupported rx vector buffers
|
||||||
|
uint32_t unsuprxvec_bufsz;
|
||||||
|
|
||||||
|
// Index used that points to the first free TX desc
|
||||||
|
uint32_t txdesc_free_idx[IPC_TXQUEUE_CNT][CONFIG_USER_MAX];
|
||||||
|
// Index used that points to the first used TX desc
|
||||||
|
uint32_t txdesc_used_idx[IPC_TXQUEUE_CNT][CONFIG_USER_MAX];
|
||||||
|
// Array storing the currently pushed host ids for the BK queue
|
||||||
|
void *tx_host_id0[CONFIG_USER_MAX][NX_TXDESC_CNT0];
|
||||||
|
// Array storing the currently pushed host ids for the BE queue
|
||||||
|
void *tx_host_id1[CONFIG_USER_MAX][NX_TXDESC_CNT1];
|
||||||
|
// Array storing the currently pushed host ids for the VI queue
|
||||||
|
void *tx_host_id2[CONFIG_USER_MAX][NX_TXDESC_CNT2];
|
||||||
|
// Array storing the currently pushed host ids for the VO queue
|
||||||
|
void *tx_host_id3[CONFIG_USER_MAX][NX_TXDESC_CNT3];
|
||||||
|
#if NX_TXQ_CNT == 5
|
||||||
|
// Array storing the currently pushed host ids for the BCN queue
|
||||||
|
void *tx_host_id4[1][NX_TXDESC_CNT4];
|
||||||
|
#endif
|
||||||
|
// Pointer to the different host ids arrays, per IPC queue
|
||||||
|
void **tx_host_id[IPC_TXQUEUE_CNT][CONFIG_USER_MAX];
|
||||||
|
// Pointer to the different TX descriptor arrays, per IPC queue
|
||||||
|
volatile struct txdesc_host *txdesc[IPC_TXQUEUE_CNT][CONFIG_USER_MAX];
|
||||||
|
|
||||||
|
/// Fields for Emb->App MSGs handling
|
||||||
|
// Global array used to store the hostid and hostbuf addresses for msg/ind
|
||||||
|
struct ipc_hostbuf ipc_host_msgbuf_array[IPC_MSGE2A_BUF_CNT];
|
||||||
|
// Index of the MSG E2A buffers array to point to current buffer
|
||||||
|
uint8_t ipc_host_msge2a_idx;
|
||||||
|
// Store the number of E2A MSG buffers
|
||||||
|
uint32_t ipc_e2amsg_bufnb;
|
||||||
|
// Store the size of the E2A MSG buffers
|
||||||
|
uint32_t ipc_e2amsg_bufsz;
|
||||||
|
|
||||||
|
/// E2A ACKs of A2E MSGs
|
||||||
|
uint8_t msga2e_cnt;
|
||||||
|
void *msga2e_hostid;
|
||||||
|
|
||||||
|
/// Fields for Debug MSGs handling
|
||||||
|
// Global array used to store the hostid and hostbuf addresses for Debug messages
|
||||||
|
struct ipc_hostbuf ipc_host_dbgbuf_array[IPC_DBGBUF_CNT];
|
||||||
|
// Index of the Debug messages buffers array to point to current buffer
|
||||||
|
uint8_t ipc_host_dbg_idx;
|
||||||
|
// Store the number of Debug messages buffers
|
||||||
|
uint32_t ipc_dbg_bufnb;
|
||||||
|
// Store the size of the Debug messages buffers
|
||||||
|
uint32_t ipc_dbg_bufsz;
|
||||||
|
|
||||||
|
/// Pointer to the attached object (used in callbacks and register accesses)
|
||||||
|
void *pthis;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern const int nx_txdesc_cnt[];
|
||||||
|
extern const int nx_txuser_cnt[];
|
||||||
|
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* @brief Returns the full/not full status of the queue the index of which is
|
||||||
|
* passed as parameter.
|
||||||
|
*
|
||||||
|
* @param[in] env Pointer to the IPC host environment
|
||||||
|
* @param[in] queue_idx Index of the queue to be checked
|
||||||
|
*
|
||||||
|
* @return true if the queue is full, false otherwise
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
__INLINE bool ipc_host_queue_full(struct ipc_host_env_tag *env,
|
||||||
|
const int queue_idx)
|
||||||
|
{
|
||||||
|
return (env->txdesc_free_idx[queue_idx] ==
|
||||||
|
(env->txdesc_used_idx[queue_idx] + nx_txdesc_cnt[queue_idx]));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* @brief Initialize the IPC running on the Application CPU.
|
||||||
|
*
|
||||||
|
* This function:
|
||||||
|
* - initializes the IPC software environments
|
||||||
|
* - enables the interrupts in the IPC block
|
||||||
|
*
|
||||||
|
* @param[in] env Pointer to the IPC host environment
|
||||||
|
*
|
||||||
|
* @warning Since this function resets the IPC Shared memory, it must be called
|
||||||
|
* before the LMAC FW is launched because LMAC sets some init values in IPC
|
||||||
|
* Shared memory at boot.
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
void ipc_host_init(struct ipc_host_env_tag *env,
|
||||||
|
struct ipc_host_cb_tag *cb,
|
||||||
|
struct ipc_shared_env_tag *shared_env_ptr,
|
||||||
|
void *pthis);
|
||||||
|
|
||||||
|
/** @addtogroup IPC_TX
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* @brief Retrieve a new free Tx descriptor (host side).
|
||||||
|
*
|
||||||
|
* This function returns a pointer to the next Tx descriptor available from the
|
||||||
|
* queue queue_idx to the host driver. The driver will have to fill it with the
|
||||||
|
* appropriate endianness and to send it to the
|
||||||
|
* emb side with ipc_host_txdesc_push().
|
||||||
|
*
|
||||||
|
* This function should only be called once until ipc_host_txdesc_push() is called.
|
||||||
|
*
|
||||||
|
* This function will return NULL if the queue is full.
|
||||||
|
*
|
||||||
|
* @param[in] env Pointer to the IPC host environment
|
||||||
|
* @param[in] queue_idx Queue index. The index can be inferred from the
|
||||||
|
* user priority of the incoming packet.
|
||||||
|
* @param[in] user_pos User position. If MU-MIMO is not used, this value
|
||||||
|
* shall be 0.
|
||||||
|
* @return Pointer to the next Tx descriptor free. This can
|
||||||
|
* point to the host memory or to shared memory,
|
||||||
|
* depending on IPC implementation.
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
volatile struct txdesc_host *ipc_host_txdesc_get(struct ipc_host_env_tag *env,
|
||||||
|
const int queue_idx,
|
||||||
|
const int user_pos);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* @brief Push a filled Tx descriptor (host side).
|
||||||
|
*
|
||||||
|
* This function sets the next Tx descriptor available by the host side:
|
||||||
|
* - as used for the host side
|
||||||
|
* - as available for the emb side.
|
||||||
|
* The Tx descriptor must be correctly filled before calling this function.
|
||||||
|
*
|
||||||
|
* This function may trigger an IRQ to the emb CPU depending on the interrupt
|
||||||
|
* mitigation policy and on the push count.
|
||||||
|
*
|
||||||
|
* @param[in] env Pointer to the IPC host environment
|
||||||
|
* @param[in] queue_idx Queue index. Same value than ipc_host_txdesc_get()
|
||||||
|
* @param[in] user_pos User position. If MU-MIMO is not used, this value
|
||||||
|
* shall be 0.
|
||||||
|
* @param[in] host_id Parameter indicated by the IPC at TX confirmation,
|
||||||
|
* that allows the driver finding the buffer
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
void ipc_host_txdesc_push(struct ipc_host_env_tag *env, const int queue_idx,
|
||||||
|
const int user_pos, void *host_id);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* @brief Check if there are TX frames pending in the TX queues.
|
||||||
|
*
|
||||||
|
* @param[in] env Pointer to the IPC host environment
|
||||||
|
*
|
||||||
|
* @return true if there are frames pending, false otherwise.
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
bool ipc_host_tx_frames_pending(struct ipc_host_env_tag *env);
|
||||||
|
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* @brief Get and flush a packet from the IPC queue passed as parameter.
|
||||||
|
*
|
||||||
|
* @param[in] env Pointer to the IPC host environment
|
||||||
|
* @param[in] queue_idx Index of the queue to flush
|
||||||
|
* @param[in] user_pos User position to flush
|
||||||
|
*
|
||||||
|
* @return The flushed hostid if there is one, 0 otherwise.
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
void *ipc_host_tx_flush(struct ipc_host_env_tag *env, const int queue_idx,
|
||||||
|
const int user_pos);
|
||||||
|
|
||||||
|
/// @} IPC_TX
|
||||||
|
|
||||||
|
/** @addtogroup IPC_RX
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
void ipc_host_patt_addr_push(struct ipc_host_env_tag *env, uint32_t addr);
|
||||||
|
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* @brief Push a pre-allocated buffer descriptor for Rx packet (host side)
|
||||||
|
*
|
||||||
|
* This function should be called by the host IRQ handler to supply the
|
||||||
|
* embedded side with new empty buffer.
|
||||||
|
*
|
||||||
|
* @param[in] env Pointer to the IPC host environment
|
||||||
|
* @param[in] hostid Packet ID used by the host (skbuff pointer on Linux)
|
||||||
|
* @param[in] hostbuf Pointer to the start of the buffer payload in the
|
||||||
|
* host memory (this may be inferred from the skbuff?)
|
||||||
|
* The length of this buffer should be predefined
|
||||||
|
* between host and emb statically (constant needed?).
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
int ipc_host_rxbuf_push(struct ipc_host_env_tag *env,
|
||||||
|
#ifdef CONFIG_RWNX_FULLMAC
|
||||||
|
uint32_t hostid,
|
||||||
|
#endif
|
||||||
|
uint32_t hostbuf);
|
||||||
|
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* @brief Push a pre-allocated Descriptor
|
||||||
|
*
|
||||||
|
* This function should be called by the host IRQ handler to supply the
|
||||||
|
* embedded side with new empty buffer.
|
||||||
|
*
|
||||||
|
* @param[in] env Pointer to the IPC host environment
|
||||||
|
* @param[in] hostid Address of packet for host
|
||||||
|
* @param[in] hostbuf Pointer to the start of the buffer payload in the
|
||||||
|
* host memory. The length of this buffer should be
|
||||||
|
* predefined between host and emb statically.
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
int ipc_host_rxdesc_push(struct ipc_host_env_tag *env, void *hostid,
|
||||||
|
uint32_t hostbuf);
|
||||||
|
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* @brief Push a pre-allocated radar event buffer descriptor
|
||||||
|
*
|
||||||
|
* This function is called at Init time to initialize all radar event buffers.
|
||||||
|
* Then each time embedded send a radar event, this function is used to push
|
||||||
|
* back the same buffer once it has been handled.
|
||||||
|
*
|
||||||
|
* @param[in] env Pointer to the IPC host environment
|
||||||
|
* @param[in] hostid Address of packet for host
|
||||||
|
* @param[in] hostbuf Pointer to the start of the buffer payload in the
|
||||||
|
* host memory. The length of this buffer should be
|
||||||
|
* predefined between host and emb statically.
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
int ipc_host_radarbuf_push(struct ipc_host_env_tag *env, void *hostid,
|
||||||
|
uint32_t hostbuf);
|
||||||
|
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* @brief Push a pre-allocated unsupported rx vector buffer descriptor
|
||||||
|
*
|
||||||
|
* This function is called at Init time to initialize all unsupported rx vector
|
||||||
|
* buffers. Then each time the embedded sends a unsupported rx vector, this
|
||||||
|
* function is used to push a new unsupported rx vector buffer.
|
||||||
|
*
|
||||||
|
* @param[in] env Pointer to the IPC host environment
|
||||||
|
* @param[in] hostid Address of packet for host
|
||||||
|
* @param[in] hostbuf Pointer to the start of the buffer payload in the
|
||||||
|
* host memory. The length of this buffer should be
|
||||||
|
* predefined between host and emb statically.
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
int ipc_host_unsup_rx_vec_buf_push(struct ipc_host_env_tag *env, void *hostid,
|
||||||
|
uint32_t hostbuf);
|
||||||
|
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* @brief Push a pre-allocated buffer descriptor for IPC MSGs (host side)
|
||||||
|
*
|
||||||
|
* This function is called at Init time to initialize all Emb2App messages
|
||||||
|
* buffers. Then each time embedded send a IPC message, this function is used
|
||||||
|
* to push back the same buffer once it has been handled.
|
||||||
|
*
|
||||||
|
* @param[in] env Pointer to the IPC host environment
|
||||||
|
* @param[in] hostid Address of buffer for host
|
||||||
|
* @param[in] hostbuf Address of buffer for embedded
|
||||||
|
* The length of this buffer should be predefined
|
||||||
|
* between host and emb statically.
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
int ipc_host_msgbuf_push(struct ipc_host_env_tag *env, void *hostid,
|
||||||
|
uint32_t hostbuf);
|
||||||
|
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* @brief Push a pre-allocated buffer descriptor for Debug messages (host side)
|
||||||
|
*
|
||||||
|
* This function is called at Init time to initialize all debug messages.
|
||||||
|
* Then each time embedded send a debug message, this function is used to push
|
||||||
|
* back the same buffer once it has been handled.
|
||||||
|
*
|
||||||
|
* @param[in] env Pointer to the IPC host environment
|
||||||
|
* @param[in] hostid Address of buffer for host
|
||||||
|
* @param[in] hostbuf Address of buffer for embedded
|
||||||
|
* The length of this buffer should be predefined
|
||||||
|
* between host and emb statically.
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
int ipc_host_dbgbuf_push(struct ipc_host_env_tag *env, void *hostid,
|
||||||
|
uint32_t hostbuf);
|
||||||
|
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* @brief Push the pre-allocated logic analyzer and debug information buffer
|
||||||
|
*
|
||||||
|
* @param[in] env Pointer to the IPC host environment
|
||||||
|
* @param[in] infobuf Address of buffer for embedded
|
||||||
|
* The length of this buffer should be predefined
|
||||||
|
* between host and emb statically.
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
void ipc_host_dbginfobuf_push(struct ipc_host_env_tag *env, uint32_t infobuf);
|
||||||
|
|
||||||
|
/// @} IPC_RX
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/** @addtogroup IPC_MISC
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* @brief Handle all IPC interrupts on the host side.
|
||||||
|
*
|
||||||
|
* The following interrupts should be handled:
|
||||||
|
* Tx confirmation, Rx buffer requests, Rx packet ready and kernel messages
|
||||||
|
*
|
||||||
|
* @param[in] env Pointer to the IPC host environment
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
void ipc_host_irq(struct ipc_host_env_tag *env, uint32_t status);
|
||||||
|
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* @brief Send a message to the embedded side
|
||||||
|
*
|
||||||
|
* @param[in] env Pointer to the IPC host environment
|
||||||
|
* @param[in] msg_buf Pointer to the message buffer
|
||||||
|
* @param[in] msg_len Length of the message to be transmitted
|
||||||
|
*
|
||||||
|
* @return Non-null value on failure
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
int ipc_host_msg_push(struct ipc_host_env_tag *env, void *msg_buf, uint16_t len);
|
||||||
|
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* @brief Enable IPC interrupts
|
||||||
|
*
|
||||||
|
* @param[in] env Global ipc_host environment pointer
|
||||||
|
* @param[in] value Bitfield of the interrupts to enable
|
||||||
|
*
|
||||||
|
* @warning After calling this function, IPC interrupts can be triggered at any
|
||||||
|
* time. Potentially, an interrupt could happen even before returning from the
|
||||||
|
* function if there is a request pending from the embedded side.
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
void ipc_host_enable_irq(struct ipc_host_env_tag *env, uint32_t value);
|
||||||
|
void ipc_host_disable_irq(struct ipc_host_env_tag *env, uint32_t value);
|
||||||
|
|
||||||
|
uint32_t ipc_host_get_status(struct ipc_host_env_tag *env);
|
||||||
|
uint32_t ipc_host_get_rawstatus(struct ipc_host_env_tag *env);
|
||||||
|
|
||||||
|
/// @} IPC_MISC
|
||||||
|
|
||||||
|
|
||||||
|
#endif // _IPC_HOST_H_
|
||||||
802
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/ipc_shared.h
Normal file
802
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/ipc_shared.h
Normal file
|
|
@ -0,0 +1,802 @@
|
||||||
|
/**
|
||||||
|
****************************************************************************************
|
||||||
|
*
|
||||||
|
* @file ipc_shared.h
|
||||||
|
*
|
||||||
|
* @brief Shared data between both IPC modules.
|
||||||
|
*
|
||||||
|
* Copyright (C) RivieraWaves 2011-2019
|
||||||
|
*
|
||||||
|
****************************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _IPC_SHARED_H_
|
||||||
|
#define _IPC_SHARED_H_
|
||||||
|
|
||||||
|
/*
|
||||||
|
* INCLUDE FILES
|
||||||
|
****************************************************************************************
|
||||||
|
*/
|
||||||
|
#include "ipc_compat.h"
|
||||||
|
#include "lmac_mac.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* DEFINES AND MACROS
|
||||||
|
****************************************************************************************
|
||||||
|
*/
|
||||||
|
#define CO_BIT(pos) (1U<<(pos))
|
||||||
|
|
||||||
|
#define IPC_TXQUEUE_CNT NX_TXQ_CNT
|
||||||
|
#define NX_TXDESC_CNT0 8
|
||||||
|
#define NX_TXDESC_CNT1 64
|
||||||
|
#define NX_TXDESC_CNT2 64
|
||||||
|
#define NX_TXDESC_CNT3 32
|
||||||
|
#if NX_TXQ_CNT == 5
|
||||||
|
#define NX_TXDESC_CNT4 8
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Number of Host buffers available for Data Rx handling (through DMA)
|
||||||
|
*/
|
||||||
|
#define IPC_RXBUF_CNT 128
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Number of shared descriptors available for Data RX handling
|
||||||
|
*/
|
||||||
|
#define IPC_RXDESC_CNT 128
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Number of Host buffers available for Radar events handling (through DMA)
|
||||||
|
*/
|
||||||
|
#define IPC_RADARBUF_CNT 16
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Number of Host buffers available for unsupported Rx vectors handling (through DMA)
|
||||||
|
*/
|
||||||
|
#define IPC_UNSUPRXVECBUF_CNT 8
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Size of RxVector
|
||||||
|
*/
|
||||||
|
#define IPC_RXVEC_SIZE 16
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Number of Host buffers available for Emb->App MSGs sending (through DMA)
|
||||||
|
*/
|
||||||
|
#ifdef CONFIG_RWNX_FULLMAC
|
||||||
|
#define IPC_MSGE2A_BUF_CNT 64
|
||||||
|
#endif
|
||||||
|
/*
|
||||||
|
* Number of Host buffers available for Debug Messages sending (through DMA)
|
||||||
|
*/
|
||||||
|
#define IPC_DBGBUF_CNT 32
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Length used in MSGs structures
|
||||||
|
*/
|
||||||
|
#define IPC_A2E_MSG_BUF_SIZE 127 // size in 4-byte words
|
||||||
|
#ifdef CONFIG_RWNX_FULLMAC
|
||||||
|
#define IPC_E2A_MSG_SIZE_BASE 256 // size in 4-byte words
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_RWNX_TL4
|
||||||
|
#define IPC_E2A_MSG_PARAM_SIZE (IPC_E2A_MSG_SIZE_BASE + (IPC_E2A_MSG_SIZE_BASE / 2))
|
||||||
|
#else
|
||||||
|
#define IPC_E2A_MSG_PARAM_SIZE IPC_E2A_MSG_SIZE_BASE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Debug messages buffers size (in bytes)
|
||||||
|
*/
|
||||||
|
#define IPC_DBG_PARAM_SIZE 256
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Define used for Rx hostbuf validity.
|
||||||
|
* This value should appear only when hostbuf was used for a Reception.
|
||||||
|
*/
|
||||||
|
#define RX_DMA_OVER_PATTERN 0xAAAAAA00
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Define used for MSG buffers validity.
|
||||||
|
* This value will be written only when a MSG buffer is used for sending from Emb to App.
|
||||||
|
*/
|
||||||
|
#define IPC_MSGE2A_VALID_PATTERN 0xADDEDE2A
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Define used for Debug messages buffers validity.
|
||||||
|
* This value will be written only when a DBG buffer is used for sending from Emb to App.
|
||||||
|
*/
|
||||||
|
#define IPC_DBG_VALID_PATTERN 0x000CACA0
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Length of the receive vectors, in bytes
|
||||||
|
*/
|
||||||
|
#define DMA_HDR_PHYVECT_LEN 36
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Maximum number of payload addresses and lengths present in the descriptor
|
||||||
|
*/
|
||||||
|
#define NX_TX_PAYLOAD_MAX 6
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Message struct/ID API version
|
||||||
|
*/
|
||||||
|
#define MSG_API_VER 15
|
||||||
|
|
||||||
|
/*
|
||||||
|
****************************************************************************************
|
||||||
|
*/
|
||||||
|
// c.f LMAC/src/tx/tx_swdesc.h
|
||||||
|
/// Descriptor filled by the Host
|
||||||
|
struct hostdesc
|
||||||
|
{
|
||||||
|
/// Pointer to packet payload
|
||||||
|
//u32_l packet_addr;
|
||||||
|
/// Size of the payload
|
||||||
|
u16_l packet_len;
|
||||||
|
u16_l flags_ext;
|
||||||
|
|
||||||
|
#ifdef CONFIG_RWNX_FULLMAC
|
||||||
|
/// Address of the status descriptor in host memory (used for confirmation upload)
|
||||||
|
u32_l status_desc_addr;
|
||||||
|
/// Destination Address
|
||||||
|
struct mac_addr eth_dest_addr;
|
||||||
|
/// Source Address
|
||||||
|
struct mac_addr eth_src_addr;
|
||||||
|
/// Ethernet Type
|
||||||
|
u16_l ethertype;
|
||||||
|
#else /* ! CONFIG_RWNX_FULLMAC */
|
||||||
|
#ifdef CONFIG_RWNX_AGG_TX
|
||||||
|
///Sequence Number for AMPDU MPDUs - for quick check if it's allowed within window
|
||||||
|
u16_l sn;
|
||||||
|
#endif /* CONFIG_RWNX_AGG_TX */
|
||||||
|
/// Padding between the buffer control structure and the MPDU in host memory
|
||||||
|
u8_l padding;
|
||||||
|
#endif /* CONFIG_RWNX_FULLMAC */
|
||||||
|
u8_l ac;
|
||||||
|
/// Packet TID (0xFF if not a QoS frame)
|
||||||
|
u8_l tid;
|
||||||
|
/// Interface Id
|
||||||
|
u8_l vif_idx;
|
||||||
|
/// Station Id (0xFF if station is unknown)
|
||||||
|
u8_l staid;
|
||||||
|
#ifdef CONFIG_RWNX_MUMIMO_TX
|
||||||
|
/// MU-MIMO information (GroupId and User Position in the group) - The GroupId
|
||||||
|
/// is located on bits 0-5 and the User Position on bits 6-7. The GroupId value is set
|
||||||
|
/// to 63 if MU-MIMO shall not be used
|
||||||
|
u8_l mumimo_info;
|
||||||
|
#endif /* CONFIG_RWNX_MUMIMO_TX */
|
||||||
|
#ifdef CONFIG_RWNX_FULLMAC
|
||||||
|
/// TX flags
|
||||||
|
u16_l flags;
|
||||||
|
#endif /* CONFIG_RWNX_FULLMAC */
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Descriptor filled by the UMAC
|
||||||
|
struct umacdesc
|
||||||
|
{
|
||||||
|
#ifdef CONFIG_RWNX_AGG_TX
|
||||||
|
///First Sequence Number of the BlockAck window
|
||||||
|
u16_l sn_win;
|
||||||
|
/// Flags from UMAC (match tx_hd.macctrlinfo2 format)
|
||||||
|
u32_l flags;
|
||||||
|
/// PHY related flags field - rate, GI type, BW type - filled by driver
|
||||||
|
u32_l phy_flags;
|
||||||
|
#endif //(CONFIG_RWNX_AGG_TX)
|
||||||
|
};
|
||||||
|
|
||||||
|
struct txdesc_api
|
||||||
|
{
|
||||||
|
/// Information provided by Host
|
||||||
|
struct hostdesc host;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct txdesc_host
|
||||||
|
{
|
||||||
|
u32_l ready;
|
||||||
|
|
||||||
|
/// API of the embedded part
|
||||||
|
struct txdesc_api api;
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Comes from ipc_dma.h
|
||||||
|
/// Element in the pool of TX DMA bridge descriptors.
|
||||||
|
struct dma_desc
|
||||||
|
{
|
||||||
|
/** Application subsystem address which is used as source address for DMA payload
|
||||||
|
* transfer*/
|
||||||
|
u32_l src;
|
||||||
|
/** Points to the start of the embedded data buffer associated with this descriptor.
|
||||||
|
* This address acts as the destination address for the DMA payload transfer*/
|
||||||
|
u32_l dest;
|
||||||
|
/// Complete length of the buffer in memory
|
||||||
|
u16_l length;
|
||||||
|
/// Control word for the DMA engine (e.g. for interrupt generation)
|
||||||
|
u16_l ctrl;
|
||||||
|
/// Pointer to the next element of the chained list
|
||||||
|
u32_l next;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Comes from la.h
|
||||||
|
/// Length of the configuration data of a logic analyzer
|
||||||
|
#define LA_CONF_LEN 10
|
||||||
|
|
||||||
|
/// Structure containing the configuration data of a logic analyzer
|
||||||
|
struct la_conf_tag
|
||||||
|
{
|
||||||
|
u32_l conf[LA_CONF_LEN];
|
||||||
|
u32_l trace_len;
|
||||||
|
u32_l diag_conf;
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Size of a logic analyzer memory
|
||||||
|
#define LA_MEM_LEN (1024 * 1024)
|
||||||
|
|
||||||
|
/// Type of errors
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
/// Recoverable error, not requiring any action from Upper MAC
|
||||||
|
DBG_ERROR_RECOVERABLE = 0,
|
||||||
|
/// Fatal error, requiring Upper MAC to reset Lower MAC and HW and restart operation
|
||||||
|
DBG_ERROR_FATAL
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Maximum length of the SW diag trace
|
||||||
|
#define DBG_SW_DIAG_MAX_LEN 1024
|
||||||
|
|
||||||
|
/// Maximum length of the error trace
|
||||||
|
#define DBG_ERROR_TRACE_SIZE 256
|
||||||
|
|
||||||
|
/// Number of MAC diagnostic port banks
|
||||||
|
#define DBG_DIAGS_MAC_MAX 48
|
||||||
|
|
||||||
|
/// Number of PHY diagnostic port banks
|
||||||
|
#define DBG_DIAGS_PHY_MAX 32
|
||||||
|
|
||||||
|
/// Maximum size of the RX header descriptor information in the debug dump
|
||||||
|
#define DBG_RHD_MEM_LEN (5 * 1024)
|
||||||
|
|
||||||
|
/// Maximum size of the RX buffer descriptor information in the debug dump
|
||||||
|
#define DBG_RBD_MEM_LEN (5 * 1024)
|
||||||
|
|
||||||
|
/// Maximum size of the TX header descriptor information in the debug dump
|
||||||
|
#define DBG_THD_MEM_LEN (10 * 1024)
|
||||||
|
|
||||||
|
/// Structure containing the information about the PHY channel that is used
|
||||||
|
struct phy_channel_info
|
||||||
|
{
|
||||||
|
/// PHY channel information 1
|
||||||
|
u32_l info1;
|
||||||
|
/// PHY channel information 2
|
||||||
|
u32_l info2;
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Debug information forwarded to host when an error occurs
|
||||||
|
struct dbg_debug_info_tag
|
||||||
|
{
|
||||||
|
/// Type of error (0: recoverable, 1: fatal)
|
||||||
|
u32_l error_type;
|
||||||
|
/// Pointer to the first RX Header Descriptor chained to the MAC HW
|
||||||
|
u32_l rhd;
|
||||||
|
/// Size of the RX header descriptor buffer
|
||||||
|
u32_l rhd_len;
|
||||||
|
/// Pointer to the first RX Buffer Descriptor chained to the MAC HW
|
||||||
|
u32_l rbd;
|
||||||
|
/// Size of the RX buffer descriptor buffer
|
||||||
|
u32_l rbd_len;
|
||||||
|
/// Pointer to the first TX Header Descriptors chained to the MAC HW
|
||||||
|
u32_l thd[NX_TXQ_CNT];
|
||||||
|
/// Size of the TX header descriptor buffer
|
||||||
|
u32_l thd_len[NX_TXQ_CNT];
|
||||||
|
/// MAC HW diag configuration
|
||||||
|
u32_l hw_diag;
|
||||||
|
/// Error message
|
||||||
|
u32_l error[DBG_ERROR_TRACE_SIZE/4];
|
||||||
|
/// SW diag configuration length
|
||||||
|
u32_l sw_diag_len;
|
||||||
|
/// SW diag configuration
|
||||||
|
u32_l sw_diag[DBG_SW_DIAG_MAX_LEN/4];
|
||||||
|
/// PHY channel information
|
||||||
|
struct phy_channel_info chan_info;
|
||||||
|
/// Embedded LA configuration
|
||||||
|
struct la_conf_tag la_conf;
|
||||||
|
/// MAC diagnostic port state
|
||||||
|
u16_l diags_mac[DBG_DIAGS_MAC_MAX];
|
||||||
|
/// PHY diagnostic port state
|
||||||
|
u16_l diags_phy[DBG_DIAGS_PHY_MAX];
|
||||||
|
/// MAC HW RX Header descriptor pointer
|
||||||
|
u32_l rhd_hw_ptr;
|
||||||
|
/// MAC HW RX Buffer descriptor pointer
|
||||||
|
u32_l rbd_hw_ptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Full debug dump that is forwarded to host in case of error
|
||||||
|
struct dbg_debug_dump_tag
|
||||||
|
{
|
||||||
|
/// Debug information
|
||||||
|
struct dbg_debug_info_tag dbg_info;
|
||||||
|
|
||||||
|
/// RX header descriptor memory
|
||||||
|
u32_l rhd_mem[DBG_RHD_MEM_LEN/4];
|
||||||
|
|
||||||
|
/// RX buffer descriptor memory
|
||||||
|
u32_l rbd_mem[DBG_RBD_MEM_LEN/4];
|
||||||
|
|
||||||
|
/// TX header descriptor memory
|
||||||
|
u32_l thd_mem[NX_TXQ_CNT][DBG_THD_MEM_LEN/4];
|
||||||
|
|
||||||
|
/// Logic analyzer memory
|
||||||
|
u32_l la_mem[LA_MEM_LEN/4];
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/// Number of pulses in a radar event structure
|
||||||
|
#define RADAR_PULSE_MAX 4
|
||||||
|
|
||||||
|
/// Definition of an array of radar pulses
|
||||||
|
struct radar_pulse_array_desc
|
||||||
|
{
|
||||||
|
/// Buffer containing the radar pulses
|
||||||
|
u32_l pulse[RADAR_PULSE_MAX];
|
||||||
|
/// Index of the radar detection chain that detected those pulses
|
||||||
|
u32_l idx;
|
||||||
|
/// Number of valid pulses in the buffer
|
||||||
|
u32_l cnt;
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Bit mapping inside a radar pulse element
|
||||||
|
struct radar_pulse {
|
||||||
|
s32_l freq:6; /** Freq (resolution is 2Mhz range is [-Fadc/4 .. Fadc/4]) */
|
||||||
|
u32_l fom:4; /** Figure of Merit */
|
||||||
|
u32_l len:6; /** Length of the current radar pulse (resolution is 2us) */
|
||||||
|
u32_l rep:16; /** Time interval between the previous radar event
|
||||||
|
and the current one (in us) */
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Definition of a RX vector descriptor
|
||||||
|
struct rx_vector_desc
|
||||||
|
{
|
||||||
|
/// PHY channel information
|
||||||
|
struct phy_channel_info phy_info;
|
||||||
|
|
||||||
|
/// RX vector 1
|
||||||
|
u32_l rx_vect1[IPC_RXVEC_SIZE/4];
|
||||||
|
|
||||||
|
/// Used to print a valid rx vector
|
||||||
|
u32_l pattern;
|
||||||
|
};
|
||||||
|
|
||||||
|
///
|
||||||
|
struct rxdesc_tag
|
||||||
|
{
|
||||||
|
/// Host Buffer Address
|
||||||
|
u32_l host_id;
|
||||||
|
/// Length
|
||||||
|
u32_l frame_len;
|
||||||
|
/// Status
|
||||||
|
u16_l status;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
****************************************************************************************
|
||||||
|
* @defgroup IPC IPC
|
||||||
|
* @ingroup NXMAC
|
||||||
|
* @brief Inter Processor Communication module.
|
||||||
|
*
|
||||||
|
* The IPC module implements the protocol to communicate between the Host CPU
|
||||||
|
* and the Embedded CPU.
|
||||||
|
*
|
||||||
|
* @see http://en.wikipedia.org/wiki/Circular_buffer
|
||||||
|
* For more information about the ring buffer typical use and difficulties.
|
||||||
|
****************************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
****************************************************************************************
|
||||||
|
* @addtogroup IPC_TX IPC Tx path
|
||||||
|
* @ingroup IPC
|
||||||
|
* @brief IPC Tx path structures and functions
|
||||||
|
*
|
||||||
|
* A typical use case of the IPC Tx path API:
|
||||||
|
* @msc
|
||||||
|
* hscale = "2";
|
||||||
|
*
|
||||||
|
* a [label=Driver],
|
||||||
|
* b [label="IPC host"],
|
||||||
|
* c [label="IPC emb"],
|
||||||
|
* d [label=Firmware];
|
||||||
|
*
|
||||||
|
* --- [label="Tx descriptor queue example"];
|
||||||
|
* a=>a [label="Driver receives a Tx packet from OS"];
|
||||||
|
* a=>b [label="ipc_host_txdesc_get()"];
|
||||||
|
* a<<b [label="struct txdesc_host *"];
|
||||||
|
* a=>a [label="Driver fill the descriptor"];
|
||||||
|
* a=>b [label="ipc_host_txdesc_push()"];
|
||||||
|
* ... [label="(several Tx desc can be pushed)"];
|
||||||
|
* b:>c [label="Tx desc queue filled IRQ"];
|
||||||
|
* c=>>d [label="EDCA sub-scheduler callback"];
|
||||||
|
* c<<d [label="Tx desc queue to pop"];
|
||||||
|
* c=>>d [label="UMAC Tx desc callback"];
|
||||||
|
* ... [label="(several Tx desc can be popped)"];
|
||||||
|
* d=>d [label="Packets are sent or discarded"];
|
||||||
|
* --- [label="Tx confirm queue example"];
|
||||||
|
* c<=d [label="ipc_emb_txcfm_push()"];
|
||||||
|
* c>>d [label="Request accepted"];
|
||||||
|
* ... [label="(several Tx cfm can be pushed)"];
|
||||||
|
* b<:c [label="Tx cfm queue filled IRQ"];
|
||||||
|
* a<<=b [label="Driver's Tx Confirm callback"];
|
||||||
|
* a=>b [label="ipc_host_txcfm_pop()"];
|
||||||
|
* a<<b [label="struct ipc_txcfm"];
|
||||||
|
* a<=a [label="Packets are freed by the driver"];
|
||||||
|
* @endmsc
|
||||||
|
*
|
||||||
|
* @{
|
||||||
|
****************************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
/// @} IPC_TX
|
||||||
|
|
||||||
|
/**
|
||||||
|
****************************************************************************************
|
||||||
|
* @defgroup IPC_RX IPC Rx path
|
||||||
|
* @ingroup IPC
|
||||||
|
* @brief IPC Rx path functions and structures
|
||||||
|
*
|
||||||
|
* A typical use case of the IPC Rx path API:
|
||||||
|
* @msc
|
||||||
|
* hscale = "2";
|
||||||
|
*
|
||||||
|
* a [label=Firmware],
|
||||||
|
* b [label="IPC emb"],
|
||||||
|
* c [label="IPC host"],
|
||||||
|
* d [label=Driver];
|
||||||
|
*
|
||||||
|
* --- [label="Rx buffer and desc queues usage example"];
|
||||||
|
* d=>c [label="ipc_host_rxbuf_push()"];
|
||||||
|
* d=>c [label="ipc_host_rxbuf_push()"];
|
||||||
|
* d=>c [label="ipc_host_rxbuf_push()"];
|
||||||
|
* ... [label="(several Rx buffer are pushed)"];
|
||||||
|
* a=>a [label=" Frame is received\n from the medium"];
|
||||||
|
* a<<b [label="struct ipc_rxbuf"];
|
||||||
|
* a=>a [label=" Firmware fill the buffer\n with received frame"];
|
||||||
|
* a<<b [label="Push accepted"];
|
||||||
|
* ... [label="(several Rx desc can be pushed)"];
|
||||||
|
* b:>c [label="Rx desc queue filled IRQ"];
|
||||||
|
* c=>>d [label="Driver Rx packet callback"];
|
||||||
|
* c<=d [label="ipc_host_rxdesc_pop()"];
|
||||||
|
* d=>d [label="Rx packet is handed \nover to the OS "];
|
||||||
|
* ... [label="(several Rx desc can be poped)"];
|
||||||
|
* --- [label="Rx buffer request exemple"];
|
||||||
|
* b:>c [label="Low Rx buffer count IRQ"];
|
||||||
|
* a<<b [label="struct ipc_rxbuf"];
|
||||||
|
* c=>>d [label="Driver Rx buffer callback"];
|
||||||
|
* d=>c [label="ipc_host_rxbuf_push()"];
|
||||||
|
* d=>c [label="ipc_host_rxbuf_push()"];
|
||||||
|
* d=>c [label="ipc_host_rxbuf_push()"];
|
||||||
|
* ... [label="(several Rx buffer are pushed)"];
|
||||||
|
* @endmsc
|
||||||
|
*
|
||||||
|
* @addtogroup IPC_RX
|
||||||
|
* @{
|
||||||
|
****************************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
/// @} IPC_RX
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
****************************************************************************************
|
||||||
|
* @defgroup IPC_MISC IPC Misc
|
||||||
|
* @ingroup IPC
|
||||||
|
* @brief IPC miscellaneous functions
|
||||||
|
****************************************************************************************
|
||||||
|
*/
|
||||||
|
/** IPC header structure. This structure is stored at the beginning of every IPC message.
|
||||||
|
* @warning This structure's size must NOT exceed 4 bytes in length.
|
||||||
|
*/
|
||||||
|
struct ipc_header
|
||||||
|
{
|
||||||
|
/// IPC message type.
|
||||||
|
u16_l type;
|
||||||
|
/// IPC message size in number of bytes.
|
||||||
|
u16_l size;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ipc_msg_elt
|
||||||
|
{
|
||||||
|
/// Message header (alignment forced on word size, see allocation in shared env).
|
||||||
|
struct ipc_header header __ALIGN4;
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Message structure for MSGs from Emb to App
|
||||||
|
struct ipc_e2a_msg
|
||||||
|
{
|
||||||
|
u16_l id; ///< Message id.
|
||||||
|
u16_l dummy_dest_id;
|
||||||
|
u16_l dummy_src_id;
|
||||||
|
u16_l param_len; ///< Parameter embedded struct length.
|
||||||
|
u32_l pattern; ///< Used to stamp a valid MSG buffer
|
||||||
|
u32_l param[IPC_E2A_MSG_PARAM_SIZE]; ///< Parameter embedded struct. Must be word-aligned.
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Message structure for Debug messages from Emb to App
|
||||||
|
struct ipc_dbg_msg
|
||||||
|
{
|
||||||
|
u32_l string[IPC_DBG_PARAM_SIZE/4]; ///< Debug string
|
||||||
|
u32_l pattern; ///< Used to stamp a valid buffer
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Message structure for MSGs from App to Emb.
|
||||||
|
/// Actually a sub-structure will be used when filling the messages.
|
||||||
|
struct ipc_a2e_msg
|
||||||
|
{
|
||||||
|
u32_l dummy_word; // used to cope with kernel message structure
|
||||||
|
u32_l msg[IPC_A2E_MSG_BUF_SIZE]; // body of the msg
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ipc_shared_rx_buf
|
||||||
|
{
|
||||||
|
/// < ptr to hostbuf client (ipc_host client) structure
|
||||||
|
u32_l hostid;
|
||||||
|
/// < ptr to real hostbuf dma address
|
||||||
|
u32_l dma_addr;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ipc_shared_rx_desc
|
||||||
|
{
|
||||||
|
/// DMA Address
|
||||||
|
u32_l dma_addr;
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Structure containing FW characteristics for compatibility checking
|
||||||
|
struct compatibility_tag {
|
||||||
|
/// Size of IPC shared memory
|
||||||
|
u16_l ipc_shared_size;
|
||||||
|
/// Message struct/ID API version
|
||||||
|
u16_l msg_api;
|
||||||
|
/// Version of IPC shared
|
||||||
|
u8_l ipc_shared_version;
|
||||||
|
/// Number of host buffers available for Emb->App MSGs sending
|
||||||
|
u8_l msge2a_buf_cnt;
|
||||||
|
/// Number of host buffers available for Debug Messages sending
|
||||||
|
u8_l dbgbuf_cnt;
|
||||||
|
/// Number of host buffers available for Radar events handling
|
||||||
|
u8_l radarbuf_cnt;
|
||||||
|
/// Number of host buffers available for unsupported Rx vectors handling
|
||||||
|
u8_l unsuprxvecbuf_cnt;
|
||||||
|
/// Number of shared descriptors available for Data RX handling
|
||||||
|
u8_l rxdesc_cnt;
|
||||||
|
/// Number of host buffers available for Data Rx handling
|
||||||
|
u8_l rxbuf_cnt;
|
||||||
|
/// Number of descriptors in BK TX queue (power of 2, min 4, max 64)
|
||||||
|
u8_l bk_txq;
|
||||||
|
/// Number of descriptors in BE TX queue (power of 2, min 4, max 64)
|
||||||
|
u8_l be_txq;
|
||||||
|
/// Number of descriptors in VI TX queue (power of 2, min 4, max 64)
|
||||||
|
u8_l vi_txq;
|
||||||
|
/// Number of descriptors in VO TX queue (power of 2, min 4, max 64)
|
||||||
|
u8_l vo_txq;
|
||||||
|
/// Number of descriptors in BCN TX queue (power of 2, min 4, max 64)
|
||||||
|
u8_l bcn_txq;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* TYPE and STRUCT DEFINITIONS
|
||||||
|
****************************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
// Indexes are defined in the MIB shared structure
|
||||||
|
struct ipc_shared_env_tag
|
||||||
|
{
|
||||||
|
volatile struct compatibility_tag comp_info; //FW characteristics
|
||||||
|
|
||||||
|
volatile struct ipc_a2e_msg msg_a2e_buf; // room for MSG to be sent from App to Emb
|
||||||
|
|
||||||
|
// Fields for MSGs sending from Emb to App
|
||||||
|
volatile struct ipc_e2a_msg msg_e2a_buf; // room to build the MSG to be DMA Xferred
|
||||||
|
volatile struct dma_desc msg_dma_desc; // DMA descriptor for Emb->App MSGs Xfers
|
||||||
|
volatile u32_l msg_e2a_hostbuf_addr [IPC_MSGE2A_BUF_CNT]; // buffers @ for DMA Xfers
|
||||||
|
|
||||||
|
// Fields for Debug MSGs sending from Emb to App
|
||||||
|
volatile struct ipc_dbg_msg dbg_buf; // room to build the MSG to be DMA Xferred
|
||||||
|
volatile struct dma_desc dbg_dma_desc; // DMA descriptor for Emb->App MSGs Xfers
|
||||||
|
volatile u32_l dbg_hostbuf_addr [IPC_DBGBUF_CNT]; // buffers @ for MSGs DMA Xfers
|
||||||
|
volatile u32_l la_dbginfo_addr; // Host buffer address for the debug information
|
||||||
|
volatile u32_l pattern_addr;
|
||||||
|
volatile u32_l radarbuf_hostbuf [IPC_RADARBUF_CNT]; // buffers @ for Radar Events
|
||||||
|
volatile u32_l unsuprxvecbuf_hostbuf [IPC_UNSUPRXVECBUF_CNT]; // buffers @ for unsupported Rx vectors
|
||||||
|
volatile struct txdesc_host txdesc0[CONFIG_USER_MAX][NX_TXDESC_CNT0];
|
||||||
|
volatile struct txdesc_host txdesc1[CONFIG_USER_MAX][NX_TXDESC_CNT1];
|
||||||
|
volatile struct txdesc_host txdesc2[CONFIG_USER_MAX][NX_TXDESC_CNT2];
|
||||||
|
volatile struct txdesc_host txdesc3[CONFIG_USER_MAX][NX_TXDESC_CNT3];
|
||||||
|
#if NX_TXQ_CNT == 5
|
||||||
|
volatile struct txdesc_host txdesc4[1][NX_TXDESC_CNT4];
|
||||||
|
#endif
|
||||||
|
#ifdef CONFIG_RWNX_FULLMAC
|
||||||
|
// RX Descriptors Array
|
||||||
|
volatile struct ipc_shared_rx_desc host_rxdesc[IPC_RXDESC_CNT];
|
||||||
|
// RX Buffers Array
|
||||||
|
volatile struct ipc_shared_rx_buf host_rxbuf[IPC_RXBUF_CNT];
|
||||||
|
#else
|
||||||
|
// buffers @ for Data Rx
|
||||||
|
volatile u32_l host_rxbuf[IPC_RXBUF_CNT];
|
||||||
|
#endif /* CONFIG_RWNX_FULLMAC */
|
||||||
|
|
||||||
|
u32_l buffered[NX_REMOTE_STA_MAX][TID_MAX];
|
||||||
|
|
||||||
|
volatile uint16_t trace_pattern;
|
||||||
|
volatile uint32_t trace_start;
|
||||||
|
volatile uint32_t trace_end;
|
||||||
|
volatile uint32_t trace_size;
|
||||||
|
volatile uint32_t trace_offset;
|
||||||
|
volatile uint32_t trace_nb_compo;
|
||||||
|
volatile uint32_t trace_offset_compo;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern struct ipc_shared_env_tag ipc_shared_env;
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* TYPE and STRUCT DEFINITIONS
|
||||||
|
****************************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
// IRQs from app to emb
|
||||||
|
/// Interrupts bits used for the TX descriptors of the AC queues
|
||||||
|
#ifdef CONFIG_RWNX_MUMIMO_TX
|
||||||
|
#ifdef CONFIG_RWNX_OLD_IPC
|
||||||
|
#error "MU-MIMO cannot be compiled for old IPC"
|
||||||
|
#endif
|
||||||
|
/// Interrupts bits used
|
||||||
|
#if CONFIG_USER_MAX > 3
|
||||||
|
#define IPC_IRQ_A2E_USER_MSK 0xF
|
||||||
|
#elif CONFIG_USER_MAX > 2
|
||||||
|
#define IPC_IRQ_A2E_USER_MSK 0x7
|
||||||
|
#else
|
||||||
|
#define IPC_IRQ_A2E_USER_MSK 0x3
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/// Offset of the interrupts for AC0
|
||||||
|
#define IPC_IRQ_A2E_AC0_OFT 8
|
||||||
|
/// Mask of the interrupts for AC0
|
||||||
|
#define IPC_IRQ_A2E_AC0_MSK (IPC_IRQ_A2E_USER_MSK << IPC_IRQ_A2E_AC0_OFT)
|
||||||
|
/// Offset of the interrupts for AC1
|
||||||
|
#define IPC_IRQ_A2E_AC1_OFT (IPC_IRQ_A2E_AC0_OFT + CONFIG_USER_MAX)
|
||||||
|
/// Mask of the interrupts for AC1
|
||||||
|
#define IPC_IRQ_A2E_AC1_MSK (IPC_IRQ_A2E_USER_MSK << IPC_IRQ_A2E_AC1_OFT)
|
||||||
|
/// Offset of the interrupts for AC2
|
||||||
|
#define IPC_IRQ_A2E_AC2_OFT (IPC_IRQ_A2E_AC1_OFT + CONFIG_USER_MAX)
|
||||||
|
/// Mask of the interrupts for AC2
|
||||||
|
#define IPC_IRQ_A2E_AC2_MSK (IPC_IRQ_A2E_USER_MSK << IPC_IRQ_A2E_AC2_OFT)
|
||||||
|
/// Offset of the interrupts for AC3
|
||||||
|
#define IPC_IRQ_A2E_AC3_OFT (IPC_IRQ_A2E_AC2_OFT + CONFIG_USER_MAX)
|
||||||
|
/// Mask of the interrupts for AC3
|
||||||
|
#define IPC_IRQ_A2E_AC3_MSK (IPC_IRQ_A2E_USER_MSK << IPC_IRQ_A2E_AC3_OFT)
|
||||||
|
/// Offset of the interrupts for BCN
|
||||||
|
#define IPC_IRQ_A2E_BCN_OFT (IPC_IRQ_A2E_AC3_OFT + CONFIG_USER_MAX)
|
||||||
|
/// Mask of the interrupts for BCN
|
||||||
|
#define IPC_IRQ_A2E_BCN_MSK CO_BIT(IPC_IRQ_A2E_BCN_OFT)
|
||||||
|
|
||||||
|
#define IPC_IRQ_A2E_AC_TXDESC (IPC_IRQ_A2E_AC0_MSK | IPC_IRQ_A2E_AC1_MSK | \
|
||||||
|
IPC_IRQ_A2E_AC2_MSK | IPC_IRQ_A2E_AC3_MSK)
|
||||||
|
|
||||||
|
/// Interrupts bits used for the TX descriptors of the BCN queue
|
||||||
|
#if NX_TXQ_CNT < 5
|
||||||
|
#define IPC_IRQ_A2E_BCN_TXDESC 0
|
||||||
|
#else
|
||||||
|
#define IPC_IRQ_A2E_BCN_TXDESC (0x01 << IPC_IRQ_A2E_BCN_OFT)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/// IPC TX descriptor interrupt mask
|
||||||
|
#define IPC_IRQ_A2E_TXDESC (IPC_IRQ_A2E_AC_TXDESC | IPC_IRQ_A2E_BCN_TXDESC)
|
||||||
|
#else
|
||||||
|
/// IPC TX descriptor interrupt mask
|
||||||
|
#define IPC_IRQ_A2E_TXDESC 0xFF00
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define IPC_IRQ_A2E_TXDESC_FIRSTBIT (8)
|
||||||
|
#define IPC_IRQ_A2E_RXBUF_BACK CO_BIT(5)
|
||||||
|
#define IPC_IRQ_A2E_RXDESC_BACK CO_BIT(4)
|
||||||
|
|
||||||
|
#define IPC_IRQ_A2E_MSG CO_BIT(1)
|
||||||
|
#define IPC_IRQ_A2E_DBG CO_BIT(0)
|
||||||
|
|
||||||
|
#define IPC_IRQ_A2E_ALL (IPC_IRQ_A2E_TXDESC|IPC_IRQ_A2E_MSG|IPC_IRQ_A2E_DBG)
|
||||||
|
|
||||||
|
// IRQs from emb to app
|
||||||
|
#define IPC_IRQ_E2A_TXCFM_POS 7
|
||||||
|
|
||||||
|
#ifdef CONFIG_RWNX_MUMIMO_TX
|
||||||
|
#ifdef CONFIG_RWNX_OLD_IPC
|
||||||
|
#error "MU-MIMO cannot be compiled for old IPC"
|
||||||
|
#endif
|
||||||
|
/// Interrupts bits used
|
||||||
|
#if CONFIG_USER_MAX > 3
|
||||||
|
#define IPC_IRQ_E2A_USER_MSK 0xF
|
||||||
|
#elif CONFIG_USER_MAX > 2
|
||||||
|
#define IPC_IRQ_E2A_USER_MSK 0x7
|
||||||
|
#else
|
||||||
|
#define IPC_IRQ_E2A_USER_MSK 0x3
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/// Offset of the interrupts for AC0
|
||||||
|
#define IPC_IRQ_E2A_AC0_OFT IPC_IRQ_E2A_TXCFM_POS
|
||||||
|
/// Mask of the interrupts for AC0
|
||||||
|
#define IPC_IRQ_E2A_AC0_MSK (IPC_IRQ_E2A_USER_MSK << IPC_IRQ_E2A_AC0_OFT)
|
||||||
|
/// Offset of the interrupts for AC1
|
||||||
|
#define IPC_IRQ_E2A_AC1_OFT (IPC_IRQ_E2A_AC0_OFT + CONFIG_USER_MAX)
|
||||||
|
/// Mask of the interrupts for AC1
|
||||||
|
#define IPC_IRQ_E2A_AC1_MSK (IPC_IRQ_E2A_USER_MSK << IPC_IRQ_E2A_AC1_OFT)
|
||||||
|
/// Offset of the interrupts for AC2
|
||||||
|
#define IPC_IRQ_E2A_AC2_OFT (IPC_IRQ_E2A_AC1_OFT + CONFIG_USER_MAX)
|
||||||
|
/// Mask of the interrupts for AC2
|
||||||
|
#define IPC_IRQ_E2A_AC2_MSK (IPC_IRQ_E2A_USER_MSK << IPC_IRQ_E2A_AC2_OFT)
|
||||||
|
/// Offset of the interrupts for AC3
|
||||||
|
#define IPC_IRQ_E2A_AC3_OFT (IPC_IRQ_E2A_AC2_OFT + CONFIG_USER_MAX)
|
||||||
|
/// Mask of the interrupts for AC3
|
||||||
|
#define IPC_IRQ_E2A_AC3_MSK (IPC_IRQ_E2A_USER_MSK << IPC_IRQ_E2A_AC3_OFT)
|
||||||
|
/// Offset of the interrupts for BCN
|
||||||
|
#define IPC_IRQ_E2A_BCN_OFT (IPC_IRQ_E2A_AC3_OFT + CONFIG_USER_MAX)
|
||||||
|
/// Mask of the interrupts for BCN
|
||||||
|
#define IPC_IRQ_E2A_BCN_MSK CO_BIT(IPC_IRQ_E2A_BCN_OFT)
|
||||||
|
|
||||||
|
#define IPC_IRQ_E2A_AC_TXCFM (IPC_IRQ_E2A_AC0_MSK | IPC_IRQ_E2A_AC1_MSK | \
|
||||||
|
IPC_IRQ_E2A_AC2_MSK | IPC_IRQ_E2A_AC3_MSK)
|
||||||
|
|
||||||
|
/// Interrupts bits used for the TX descriptors of the BCN queue
|
||||||
|
#if NX_TXQ_CNT < 5
|
||||||
|
#define IPC_IRQ_E2A_BCN_TXCFM 0
|
||||||
|
#else
|
||||||
|
#define IPC_IRQ_E2A_BCN_TXCFM (0x01 << IPC_IRQ_E2A_BCN_OFT)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/// IPC TX descriptor interrupt mask
|
||||||
|
#define IPC_IRQ_E2A_TXCFM (IPC_IRQ_E2A_AC_TXCFM | IPC_IRQ_E2A_BCN_TXCFM)
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#define IPC_IRQ_E2A_TXCFM ((1 << NX_TXQ_CNT) - 1 ) << IPC_IRQ_E2A_TXCFM_POS
|
||||||
|
|
||||||
|
#endif /* CONFIG_RWNX_MUMIMO_TX */
|
||||||
|
|
||||||
|
#define IPC_IRQ_E2A_UNSUP_RX_VEC CO_BIT(7)
|
||||||
|
#define IPC_IRQ_E2A_RADAR CO_BIT(6)
|
||||||
|
#define IPC_IRQ_E2A_TBTT_SEC CO_BIT(5)
|
||||||
|
#define IPC_IRQ_E2A_TBTT_PRIM CO_BIT(4)
|
||||||
|
#define IPC_IRQ_E2A_RXDESC CO_BIT(3)
|
||||||
|
#define IPC_IRQ_E2A_MSG_ACK CO_BIT(2)
|
||||||
|
#define IPC_IRQ_E2A_MSG CO_BIT(1)
|
||||||
|
#define IPC_IRQ_E2A_DBG CO_BIT(0)
|
||||||
|
|
||||||
|
#define IPC_IRQ_E2A_ALL ( IPC_IRQ_E2A_TXCFM \
|
||||||
|
| IPC_IRQ_E2A_RXDESC \
|
||||||
|
| IPC_IRQ_E2A_MSG_ACK \
|
||||||
|
| IPC_IRQ_E2A_MSG \
|
||||||
|
| IPC_IRQ_E2A_DBG \
|
||||||
|
| IPC_IRQ_E2A_TBTT_PRIM \
|
||||||
|
| IPC_IRQ_E2A_TBTT_SEC \
|
||||||
|
| IPC_IRQ_E2A_RADAR \
|
||||||
|
| IPC_IRQ_E2A_UNSUP_RX_VEC)
|
||||||
|
|
||||||
|
// FLAGS for RX desc
|
||||||
|
#define IPC_RX_FORWARD CO_BIT(1)
|
||||||
|
#define IPC_RX_INTRABSS CO_BIT(0)
|
||||||
|
|
||||||
|
|
||||||
|
// IPC message TYPE
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
IPC_MSG_NONE = 0,
|
||||||
|
IPC_MSG_WRAP,
|
||||||
|
IPC_MSG_KMSG,
|
||||||
|
|
||||||
|
IPC_DBG_STRING,
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // _IPC_SHARED_H_
|
||||||
|
|
||||||
589
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/lmac_mac.h
Normal file
589
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/lmac_mac.h
Normal file
|
|
@ -0,0 +1,589 @@
|
||||||
|
/**
|
||||||
|
****************************************************************************************
|
||||||
|
*
|
||||||
|
* @file lmac_mac_types.h
|
||||||
|
*
|
||||||
|
* @brief MAC related definitions.
|
||||||
|
*
|
||||||
|
* Adapted from mac_types.h to used lmac_types.h instead of standard types
|
||||||
|
* eg: perl -pi -e '$_ =~ s/uint(\d{1,2})_t/u$1_l/g; \
|
||||||
|
* $_ =~ s/int(\d{1,2})_t/s$1_l/g; \
|
||||||
|
* $_ =~ s/CO_BIT/BIT/g;' lmac_mac.h
|
||||||
|
*
|
||||||
|
* Copyright (C) RivieraWaves 2011-2019
|
||||||
|
*
|
||||||
|
****************************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef LMAC_MAC_H_
|
||||||
|
#define LMAC_MAC_H_
|
||||||
|
|
||||||
|
#include "lmac_types.h"
|
||||||
|
|
||||||
|
/// Interface types
|
||||||
|
enum mac_vif_type
|
||||||
|
{
|
||||||
|
/// ESS STA interface
|
||||||
|
VIF_STA,
|
||||||
|
/// IBSS STA interface
|
||||||
|
VIF_IBSS,
|
||||||
|
/// AP interface
|
||||||
|
VIF_AP,
|
||||||
|
/// Mesh Point interface
|
||||||
|
VIF_MESH_POINT,
|
||||||
|
/// Monitor interface
|
||||||
|
VIF_MONITOR,
|
||||||
|
/// Unknown type
|
||||||
|
VIF_UNKNOWN
|
||||||
|
};
|
||||||
|
|
||||||
|
/// MAC address length in bytes.
|
||||||
|
#define MAC_ADDR_LEN 6
|
||||||
|
|
||||||
|
/// MAC address structure.
|
||||||
|
struct mac_addr
|
||||||
|
{
|
||||||
|
/// Array of 16-bit words that make up the MAC address.
|
||||||
|
u16_l array[MAC_ADDR_LEN/2];
|
||||||
|
};
|
||||||
|
|
||||||
|
/// SSID maximum length.
|
||||||
|
#define MAC_SSID_LEN 32
|
||||||
|
|
||||||
|
/// SSID.
|
||||||
|
struct mac_ssid
|
||||||
|
{
|
||||||
|
/// Actual length of the SSID.
|
||||||
|
u8_l length;
|
||||||
|
/// Array containing the SSID name.
|
||||||
|
u8_l array[MAC_SSID_LEN];
|
||||||
|
};
|
||||||
|
|
||||||
|
/// BSS type
|
||||||
|
enum mac_bss_type
|
||||||
|
{
|
||||||
|
INFRASTRUCTURE_MODE = 1,
|
||||||
|
INDEPENDENT_BSS_MODE,
|
||||||
|
ANY_BSS_MODE
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Channel Band
|
||||||
|
enum mac_chan_band
|
||||||
|
{
|
||||||
|
/// 2.4GHz Band
|
||||||
|
PHY_BAND_2G4,
|
||||||
|
/// 5GHz band
|
||||||
|
PHY_BAND_5G,
|
||||||
|
/// Number of bands
|
||||||
|
PHY_BAND_MAX,
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Operating Channel Bandwidth
|
||||||
|
enum mac_chan_bandwidth
|
||||||
|
{
|
||||||
|
/// 20MHz BW
|
||||||
|
PHY_CHNL_BW_20,
|
||||||
|
/// 40MHz BW
|
||||||
|
PHY_CHNL_BW_40,
|
||||||
|
/// 80MHz BW
|
||||||
|
PHY_CHNL_BW_80,
|
||||||
|
/// 160MHz BW
|
||||||
|
PHY_CHNL_BW_160,
|
||||||
|
/// 80+80MHz BW
|
||||||
|
PHY_CHNL_BW_80P80,
|
||||||
|
/// Reserved BW
|
||||||
|
PHY_CHNL_BW_OTHER,
|
||||||
|
};
|
||||||
|
|
||||||
|
/// max number of channels in the 2.4 GHZ band
|
||||||
|
#define MAC_DOMAINCHANNEL_24G_MAX 14
|
||||||
|
|
||||||
|
/// max number of channels in the 5 GHZ band
|
||||||
|
#define MAC_DOMAINCHANNEL_5G_MAX 28
|
||||||
|
|
||||||
|
/// Channel Flag
|
||||||
|
enum mac_chan_flags
|
||||||
|
{
|
||||||
|
/// Cannot initiate radiation on this channel
|
||||||
|
CHAN_NO_IR = BIT(0),
|
||||||
|
/// Channel is not allowed
|
||||||
|
CHAN_DISABLED = BIT(1),
|
||||||
|
/// Radar detection required on this channel
|
||||||
|
CHAN_RADAR = BIT(2),
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Primary Channel definition
|
||||||
|
struct mac_chan_def
|
||||||
|
{
|
||||||
|
/// Frequency of the channel (in MHz)
|
||||||
|
u16_l freq;
|
||||||
|
/// RF band (@ref mac_chan_band)
|
||||||
|
u8_l band;
|
||||||
|
/// Additional information (@ref mac_chan_flags)
|
||||||
|
u8_l flags;
|
||||||
|
/// Max transmit power allowed on this channel (dBm)
|
||||||
|
s8_l tx_power;
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Operating Channel
|
||||||
|
struct mac_chan_op
|
||||||
|
{
|
||||||
|
/// Band (@ref mac_chan_band)
|
||||||
|
u8_l band;
|
||||||
|
/// Channel type (@ref mac_chan_bandwidth)
|
||||||
|
u8_l type;
|
||||||
|
/// Frequency for Primary 20MHz channel (in MHz)
|
||||||
|
u16_l prim20_freq;
|
||||||
|
/// Frequency center of the contiguous channel or center of Primary 80+80 (in MHz)
|
||||||
|
u16_l center1_freq;
|
||||||
|
/// Frequency center of the non-contiguous secondary 80+80 (in MHz)
|
||||||
|
u16_l center2_freq;
|
||||||
|
/// Max transmit power allowed on this channel (dBm)
|
||||||
|
s8_l tx_power;
|
||||||
|
/// Additional information (@ref mac_chan_flags)
|
||||||
|
u8_l flags;
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Cipher suites (order is important as it is used by MACHW)
|
||||||
|
enum mac_cipher_suite
|
||||||
|
{
|
||||||
|
/// 00-0F-AC 1
|
||||||
|
MAC_CIPHER_WEP40 = 0,
|
||||||
|
/// 00-0F-AC 2
|
||||||
|
MAC_CIPHER_TKIP = 1,
|
||||||
|
/// 00-0F-AC 4
|
||||||
|
MAC_CIPHER_CCMP = 2,
|
||||||
|
/// 00-0F-AC 5
|
||||||
|
MAC_CIPHER_WEP104 = 3,
|
||||||
|
/// 00-14-72 1
|
||||||
|
MAC_CIPHER_WPI_SMS4 = 4,
|
||||||
|
/// 00-0F-AC 6 (aka AES_CMAC)
|
||||||
|
MAC_CIPHER_BIP_CMAC_128 = 5,
|
||||||
|
|
||||||
|
// following cipher are not supported by MACHW
|
||||||
|
/// 00-0F-AC 08
|
||||||
|
MAC_CIPHER_GCMP_128,
|
||||||
|
/// 00-0F-AC 09
|
||||||
|
MAC_CIPHER_GCMP_256,
|
||||||
|
/// 00-0F-AC 10
|
||||||
|
MAC_CIPHER_CCMP_256,
|
||||||
|
/// 00-0F-AC 11
|
||||||
|
MAC_CIPHER_BIP_GMAC_128,
|
||||||
|
/// 00-0F-AC 12
|
||||||
|
MAC_CIPHER_BIP_GMAC_256,
|
||||||
|
/// 00-0F-AC 13
|
||||||
|
MAC_CIPHER_BIP_CMAC_256,
|
||||||
|
|
||||||
|
MAC_CIPHER_INVALID = 0xFF
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Authentication and Key Management suite
|
||||||
|
enum mac_akm_suite
|
||||||
|
{
|
||||||
|
/// No security
|
||||||
|
MAC_AKM_NONE,
|
||||||
|
/// Pre RSN (WEP or WPA)
|
||||||
|
MAC_AKM_PRE_RSN,
|
||||||
|
/// 00-0F-AC 1
|
||||||
|
MAC_AKM_8021X,
|
||||||
|
/// 00-0F-AC 2
|
||||||
|
MAC_AKM_PSK,
|
||||||
|
/// 00-0F-AC 3
|
||||||
|
MAC_AKM_FT_8021X,
|
||||||
|
/// 00-0F-AC 4
|
||||||
|
MAC_AKM_FT_PSK,
|
||||||
|
/// 00-0F-AC 5
|
||||||
|
MAC_AKM_8021X_SHA256,
|
||||||
|
/// 00-0F-AC 6
|
||||||
|
MAC_AKM_PSK_SHA256,
|
||||||
|
/// 00-0F-AC 7
|
||||||
|
MAC_AKM_TDLS,
|
||||||
|
/// 00-0F-AC 8
|
||||||
|
MAC_AKM_SAE,
|
||||||
|
/// 00-0F-AC 9
|
||||||
|
MAC_AKM_FT_OVER_SAE,
|
||||||
|
/// 00-0F-AC 11
|
||||||
|
MAC_AKM_8021X_SUITE_B,
|
||||||
|
/// 00-0F-AC 12
|
||||||
|
MAC_AKM_8021X_SUITE_B_192,
|
||||||
|
/// 00-0F-AC 14
|
||||||
|
MAC_AKM_FILS_SHA256,
|
||||||
|
/// 00-0F-AC 15
|
||||||
|
MAC_AKM_FILS_SHA384,
|
||||||
|
/// 00-0F-AC 16
|
||||||
|
MAC_AKM_FT_FILS_SHA256,
|
||||||
|
/// 00-0F-AC 17
|
||||||
|
MAC_AKM_FT_FILS_SHA384,
|
||||||
|
/// 00-0F-AC 18
|
||||||
|
MAC_AKM_OWE,
|
||||||
|
|
||||||
|
/// 00-14-72 1
|
||||||
|
MAC_AKM_WAPI_CERT,
|
||||||
|
/// 00-14-72 2
|
||||||
|
MAC_AKM_WAPI_PSK,
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Scan result element, parsed from beacon or probe response frames.
|
||||||
|
struct mac_scan_result
|
||||||
|
{
|
||||||
|
/// Scan result is valid
|
||||||
|
bool valid_flag;
|
||||||
|
/// Network BSSID.
|
||||||
|
struct mac_addr bssid;
|
||||||
|
/// Network name.
|
||||||
|
struct mac_ssid ssid;
|
||||||
|
/// Network type (@ref mac_bss_type).
|
||||||
|
u16_l bsstype;
|
||||||
|
/// Network channel.
|
||||||
|
struct mac_chan_def *chan;
|
||||||
|
/// Network beacon period (in TU).
|
||||||
|
u16_l beacon_period;
|
||||||
|
/// Capability information
|
||||||
|
u16_l cap_info;
|
||||||
|
/// Supported AKM (bit-field of @ref mac_akm_suite)
|
||||||
|
u32_l akm;
|
||||||
|
/// Group cipher (bit-field of @ref mac_cipher_suite)
|
||||||
|
u16_l group_cipher;
|
||||||
|
/// Group cipher (bit-field of @ref mac_cipher_suite)
|
||||||
|
u16_l pairwise_cipher;
|
||||||
|
/// RSSI of the scanned BSS (in dBm)
|
||||||
|
s8_l rssi;
|
||||||
|
///Multi-BSSID index (0 if this is the reference (i.e. transmitted) BSSID)
|
||||||
|
u8_l mluti_bssid_index;
|
||||||
|
///Maximum BSSID indicator
|
||||||
|
u8_l max_bssid_indicator;
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Legacy rate 802.11 definitions
|
||||||
|
enum mac_legacy_rates
|
||||||
|
{
|
||||||
|
/// DSSS/CCK 1Mbps
|
||||||
|
MAC_RATE_1MBPS = 2,
|
||||||
|
/// DSSS/CCK 2Mbps
|
||||||
|
MAC_RATE_2MBPS = 4,
|
||||||
|
/// DSSS/CCK 5.5Mbps
|
||||||
|
MAC_RATE_5_5MBPS = 11,
|
||||||
|
/// OFDM 6Mbps
|
||||||
|
MAC_RATE_6MBPS = 12,
|
||||||
|
/// OFDM 9Mbps
|
||||||
|
MAC_RATE_9MBPS = 18,
|
||||||
|
/// DSSS/CCK 11Mbps
|
||||||
|
MAC_RATE_11MBPS = 22,
|
||||||
|
/// OFDM 12Mbps
|
||||||
|
MAC_RATE_12MBPS = 24,
|
||||||
|
/// OFDM 18Mbps
|
||||||
|
MAC_RATE_18MBPS = 36,
|
||||||
|
/// OFDM 24Mbps
|
||||||
|
MAC_RATE_24MBPS = 48,
|
||||||
|
/// OFDM 36Mbps
|
||||||
|
MAC_RATE_36MBPS = 72,
|
||||||
|
/// OFDM 48Mbps
|
||||||
|
MAC_RATE_48MBPS = 96,
|
||||||
|
/// OFDM 54Mbps
|
||||||
|
MAC_RATE_54MBPS = 108
|
||||||
|
};
|
||||||
|
|
||||||
|
/// BSS Membership Selector definitions
|
||||||
|
enum mac_bss_membership
|
||||||
|
{
|
||||||
|
/// HT PHY
|
||||||
|
MAC_BSS_MEMBERSHIP_HT_PHY = 127,
|
||||||
|
/// VHT PHY
|
||||||
|
MAC_BSS_MEMBERSHIP_VHT_PHY = 126,
|
||||||
|
};
|
||||||
|
|
||||||
|
/// MAC rateset maximum length
|
||||||
|
#define MAC_RATESET_LEN 12
|
||||||
|
|
||||||
|
/// Structure containing the legacy rateset of a station
|
||||||
|
struct mac_rateset
|
||||||
|
{
|
||||||
|
/// Number of legacy rates supported
|
||||||
|
u8_l length;
|
||||||
|
/// Array of legacy rates
|
||||||
|
u8_l array[MAC_RATESET_LEN];
|
||||||
|
};
|
||||||
|
|
||||||
|
/// MAC Security Key maximum length
|
||||||
|
#define MAC_SEC_KEY_LEN 32 // TKIP keys 256 bits (max length) with MIC keys
|
||||||
|
|
||||||
|
/// Structure defining a security key
|
||||||
|
struct mac_sec_key
|
||||||
|
{
|
||||||
|
/// Key material length
|
||||||
|
u8_l length;
|
||||||
|
/// Key material
|
||||||
|
u32_l array[MAC_SEC_KEY_LEN/4];
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Access Category enumeration
|
||||||
|
enum mac_ac
|
||||||
|
{
|
||||||
|
/// Background
|
||||||
|
AC_BK = 0,
|
||||||
|
/// Best-effort
|
||||||
|
AC_BE,
|
||||||
|
/// Video
|
||||||
|
AC_VI,
|
||||||
|
/// Voice
|
||||||
|
AC_VO,
|
||||||
|
/// Number of access categories
|
||||||
|
AC_MAX
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Traffic ID enumeration
|
||||||
|
enum mac_tid
|
||||||
|
{
|
||||||
|
/// TID_0. Mapped to @ref AC_BE as per 802.11 standard.
|
||||||
|
TID_0,
|
||||||
|
/// TID_1. Mapped to @ref AC_BK as per 802.11 standard.
|
||||||
|
TID_1,
|
||||||
|
/// TID_2. Mapped to @ref AC_BK as per 802.11 standard.
|
||||||
|
TID_2,
|
||||||
|
/// TID_3. Mapped to @ref AC_BE as per 802.11 standard.
|
||||||
|
TID_3,
|
||||||
|
/// TID_4. Mapped to @ref AC_VI as per 802.11 standard.
|
||||||
|
TID_4,
|
||||||
|
/// TID_5. Mapped to @ref AC_VI as per 802.11 standard.
|
||||||
|
TID_5,
|
||||||
|
/// TID_6. Mapped to @ref AC_VO as per 802.11 standard.
|
||||||
|
TID_6,
|
||||||
|
/// TID_7. Mapped to @ref AC_VO as per 802.11 standard.
|
||||||
|
TID_7,
|
||||||
|
/// Non standard Management TID used internally
|
||||||
|
TID_MGT,
|
||||||
|
/// Number of TID supported
|
||||||
|
TID_MAX
|
||||||
|
};
|
||||||
|
|
||||||
|
/// MCS bitfield maximum size (in bytes)
|
||||||
|
#define MAX_MCS_LEN 16 // 16 * 8 = 128
|
||||||
|
|
||||||
|
/// MAC HT capability information element
|
||||||
|
struct mac_htcapability
|
||||||
|
{
|
||||||
|
/// HT capability information
|
||||||
|
u16_l ht_capa_info;
|
||||||
|
/// A-MPDU parameters
|
||||||
|
u8_l a_mpdu_param;
|
||||||
|
/// Supported MCS
|
||||||
|
u8_l mcs_rate[MAX_MCS_LEN];
|
||||||
|
/// HT extended capability information
|
||||||
|
u16_l ht_extended_capa;
|
||||||
|
/// Beamforming capability information
|
||||||
|
u32_l tx_beamforming_capa;
|
||||||
|
/// Antenna selection capability information
|
||||||
|
u8_l asel_capa;
|
||||||
|
};
|
||||||
|
|
||||||
|
/// MAC VHT capability information element
|
||||||
|
struct mac_vhtcapability
|
||||||
|
{
|
||||||
|
/// VHT capability information
|
||||||
|
u32_l vht_capa_info;
|
||||||
|
/// RX MCS map
|
||||||
|
u16_l rx_mcs_map;
|
||||||
|
/// RX highest data rate
|
||||||
|
u16_l rx_highest;
|
||||||
|
/// TX MCS map
|
||||||
|
u16_l tx_mcs_map;
|
||||||
|
/// TX highest data rate
|
||||||
|
u16_l tx_highest;
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Length (in bytes) of the MAC HE capability field
|
||||||
|
#define MAC_HE_MAC_CAPA_LEN 6
|
||||||
|
/// Length (in bytes) of the PHY HE capability field
|
||||||
|
#define MAC_HE_PHY_CAPA_LEN 11
|
||||||
|
/// Maximum length (in bytes) of the PPE threshold data
|
||||||
|
#define MAC_HE_PPE_THRES_MAX_LEN 25
|
||||||
|
|
||||||
|
/// Structure listing the per-NSS, per-BW supported MCS combinations
|
||||||
|
struct mac_he_mcs_nss_supp
|
||||||
|
{
|
||||||
|
/// per-NSS supported MCS in RX, for BW <= 80MHz
|
||||||
|
u16_l rx_mcs_80;
|
||||||
|
/// per-NSS supported MCS in TX, for BW <= 80MHz
|
||||||
|
u16_l tx_mcs_80;
|
||||||
|
/// per-NSS supported MCS in RX, for BW = 160MHz
|
||||||
|
u16_l rx_mcs_160;
|
||||||
|
/// per-NSS supported MCS in TX, for BW = 160MHz
|
||||||
|
u16_l tx_mcs_160;
|
||||||
|
/// per-NSS supported MCS in RX, for BW = 80+80MHz
|
||||||
|
u16_l rx_mcs_80p80;
|
||||||
|
/// per-NSS supported MCS in TX, for BW = 80+80MHz
|
||||||
|
u16_l tx_mcs_80p80;
|
||||||
|
};
|
||||||
|
|
||||||
|
/// MAC HE capability information element
|
||||||
|
struct mac_hecapability
|
||||||
|
{
|
||||||
|
/// MAC HE capabilities
|
||||||
|
u8_l mac_cap_info[MAC_HE_MAC_CAPA_LEN];
|
||||||
|
/// PHY HE capabilities
|
||||||
|
u8_l phy_cap_info[MAC_HE_PHY_CAPA_LEN];
|
||||||
|
/// Supported MCS combinations
|
||||||
|
struct mac_he_mcs_nss_supp mcs_supp;
|
||||||
|
/// PPE Thresholds data
|
||||||
|
u8_l ppe_thres[MAC_HE_PPE_THRES_MAX_LEN];
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Station flags
|
||||||
|
enum mac_sta_flags
|
||||||
|
{
|
||||||
|
/// Bit indicating that a STA has QoS (WMM) capability
|
||||||
|
STA_QOS_CAPA = BIT(0),
|
||||||
|
/// Bit indicating that a STA has HT capability
|
||||||
|
STA_HT_CAPA = BIT(1),
|
||||||
|
/// Bit indicating that a STA has VHT capability
|
||||||
|
STA_VHT_CAPA = BIT(2),
|
||||||
|
/// Bit indicating that a STA has MFP capability
|
||||||
|
STA_MFP_CAPA = BIT(3),
|
||||||
|
/// Bit indicating that the STA included the Operation Notification IE
|
||||||
|
STA_OPMOD_NOTIF = BIT(4),
|
||||||
|
/// Bit indicating that a STA has HE capability
|
||||||
|
STA_HE_CAPA = BIT(5),
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Connection flags
|
||||||
|
enum mac_connection_flags
|
||||||
|
{
|
||||||
|
/// Flag indicating whether the control port is controlled by host or not
|
||||||
|
CONTROL_PORT_HOST = BIT(0),
|
||||||
|
/// Flag indicating whether the control port frame shall be sent unencrypted
|
||||||
|
CONTROL_PORT_NO_ENC = BIT(1),
|
||||||
|
/// Flag indicating whether HT and VHT shall be disabled or not
|
||||||
|
DISABLE_HT = BIT(2),
|
||||||
|
/// Flag indicating whether WPA or WPA2 authentication is in use
|
||||||
|
WPA_WPA2_IN_USE = BIT(3),
|
||||||
|
/// Flag indicating whether MFP is in use
|
||||||
|
MFP_IN_USE = BIT(4),
|
||||||
|
// Flag indicating Roam
|
||||||
|
REASSOCIATION = BIT(5),
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef CONFIG_HE_FOR_OLD_KERNEL
|
||||||
|
#define IEEE80211_HE_MAC_CAP2_ALL_ACK 0x02
|
||||||
|
#define IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_IN_2G 0x02
|
||||||
|
#define IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_80MHZ_IN_5G 0x04
|
||||||
|
#define IEEE80211_HE_PHY_CAP1_LDPC_CODING_IN_PAYLOAD 0x20
|
||||||
|
#define IEEE80211_HE_PHY_CAP1_HE_LTF_AND_GI_FOR_HE_PPDUS_0_8US 0x40
|
||||||
|
#define IEEE80211_HE_PHY_CAP1_MIDAMBLE_RX_TX_MAX_NSTS 0x80
|
||||||
|
#define IEEE80211_HE_PHY_CAP2_MIDAMBLE_RX_TX_MAX_NSTS 0x01
|
||||||
|
#define IEEE80211_HE_PHY_CAP2_NDP_4x_LTF_AND_3_2US 0x02
|
||||||
|
#define IEEE80211_HE_PHY_CAP2_DOPPLER_RX 0x20
|
||||||
|
#define IEEE80211_HE_PHY_CAP2_STBC_TX_UNDER_80MHZ 0x04
|
||||||
|
#define IEEE80211_HE_PHY_CAP2_STBC_RX_UNDER_80MHZ 0x08
|
||||||
|
#define IEEE80211_HE_PHY_CAP3_DCM_MAX_CONST_RX_16_QAM 0x18
|
||||||
|
#define IEEE80211_HE_PHY_CAP3_DCM_MAX_RX_NSS_1 0x00
|
||||||
|
#define IEEE80211_HE_PHY_CAP3_RX_HE_MU_PPDU_FROM_NON_AP_STA 0x40
|
||||||
|
#define IEEE80211_HE_PHY_CAP4_SU_BEAMFORMEE 0x01
|
||||||
|
#define IEEE80211_HE_PHY_CAP4_BEAMFORMEE_MAX_STS_UNDER_80MHZ_4 0x0c
|
||||||
|
#define IEEE80211_HE_PHY_CAP5_NG16_SU_FEEDBACK 0x40
|
||||||
|
#define IEEE80211_HE_PHY_CAP5_NG16_MU_FEEDBACK 0x80
|
||||||
|
#define IEEE80211_HE_PHY_CAP6_CODEBOOK_SIZE_42_SU 0x01
|
||||||
|
#define IEEE80211_HE_PHY_CAP6_CODEBOOK_SIZE_75_MU 0x02
|
||||||
|
#define IEEE80211_HE_PHY_CAP6_TRIG_SU_BEAMFORMER_FB 0x04
|
||||||
|
#define IEEE80211_HE_PHY_CAP6_TRIG_MU_BEAMFORMER_FB 0x08
|
||||||
|
#define IEEE80211_HE_PHY_CAP6_PPE_THRESHOLD_PRESENT 0x80
|
||||||
|
#define IEEE80211_HE_PHY_CAP6_PARTIAL_BANDWIDTH_DL_MUMIMO 0x40
|
||||||
|
#define IEEE80211_HE_PHY_CAP7_HE_SU_MU_PPDU_4XLTF_AND_08_US_GI 0x04
|
||||||
|
#define IEEE80211_HE_PHY_CAP8_20MHZ_IN_40MHZ_HE_PPDU_IN_2G 0x02
|
||||||
|
#define IEEE80211_HE_PHY_CAP9_RX_FULL_BW_SU_USING_MU_WITH_COMP_SIGB 0x10
|
||||||
|
#define IEEE80211_HE_PHY_CAP9_RX_FULL_BW_SU_USING_MU_WITH_NON_COMP_SIGB 0x20
|
||||||
|
|
||||||
|
struct ieee80211_he_cap_elem {
|
||||||
|
u8 mac_cap_info[6];
|
||||||
|
u8 phy_cap_info[11];
|
||||||
|
} __packed;
|
||||||
|
|
||||||
|
struct ieee80211_he_mcs_nss_supp {
|
||||||
|
__le16 rx_mcs_80;
|
||||||
|
__le16 tx_mcs_80;
|
||||||
|
__le16 rx_mcs_160;
|
||||||
|
__le16 tx_mcs_160;
|
||||||
|
__le16 rx_mcs_80p80;
|
||||||
|
__le16 tx_mcs_80p80;
|
||||||
|
} __packed;
|
||||||
|
|
||||||
|
#define IEEE80211_HE_PPE_THRES_MAX_LEN 25
|
||||||
|
|
||||||
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0)
|
||||||
|
#define WLAN_EID_EXTENSION 255
|
||||||
|
/* Element ID Extensions for Element ID 255 */
|
||||||
|
|
||||||
|
enum ieee80211_eid_ext {
|
||||||
|
WLAN_EID_EXT_ASSOC_DELAY_INFO = 1,
|
||||||
|
WLAN_EID_EXT_FILS_REQ_PARAMS = 2,
|
||||||
|
WLAN_EID_EXT_FILS_KEY_CONFIRM = 3,
|
||||||
|
WLAN_EID_EXT_FILS_SESSION = 4,
|
||||||
|
WLAN_EID_EXT_FILS_HLP_CONTAINER = 5,
|
||||||
|
WLAN_EID_EXT_FILS_IP_ADDR_ASSIGN = 6,
|
||||||
|
WLAN_EID_EXT_KEY_DELIVERY = 7,
|
||||||
|
WLAN_EID_EXT_FILS_WRAPPED_DATA = 8,
|
||||||
|
WLAN_EID_EXT_FILS_PUBLIC_KEY = 12,
|
||||||
|
WLAN_EID_EXT_FILS_NONCE = 13,
|
||||||
|
WLAN_EID_EXT_FUTURE_CHAN_GUIDANCE = 14,
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 19, 0)
|
||||||
|
#define WLAN_EID_EXT_HE_CAPABILITY 35
|
||||||
|
#define WLAN_EID_EXT_HE_OPERATION 36
|
||||||
|
#define WLAN_EID_EXT_UORA 37
|
||||||
|
#define WLAN_EID_EXT_HE_MU_EDCA 38
|
||||||
|
#define WLAN_EID_EXT_HE_SPR 39
|
||||||
|
#define WLAN_EID_EXT_NDP_FEEDBACK_REPORT_PARAMSET 41
|
||||||
|
#define WLAN_EID_EXT_BSS_COLOR_CHG_ANN 42
|
||||||
|
#define WLAN_EID_EXT_QUIET_TIME_PERIOD_SETUP 43
|
||||||
|
#define WLAN_EID_EXT_ESS_REPORT 45
|
||||||
|
#define WLAN_EID_EXT_OPS 46
|
||||||
|
#define WLAN_EID_EXT_HE_BSS_LOAD 47
|
||||||
|
#define WLAN_EID_EXT_MAX_CHANNEL_SWITCH_TIME 52
|
||||||
|
#define WLAN_EID_EXT_MULTIPLE_BSSID_CONFIGURATION 55
|
||||||
|
#define WLAN_EID_EXT_NON_INHERITANCE 56
|
||||||
|
#define WLAN_EID_EXT_KNOWN_BSSID 57
|
||||||
|
#define WLAN_EID_EXT_SHORT_SSID_LIST 58
|
||||||
|
#define WLAN_EID_EXT_HE_6GHZ_CAPA 59
|
||||||
|
#define WLAN_EID_EXT_UL_MU_POWER_CAPA 60
|
||||||
|
#define WLAN_EID_EXT_EHT_OPERATION 106
|
||||||
|
#define WLAN_EID_EXT_EHT_MULTI_LINK 107
|
||||||
|
#define WLAN_EID_EXT_EHT_CAPABILITY 108
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct ieee80211_sta_he_cap {
|
||||||
|
bool has_he;
|
||||||
|
struct ieee80211_he_cap_elem he_cap_elem;
|
||||||
|
struct ieee80211_he_mcs_nss_supp he_mcs_nss_supp;
|
||||||
|
u8 ppe_thres[IEEE80211_HE_PPE_THRES_MAX_LEN];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ieee80211_sband_iftype_data {
|
||||||
|
u16 types_mask;
|
||||||
|
struct ieee80211_sta_he_cap he_cap;
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0) || defined(CONFIG_VHT_FOR_OLD_KERNEL)
|
||||||
|
struct ieee80211_vht_mcs_info {
|
||||||
|
__le16 rx_mcs_map;
|
||||||
|
__le16 rx_highest;
|
||||||
|
__le16 tx_mcs_map;
|
||||||
|
__le16 tx_highest;
|
||||||
|
} __packed;
|
||||||
|
|
||||||
|
struct ieee80211_vht_cap {
|
||||||
|
__le32 vht_cap_info;
|
||||||
|
struct ieee80211_vht_mcs_info supp_mcs;
|
||||||
|
};
|
||||||
|
#define WLAN_EID_VHT_CAPABILITY 191
|
||||||
|
|
||||||
|
struct ieee80211_sta_vht_cap {
|
||||||
|
bool vht_supported;
|
||||||
|
u32 cap; /* use IEEE80211_VHT_CAP_ */
|
||||||
|
struct ieee80211_vht_mcs_info vht_mcs;
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
#endif // LMAC_MAC_H_
|
||||||
3468
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/lmac_msg.h
Normal file
3468
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/lmac_msg.h
Normal file
File diff suppressed because it is too large
Load diff
62
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/lmac_types.h
Executable file
62
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/lmac_types.h
Executable file
|
|
@ -0,0 +1,62 @@
|
||||||
|
/**
|
||||||
|
****************************************************************************************
|
||||||
|
*
|
||||||
|
* @file co_types.h
|
||||||
|
*
|
||||||
|
* @brief This file replaces the need to include stdint or stdbool typical headers,
|
||||||
|
* which may not be available in all toolchains, and adds new types
|
||||||
|
*
|
||||||
|
* Copyright (C) RivieraWaves 2009-2019
|
||||||
|
*
|
||||||
|
* $Rev: $
|
||||||
|
*
|
||||||
|
****************************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _LMAC_INT_H_
|
||||||
|
#define _LMAC_INT_H_
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
****************************************************************************************
|
||||||
|
* @addtogroup CO_INT
|
||||||
|
* @ingroup COMMON
|
||||||
|
* @brief Common integer standard types (removes use of stdint)
|
||||||
|
*
|
||||||
|
* @{
|
||||||
|
****************************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* DEFINES
|
||||||
|
****************************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <linux/version.h>
|
||||||
|
#include <linux/types.h>
|
||||||
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0)
|
||||||
|
#include <linux/bits.h>
|
||||||
|
#else
|
||||||
|
#include <linux/bitops.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_RWNX_TL4
|
||||||
|
typedef uint16_t u8_l;
|
||||||
|
typedef int16_t s8_l;
|
||||||
|
typedef uint16_t bool_l;
|
||||||
|
#else
|
||||||
|
typedef uint8_t u8_l;
|
||||||
|
typedef int8_t s8_l;
|
||||||
|
typedef bool bool_l;
|
||||||
|
#endif
|
||||||
|
typedef uint16_t u16_l;
|
||||||
|
typedef int16_t s16_l;
|
||||||
|
typedef uint32_t u32_l;
|
||||||
|
typedef int32_t s32_l;
|
||||||
|
typedef uint64_t u64_l;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/// @} CO_INT
|
||||||
|
#endif // _LMAC_INT_H_
|
||||||
161
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/md5.c
Normal file
161
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/md5.c
Normal file
|
|
@ -0,0 +1,161 @@
|
||||||
|
#include <linux/memory.h>
|
||||||
|
#include "md5.h"
|
||||||
|
|
||||||
|
unsigned char PADDING[]={0x80,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||||
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||||
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||||
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
|
||||||
|
|
||||||
|
void MD5Init(MD5_CTX *context)
|
||||||
|
{
|
||||||
|
context->count[0] = 0;
|
||||||
|
context->count[1] = 0;
|
||||||
|
context->state[0] = 0x67452301;
|
||||||
|
context->state[1] = 0xEFCDAB89;
|
||||||
|
context->state[2] = 0x98BADCFE;
|
||||||
|
context->state[3] = 0x10325476;
|
||||||
|
}
|
||||||
|
void MD5Update(MD5_CTX *context,unsigned char *input,unsigned int inputlen)
|
||||||
|
{
|
||||||
|
unsigned int i = 0,index = 0,partlen = 0;
|
||||||
|
index = (context->count[0] >> 3) & 0x3F;
|
||||||
|
partlen = 64 - index;
|
||||||
|
context->count[0] += inputlen << 3;
|
||||||
|
if(context->count[0] < (inputlen << 3))
|
||||||
|
context->count[1]++;
|
||||||
|
context->count[1] += inputlen >> 29;
|
||||||
|
|
||||||
|
if(inputlen >= partlen)
|
||||||
|
{
|
||||||
|
memcpy(&context->buffer[index],input,partlen);
|
||||||
|
MD5Transform(context->state,context->buffer);
|
||||||
|
for(i = partlen;i+64 <= inputlen;i+=64)
|
||||||
|
MD5Transform(context->state,&input[i]);
|
||||||
|
index = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
i = 0;
|
||||||
|
}
|
||||||
|
memcpy(&context->buffer[index],&input[i],inputlen-i);
|
||||||
|
}
|
||||||
|
void MD5Final(MD5_CTX *context,unsigned char digest[16])
|
||||||
|
{
|
||||||
|
unsigned int index = 0,padlen = 0;
|
||||||
|
unsigned char bits[8];
|
||||||
|
index = (context->count[0] >> 3) & 0x3F;
|
||||||
|
padlen = (index < 56)?(56-index):(120-index);
|
||||||
|
MD5Encode(bits,context->count,8);
|
||||||
|
MD5Update(context,PADDING,padlen);
|
||||||
|
MD5Update(context,bits,8);
|
||||||
|
MD5Encode(digest,context->state,16);
|
||||||
|
}
|
||||||
|
void MD5Encode(unsigned char *output,unsigned int *input,unsigned int len)
|
||||||
|
{
|
||||||
|
unsigned int i = 0,j = 0;
|
||||||
|
while(j < len)
|
||||||
|
{
|
||||||
|
output[j] = input[i] & 0xFF;
|
||||||
|
output[j+1] = (input[i] >> 8) & 0xFF;
|
||||||
|
output[j+2] = (input[i] >> 16) & 0xFF;
|
||||||
|
output[j+3] = (input[i] >> 24) & 0xFF;
|
||||||
|
i++;
|
||||||
|
j+=4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void MD5Decode(unsigned int *output,unsigned char *input,unsigned int len)
|
||||||
|
{
|
||||||
|
unsigned int i = 0,j = 0;
|
||||||
|
while(j < len)
|
||||||
|
{
|
||||||
|
output[i] = (input[j]) |
|
||||||
|
(input[j+1] << 8) |
|
||||||
|
(input[j+2] << 16) |
|
||||||
|
(input[j+3] << 24);
|
||||||
|
i++;
|
||||||
|
j+=4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void MD5Transform(unsigned int state[4],unsigned char block[64])
|
||||||
|
{
|
||||||
|
unsigned int a = state[0];
|
||||||
|
unsigned int b = state[1];
|
||||||
|
unsigned int c = state[2];
|
||||||
|
unsigned int d = state[3];
|
||||||
|
unsigned int x[64];
|
||||||
|
MD5Decode(x,block,64);
|
||||||
|
FF(a, b, c, d, x[ 0], 7, 0xd76aa478); /* 1 */
|
||||||
|
FF(d, a, b, c, x[ 1], 12, 0xe8c7b756); /* 2 */
|
||||||
|
FF(c, d, a, b, x[ 2], 17, 0x242070db); /* 3 */
|
||||||
|
FF(b, c, d, a, x[ 3], 22, 0xc1bdceee); /* 4 */
|
||||||
|
FF(a, b, c, d, x[ 4], 7, 0xf57c0faf); /* 5 */
|
||||||
|
FF(d, a, b, c, x[ 5], 12, 0x4787c62a); /* 6 */
|
||||||
|
FF(c, d, a, b, x[ 6], 17, 0xa8304613); /* 7 */
|
||||||
|
FF(b, c, d, a, x[ 7], 22, 0xfd469501); /* 8 */
|
||||||
|
FF(a, b, c, d, x[ 8], 7, 0x698098d8); /* 9 */
|
||||||
|
FF(d, a, b, c, x[ 9], 12, 0x8b44f7af); /* 10 */
|
||||||
|
FF(c, d, a, b, x[10], 17, 0xffff5bb1); /* 11 */
|
||||||
|
FF(b, c, d, a, x[11], 22, 0x895cd7be); /* 12 */
|
||||||
|
FF(a, b, c, d, x[12], 7, 0x6b901122); /* 13 */
|
||||||
|
FF(d, a, b, c, x[13], 12, 0xfd987193); /* 14 */
|
||||||
|
FF(c, d, a, b, x[14], 17, 0xa679438e); /* 15 */
|
||||||
|
FF(b, c, d, a, x[15], 22, 0x49b40821); /* 16 */
|
||||||
|
|
||||||
|
/* Round 2 */
|
||||||
|
GG(a, b, c, d, x[ 1], 5, 0xf61e2562); /* 17 */
|
||||||
|
GG(d, a, b, c, x[ 6], 9, 0xc040b340); /* 18 */
|
||||||
|
GG(c, d, a, b, x[11], 14, 0x265e5a51); /* 19 */
|
||||||
|
GG(b, c, d, a, x[ 0], 20, 0xe9b6c7aa); /* 20 */
|
||||||
|
GG(a, b, c, d, x[ 5], 5, 0xd62f105d); /* 21 */
|
||||||
|
GG(d, a, b, c, x[10], 9, 0x2441453); /* 22 */
|
||||||
|
GG(c, d, a, b, x[15], 14, 0xd8a1e681); /* 23 */
|
||||||
|
GG(b, c, d, a, x[ 4], 20, 0xe7d3fbc8); /* 24 */
|
||||||
|
GG(a, b, c, d, x[ 9], 5, 0x21e1cde6); /* 25 */
|
||||||
|
GG(d, a, b, c, x[14], 9, 0xc33707d6); /* 26 */
|
||||||
|
GG(c, d, a, b, x[ 3], 14, 0xf4d50d87); /* 27 */
|
||||||
|
GG(b, c, d, a, x[ 8], 20, 0x455a14ed); /* 28 */
|
||||||
|
GG(a, b, c, d, x[13], 5, 0xa9e3e905); /* 29 */
|
||||||
|
GG(d, a, b, c, x[ 2], 9, 0xfcefa3f8); /* 30 */
|
||||||
|
GG(c, d, a, b, x[ 7], 14, 0x676f02d9); /* 31 */
|
||||||
|
GG(b, c, d, a, x[12], 20, 0x8d2a4c8a); /* 32 */
|
||||||
|
|
||||||
|
/* Round 3 */
|
||||||
|
HH(a, b, c, d, x[ 5], 4, 0xfffa3942); /* 33 */
|
||||||
|
HH(d, a, b, c, x[ 8], 11, 0x8771f681); /* 34 */
|
||||||
|
HH(c, d, a, b, x[11], 16, 0x6d9d6122); /* 35 */
|
||||||
|
HH(b, c, d, a, x[14], 23, 0xfde5380c); /* 36 */
|
||||||
|
HH(a, b, c, d, x[ 1], 4, 0xa4beea44); /* 37 */
|
||||||
|
HH(d, a, b, c, x[ 4], 11, 0x4bdecfa9); /* 38 */
|
||||||
|
HH(c, d, a, b, x[ 7], 16, 0xf6bb4b60); /* 39 */
|
||||||
|
HH(b, c, d, a, x[10], 23, 0xbebfbc70); /* 40 */
|
||||||
|
HH(a, b, c, d, x[13], 4, 0x289b7ec6); /* 41 */
|
||||||
|
HH(d, a, b, c, x[ 0], 11, 0xeaa127fa); /* 42 */
|
||||||
|
HH(c, d, a, b, x[ 3], 16, 0xd4ef3085); /* 43 */
|
||||||
|
HH(b, c, d, a, x[ 6], 23, 0x4881d05); /* 44 */
|
||||||
|
HH(a, b, c, d, x[ 9], 4, 0xd9d4d039); /* 45 */
|
||||||
|
HH(d, a, b, c, x[12], 11, 0xe6db99e5); /* 46 */
|
||||||
|
HH(c, d, a, b, x[15], 16, 0x1fa27cf8); /* 47 */
|
||||||
|
HH(b, c, d, a, x[ 2], 23, 0xc4ac5665); /* 48 */
|
||||||
|
|
||||||
|
/* Round 4 */
|
||||||
|
II(a, b, c, d, x[ 0], 6, 0xf4292244); /* 49 */
|
||||||
|
II(d, a, b, c, x[ 7], 10, 0x432aff97); /* 50 */
|
||||||
|
II(c, d, a, b, x[14], 15, 0xab9423a7); /* 51 */
|
||||||
|
II(b, c, d, a, x[ 5], 21, 0xfc93a039); /* 52 */
|
||||||
|
II(a, b, c, d, x[12], 6, 0x655b59c3); /* 53 */
|
||||||
|
II(d, a, b, c, x[ 3], 10, 0x8f0ccc92); /* 54 */
|
||||||
|
II(c, d, a, b, x[10], 15, 0xffeff47d); /* 55 */
|
||||||
|
II(b, c, d, a, x[ 1], 21, 0x85845dd1); /* 56 */
|
||||||
|
II(a, b, c, d, x[ 8], 6, 0x6fa87e4f); /* 57 */
|
||||||
|
II(d, a, b, c, x[15], 10, 0xfe2ce6e0); /* 58 */
|
||||||
|
II(c, d, a, b, x[ 6], 15, 0xa3014314); /* 59 */
|
||||||
|
II(b, c, d, a, x[13], 21, 0x4e0811a1); /* 60 */
|
||||||
|
II(a, b, c, d, x[ 4], 6, 0xf7537e82); /* 61 */
|
||||||
|
II(d, a, b, c, x[11], 10, 0xbd3af235); /* 62 */
|
||||||
|
II(c, d, a, b, x[ 2], 15, 0x2ad7d2bb); /* 63 */
|
||||||
|
II(b, c, d, a, x[ 9], 21, 0xeb86d391); /* 64 */
|
||||||
|
state[0] += a;
|
||||||
|
state[1] += b;
|
||||||
|
state[2] += c;
|
||||||
|
state[3] += d;
|
||||||
|
}
|
||||||
48
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/md5.h
Normal file
48
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/md5.h
Normal file
|
|
@ -0,0 +1,48 @@
|
||||||
|
#ifndef MD5_H
|
||||||
|
#define MD5_H
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
unsigned int count[2];
|
||||||
|
unsigned int state[4];
|
||||||
|
unsigned char buffer[64];
|
||||||
|
}MD5_CTX;
|
||||||
|
|
||||||
|
|
||||||
|
#define F(x,y,z) ((x & y) | (~x & z))
|
||||||
|
#define G(x,y,z) ((x & z) | (y & ~z))
|
||||||
|
#define H(x,y,z) (x^y^z)
|
||||||
|
#define I(x,y,z) (y ^ (x | ~z))
|
||||||
|
#define ROTATE_LEFT(x,n) ((x << n) | (x >> (32-n)))
|
||||||
|
#define FF(a,b,c,d,x,s,ac) \
|
||||||
|
{ \
|
||||||
|
a += F(b,c,d) + x + ac; \
|
||||||
|
a = ROTATE_LEFT(a,s); \
|
||||||
|
a += b; \
|
||||||
|
}
|
||||||
|
#define GG(a,b,c,d,x,s,ac) \
|
||||||
|
{ \
|
||||||
|
a += G(b,c,d) + x + ac; \
|
||||||
|
a = ROTATE_LEFT(a,s); \
|
||||||
|
a += b; \
|
||||||
|
}
|
||||||
|
#define HH(a,b,c,d,x,s,ac) \
|
||||||
|
{ \
|
||||||
|
a += H(b,c,d) + x + ac; \
|
||||||
|
a = ROTATE_LEFT(a,s); \
|
||||||
|
a += b; \
|
||||||
|
}
|
||||||
|
#define II(a,b,c,d,x,s,ac) \
|
||||||
|
{ \
|
||||||
|
a += I(b,c,d) + x + ac; \
|
||||||
|
a = ROTATE_LEFT(a,s); \
|
||||||
|
a += b; \
|
||||||
|
}
|
||||||
|
void MD5Init(MD5_CTX *context);
|
||||||
|
void MD5Update(MD5_CTX *context,unsigned char *input,unsigned int inputlen);
|
||||||
|
void MD5Final(MD5_CTX *context,unsigned char digest[16]);
|
||||||
|
void MD5Transform(unsigned int state[4],unsigned char block[64]);
|
||||||
|
void MD5Encode(unsigned char *output,unsigned int *input,unsigned int len);
|
||||||
|
void MD5Decode(unsigned int *output,unsigned char *input,unsigned int len);
|
||||||
|
|
||||||
|
#endif
|
||||||
161
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/reg_access.h
Normal file
161
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/reg_access.h
Normal file
|
|
@ -0,0 +1,161 @@
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
*
|
||||||
|
* @file reg_access.h
|
||||||
|
*
|
||||||
|
* @brief Definitions and macros for MAC HW and platform register accesses
|
||||||
|
*
|
||||||
|
* Copyright (C) RivieraWaves 2011-2019
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef REG_ACCESS_H_
|
||||||
|
#define REG_ACCESS_H_
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
* Addresses within RWNX_ADDR_CPU
|
||||||
|
*****************************************************************************/
|
||||||
|
#define RAM_LMAC_FW_ADDR 0x00150000
|
||||||
|
|
||||||
|
#define ROM_FMAC_FW_ADDR 0x00010000
|
||||||
|
#define RAM_FMAC_FW_ADDR 0x00120000
|
||||||
|
#define ROM_FMAC_PATCH_ADDR 0x00180000
|
||||||
|
#if defined(CONFIG_DPD) || defined(CONFIG_LOFT_CALIB)
|
||||||
|
#define ROM_FMAC_CALIB_ADDR 0x00130000
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
* Addresses within RWNX_ADDR_SYSTEM
|
||||||
|
*****************************************************************************/
|
||||||
|
/* Shard RAM */
|
||||||
|
#define SHARED_RAM_START_ADDR 0x00000000
|
||||||
|
|
||||||
|
/* IPC registers */
|
||||||
|
#define IPC_REG_BASE_ADDR 0x00800000
|
||||||
|
|
||||||
|
/* System Controller Registers */
|
||||||
|
#define SYSCTRL_SIGNATURE_ADDR 0x00900000
|
||||||
|
// old diag register name
|
||||||
|
#define SYSCTRL_DIAG_CONF_ADDR 0x00900068
|
||||||
|
#define SYSCTRL_PHYDIAG_CONF_ADDR 0x00900074
|
||||||
|
#define SYSCTRL_RIUDIAG_CONF_ADDR 0x00900078
|
||||||
|
// new diag register name
|
||||||
|
#define SYSCTRL_DIAG_CONF0 0x00900064
|
||||||
|
#define SYSCTRL_DIAG_CONF1 0x00900068
|
||||||
|
#define SYSCTRL_DIAG_CONF2 0x00900074
|
||||||
|
#define SYSCTRL_DIAG_CONF3 0x00900078
|
||||||
|
#define SYSCTRL_MISC_CNTL_ADDR 0x009000E0
|
||||||
|
#define BOOTROM_ENABLE BIT(4)
|
||||||
|
#define FPGA_B_RESET BIT(1)
|
||||||
|
#define SOFT_RESET BIT(0)
|
||||||
|
|
||||||
|
/* MAC platform */
|
||||||
|
#define NXMAC_VERSION_1_ADDR 0x00B00004
|
||||||
|
#define NXMAC_MU_MIMO_TX_BIT BIT(19)
|
||||||
|
#define NXMAC_BFMER_BIT BIT(18)
|
||||||
|
#define NXMAC_BFMEE_BIT BIT(17)
|
||||||
|
#define NXMAC_MAC_80211MH_FORMAT_BIT BIT(16)
|
||||||
|
#define NXMAC_COEX_BIT BIT(14)
|
||||||
|
#define NXMAC_WAPI_BIT BIT(13)
|
||||||
|
#define NXMAC_TPC_BIT BIT(12)
|
||||||
|
#define NXMAC_VHT_BIT BIT(11)
|
||||||
|
#define NXMAC_HT_BIT BIT(10)
|
||||||
|
#define NXMAC_RCE_BIT BIT(8)
|
||||||
|
#define NXMAC_CCMP_BIT BIT(7)
|
||||||
|
#define NXMAC_TKIP_BIT BIT(6)
|
||||||
|
#define NXMAC_WEP_BIT BIT(5)
|
||||||
|
#define NXMAC_SECURITY_BIT BIT(4)
|
||||||
|
#define NXMAC_SME_BIT BIT(3)
|
||||||
|
#define NXMAC_HCCA_BIT BIT(2)
|
||||||
|
#define NXMAC_EDCA_BIT BIT(1)
|
||||||
|
#define NXMAC_QOS_BIT BIT(0)
|
||||||
|
|
||||||
|
#define NXMAC_RX_CNTRL_ADDR 0x00B00060
|
||||||
|
#define NXMAC_EN_DUPLICATE_DETECTION_BIT BIT(31)
|
||||||
|
#define NXMAC_ACCEPT_UNKNOWN_BIT BIT(30)
|
||||||
|
#define NXMAC_ACCEPT_OTHER_DATA_FRAMES_BIT BIT(29)
|
||||||
|
#define NXMAC_ACCEPT_QO_S_NULL_BIT BIT(28)
|
||||||
|
#define NXMAC_ACCEPT_QCFWO_DATA_BIT BIT(27)
|
||||||
|
#define NXMAC_ACCEPT_Q_DATA_BIT BIT(26)
|
||||||
|
#define NXMAC_ACCEPT_CFWO_DATA_BIT BIT(25)
|
||||||
|
#define NXMAC_ACCEPT_DATA_BIT BIT(24)
|
||||||
|
#define NXMAC_ACCEPT_OTHER_CNTRL_FRAMES_BIT BIT(23)
|
||||||
|
#define NXMAC_ACCEPT_CF_END_BIT BIT(22)
|
||||||
|
#define NXMAC_ACCEPT_ACK_BIT BIT(21)
|
||||||
|
#define NXMAC_ACCEPT_CTS_BIT BIT(20)
|
||||||
|
#define NXMAC_ACCEPT_RTS_BIT BIT(19)
|
||||||
|
#define NXMAC_ACCEPT_PS_POLL_BIT BIT(18)
|
||||||
|
#define NXMAC_ACCEPT_BA_BIT BIT(17)
|
||||||
|
#define NXMAC_ACCEPT_BAR_BIT BIT(16)
|
||||||
|
#define NXMAC_ACCEPT_OTHER_MGMT_FRAMES_BIT BIT(15)
|
||||||
|
#define NXMAC_ACCEPT_BFMEE_FRAMES_BIT BIT(14)
|
||||||
|
#define NXMAC_ACCEPT_ALL_BEACON_BIT BIT(13)
|
||||||
|
#define NXMAC_ACCEPT_NOT_EXPECTED_BA_BIT BIT(12)
|
||||||
|
#define NXMAC_ACCEPT_DECRYPT_ERROR_FRAMES_BIT BIT(11)
|
||||||
|
#define NXMAC_ACCEPT_BEACON_BIT BIT(10)
|
||||||
|
#define NXMAC_ACCEPT_PROBE_RESP_BIT BIT(9)
|
||||||
|
#define NXMAC_ACCEPT_PROBE_REQ_BIT BIT(8)
|
||||||
|
#define NXMAC_ACCEPT_MY_UNICAST_BIT BIT(7)
|
||||||
|
#define NXMAC_ACCEPT_UNICAST_BIT BIT(6)
|
||||||
|
#define NXMAC_ACCEPT_ERROR_FRAMES_BIT BIT(5)
|
||||||
|
#define NXMAC_ACCEPT_OTHER_BSSID_BIT BIT(4)
|
||||||
|
#define NXMAC_ACCEPT_BROADCAST_BIT BIT(3)
|
||||||
|
#define NXMAC_ACCEPT_MULTICAST_BIT BIT(2)
|
||||||
|
#define NXMAC_DONT_DECRYPT_BIT BIT(1)
|
||||||
|
#define NXMAC_EXC_UNENCRYPTED_BIT BIT(0)
|
||||||
|
|
||||||
|
#define NXMAC_DEBUG_PORT_SEL_ADDR 0x00B00510
|
||||||
|
#define NXMAC_SW_SET_PROFILING_ADDR 0x00B08564
|
||||||
|
#define NXMAC_SW_CLEAR_PROFILING_ADDR 0x00B08568
|
||||||
|
|
||||||
|
/* Modem Status */
|
||||||
|
#define MDM_HDMCONFIG_ADDR 0x00C00000
|
||||||
|
|
||||||
|
/* Clock gating configuration */
|
||||||
|
#define MDM_MEMCLKCTRL0_ADDR 0x00C00848
|
||||||
|
#define MDM_CLKGATEFCTRL0_ADDR 0x00C00874
|
||||||
|
#define CRM_CLKGATEFCTRL0_ADDR 0x00940010
|
||||||
|
|
||||||
|
/* AGC (trident) */
|
||||||
|
#define AGC_RWNXAGCCNTL_ADDR 0x00C02060
|
||||||
|
|
||||||
|
/* LDPC RAM*/
|
||||||
|
#define PHY_LDPC_RAM_ADDR 0x00C09000
|
||||||
|
|
||||||
|
/* FCU (elma )*/
|
||||||
|
#define FCU_RWNXFCAGCCNTL_ADDR 0x00C09034
|
||||||
|
|
||||||
|
/* AGC RAM */
|
||||||
|
#define PHY_AGC_UCODE_ADDR 0x00C0A000
|
||||||
|
|
||||||
|
/* RIU */
|
||||||
|
#define RIU_RWNXVERSION_ADDR 0x00C0B000
|
||||||
|
#define RIU_RWNXDYNAMICCONFIG_ADDR 0x00C0B008
|
||||||
|
#define RIU_AGCMEMBISTSTAT_ADDR 0x00C0B238
|
||||||
|
#define RIU_AGCMEMSIGNATURESTAT_ADDR 0x00C0B23C
|
||||||
|
#define RIU_RWNXAGCCNTL_ADDR 0x00C0B390
|
||||||
|
|
||||||
|
/* FCU RAM */
|
||||||
|
#define PHY_FCU_UCODE_ADDR 0x00C0E000
|
||||||
|
|
||||||
|
/* RF ITF */
|
||||||
|
#define FPGAB_MPIF_SEL_ADDR 0x00C10030
|
||||||
|
#define RF_V6_DIAGPORT_CONF1_ADDR 0x00C10010
|
||||||
|
#define RF_v6_PHYDIAG_CONF1_ADDR 0x00C10018
|
||||||
|
|
||||||
|
#define RF_V7_DIAGPORT_CONF1_ADDR 0x00F10010
|
||||||
|
#define RF_v7_PHYDIAG_CONF1_ADDR 0x00F10018
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
* Macros for generated register files
|
||||||
|
*****************************************************************************/
|
||||||
|
/* Macros for IPC registers access (used in reg_ipc_app.h) */
|
||||||
|
#define REG_IPC_APP_RD(env, INDEX) \
|
||||||
|
(*(volatile u32*)((u8*)env + IPC_REG_BASE_ADDR + 4*(INDEX)))
|
||||||
|
|
||||||
|
#define REG_IPC_APP_WR(env, INDEX, value) \
|
||||||
|
(*(volatile u32*)((u8*)env + IPC_REG_BASE_ADDR + 4*(INDEX)) = value)
|
||||||
|
|
||||||
|
#endif /* REG_ACCESS_H_ */
|
||||||
299
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/reg_ipc_app.h
Normal file
299
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/reg_ipc_app.h
Normal file
|
|
@ -0,0 +1,299 @@
|
||||||
|
/**
|
||||||
|
****************************************************************************************
|
||||||
|
*
|
||||||
|
* @file rwnx_ipc_app.h
|
||||||
|
*
|
||||||
|
* @brief IPC module register definitions
|
||||||
|
*
|
||||||
|
* Copyright (C) RivieraWaves 2011-2019
|
||||||
|
*
|
||||||
|
****************************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _REG_IPC_APP_H_
|
||||||
|
#define _REG_IPC_APP_H_
|
||||||
|
|
||||||
|
#ifndef __KERNEL__
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "arch.h"
|
||||||
|
#else
|
||||||
|
#include "ipc_compat.h"
|
||||||
|
#endif
|
||||||
|
#include "reg_access.h"
|
||||||
|
|
||||||
|
#define REG_IPC_APP_DECODING_MASK 0x0000007F
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief APP2EMB_TRIGGER register definition
|
||||||
|
* <pre>
|
||||||
|
* Bits Field Name Reset Value
|
||||||
|
* ----- ------------------ -----------
|
||||||
|
* 31:00 APP2EMB_TRIGGER 0x0
|
||||||
|
* </pre>
|
||||||
|
*/
|
||||||
|
#define IPC_APP2EMB_TRIGGER_ADDR 0x12000000
|
||||||
|
#define IPC_APP2EMB_TRIGGER_OFFSET 0x00000000
|
||||||
|
#define IPC_APP2EMB_TRIGGER_INDEX 0x00000000
|
||||||
|
#define IPC_APP2EMB_TRIGGER_RESET 0x00000000
|
||||||
|
|
||||||
|
__INLINE u32 ipc_app2emb_trigger_get(void *env)
|
||||||
|
{
|
||||||
|
return REG_IPC_APP_RD(env, IPC_APP2EMB_TRIGGER_INDEX);
|
||||||
|
}
|
||||||
|
|
||||||
|
__INLINE void ipc_app2emb_trigger_set(void *env, u32 value)
|
||||||
|
{
|
||||||
|
REG_IPC_APP_WR(env, IPC_APP2EMB_TRIGGER_INDEX, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
// field definitions
|
||||||
|
#define IPC_APP2EMB_TRIGGER_MASK ((u32)0xFFFFFFFF)
|
||||||
|
#define IPC_APP2EMB_TRIGGER_LSB 0
|
||||||
|
#define IPC_APP2EMB_TRIGGER_WIDTH ((u32)0x00000020)
|
||||||
|
|
||||||
|
#define IPC_APP2EMB_TRIGGER_RST 0x0
|
||||||
|
|
||||||
|
__INLINE u32 ipc_app2emb_trigger_getf(void *env)
|
||||||
|
{
|
||||||
|
u32 localVal = REG_IPC_APP_RD(env, IPC_APP2EMB_TRIGGER_INDEX);
|
||||||
|
ASSERT_ERR((localVal & ~((u32)0xFFFFFFFF)) == 0);
|
||||||
|
return (localVal >> 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
__INLINE void ipc_app2emb_trigger_setf(void *env, u32 app2embtrigger)
|
||||||
|
{
|
||||||
|
ASSERT_ERR((((u32)app2embtrigger << 0) & ~((u32)0xFFFFFFFF)) == 0);
|
||||||
|
REG_IPC_APP_WR(env, IPC_APP2EMB_TRIGGER_INDEX, (u32)app2embtrigger << 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief EMB2APP_RAWSTATUS register definition
|
||||||
|
* <pre>
|
||||||
|
* Bits Field Name Reset Value
|
||||||
|
* ----- ------------------ -----------
|
||||||
|
* 31:00 EMB2APP_RAWSTATUS 0x0
|
||||||
|
* </pre>
|
||||||
|
*/
|
||||||
|
#define IPC_EMB2APP_RAWSTATUS_ADDR 0x12000004
|
||||||
|
#define IPC_EMB2APP_RAWSTATUS_OFFSET 0x00000004
|
||||||
|
#define IPC_EMB2APP_RAWSTATUS_INDEX 0x00000001
|
||||||
|
#define IPC_EMB2APP_RAWSTATUS_RESET 0x00000000
|
||||||
|
|
||||||
|
__INLINE u32 ipc_emb2app_rawstatus_get(void *env)
|
||||||
|
{
|
||||||
|
return REG_IPC_APP_RD(env, IPC_EMB2APP_RAWSTATUS_INDEX);
|
||||||
|
}
|
||||||
|
|
||||||
|
__INLINE void ipc_emb2app_rawstatus_set(void *env, u32 value)
|
||||||
|
{
|
||||||
|
REG_IPC_APP_WR(env, IPC_EMB2APP_RAWSTATUS_INDEX, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
// field definitions
|
||||||
|
#define IPC_EMB2APP_RAWSTATUS_MASK ((u32)0xFFFFFFFF)
|
||||||
|
#define IPC_EMB2APP_RAWSTATUS_LSB 0
|
||||||
|
#define IPC_EMB2APP_RAWSTATUS_WIDTH ((u32)0x00000020)
|
||||||
|
|
||||||
|
#define IPC_EMB2APP_RAWSTATUS_RST 0x0
|
||||||
|
|
||||||
|
__INLINE u32 ipc_emb2app_rawstatus_getf(void *env)
|
||||||
|
{
|
||||||
|
u32 localVal = REG_IPC_APP_RD(env, IPC_EMB2APP_RAWSTATUS_INDEX);
|
||||||
|
ASSERT_ERR((localVal & ~((u32)0xFFFFFFFF)) == 0);
|
||||||
|
return (localVal >> 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief EMB2APP_ACK register definition
|
||||||
|
* <pre>
|
||||||
|
* Bits Field Name Reset Value
|
||||||
|
* ----- ------------------ -----------
|
||||||
|
* 31:00 EMB2APP_ACK 0x0
|
||||||
|
* </pre>
|
||||||
|
*/
|
||||||
|
#define IPC_EMB2APP_ACK_ADDR 0x12000008
|
||||||
|
#define IPC_EMB2APP_ACK_OFFSET 0x00000008
|
||||||
|
#define IPC_EMB2APP_ACK_INDEX 0x00000002
|
||||||
|
#define IPC_EMB2APP_ACK_RESET 0x00000000
|
||||||
|
|
||||||
|
__INLINE u32 ipc_emb2app_ack_get(void *env)
|
||||||
|
{
|
||||||
|
return REG_IPC_APP_RD(env, IPC_EMB2APP_ACK_INDEX);
|
||||||
|
}
|
||||||
|
|
||||||
|
__INLINE void ipc_emb2app_ack_clear(void *env, u32 value)
|
||||||
|
{
|
||||||
|
REG_IPC_APP_WR(env, IPC_EMB2APP_ACK_INDEX, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
// field definitions
|
||||||
|
#define IPC_EMB2APP_ACK_MASK ((u32)0xFFFFFFFF)
|
||||||
|
#define IPC_EMB2APP_ACK_LSB 0
|
||||||
|
#define IPC_EMB2APP_ACK_WIDTH ((u32)0x00000020)
|
||||||
|
|
||||||
|
#define IPC_EMB2APP_ACK_RST 0x0
|
||||||
|
|
||||||
|
__INLINE u32 ipc_emb2app_ack_getf(void *env)
|
||||||
|
{
|
||||||
|
u32 localVal = REG_IPC_APP_RD(env, IPC_EMB2APP_ACK_INDEX);
|
||||||
|
ASSERT_ERR((localVal & ~((u32)0xFFFFFFFF)) == 0);
|
||||||
|
return (localVal >> 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
__INLINE void ipc_emb2app_ack_clearf(void *env, u32 emb2appack)
|
||||||
|
{
|
||||||
|
ASSERT_ERR((((u32)emb2appack << 0) & ~((u32)0xFFFFFFFF)) == 0);
|
||||||
|
REG_IPC_APP_WR(env, IPC_EMB2APP_ACK_INDEX, (u32)emb2appack << 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief EMB2APP_UNMASK_SET register definition
|
||||||
|
* <pre>
|
||||||
|
* Bits Field Name Reset Value
|
||||||
|
* ----- ------------------ -----------
|
||||||
|
* 31:00 EMB2APP_UNMASK 0x0
|
||||||
|
* </pre>
|
||||||
|
*/
|
||||||
|
#define IPC_EMB2APP_UNMASK_SET_ADDR 0x1200000C
|
||||||
|
#define IPC_EMB2APP_UNMASK_SET_OFFSET 0x0000000C
|
||||||
|
#define IPC_EMB2APP_UNMASK_SET_INDEX 0x00000003
|
||||||
|
#define IPC_EMB2APP_UNMASK_SET_RESET 0x00000000
|
||||||
|
|
||||||
|
__INLINE u32 ipc_emb2app_unmask_get(void *env)
|
||||||
|
{
|
||||||
|
return REG_IPC_APP_RD(env, IPC_EMB2APP_UNMASK_SET_INDEX);
|
||||||
|
}
|
||||||
|
|
||||||
|
__INLINE void ipc_emb2app_unmask_set(void *env, u32 value)
|
||||||
|
{
|
||||||
|
REG_IPC_APP_WR(env, IPC_EMB2APP_UNMASK_SET_INDEX, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
// field definitions
|
||||||
|
#define IPC_EMB2APP_UNMASK_MASK ((u32)0xFFFFFFFF)
|
||||||
|
#define IPC_EMB2APP_UNMASK_LSB 0
|
||||||
|
#define IPC_EMB2APP_UNMASK_WIDTH ((u32)0x00000020)
|
||||||
|
|
||||||
|
#define IPC_EMB2APP_UNMASK_RST 0x0
|
||||||
|
|
||||||
|
__INLINE u32 ipc_emb2app_unmask_getf(void *env)
|
||||||
|
{
|
||||||
|
u32 localVal = REG_IPC_APP_RD(env, IPC_EMB2APP_UNMASK_SET_INDEX);
|
||||||
|
ASSERT_ERR((localVal & ~((u32)0xFFFFFFFF)) == 0);
|
||||||
|
return (localVal >> 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
__INLINE void ipc_emb2app_unmask_setf(void *env, u32 emb2appunmask)
|
||||||
|
{
|
||||||
|
ASSERT_ERR((((u32)emb2appunmask << 0) & ~((u32)0xFFFFFFFF)) == 0);
|
||||||
|
REG_IPC_APP_WR(env, IPC_EMB2APP_UNMASK_SET_INDEX, (u32)emb2appunmask << 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief EMB2APP_UNMASK_CLEAR register definition
|
||||||
|
* <pre>
|
||||||
|
* Bits Field Name Reset Value
|
||||||
|
* ----- ------------------ -----------
|
||||||
|
* 31:00 EMB2APP_UNMASK 0x0
|
||||||
|
* </pre>
|
||||||
|
*/
|
||||||
|
#define IPC_EMB2APP_UNMASK_CLEAR_ADDR 0x12000010
|
||||||
|
#define IPC_EMB2APP_UNMASK_CLEAR_OFFSET 0x00000010
|
||||||
|
#define IPC_EMB2APP_UNMASK_CLEAR_INDEX 0x00000004
|
||||||
|
#define IPC_EMB2APP_UNMASK_CLEAR_RESET 0x00000000
|
||||||
|
|
||||||
|
__INLINE void ipc_emb2app_unmask_clear(void *env, u32 value)
|
||||||
|
{
|
||||||
|
REG_IPC_APP_WR(env, IPC_EMB2APP_UNMASK_CLEAR_INDEX, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
// fields defined in symmetrical set/clear register
|
||||||
|
__INLINE void ipc_emb2app_unmask_clearf(void *env, u32 emb2appunmask)
|
||||||
|
{
|
||||||
|
ASSERT_ERR((((u32)emb2appunmask << 0) & ~((u32)0xFFFFFFFF)) == 0);
|
||||||
|
REG_IPC_APP_WR(env, IPC_EMB2APP_UNMASK_CLEAR_INDEX, (u32)emb2appunmask << 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief EMB2APP_STATUS register definition
|
||||||
|
* <pre>
|
||||||
|
* Bits Field Name Reset Value
|
||||||
|
* ----- ------------------ -----------
|
||||||
|
* 31:00 EMB2APP_STATUS 0x0
|
||||||
|
* </pre>
|
||||||
|
*/
|
||||||
|
#ifdef CONFIG_RWNX_OLD_IPC
|
||||||
|
#define IPC_EMB2APP_STATUS_ADDR 0x12000014
|
||||||
|
#define IPC_EMB2APP_STATUS_OFFSET 0x00000014
|
||||||
|
#define IPC_EMB2APP_STATUS_INDEX 0x00000005
|
||||||
|
#else
|
||||||
|
#define IPC_EMB2APP_STATUS_ADDR 0x1200001C
|
||||||
|
#define IPC_EMB2APP_STATUS_OFFSET 0x0000001C
|
||||||
|
#define IPC_EMB2APP_STATUS_INDEX 0x00000007
|
||||||
|
#endif
|
||||||
|
#define IPC_EMB2APP_STATUS_RESET 0x00000000
|
||||||
|
|
||||||
|
__INLINE u32 ipc_emb2app_status_get(void *env)
|
||||||
|
{
|
||||||
|
return REG_IPC_APP_RD(env, IPC_EMB2APP_STATUS_INDEX);
|
||||||
|
}
|
||||||
|
|
||||||
|
__INLINE void ipc_emb2app_status_set(void *env, u32 value)
|
||||||
|
{
|
||||||
|
REG_IPC_APP_WR(env, IPC_EMB2APP_STATUS_INDEX, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
// field definitions
|
||||||
|
#define IPC_EMB2APP_STATUS_MASK ((u32)0xFFFFFFFF)
|
||||||
|
#define IPC_EMB2APP_STATUS_LSB 0
|
||||||
|
#define IPC_EMB2APP_STATUS_WIDTH ((u32)0x00000020)
|
||||||
|
|
||||||
|
#define IPC_EMB2APP_STATUS_RST 0x0
|
||||||
|
|
||||||
|
__INLINE u32 ipc_emb2app_status_getf(void *env)
|
||||||
|
{
|
||||||
|
u32 localVal = REG_IPC_APP_RD(env, IPC_EMB2APP_STATUS_INDEX);
|
||||||
|
ASSERT_ERR((localVal & ~((u32)0xFFFFFFFF)) == 0);
|
||||||
|
return (localVal >> 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief APP_SIGNATURE register definition
|
||||||
|
* <pre>
|
||||||
|
* Bits Field Name Reset Value
|
||||||
|
* ----- ------------------ ----------
|
||||||
|
* 31:00 APP_SIGNATURE 0x0
|
||||||
|
* </pre>
|
||||||
|
*/
|
||||||
|
#define IPC_APP_SIGNATURE_ADDR 0x12000040
|
||||||
|
#define IPC_APP_SIGNATURE_OFFSET 0x00000040
|
||||||
|
#define IPC_APP_SIGNATURE_INDEX 0x00000010
|
||||||
|
#define IPC_APP_SIGNATURE_RESET 0x00000000
|
||||||
|
|
||||||
|
__INLINE u32 ipc_app_signature_get(void *env)
|
||||||
|
{
|
||||||
|
return REG_IPC_APP_RD(env, IPC_APP_SIGNATURE_INDEX);
|
||||||
|
}
|
||||||
|
|
||||||
|
__INLINE void ipc_app_signature_set(void *env, u32 value)
|
||||||
|
{
|
||||||
|
REG_IPC_APP_WR(env, IPC_APP_SIGNATURE_INDEX, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
// field definitions
|
||||||
|
#define IPC_APP_SIGNATURE_MASK ((u32)0xFFFFFFFF)
|
||||||
|
#define IPC_APP_SIGNATURE_LSB 0
|
||||||
|
#define IPC_APP_SIGNATURE_WIDTH ((u32)0x00000020)
|
||||||
|
|
||||||
|
#define IPC_APP_SIGNATURE_RST 0x0
|
||||||
|
|
||||||
|
__INLINE u32 ipc_app_signature_getf(void *env)
|
||||||
|
{
|
||||||
|
u32 localVal = REG_IPC_APP_RD(env, IPC_APP_SIGNATURE_INDEX);
|
||||||
|
ASSERT_ERR((localVal & ~((u32)0xFFFFFFFF)) == 0);
|
||||||
|
return (localVal >> 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif // _REG_IPC_APP_H_
|
||||||
|
|
||||||
2878
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/regdb.c
Normal file
2878
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/regdb.c
Normal file
File diff suppressed because it is too large
Load diff
105
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/rwnx_bfmer.c
Normal file
105
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/rwnx_bfmer.c
Normal file
|
|
@ -0,0 +1,105 @@
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
*
|
||||||
|
* @file rwnx_bfmer.c
|
||||||
|
*
|
||||||
|
* @brief VHT Beamformer function definitions
|
||||||
|
*
|
||||||
|
* Copyright (C) RivieraWaves 2016-2019
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* INCLUDE FILES
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <linux/slab.h>
|
||||||
|
#include "rwnx_bfmer.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* FUNCTION DEFINITIONS
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
int rwnx_bfmer_report_add(struct rwnx_hw *rwnx_hw, struct rwnx_sta *rwnx_sta,
|
||||||
|
unsigned int length)
|
||||||
|
{
|
||||||
|
gfp_t flags;
|
||||||
|
struct rwnx_bfmer_report *bfm_report ;
|
||||||
|
|
||||||
|
if (in_softirq())
|
||||||
|
flags = GFP_ATOMIC;
|
||||||
|
else
|
||||||
|
flags = GFP_KERNEL;
|
||||||
|
|
||||||
|
/* Allocate a structure that will contain the beamforming report */
|
||||||
|
bfm_report = kmalloc(sizeof(*bfm_report) + length, flags);
|
||||||
|
|
||||||
|
|
||||||
|
/* Check report allocation */
|
||||||
|
if (!bfm_report) {
|
||||||
|
/* Do not use beamforming */
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Store report length */
|
||||||
|
bfm_report->length = length;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Need to provide a Virtual Address to the MAC so that it can
|
||||||
|
* upload the received Beamforming Report in driver memory
|
||||||
|
*/
|
||||||
|
bfm_report->dma_addr = dma_map_single(rwnx_hw->dev, &bfm_report->report[0],
|
||||||
|
length, DMA_FROM_DEVICE);
|
||||||
|
|
||||||
|
/* Check DMA mapping result */
|
||||||
|
if (dma_mapping_error(rwnx_hw->dev, bfm_report->dma_addr)) {
|
||||||
|
/* Free allocated report */
|
||||||
|
kfree(bfm_report);
|
||||||
|
/* And leave */
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Store report structure */
|
||||||
|
rwnx_sta->bfm_report = bfm_report;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void rwnx_bfmer_report_del(struct rwnx_hw *rwnx_hw, struct rwnx_sta *rwnx_sta)
|
||||||
|
{
|
||||||
|
/* Verify if a report has been allocated */
|
||||||
|
if (rwnx_sta->bfm_report) {
|
||||||
|
struct rwnx_bfmer_report *bfm_report = rwnx_sta->bfm_report;
|
||||||
|
|
||||||
|
/* Unmap DMA region */
|
||||||
|
dma_unmap_single(rwnx_hw->dev, bfm_report->dma_addr,
|
||||||
|
bfm_report->length, DMA_BIDIRECTIONAL);
|
||||||
|
|
||||||
|
/* Free allocated report structure and clean the pointer */
|
||||||
|
kfree(bfm_report);
|
||||||
|
rwnx_sta->bfm_report = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_RWNX_FULLMAC
|
||||||
|
u8 rwnx_bfmer_get_rx_nss(const struct ieee80211_vht_cap *vht_capa)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
u8 rx_nss = 0;
|
||||||
|
u16 rx_mcs_map = le16_to_cpu(vht_capa->supp_mcs.rx_mcs_map);
|
||||||
|
|
||||||
|
for (i = 7; i >= 0; i--) {
|
||||||
|
u8 mcs = (rx_mcs_map >> (2 * i)) & 3;
|
||||||
|
|
||||||
|
if (mcs != IEEE80211_VHT_MCS_NOT_SUPPORTED) {
|
||||||
|
rx_nss = i + 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return rx_nss;
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_RWNX_FULLMAC */
|
||||||
100
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/rwnx_bfmer.h
Normal file
100
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/rwnx_bfmer.h
Normal file
|
|
@ -0,0 +1,100 @@
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
*
|
||||||
|
* @file rwnx_bfmer.h
|
||||||
|
*
|
||||||
|
* @brief VHT Beamformer function declarations
|
||||||
|
*
|
||||||
|
* Copyright (C) RivieraWaves 2016-2019
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _RWNX_BFMER_H_
|
||||||
|
#define _RWNX_BFMER_H_
|
||||||
|
|
||||||
|
/**
|
||||||
|
* INCLUDE FILES
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "rwnx_defs.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DEFINES
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
/// Maximal supported report length (in bytes)
|
||||||
|
#define RWNX_BFMER_REPORT_MAX_LEN 2048
|
||||||
|
|
||||||
|
/// Size of the allocated report space (twice the maximum report length)
|
||||||
|
#define RWNX_BFMER_REPORT_SPACE_SIZE (RWNX_BFMER_REPORT_MAX_LEN * 2)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TYPE DEFINITIONS
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Structure used to store a beamforming report.
|
||||||
|
*/
|
||||||
|
struct rwnx_bfmer_report {
|
||||||
|
dma_addr_t dma_addr; /* Virtual address provided to MAC for
|
||||||
|
DMA transfer of the Beamforming Report */
|
||||||
|
unsigned int length; /* Report Length */
|
||||||
|
u8 report[1]; /* Report to be used for VHT TX Beamforming */
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* FUNCTION DECLARATIONS
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* @brief Allocate memory aiming to contains the Beamforming Report received
|
||||||
|
* from a Beamformee capable capable.
|
||||||
|
* The providing length shall be large enough to contain the VHT Compressed
|
||||||
|
* Beaforming Report and the MU Exclusive part.
|
||||||
|
* It also perform a DMA Mapping providing an address to be provided to the HW
|
||||||
|
* responsible for the DMA transfer of the report.
|
||||||
|
* If successful a struct rwnx_bfmer_report object is allocated, it's address
|
||||||
|
* is stored in rwnx_sta->bfm_report.
|
||||||
|
*
|
||||||
|
* @param[in] rwnx_hw PHY Information
|
||||||
|
* @param[in] rwnx_sta Peer STA Information
|
||||||
|
* @param[in] length Memory size to be allocated
|
||||||
|
*
|
||||||
|
* @return 0 if operation is successful, else -1.
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
int rwnx_bfmer_report_add(struct rwnx_hw *rwnx_hw, struct rwnx_sta *rwnx_sta,
|
||||||
|
unsigned int length);
|
||||||
|
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* @brief Free a previously allocated memory intended to be used for
|
||||||
|
* Beamforming Reports.
|
||||||
|
*
|
||||||
|
* @param[in] rwnx_hw PHY Information
|
||||||
|
* @param[in] rwnx_sta Peer STA Information
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
void rwnx_bfmer_report_del(struct rwnx_hw *rwnx_hw, struct rwnx_sta *rwnx_sta);
|
||||||
|
|
||||||
|
#ifdef CONFIG_RWNX_FULLMAC
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* @brief Parse a Rx VHT-MCS map in order to deduce the maximum number of
|
||||||
|
* Spatial Streams supported by a beamformee.
|
||||||
|
*
|
||||||
|
* @param[in] vht_capa Received VHT Capability field.
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
u8 rwnx_bfmer_get_rx_nss(const struct ieee80211_vht_cap *vht_capa);
|
||||||
|
#endif /* CONFIG_RWNX_FULLMAC */
|
||||||
|
|
||||||
|
#endif /* _RWNX_BFMER_H_ */
|
||||||
237
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/rwnx_cfgfile.c
Normal file
237
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/rwnx_cfgfile.c
Normal file
|
|
@ -0,0 +1,237 @@
|
||||||
|
/**
|
||||||
|
****************************************************************************************
|
||||||
|
*
|
||||||
|
* @file rwnx_configparse.c
|
||||||
|
*
|
||||||
|
* Copyright (C) RivieraWaves 2012-2019
|
||||||
|
*
|
||||||
|
****************************************************************************************
|
||||||
|
*/
|
||||||
|
#include <linux/firmware.h>
|
||||||
|
#include <linux/if_ether.h>
|
||||||
|
|
||||||
|
#include "rwnx_defs.h"
|
||||||
|
#include "rwnx_cfgfile.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
static const char *rwnx_find_tag(const u8 *file_data, unsigned int file_size,
|
||||||
|
const char *tag_name, unsigned int tag_len)
|
||||||
|
{
|
||||||
|
unsigned int curr, line_start = 0, line_size;
|
||||||
|
|
||||||
|
RWNX_DBG(RWNX_FN_ENTRY_STR);
|
||||||
|
|
||||||
|
/* Walk through all the lines of the configuration file */
|
||||||
|
while (line_start < file_size) {
|
||||||
|
/* Search the end of the current line (or the end of the file) */
|
||||||
|
for (curr = line_start; curr < file_size; curr++)
|
||||||
|
if (file_data[curr] == '\n')
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* Compute the line size */
|
||||||
|
line_size = curr - line_start;
|
||||||
|
|
||||||
|
/* Check if this line contains the expected tag */
|
||||||
|
if ((line_size == (strlen(tag_name) + tag_len)) &&
|
||||||
|
(!strncmp(&file_data[line_start], tag_name, strlen(tag_name))))
|
||||||
|
return (&file_data[line_start + strlen(tag_name)]);
|
||||||
|
|
||||||
|
/* Move to next line */
|
||||||
|
line_start = curr + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Tag not found */
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse the Config file used at init time
|
||||||
|
*/
|
||||||
|
int rwnx_parse_configfile(struct rwnx_hw *rwnx_hw, const char *filename,
|
||||||
|
struct rwnx_conf_file *config)
|
||||||
|
{
|
||||||
|
const struct firmware *config_fw;
|
||||||
|
u8 dflt_mac[ETH_ALEN] = { 0, 111, 111, 111, 111, 0 };
|
||||||
|
int ret;
|
||||||
|
const u8 *tag_ptr;
|
||||||
|
|
||||||
|
RWNX_DBG(RWNX_FN_ENTRY_STR);
|
||||||
|
|
||||||
|
if ((ret = request_firmware(&config_fw, filename, rwnx_hw->dev))) {
|
||||||
|
printk(KERN_CRIT "%s: Failed to get %s (%d)\n", __func__, filename, ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get MAC Address */
|
||||||
|
tag_ptr = rwnx_find_tag(config_fw->data, config_fw->size,
|
||||||
|
"MAC_ADDR=", strlen("00:00:00:00:00:00"));
|
||||||
|
if (tag_ptr != NULL) {
|
||||||
|
u8 *addr = config->mac_addr;
|
||||||
|
if (sscanf(tag_ptr,
|
||||||
|
"%hhx:%hhx:%hhx:%hhx:%hhx:%hhx",
|
||||||
|
addr + 0, addr + 1, addr + 2,
|
||||||
|
addr + 3, addr + 4, addr + 5) != ETH_ALEN)
|
||||||
|
memcpy(config->mac_addr, dflt_mac, ETH_ALEN);
|
||||||
|
} else
|
||||||
|
memcpy(config->mac_addr, dflt_mac, ETH_ALEN);
|
||||||
|
|
||||||
|
RWNX_DBG("MAC Address is:\n%pM\n", config->mac_addr);
|
||||||
|
|
||||||
|
/* Release the configuration file */
|
||||||
|
release_firmware(config_fw);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse the Config file used at init time
|
||||||
|
*/
|
||||||
|
int rwnx_parse_phy_configfile(struct rwnx_hw *rwnx_hw, const char *filename,
|
||||||
|
struct rwnx_phy_conf_file *config, int path)
|
||||||
|
{
|
||||||
|
const struct firmware *config_fw;
|
||||||
|
int ret;
|
||||||
|
const u8 *tag_ptr;
|
||||||
|
|
||||||
|
RWNX_DBG(RWNX_FN_ENTRY_STR);
|
||||||
|
|
||||||
|
if ((ret = request_firmware(&config_fw, filename, rwnx_hw->dev))) {
|
||||||
|
printk(KERN_CRIT "%s: Failed to get %s (%d)\n", __func__, filename, ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get Trident path mapping */
|
||||||
|
tag_ptr = rwnx_find_tag(config_fw->data, config_fw->size,
|
||||||
|
"TRD_PATH_MAPPING=", strlen("00"));
|
||||||
|
if (tag_ptr != NULL) {
|
||||||
|
u8 val;
|
||||||
|
if (sscanf(tag_ptr, "%hhx", &val) == 1)
|
||||||
|
config->trd.path_mapping = val;
|
||||||
|
else
|
||||||
|
config->trd.path_mapping = path;
|
||||||
|
} else
|
||||||
|
config->trd.path_mapping = path;
|
||||||
|
|
||||||
|
RWNX_DBG("Trident path mapping is: %d\n", config->trd.path_mapping);
|
||||||
|
|
||||||
|
/* Get DC offset compensation */
|
||||||
|
tag_ptr = rwnx_find_tag(config_fw->data, config_fw->size,
|
||||||
|
"TX_DC_OFF_COMP=", strlen("00000000"));
|
||||||
|
if (tag_ptr != NULL) {
|
||||||
|
if (sscanf(tag_ptr, "%08x", &config->trd.tx_dc_off_comp) != 1)
|
||||||
|
config->trd.tx_dc_off_comp = 0;
|
||||||
|
} else
|
||||||
|
config->trd.tx_dc_off_comp = 0;
|
||||||
|
|
||||||
|
RWNX_DBG("TX DC offset compensation is: %08X\n", config->trd.tx_dc_off_comp);
|
||||||
|
|
||||||
|
/* Get Karst TX IQ compensation value for path0 on 2.4GHz */
|
||||||
|
tag_ptr = rwnx_find_tag(config_fw->data, config_fw->size,
|
||||||
|
"KARST_TX_IQ_COMP_2_4G_PATH_0=", strlen("00000000"));
|
||||||
|
if (tag_ptr != NULL) {
|
||||||
|
if (sscanf(tag_ptr, "%08x", &config->karst.tx_iq_comp_2_4G[0]) != 1)
|
||||||
|
config->karst.tx_iq_comp_2_4G[0] = 0x01000000;
|
||||||
|
} else
|
||||||
|
config->karst.tx_iq_comp_2_4G[0] = 0x01000000;
|
||||||
|
|
||||||
|
RWNX_DBG("Karst TX IQ compensation for path 0 on 2.4GHz is: %08X\n", config->karst.tx_iq_comp_2_4G[0]);
|
||||||
|
|
||||||
|
/* Get Karst TX IQ compensation value for path1 on 2.4GHz */
|
||||||
|
tag_ptr = rwnx_find_tag(config_fw->data, config_fw->size,
|
||||||
|
"KARST_TX_IQ_COMP_2_4G_PATH_1=", strlen("00000000"));
|
||||||
|
if (tag_ptr != NULL) {
|
||||||
|
if (sscanf(tag_ptr, "%08x", &config->karst.tx_iq_comp_2_4G[1]) != 1)
|
||||||
|
config->karst.tx_iq_comp_2_4G[1] = 0x01000000;
|
||||||
|
} else
|
||||||
|
config->karst.tx_iq_comp_2_4G[1] = 0x01000000;
|
||||||
|
|
||||||
|
RWNX_DBG("Karst TX IQ compensation for path 1 on 2.4GHz is: %08X\n", config->karst.tx_iq_comp_2_4G[1]);
|
||||||
|
|
||||||
|
/* Get Karst RX IQ compensation value for path0 on 2.4GHz */
|
||||||
|
tag_ptr = rwnx_find_tag(config_fw->data, config_fw->size,
|
||||||
|
"KARST_RX_IQ_COMP_2_4G_PATH_0=", strlen("00000000"));
|
||||||
|
if (tag_ptr != NULL) {
|
||||||
|
if (sscanf(tag_ptr, "%08x", &config->karst.rx_iq_comp_2_4G[0]) != 1)
|
||||||
|
config->karst.rx_iq_comp_2_4G[0] = 0x01000000;
|
||||||
|
} else
|
||||||
|
config->karst.rx_iq_comp_2_4G[0] = 0x01000000;
|
||||||
|
|
||||||
|
RWNX_DBG("Karst RX IQ compensation for path 0 on 2.4GHz is: %08X\n", config->karst.rx_iq_comp_2_4G[0]);
|
||||||
|
|
||||||
|
/* Get Karst RX IQ compensation value for path1 on 2.4GHz */
|
||||||
|
tag_ptr = rwnx_find_tag(config_fw->data, config_fw->size,
|
||||||
|
"KARST_RX_IQ_COMP_2_4G_PATH_1=", strlen("00000000"));
|
||||||
|
if (tag_ptr != NULL) {
|
||||||
|
if (sscanf(tag_ptr, "%08x", &config->karst.rx_iq_comp_2_4G[1]) != 1)
|
||||||
|
config->karst.rx_iq_comp_2_4G[1] = 0x01000000;
|
||||||
|
} else
|
||||||
|
config->karst.rx_iq_comp_2_4G[1] = 0x01000000;
|
||||||
|
|
||||||
|
RWNX_DBG("Karst RX IQ compensation for path 1 on 2.4GHz is: %08X\n", config->karst.rx_iq_comp_2_4G[1]);
|
||||||
|
|
||||||
|
/* Get Karst TX IQ compensation value for path0 on 5GHz */
|
||||||
|
tag_ptr = rwnx_find_tag(config_fw->data, config_fw->size,
|
||||||
|
"KARST_TX_IQ_COMP_5G_PATH_0=", strlen("00000000"));
|
||||||
|
if (tag_ptr != NULL) {
|
||||||
|
if (sscanf(tag_ptr, "%08x", &config->karst.tx_iq_comp_5G[0]) != 1)
|
||||||
|
config->karst.tx_iq_comp_5G[0] = 0x01000000;
|
||||||
|
} else
|
||||||
|
config->karst.tx_iq_comp_5G[0] = 0x01000000;
|
||||||
|
|
||||||
|
RWNX_DBG("Karst TX IQ compensation for path 0 on 5GHz is: %08X\n", config->karst.tx_iq_comp_5G[0]);
|
||||||
|
|
||||||
|
/* Get Karst TX IQ compensation value for path1 on 5GHz */
|
||||||
|
tag_ptr = rwnx_find_tag(config_fw->data, config_fw->size,
|
||||||
|
"KARST_TX_IQ_COMP_5G_PATH_1=", strlen("00000000"));
|
||||||
|
if (tag_ptr != NULL) {
|
||||||
|
if (sscanf(tag_ptr, "%08x", &config->karst.tx_iq_comp_5G[1]) != 1)
|
||||||
|
config->karst.tx_iq_comp_5G[1] = 0x01000000;
|
||||||
|
} else
|
||||||
|
config->karst.tx_iq_comp_5G[1] = 0x01000000;
|
||||||
|
|
||||||
|
RWNX_DBG("Karst TX IQ compensation for path 1 on 5GHz is: %08X\n", config->karst.tx_iq_comp_5G[1]);
|
||||||
|
|
||||||
|
/* Get Karst RX IQ compensation value for path0 on 5GHz */
|
||||||
|
tag_ptr = rwnx_find_tag(config_fw->data, config_fw->size,
|
||||||
|
"KARST_RX_IQ_COMP_5G_PATH_0=", strlen("00000000"));
|
||||||
|
if (tag_ptr != NULL) {
|
||||||
|
if (sscanf(tag_ptr, "%08x", &config->karst.rx_iq_comp_5G[0]) != 1)
|
||||||
|
config->karst.rx_iq_comp_5G[0] = 0x01000000;
|
||||||
|
} else
|
||||||
|
config->karst.rx_iq_comp_5G[0] = 0x01000000;
|
||||||
|
|
||||||
|
RWNX_DBG("Karst RX IQ compensation for path 0 on 5GHz is: %08X\n", config->karst.rx_iq_comp_5G[0]);
|
||||||
|
|
||||||
|
/* Get Karst RX IQ compensation value for path1 on 5GHz */
|
||||||
|
tag_ptr = rwnx_find_tag(config_fw->data, config_fw->size,
|
||||||
|
"KARST_RX_IQ_COMP_5G_PATH_1=", strlen("00000000"));
|
||||||
|
if (tag_ptr != NULL) {
|
||||||
|
if (sscanf(tag_ptr, "%08x", &config->karst.rx_iq_comp_5G[1]) != 1)
|
||||||
|
config->karst.rx_iq_comp_5G[1] = 0x01000000;
|
||||||
|
} else
|
||||||
|
config->karst.rx_iq_comp_5G[1] = 0x01000000;
|
||||||
|
|
||||||
|
RWNX_DBG("Karst RX IQ compensation for path 1 on 5GHz is: %08X\n", config->karst.rx_iq_comp_5G[1]);
|
||||||
|
|
||||||
|
/* Get Karst default path */
|
||||||
|
tag_ptr = rwnx_find_tag(config_fw->data, config_fw->size,
|
||||||
|
"KARST_DEFAULT_PATH=", strlen("00"));
|
||||||
|
if (tag_ptr != NULL) {
|
||||||
|
u8 val;
|
||||||
|
if (sscanf(tag_ptr, "%hhx", &val) == 1)
|
||||||
|
config->karst.path_used = val;
|
||||||
|
else
|
||||||
|
config->karst.path_used = path;
|
||||||
|
} else
|
||||||
|
config->karst.path_used = path;
|
||||||
|
|
||||||
|
RWNX_DBG("Karst default path is: %d\n", config->karst.path_used);
|
||||||
|
|
||||||
|
/* Release the configuration file */
|
||||||
|
release_firmware(config_fw);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
35
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/rwnx_cfgfile.h
Normal file
35
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/rwnx_cfgfile.h
Normal file
|
|
@ -0,0 +1,35 @@
|
||||||
|
/**
|
||||||
|
****************************************************************************************
|
||||||
|
*
|
||||||
|
* @file rwnx_cfgfile.h
|
||||||
|
*
|
||||||
|
* Copyright (C) RivieraWaves 2012-2019
|
||||||
|
*
|
||||||
|
****************************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _RWNX_CFGFILE_H_
|
||||||
|
#define _RWNX_CFGFILE_H_
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Structure used to retrieve information from the Config file used at Initialization time
|
||||||
|
*/
|
||||||
|
struct rwnx_conf_file {
|
||||||
|
u8 mac_addr[ETH_ALEN];
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Structure used to retrieve information from the PHY Config file used at Initialization time
|
||||||
|
*/
|
||||||
|
struct rwnx_phy_conf_file {
|
||||||
|
struct phy_trd_cfg_tag trd;
|
||||||
|
struct phy_karst_cfg_tag karst;
|
||||||
|
};
|
||||||
|
|
||||||
|
int rwnx_parse_configfile(struct rwnx_hw *rwnx_hw, const char *filename,
|
||||||
|
struct rwnx_conf_file *config);
|
||||||
|
|
||||||
|
int rwnx_parse_phy_configfile(struct rwnx_hw *rwnx_hw, const char *filename,
|
||||||
|
struct rwnx_phy_conf_file *config, int path);
|
||||||
|
|
||||||
|
#endif /* _RWNX_CFGFILE_H_ */
|
||||||
604
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/rwnx_cmds.c
Executable file
604
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/rwnx_cmds.c
Executable file
|
|
@ -0,0 +1,604 @@
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
*
|
||||||
|
* rwnx_cmds.c
|
||||||
|
*
|
||||||
|
* Handles queueing (push to IPC, ack/cfm from IPC) of commands issued to
|
||||||
|
* LMAC FW
|
||||||
|
*
|
||||||
|
* Copyright (C) RivieraWaves 2014-2019
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
//#define CREATE_TRACE_POINTS
|
||||||
|
#include <linux/list.h>
|
||||||
|
|
||||||
|
#include "rwnx_cmds.h"
|
||||||
|
#include "rwnx_defs.h"
|
||||||
|
#include "rwnx_strs.h"
|
||||||
|
#include "rwnx_events.h"
|
||||||
|
#include "aicwf_txrxif.h"
|
||||||
|
#include "rwnx_wakelock.h"
|
||||||
|
#ifdef AICWF_SDIO_SUPPORT
|
||||||
|
#include "aicwf_sdio.h"
|
||||||
|
#else
|
||||||
|
#include "aicwf_usb.h"
|
||||||
|
#endif
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
extern int aicwf_sdio_writeb(struct aic_sdio_dev *sdiodev, uint regaddr, u8 val);
|
||||||
|
|
||||||
|
void rwnx_cmd_free(struct rwnx_cmd *cmd);
|
||||||
|
|
||||||
|
static void cmd_dump(const struct rwnx_cmd *cmd)
|
||||||
|
{
|
||||||
|
printk(KERN_CRIT "tkn[%d] flags:%04x result:%3d cmd:%4d-%-24s - reqcfm(%4d-%-s)\n",
|
||||||
|
cmd->tkn, cmd->flags, cmd->result, cmd->id, RWNX_ID2STR(cmd->id),
|
||||||
|
cmd->reqid, cmd->reqid != (lmac_msg_id_t)-1 ? RWNX_ID2STR(cmd->reqid) : "none");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
static void cmd_complete(struct rwnx_cmd_mgr *cmd_mgr, struct rwnx_cmd *cmd)
|
||||||
|
{
|
||||||
|
//RWNX_DBG(RWNX_FN_ENTRY_STR);
|
||||||
|
lockdep_assert_held(&cmd_mgr->lock);
|
||||||
|
|
||||||
|
//list_del(&cmd->list);
|
||||||
|
//cmd_mgr->queue_sz--;
|
||||||
|
|
||||||
|
cmd->flags |= RWNX_CMD_FLAG_DONE;
|
||||||
|
if (cmd->flags & RWNX_CMD_FLAG_NONBLOCK) {
|
||||||
|
rwnx_cmd_free(cmd);//kfree(cmd);AIDEN
|
||||||
|
} else {
|
||||||
|
if (RWNX_CMD_WAIT_COMPLETE(cmd->flags)) {
|
||||||
|
cmd->result = 0;
|
||||||
|
complete(&cmd->complete);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(cmd_mgr->queue_sz == 0){
|
||||||
|
rwnx_wakeup_unlock(g_rwnx_plat->usbdev->rwnx_hw->ws_tx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int cmd_mgr_queue_force_defer(struct rwnx_cmd_mgr *cmd_mgr, struct rwnx_cmd *cmd)
|
||||||
|
{
|
||||||
|
bool defer_push = false;
|
||||||
|
|
||||||
|
RWNX_DBG(RWNX_FN_ENTRY_STR);
|
||||||
|
#ifdef CREATE_TRACE_POINTS
|
||||||
|
trace_msg_send(cmd->id);
|
||||||
|
#endif
|
||||||
|
spin_lock_bh(&cmd_mgr->lock);
|
||||||
|
|
||||||
|
if (cmd_mgr->state == RWNX_CMD_MGR_STATE_CRASHED) {
|
||||||
|
printk(KERN_CRIT"cmd queue crashed\n");
|
||||||
|
cmd->result = -EPIPE;
|
||||||
|
spin_unlock_bh(&cmd_mgr->lock);
|
||||||
|
return -EPIPE;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef CONFIG_RWNX_FHOST
|
||||||
|
if (!list_empty(&cmd_mgr->cmds)) {
|
||||||
|
if (cmd_mgr->queue_sz == cmd_mgr->max_queue_sz) {
|
||||||
|
printk(KERN_CRIT"Too many cmds (%d) already queued\n",
|
||||||
|
cmd_mgr->max_queue_sz);
|
||||||
|
cmd->result = -ENOMEM;
|
||||||
|
spin_unlock_bh(&cmd_mgr->lock);
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
cmd->flags |= RWNX_CMD_FLAG_WAIT_PUSH;
|
||||||
|
defer_push = true;
|
||||||
|
|
||||||
|
if (cmd->flags & RWNX_CMD_FLAG_REQ_CFM)
|
||||||
|
cmd->flags |= RWNX_CMD_FLAG_WAIT_CFM;
|
||||||
|
|
||||||
|
cmd->tkn = cmd_mgr->next_tkn++;
|
||||||
|
cmd->result = -EINTR;
|
||||||
|
|
||||||
|
if (!(cmd->flags & RWNX_CMD_FLAG_NONBLOCK))
|
||||||
|
init_completion(&cmd->complete);
|
||||||
|
|
||||||
|
list_add_tail(&cmd->list, &cmd_mgr->cmds);
|
||||||
|
if(cmd_mgr->queue_sz == 0){
|
||||||
|
rwnx_wakeup_lock(g_rwnx_plat->usbdev->rwnx_hw->ws_tx);
|
||||||
|
}
|
||||||
|
cmd_mgr->queue_sz++;
|
||||||
|
spin_unlock_bh(&cmd_mgr->lock);
|
||||||
|
|
||||||
|
WAKE_CMD_WORK(cmd_mgr);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void rwnx_msg_free_(struct lmac_msg *msg);
|
||||||
|
|
||||||
|
|
||||||
|
static int cmd_mgr_queue(struct rwnx_cmd_mgr *cmd_mgr, struct rwnx_cmd *cmd)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
#ifdef AICWF_SDIO_SUPPORT
|
||||||
|
struct aic_sdio_dev *sdiodev = container_of(cmd_mgr, struct aic_sdio_dev, cmd_mgr);
|
||||||
|
#endif
|
||||||
|
#ifdef AICWF_USB_SUPPORT
|
||||||
|
|
||||||
|
struct aic_usb_dev *usbdev = container_of(cmd_mgr, struct aic_usb_dev, cmd_mgr);
|
||||||
|
#endif
|
||||||
|
bool defer_push = false;
|
||||||
|
u8_l empty = 0;
|
||||||
|
|
||||||
|
//RWNX_DBG(RWNX_FN_ENTRY_STR);
|
||||||
|
#ifdef CREATE_TRACE_POINTS
|
||||||
|
trace_msg_send(cmd->id);
|
||||||
|
#endif
|
||||||
|
if(cmd->e2a_msg != NULL) {
|
||||||
|
do {
|
||||||
|
spin_lock_bh(&cmd_mgr->lock);
|
||||||
|
if(cmd_mgr->state == RWNX_CMD_MGR_STATE_CRASHED) {
|
||||||
|
AICWFDBG(LOGERROR, "cmd queue crashed\n");
|
||||||
|
cmd->result = -EPIPE;
|
||||||
|
spin_unlock_bh(&cmd_mgr->lock);
|
||||||
|
return -EPIPE;
|
||||||
|
}
|
||||||
|
empty = list_empty(&cmd_mgr->cmds);
|
||||||
|
if(!empty) {
|
||||||
|
spin_unlock_bh(&cmd_mgr->lock);
|
||||||
|
if(in_softirq()) {
|
||||||
|
printk("in_softirq:check cmdqueue empty\n");
|
||||||
|
mdelay(10);
|
||||||
|
} else {
|
||||||
|
printk("check cmdqueue empty\n");
|
||||||
|
msleep(50);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} while(!empty);//wait for cmd queue empty
|
||||||
|
} else {
|
||||||
|
spin_lock_bh(&cmd_mgr->lock);
|
||||||
|
if (cmd_mgr->state == RWNX_CMD_MGR_STATE_CRASHED) {
|
||||||
|
printk(KERN_CRIT"cmd queue crashed\n");
|
||||||
|
cmd->result = -EPIPE;
|
||||||
|
spin_unlock_bh(&cmd_mgr->lock);
|
||||||
|
return -EPIPE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef CONFIG_RWNX_FHOST
|
||||||
|
if (!list_empty(&cmd_mgr->cmds)) {
|
||||||
|
struct rwnx_cmd *last;
|
||||||
|
|
||||||
|
if (cmd_mgr->queue_sz == cmd_mgr->max_queue_sz) {
|
||||||
|
printk(KERN_CRIT"Too many cmds (%d) already queued\n",
|
||||||
|
cmd_mgr->max_queue_sz);
|
||||||
|
cmd->result = -ENOMEM;
|
||||||
|
spin_unlock_bh(&cmd_mgr->lock);
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
last = list_entry(cmd_mgr->cmds.prev, struct rwnx_cmd, list);
|
||||||
|
if (last->flags & (RWNX_CMD_FLAG_WAIT_ACK | RWNX_CMD_FLAG_WAIT_PUSH | RWNX_CMD_FLAG_WAIT_CFM)) {
|
||||||
|
#if 0 // queue even NONBLOCK command.
|
||||||
|
if (cmd->flags & RWNX_CMD_FLAG_NONBLOCK) {
|
||||||
|
printk(KERN_CRIT"cmd queue busy\n");
|
||||||
|
cmd->result = -EBUSY;
|
||||||
|
spin_unlock_bh(&cmd_mgr->lock);
|
||||||
|
return -EBUSY;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
cmd->flags |= RWNX_CMD_FLAG_WAIT_PUSH;
|
||||||
|
defer_push = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
cmd->flags |= RWNX_CMD_FLAG_WAIT_ACK;
|
||||||
|
#endif
|
||||||
|
if (cmd->flags & RWNX_CMD_FLAG_REQ_CFM)
|
||||||
|
cmd->flags |= RWNX_CMD_FLAG_WAIT_CFM;
|
||||||
|
|
||||||
|
cmd->tkn = cmd_mgr->next_tkn++;
|
||||||
|
cmd->result = -EINTR;
|
||||||
|
|
||||||
|
if (!(cmd->flags & RWNX_CMD_FLAG_NONBLOCK))
|
||||||
|
init_completion(&cmd->complete);
|
||||||
|
|
||||||
|
list_add_tail(&cmd->list, &cmd_mgr->cmds);
|
||||||
|
if(cmd_mgr->queue_sz == 0){
|
||||||
|
rwnx_wakeup_lock(g_rwnx_plat->usbdev->rwnx_hw->ws_tx);
|
||||||
|
}
|
||||||
|
cmd_mgr->queue_sz++;
|
||||||
|
|
||||||
|
if(cmd->a2e_msg->id == ME_TRAFFIC_IND_REQ
|
||||||
|
#ifdef AICWF_ARP_OFFLOAD
|
||||||
|
|| cmd->a2e_msg->id == MM_SET_ARPOFFLOAD_REQ
|
||||||
|
#endif
|
||||||
|
) {
|
||||||
|
defer_push = true;
|
||||||
|
cmd->flags |= RWNX_CMD_FLAG_WAIT_PUSH;
|
||||||
|
//printk("defer push: tkn=%d\r\n", cmd->tkn);
|
||||||
|
}
|
||||||
|
|
||||||
|
//spin_unlock_bh(&cmd_mgr->lock);
|
||||||
|
if (!defer_push) {
|
||||||
|
spin_unlock_bh(&cmd_mgr->lock);
|
||||||
|
AICWFDBG(LOGTRACE, "queue:id=%x, param_len=%u\n",cmd->a2e_msg->id, cmd->a2e_msg->param_len);
|
||||||
|
|
||||||
|
#ifdef AICWF_SDIO_SUPPORT
|
||||||
|
aicwf_set_cmd_tx((void *)(sdiodev), cmd->a2e_msg, sizeof(struct lmac_msg) + cmd->a2e_msg->param_len);
|
||||||
|
#else
|
||||||
|
aicwf_set_cmd_tx((void *)(usbdev), cmd->a2e_msg, sizeof(struct lmac_msg) + cmd->a2e_msg->param_len);
|
||||||
|
#endif
|
||||||
|
//rwnx_ipc_msg_push(rwnx_hw, cmd, RWNX_CMD_A2EMSG_LEN(cmd->a2e_msg));
|
||||||
|
|
||||||
|
kfree(cmd->a2e_msg);
|
||||||
|
} else {
|
||||||
|
if(cmd_mgr->queue_sz <= 1) {
|
||||||
|
spin_unlock_bh(&cmd_mgr->lock);
|
||||||
|
WAKE_CMD_WORK(cmd_mgr);
|
||||||
|
} else {
|
||||||
|
spin_unlock_bh(&cmd_mgr->lock);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(cmd->flags & RWNX_CMD_FLAG_NONBLOCK)) {
|
||||||
|
#ifdef CONFIG_RWNX_FHOST
|
||||||
|
if (wait_for_completion_killable(&cmd->complete)) {
|
||||||
|
cmd->result = -EINTR;
|
||||||
|
spin_lock_bh(&cmd_mgr->lock);
|
||||||
|
cmd_complete(cmd_mgr, cmd);
|
||||||
|
spin_unlock_bh(&cmd_mgr->lock);
|
||||||
|
/* TODO: kill the cmd at fw level */
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
unsigned long tout = msecs_to_jiffies(RWNX_80211_CMD_TIMEOUT_MS/*AIDEN workaround* cmd_mgr->queue_sz*/);
|
||||||
|
if (!wait_for_completion_killable_timeout(&cmd->complete, tout)) {
|
||||||
|
printk(KERN_CRIT"%s cmd timed-out cmd_mgr->queue_sz:%d\n", __func__,cmd_mgr->queue_sz);
|
||||||
|
#ifdef AICWF_SDIO_SUPPORT
|
||||||
|
ret = aicwf_sdio_writeb(sdiodev, SDIOWIFI_WAKEUP_REG, 2);
|
||||||
|
if (ret < 0) {
|
||||||
|
sdio_err("reg:%d write failed!\n", SDIOWIFI_WAKEUP_REG);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
cmd_dump(cmd);
|
||||||
|
spin_lock_bh(&cmd_mgr->lock);
|
||||||
|
|
||||||
|
cmd_mgr->state = RWNX_CMD_MGR_STATE_CRASHED;
|
||||||
|
if (!(cmd->flags & RWNX_CMD_FLAG_DONE)) {
|
||||||
|
cmd->result = -ETIMEDOUT;
|
||||||
|
cmd_complete(cmd_mgr, cmd);
|
||||||
|
}
|
||||||
|
ret = -ETIMEDOUT;
|
||||||
|
spin_unlock_bh(&cmd_mgr->lock);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
spin_lock_bh(&cmd_mgr->lock);
|
||||||
|
list_del(&cmd->list);
|
||||||
|
cmd_mgr->queue_sz--;
|
||||||
|
if(cmd_mgr->queue_sz == 0){
|
||||||
|
rwnx_wakeup_unlock(usbdev->rwnx_hw->ws_tx);
|
||||||
|
}
|
||||||
|
spin_unlock_bh(&cmd_mgr->lock);
|
||||||
|
rwnx_cmd_free(cmd);//kfree(cmd);AIDEN
|
||||||
|
if(!list_empty(&cmd_mgr->cmds) && usbdev->state == USB_UP_ST)
|
||||||
|
WAKE_CMD_WORK(cmd_mgr);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
} else {
|
||||||
|
cmd->result = 0;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
static int cmd_mgr_llind(struct rwnx_cmd_mgr *cmd_mgr, struct rwnx_cmd *cmd)
|
||||||
|
{
|
||||||
|
struct rwnx_cmd *cur, *acked = NULL, *next = NULL;
|
||||||
|
|
||||||
|
RWNX_DBG(RWNX_FN_ENTRY_STR);
|
||||||
|
|
||||||
|
spin_lock_bh(&cmd_mgr->lock);
|
||||||
|
list_for_each_entry(cur, &cmd_mgr->cmds, list) {
|
||||||
|
if (!acked) {
|
||||||
|
if (cur->tkn == cmd->tkn) {
|
||||||
|
if (WARN_ON_ONCE(cur != cmd)) {
|
||||||
|
cmd_dump(cmd);
|
||||||
|
}
|
||||||
|
acked = cur;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (cur->flags & RWNX_CMD_FLAG_WAIT_PUSH) {
|
||||||
|
next = cur;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!acked) {
|
||||||
|
printk(KERN_CRIT "Error: acked cmd not found\n");
|
||||||
|
} else {
|
||||||
|
cmd->flags &= ~RWNX_CMD_FLAG_WAIT_ACK;
|
||||||
|
if (RWNX_CMD_WAIT_COMPLETE(cmd->flags))
|
||||||
|
cmd_complete(cmd_mgr, cmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (next) {
|
||||||
|
#if 0 //there is no ack
|
||||||
|
struct rwnx_hw *rwnx_hw = container_of(cmd_mgr, struct rwnx_hw, cmd_mgr);
|
||||||
|
next->flags &= ~RWNX_CMD_FLAG_WAIT_PUSH;
|
||||||
|
rwnx_ipc_msg_push(rwnx_hw, next, RWNX_CMD_A2EMSG_LEN(next->a2e_msg));
|
||||||
|
kfree(next->a2e_msg);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
spin_unlock(&cmd_mgr->lock);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void cmd_mgr_task_process(struct work_struct *work)
|
||||||
|
{
|
||||||
|
struct rwnx_cmd_mgr *cmd_mgr = container_of(work, struct rwnx_cmd_mgr, cmdWork);
|
||||||
|
struct rwnx_cmd *cur, *next = NULL;
|
||||||
|
unsigned long tout;
|
||||||
|
|
||||||
|
RWNX_DBG(RWNX_FN_ENTRY_STR);
|
||||||
|
|
||||||
|
while(1) {
|
||||||
|
next = NULL;
|
||||||
|
spin_lock_bh(&cmd_mgr->lock);
|
||||||
|
|
||||||
|
list_for_each_entry(cur, &cmd_mgr->cmds, list) {
|
||||||
|
if (cur->flags & RWNX_CMD_FLAG_WAIT_PUSH) { //just judge the first
|
||||||
|
next = cur;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
spin_unlock_bh(&cmd_mgr->lock);
|
||||||
|
|
||||||
|
if(next == NULL)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (next) {
|
||||||
|
#ifdef AICWF_SDIO_SUPPORT
|
||||||
|
struct aic_sdio_dev *sdiodev = container_of(cmd_mgr, struct aic_sdio_dev, cmd_mgr);
|
||||||
|
#endif
|
||||||
|
#ifdef AICWF_USB_SUPPORT
|
||||||
|
struct aic_usb_dev *usbdev = container_of(cmd_mgr, struct aic_usb_dev, cmd_mgr);
|
||||||
|
#endif
|
||||||
|
next->flags &= ~RWNX_CMD_FLAG_WAIT_PUSH;
|
||||||
|
|
||||||
|
//printk("cmd_process, cmd->id=%d, tkn=%d\r\n",next->reqid, next->tkn);
|
||||||
|
//rwnx_ipc_msg_push(rwnx_hw, next, RWNX_CMD_A2EMSG_LEN(next->a2e_msg));
|
||||||
|
#ifdef AICWF_SDIO_SUPPORT
|
||||||
|
aicwf_set_cmd_tx((void *)(sdiodev), next->a2e_msg, sizeof(struct lmac_msg) + next->a2e_msg->param_len);
|
||||||
|
#else
|
||||||
|
aicwf_set_cmd_tx((void *)(usbdev), next->a2e_msg, sizeof(struct lmac_msg) + next->a2e_msg->param_len);
|
||||||
|
#endif
|
||||||
|
kfree(next->a2e_msg);
|
||||||
|
|
||||||
|
tout = msecs_to_jiffies(RWNX_80211_CMD_TIMEOUT_MS * cmd_mgr->queue_sz);
|
||||||
|
if (!wait_for_completion_killable_timeout(&next->complete, tout)) {
|
||||||
|
printk(KERN_CRIT"%s cmd timed-out cmd_mgr->queue_sz:%d\n", __func__, cmd_mgr->queue_sz);
|
||||||
|
cmd_dump(next);
|
||||||
|
spin_lock_bh(&cmd_mgr->lock);
|
||||||
|
//AIDEN workaround
|
||||||
|
cmd_mgr->state = RWNX_CMD_MGR_STATE_CRASHED;
|
||||||
|
if (!(next->flags & RWNX_CMD_FLAG_DONE)) {
|
||||||
|
next->result = -ETIMEDOUT;
|
||||||
|
cmd_complete(cmd_mgr, next);
|
||||||
|
}
|
||||||
|
spin_unlock_bh(&cmd_mgr->lock);
|
||||||
|
} else {
|
||||||
|
spin_lock_bh(&cmd_mgr->lock);
|
||||||
|
list_del(&next->list);
|
||||||
|
cmd_mgr->queue_sz--;
|
||||||
|
if(cmd_mgr->queue_sz == 0){
|
||||||
|
rwnx_wakeup_unlock(usbdev->rwnx_hw->ws_tx);
|
||||||
|
}
|
||||||
|
spin_unlock_bh(&cmd_mgr->lock);
|
||||||
|
rwnx_cmd_free(next);//kfree(next);AIDEN
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int cmd_mgr_run_callback(struct rwnx_hw *rwnx_hw, struct rwnx_cmd *cmd,
|
||||||
|
struct rwnx_cmd_e2amsg *msg, msg_cb_fct cb)
|
||||||
|
{
|
||||||
|
int res;
|
||||||
|
|
||||||
|
if (! cb){
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
//RWNX_DBG(RWNX_FN_ENTRY_STR);
|
||||||
|
#ifndef CONFIG_DEBUG_ATOMIC_SLEEP
|
||||||
|
//spin_lock_bh(&rwnx_hw->cb_lock);
|
||||||
|
#endif
|
||||||
|
res = cb(rwnx_hw, cmd, msg);
|
||||||
|
#ifndef CONFIG_DEBUG_ATOMIC_SLEEP
|
||||||
|
//spin_unlock_bh(&rwnx_hw->cb_lock);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
|
||||||
|
*/
|
||||||
|
static int cmd_mgr_msgind(struct rwnx_cmd_mgr *cmd_mgr, struct rwnx_cmd_e2amsg *msg,
|
||||||
|
msg_cb_fct cb)
|
||||||
|
{
|
||||||
|
#ifdef AICWF_SDIO_SUPPORT
|
||||||
|
struct aic_sdio_dev *sdiodev = container_of(cmd_mgr, struct aic_sdio_dev, cmd_mgr);
|
||||||
|
struct rwnx_hw *rwnx_hw = sdiodev->rwnx_hw;
|
||||||
|
#endif
|
||||||
|
#ifdef AICWF_USB_SUPPORT
|
||||||
|
struct aic_usb_dev *usbdev = container_of(cmd_mgr, struct aic_usb_dev, cmd_mgr);
|
||||||
|
struct rwnx_hw *rwnx_hw = usbdev->rwnx_hw;
|
||||||
|
#endif
|
||||||
|
struct rwnx_cmd *cmd, *pos;
|
||||||
|
bool found = false;
|
||||||
|
|
||||||
|
// RWNX_DBG(RWNX_FN_ENTRY_STR);
|
||||||
|
#ifdef CREATE_TRACE_POINTS
|
||||||
|
trace_msg_recv(msg->id);
|
||||||
|
#endif
|
||||||
|
AICWFDBG(LOGTRACE, "%s cmd->id=%d\n", __func__, msg->id);
|
||||||
|
spin_lock_bh(&cmd_mgr->lock);
|
||||||
|
list_for_each_entry_safe(cmd, pos, &cmd_mgr->cmds, list) {
|
||||||
|
if (cmd->reqid == msg->id &&
|
||||||
|
(cmd->flags & RWNX_CMD_FLAG_WAIT_CFM)) {
|
||||||
|
|
||||||
|
if (!cmd_mgr_run_callback(rwnx_hw, cmd, msg, cb)) {
|
||||||
|
found = true;
|
||||||
|
cmd->flags &= ~RWNX_CMD_FLAG_WAIT_CFM;
|
||||||
|
|
||||||
|
if (WARN((msg->param_len > RWNX_CMD_E2AMSG_LEN_MAX),
|
||||||
|
"Unexpect E2A msg len %d > %d\n", msg->param_len,
|
||||||
|
RWNX_CMD_E2AMSG_LEN_MAX)) {
|
||||||
|
msg->param_len = RWNX_CMD_E2AMSG_LEN_MAX;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cmd->e2a_msg && msg->param_len)
|
||||||
|
memcpy(cmd->e2a_msg, &msg->param, msg->param_len);
|
||||||
|
|
||||||
|
if (RWNX_CMD_WAIT_COMPLETE(cmd->flags))
|
||||||
|
cmd_complete(cmd_mgr, cmd);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
spin_unlock_bh(&cmd_mgr->lock);
|
||||||
|
|
||||||
|
if (!found)
|
||||||
|
cmd_mgr_run_callback(rwnx_hw, NULL, msg, cb);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
static void cmd_mgr_print(struct rwnx_cmd_mgr *cmd_mgr)
|
||||||
|
{
|
||||||
|
struct rwnx_cmd *cur;
|
||||||
|
|
||||||
|
spin_lock_bh(&cmd_mgr->lock);
|
||||||
|
RWNX_DBG("q_sz/max: %2d / %2d - next tkn: %d\n",
|
||||||
|
cmd_mgr->queue_sz, cmd_mgr->max_queue_sz,
|
||||||
|
cmd_mgr->next_tkn);
|
||||||
|
list_for_each_entry(cur, &cmd_mgr->cmds, list) {
|
||||||
|
cmd_dump(cur);
|
||||||
|
}
|
||||||
|
spin_unlock_bh(&cmd_mgr->lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void cmd_mgr_drain(struct rwnx_cmd_mgr *cmd_mgr)
|
||||||
|
{
|
||||||
|
struct rwnx_cmd *cur, *nxt;
|
||||||
|
|
||||||
|
RWNX_DBG(RWNX_FN_ENTRY_STR);
|
||||||
|
|
||||||
|
spin_lock_bh(&cmd_mgr->lock);
|
||||||
|
list_for_each_entry_safe(cur, nxt, &cmd_mgr->cmds, list) {
|
||||||
|
list_del(&cur->list);
|
||||||
|
//cmd_mgr->queue_sz--;
|
||||||
|
if (!(cur->flags & RWNX_CMD_FLAG_NONBLOCK))
|
||||||
|
complete(&cur->complete);
|
||||||
|
}
|
||||||
|
spin_unlock_bh(&cmd_mgr->lock);
|
||||||
|
#if 0
|
||||||
|
if(cmd_mgr->queue_sz == 0){
|
||||||
|
rwnx_wakeup_unlock(g_rwnx_plat->usbdev->rwnx_hw->ws_tx);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void rwnx_cmd_mgr_init(struct rwnx_cmd_mgr *cmd_mgr)
|
||||||
|
{
|
||||||
|
RWNX_DBG(RWNX_FN_ENTRY_STR);
|
||||||
|
|
||||||
|
INIT_LIST_HEAD(&cmd_mgr->cmds);
|
||||||
|
cmd_mgr->state = RWNX_CMD_MGR_STATE_INITED;
|
||||||
|
spin_lock_init(&cmd_mgr->lock);
|
||||||
|
cmd_mgr->max_queue_sz = RWNX_CMD_MAX_QUEUED;
|
||||||
|
cmd_mgr->queue = &cmd_mgr_queue;
|
||||||
|
cmd_mgr->print = &cmd_mgr_print;
|
||||||
|
cmd_mgr->drain = &cmd_mgr_drain;
|
||||||
|
cmd_mgr->llind = &cmd_mgr_llind;
|
||||||
|
cmd_mgr->msgind = &cmd_mgr_msgind;
|
||||||
|
|
||||||
|
INIT_WORK(&cmd_mgr->cmdWork, cmd_mgr_task_process);
|
||||||
|
cmd_mgr->cmd_wq = create_singlethread_workqueue("cmd_wq");
|
||||||
|
if (!cmd_mgr->cmd_wq) {
|
||||||
|
txrx_err("insufficient memory to create cmd workqueue.\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void rwnx_cmd_mgr_deinit(struct rwnx_cmd_mgr *cmd_mgr)
|
||||||
|
{
|
||||||
|
if(cmd_mgr->print && cmd_mgr->drain){
|
||||||
|
cmd_mgr->print(cmd_mgr);
|
||||||
|
cmd_mgr->drain(cmd_mgr);
|
||||||
|
cmd_mgr->print(cmd_mgr);
|
||||||
|
flush_workqueue(cmd_mgr->cmd_wq);
|
||||||
|
destroy_workqueue(cmd_mgr->cmd_wq);
|
||||||
|
memset(cmd_mgr, 0, sizeof(*cmd_mgr));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void aicwf_set_cmd_tx(void *dev, struct lmac_msg *msg, uint len)
|
||||||
|
{
|
||||||
|
u8 *buffer = NULL;
|
||||||
|
u16 index = 0;
|
||||||
|
#ifdef AICWF_SDIO_SUPPORT
|
||||||
|
struct aic_sdio_dev *sdiodev = (struct aic_sdio_dev *)dev;
|
||||||
|
struct aicwf_bus *bus = sdiodev->bus_if;
|
||||||
|
#else
|
||||||
|
struct aic_usb_dev *usbdev = (struct aic_usb_dev *)dev;
|
||||||
|
struct aicwf_bus *bus = NULL;
|
||||||
|
if (!usbdev->state) {
|
||||||
|
printk("down msg \n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
bus = usbdev->bus_if;
|
||||||
|
#endif
|
||||||
|
buffer = bus->cmd_buf;
|
||||||
|
|
||||||
|
memset(buffer, 0, CMD_BUF_MAX);
|
||||||
|
buffer[0] = (len+4) & 0x00ff;
|
||||||
|
buffer[1] = ((len+4) >> 8) &0x0f;
|
||||||
|
buffer[2] = 0x11;
|
||||||
|
buffer[3] = 0x0;
|
||||||
|
index += 4;
|
||||||
|
//there is a dummy word
|
||||||
|
index += 4;
|
||||||
|
|
||||||
|
//make sure little endian
|
||||||
|
put_u16(&buffer[index], msg->id);
|
||||||
|
index += 2;
|
||||||
|
put_u16(&buffer[index], msg->dest_id);
|
||||||
|
index += 2;
|
||||||
|
put_u16(&buffer[index], msg->src_id);
|
||||||
|
index += 2;
|
||||||
|
put_u16(&buffer[index], msg->param_len);
|
||||||
|
index += 2;
|
||||||
|
memcpy(&buffer[index], (u8 *)msg->param, msg->param_len);
|
||||||
|
|
||||||
|
aicwf_bus_txmsg(bus, buffer, len + 8);
|
||||||
|
}
|
||||||
|
|
||||||
120
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/rwnx_cmds.h
Normal file
120
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/rwnx_cmds.h
Normal file
|
|
@ -0,0 +1,120 @@
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
*
|
||||||
|
* rwnx_cmds.h
|
||||||
|
*
|
||||||
|
* Copyright (C) RivieraWaves 2014-2019
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _RWNX_CMDS_H_
|
||||||
|
#define _RWNX_CMDS_H_
|
||||||
|
|
||||||
|
#include <linux/spinlock.h>
|
||||||
|
#include <linux/completion.h>
|
||||||
|
#include <linux/module.h>
|
||||||
|
#include "lmac_msg.h"
|
||||||
|
|
||||||
|
#ifdef CONFIG_RWNX_SDM
|
||||||
|
#define RWNX_80211_CMD_TIMEOUT_MS (20 * 300)
|
||||||
|
#elif defined(CONFIG_RWNX_FHOST)
|
||||||
|
#define RWNX_80211_CMD_TIMEOUT_MS (10000)
|
||||||
|
#else
|
||||||
|
#define RWNX_80211_CMD_TIMEOUT_MS 4000//500//300
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define RWNX_CMD_FLAG_NONBLOCK BIT(0)
|
||||||
|
#define RWNX_CMD_FLAG_REQ_CFM BIT(1)
|
||||||
|
#define RWNX_CMD_FLAG_WAIT_PUSH BIT(2)
|
||||||
|
#define RWNX_CMD_FLAG_WAIT_ACK BIT(3)
|
||||||
|
#define RWNX_CMD_FLAG_WAIT_CFM BIT(4)
|
||||||
|
#define RWNX_CMD_FLAG_DONE BIT(5)
|
||||||
|
/* ATM IPC design makes it possible to get the CFM before the ACK,
|
||||||
|
* otherwise this could have simply been a state enum */
|
||||||
|
#define RWNX_CMD_WAIT_COMPLETE(flags) \
|
||||||
|
(!(flags & (RWNX_CMD_FLAG_WAIT_ACK | RWNX_CMD_FLAG_WAIT_CFM)))
|
||||||
|
|
||||||
|
#define RWNX_CMD_MAX_QUEUED 16//8 AIDEN
|
||||||
|
|
||||||
|
#ifdef CONFIG_RWNX_FHOST
|
||||||
|
#include "ipc_fhost.h"
|
||||||
|
#define rwnx_cmd_e2amsg ipc_fhost_msg
|
||||||
|
#define rwnx_cmd_a2emsg ipc_fhost_msg
|
||||||
|
#define RWNX_CMD_A2EMSG_LEN(m) (m->param_len)
|
||||||
|
#define RWNX_CMD_E2AMSG_LEN_MAX IPC_FHOST_MSG_BUF_SIZE
|
||||||
|
struct rwnx_term_stream;
|
||||||
|
|
||||||
|
#else /* !CONFIG_RWNX_FHOST*/
|
||||||
|
#include "ipc_shared.h"
|
||||||
|
#define rwnx_cmd_e2amsg ipc_e2a_msg
|
||||||
|
#define rwnx_cmd_a2emsg lmac_msg
|
||||||
|
#define RWNX_CMD_A2EMSG_LEN(m) (sizeof(struct lmac_msg) + m->param_len)
|
||||||
|
#define RWNX_CMD_E2AMSG_LEN_MAX (IPC_E2A_MSG_PARAM_SIZE * 4)
|
||||||
|
|
||||||
|
#endif /* CONFIG_RWNX_FHOST*/
|
||||||
|
|
||||||
|
struct rwnx_hw;
|
||||||
|
struct rwnx_cmd;
|
||||||
|
typedef int (*msg_cb_fct)(struct rwnx_hw *rwnx_hw, struct rwnx_cmd *cmd,
|
||||||
|
struct rwnx_cmd_e2amsg *msg);
|
||||||
|
static inline void put_u16(u8 *buf, u16 data)
|
||||||
|
{
|
||||||
|
buf[0] = (u8)(data&0x00ff);
|
||||||
|
buf[1] = (u8)((data >> 8)&0x00ff);
|
||||||
|
}
|
||||||
|
|
||||||
|
enum rwnx_cmd_mgr_state {
|
||||||
|
RWNX_CMD_MGR_STATE_DEINIT,
|
||||||
|
RWNX_CMD_MGR_STATE_INITED,
|
||||||
|
RWNX_CMD_MGR_STATE_CRASHED,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct rwnx_cmd {
|
||||||
|
struct list_head list;
|
||||||
|
lmac_msg_id_t id;
|
||||||
|
lmac_msg_id_t reqid;
|
||||||
|
struct rwnx_cmd_a2emsg *a2e_msg;
|
||||||
|
char *e2a_msg;
|
||||||
|
u32 tkn;
|
||||||
|
u16 flags;
|
||||||
|
|
||||||
|
struct completion complete;
|
||||||
|
u32 result;
|
||||||
|
u8 used;
|
||||||
|
int array_id;
|
||||||
|
#ifdef CONFIG_RWNX_FHOST
|
||||||
|
struct rwnx_term_stream *stream;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
struct rwnx_cmd_mgr {
|
||||||
|
enum rwnx_cmd_mgr_state state;
|
||||||
|
spinlock_t lock;
|
||||||
|
u32 next_tkn;
|
||||||
|
u32 queue_sz;
|
||||||
|
u32 max_queue_sz;
|
||||||
|
|
||||||
|
struct list_head cmds;
|
||||||
|
|
||||||
|
int (*queue)(struct rwnx_cmd_mgr *, struct rwnx_cmd *);
|
||||||
|
int (*llind)(struct rwnx_cmd_mgr *, struct rwnx_cmd *);
|
||||||
|
int (*msgind)(struct rwnx_cmd_mgr *, struct rwnx_cmd_e2amsg *, msg_cb_fct);
|
||||||
|
void (*print)(struct rwnx_cmd_mgr *);
|
||||||
|
void (*drain)(struct rwnx_cmd_mgr *);
|
||||||
|
|
||||||
|
struct work_struct cmdWork;
|
||||||
|
struct workqueue_struct *cmd_wq;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define WAKE_CMD_WORK(cmd_mgr) \
|
||||||
|
do { \
|
||||||
|
queue_work((cmd_mgr)->cmd_wq, &cmd_mgr->cmdWork); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
void rwnx_cmd_mgr_init(struct rwnx_cmd_mgr *cmd_mgr);
|
||||||
|
void rwnx_cmd_mgr_deinit(struct rwnx_cmd_mgr *cmd_mgr);
|
||||||
|
int cmd_mgr_queue_force_defer(struct rwnx_cmd_mgr *cmd_mgr, struct rwnx_cmd *cmd);
|
||||||
|
void aicwf_set_cmd_tx(void *dev, struct lmac_msg *msg, uint len);
|
||||||
|
|
||||||
|
#endif /* _RWNX_CMDS_H_ */
|
||||||
433
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/rwnx_compat.h
Normal file
433
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/rwnx_compat.h
Normal file
|
|
@ -0,0 +1,433 @@
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
*
|
||||||
|
* @file rwnx_compat.h
|
||||||
|
*
|
||||||
|
* Ensure driver compilation for linux 3.16 to 3.19
|
||||||
|
*
|
||||||
|
* To avoid too many #if LINUX_VERSION_CODE if the code, when prototype change
|
||||||
|
* between different kernel version:
|
||||||
|
* - For external function, define a macro whose name is the function name with
|
||||||
|
* _compat suffix and prototype (actually the number of parameter) of the
|
||||||
|
* latest version. Then latest version this macro simply call the function
|
||||||
|
* and for older kernel version it call the function adapting the api.
|
||||||
|
* - For internal function (e.g. cfg80211_ops) do the same but the macro name
|
||||||
|
* doesn't need to have the _compat suffix when the function is not used
|
||||||
|
* directly by the driver
|
||||||
|
*
|
||||||
|
* Copyright (C) RivieraWaves 2018
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
#ifndef _RWNX_COMPAT_H_
|
||||||
|
#define _RWNX_COMPAT_H_
|
||||||
|
#include <linux/version.h>
|
||||||
|
|
||||||
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 10, 0)
|
||||||
|
#error "Minimum kernel version supported is 3.10"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Generic */
|
||||||
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 9, 0)
|
||||||
|
#define __bf_shf(x) (__builtin_ffsll(x) - 1)
|
||||||
|
#define FIELD_PREP(_mask, _val) \
|
||||||
|
(((typeof(_mask))(_val) << __bf_shf(_mask)) & (_mask))
|
||||||
|
#else
|
||||||
|
#include <linux/bitfield.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* CFG80211 */
|
||||||
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 20, 0)
|
||||||
|
#define IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_MASK IEEE80211_HE_MAC_CAP3_MAX_A_AMPDU_LEN_EXP_MASK
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if LINUX_VERSION_CODE > KERNEL_VERSION(5, 18, 0)
|
||||||
|
#define IEEE80211_MAX_AMPDU_BUF IEEE80211_MAX_AMPDU_BUF_HE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 19, 0)
|
||||||
|
#define IEEE80211_RADIOTAP_HE 23
|
||||||
|
#define IEEE80211_RADIOTAP_HE_MU 24
|
||||||
|
|
||||||
|
struct ieee80211_radiotap_he {
|
||||||
|
__le16 data1, data2, data3, data4, data5, data6;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum ieee80211_radiotap_he_bits {
|
||||||
|
IEEE80211_RADIOTAP_HE_DATA1_FORMAT_MASK = 3,
|
||||||
|
IEEE80211_RADIOTAP_HE_DATA1_FORMAT_SU = 0,
|
||||||
|
IEEE80211_RADIOTAP_HE_DATA1_FORMAT_EXT_SU = 1,
|
||||||
|
IEEE80211_RADIOTAP_HE_DATA1_FORMAT_MU = 2,
|
||||||
|
IEEE80211_RADIOTAP_HE_DATA1_FORMAT_TRIG = 3,
|
||||||
|
|
||||||
|
IEEE80211_RADIOTAP_HE_DATA1_BSS_COLOR_KNOWN = 0x0004,
|
||||||
|
IEEE80211_RADIOTAP_HE_DATA1_BEAM_CHANGE_KNOWN = 0x0008,
|
||||||
|
IEEE80211_RADIOTAP_HE_DATA1_UL_DL_KNOWN = 0x0010,
|
||||||
|
IEEE80211_RADIOTAP_HE_DATA1_DATA_MCS_KNOWN = 0x0020,
|
||||||
|
IEEE80211_RADIOTAP_HE_DATA1_DATA_DCM_KNOWN = 0x0040,
|
||||||
|
IEEE80211_RADIOTAP_HE_DATA1_CODING_KNOWN = 0x0080,
|
||||||
|
IEEE80211_RADIOTAP_HE_DATA1_LDPC_XSYMSEG_KNOWN = 0x0100,
|
||||||
|
IEEE80211_RADIOTAP_HE_DATA1_STBC_KNOWN = 0x0200,
|
||||||
|
IEEE80211_RADIOTAP_HE_DATA1_SPTL_REUSE_KNOWN = 0x0400,
|
||||||
|
IEEE80211_RADIOTAP_HE_DATA1_SPTL_REUSE2_KNOWN = 0x0800,
|
||||||
|
IEEE80211_RADIOTAP_HE_DATA1_SPTL_REUSE3_KNOWN = 0x1000,
|
||||||
|
IEEE80211_RADIOTAP_HE_DATA1_SPTL_REUSE4_KNOWN = 0x2000,
|
||||||
|
IEEE80211_RADIOTAP_HE_DATA1_BW_RU_ALLOC_KNOWN = 0x4000,
|
||||||
|
IEEE80211_RADIOTAP_HE_DATA1_DOPPLER_KNOWN = 0x8000,
|
||||||
|
|
||||||
|
IEEE80211_RADIOTAP_HE_DATA2_PRISEC_80_KNOWN = 0x0001,
|
||||||
|
IEEE80211_RADIOTAP_HE_DATA2_GI_KNOWN = 0x0002,
|
||||||
|
IEEE80211_RADIOTAP_HE_DATA2_NUM_LTF_SYMS_KNOWN = 0x0004,
|
||||||
|
IEEE80211_RADIOTAP_HE_DATA2_PRE_FEC_PAD_KNOWN = 0x0008,
|
||||||
|
IEEE80211_RADIOTAP_HE_DATA2_TXBF_KNOWN = 0x0010,
|
||||||
|
IEEE80211_RADIOTAP_HE_DATA2_PE_DISAMBIG_KNOWN = 0x0020,
|
||||||
|
IEEE80211_RADIOTAP_HE_DATA2_TXOP_KNOWN = 0x0040,
|
||||||
|
IEEE80211_RADIOTAP_HE_DATA2_MIDAMBLE_KNOWN = 0x0080,
|
||||||
|
IEEE80211_RADIOTAP_HE_DATA2_RU_OFFSET = 0x3f00,
|
||||||
|
IEEE80211_RADIOTAP_HE_DATA2_RU_OFFSET_KNOWN = 0x4000,
|
||||||
|
IEEE80211_RADIOTAP_HE_DATA2_PRISEC_80_SEC = 0x8000,
|
||||||
|
|
||||||
|
IEEE80211_RADIOTAP_HE_DATA3_BSS_COLOR = 0x003f,
|
||||||
|
IEEE80211_RADIOTAP_HE_DATA3_BEAM_CHANGE = 0x0040,
|
||||||
|
IEEE80211_RADIOTAP_HE_DATA3_UL_DL = 0x0080,
|
||||||
|
IEEE80211_RADIOTAP_HE_DATA3_DATA_MCS = 0x0f00,
|
||||||
|
IEEE80211_RADIOTAP_HE_DATA3_DATA_DCM = 0x1000,
|
||||||
|
IEEE80211_RADIOTAP_HE_DATA3_CODING = 0x2000,
|
||||||
|
IEEE80211_RADIOTAP_HE_DATA3_LDPC_XSYMSEG = 0x4000,
|
||||||
|
IEEE80211_RADIOTAP_HE_DATA3_STBC = 0x8000,
|
||||||
|
|
||||||
|
IEEE80211_RADIOTAP_HE_DATA4_SU_MU_SPTL_REUSE = 0x000f,
|
||||||
|
IEEE80211_RADIOTAP_HE_DATA4_MU_STA_ID = 0x7ff0,
|
||||||
|
IEEE80211_RADIOTAP_HE_DATA4_TB_SPTL_REUSE1 = 0x000f,
|
||||||
|
IEEE80211_RADIOTAP_HE_DATA4_TB_SPTL_REUSE2 = 0x00f0,
|
||||||
|
IEEE80211_RADIOTAP_HE_DATA4_TB_SPTL_REUSE3 = 0x0f00,
|
||||||
|
IEEE80211_RADIOTAP_HE_DATA4_TB_SPTL_REUSE4 = 0xf000,
|
||||||
|
|
||||||
|
IEEE80211_RADIOTAP_HE_DATA5_DATA_BW_RU_ALLOC = 0x000f,
|
||||||
|
IEEE80211_RADIOTAP_HE_DATA5_DATA_BW_RU_ALLOC_20MHZ = 0,
|
||||||
|
IEEE80211_RADIOTAP_HE_DATA5_DATA_BW_RU_ALLOC_40MHZ = 1,
|
||||||
|
IEEE80211_RADIOTAP_HE_DATA5_DATA_BW_RU_ALLOC_80MHZ = 2,
|
||||||
|
IEEE80211_RADIOTAP_HE_DATA5_DATA_BW_RU_ALLOC_160MHZ = 3,
|
||||||
|
IEEE80211_RADIOTAP_HE_DATA5_DATA_BW_RU_ALLOC_26T = 4,
|
||||||
|
IEEE80211_RADIOTAP_HE_DATA5_DATA_BW_RU_ALLOC_52T = 5,
|
||||||
|
IEEE80211_RADIOTAP_HE_DATA5_DATA_BW_RU_ALLOC_106T = 6,
|
||||||
|
IEEE80211_RADIOTAP_HE_DATA5_DATA_BW_RU_ALLOC_242T = 7,
|
||||||
|
IEEE80211_RADIOTAP_HE_DATA5_DATA_BW_RU_ALLOC_484T = 8,
|
||||||
|
IEEE80211_RADIOTAP_HE_DATA5_DATA_BW_RU_ALLOC_996T = 9,
|
||||||
|
IEEE80211_RADIOTAP_HE_DATA5_DATA_BW_RU_ALLOC_2x996T = 10,
|
||||||
|
|
||||||
|
IEEE80211_RADIOTAP_HE_DATA5_GI = 0x0030,
|
||||||
|
IEEE80211_RADIOTAP_HE_DATA5_GI_0_8 = 0,
|
||||||
|
IEEE80211_RADIOTAP_HE_DATA5_GI_1_6 = 1,
|
||||||
|
IEEE80211_RADIOTAP_HE_DATA5_GI_3_2 = 2,
|
||||||
|
|
||||||
|
IEEE80211_RADIOTAP_HE_DATA5_LTF_SIZE = 0x00c0,
|
||||||
|
IEEE80211_RADIOTAP_HE_DATA5_LTF_SIZE_UNKNOWN = 0,
|
||||||
|
IEEE80211_RADIOTAP_HE_DATA5_LTF_SIZE_1X = 1,
|
||||||
|
IEEE80211_RADIOTAP_HE_DATA5_LTF_SIZE_2X = 2,
|
||||||
|
IEEE80211_RADIOTAP_HE_DATA5_LTF_SIZE_4X = 3,
|
||||||
|
IEEE80211_RADIOTAP_HE_DATA5_NUM_LTF_SYMS = 0x0700,
|
||||||
|
IEEE80211_RADIOTAP_HE_DATA5_PRE_FEC_PAD = 0x3000,
|
||||||
|
IEEE80211_RADIOTAP_HE_DATA5_TXBF = 0x4000,
|
||||||
|
IEEE80211_RADIOTAP_HE_DATA5_PE_DISAMBIG = 0x8000,
|
||||||
|
|
||||||
|
IEEE80211_RADIOTAP_HE_DATA6_NSTS = 0x000f,
|
||||||
|
IEEE80211_RADIOTAP_HE_DATA6_DOPPLER = 0x0010,
|
||||||
|
IEEE80211_RADIOTAP_HE_DATA6_TXOP = 0x7f00,
|
||||||
|
IEEE80211_RADIOTAP_HE_DATA6_MIDAMBLE_PDCTY = 0x8000,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ieee80211_radiotap_he_mu {
|
||||||
|
__le16 flags1, flags2;
|
||||||
|
u8 ru_ch1[4];
|
||||||
|
u8 ru_ch2[4];
|
||||||
|
};
|
||||||
|
|
||||||
|
enum ieee80211_radiotap_he_mu_bits {
|
||||||
|
IEEE80211_RADIOTAP_HE_MU_FLAGS1_SIG_B_MCS = 0x000f,
|
||||||
|
IEEE80211_RADIOTAP_HE_MU_FLAGS1_SIG_B_MCS_KNOWN = 0x0010,
|
||||||
|
IEEE80211_RADIOTAP_HE_MU_FLAGS1_SIG_B_DCM = 0x0020,
|
||||||
|
IEEE80211_RADIOTAP_HE_MU_FLAGS1_SIG_B_DCM_KNOWN = 0x0040,
|
||||||
|
IEEE80211_RADIOTAP_HE_MU_FLAGS1_CH2_CTR_26T_RU_KNOWN = 0x0080,
|
||||||
|
IEEE80211_RADIOTAP_HE_MU_FLAGS1_CH1_RU_KNOWN = 0x0100,
|
||||||
|
IEEE80211_RADIOTAP_HE_MU_FLAGS1_CH2_RU_KNOWN = 0x0200,
|
||||||
|
IEEE80211_RADIOTAP_HE_MU_FLAGS1_CH1_CTR_26T_RU_KNOWN = 0x1000,
|
||||||
|
IEEE80211_RADIOTAP_HE_MU_FLAGS1_CH1_CTR_26T_RU = 0x2000,
|
||||||
|
IEEE80211_RADIOTAP_HE_MU_FLAGS1_SIG_B_COMP_KNOWN = 0x4000,
|
||||||
|
IEEE80211_RADIOTAP_HE_MU_FLAGS1_SIG_B_SYMS_USERS_KNOWN = 0x8000,
|
||||||
|
|
||||||
|
IEEE80211_RADIOTAP_HE_MU_FLAGS2_BW_FROM_SIG_A_BW = 0x0003,
|
||||||
|
IEEE80211_RADIOTAP_HE_MU_FLAGS2_BW_FROM_SIG_A_BW_20MHZ = 0x0000,
|
||||||
|
IEEE80211_RADIOTAP_HE_MU_FLAGS2_BW_FROM_SIG_A_BW_40MHZ = 0x0001,
|
||||||
|
IEEE80211_RADIOTAP_HE_MU_FLAGS2_BW_FROM_SIG_A_BW_80MHZ = 0x0002,
|
||||||
|
IEEE80211_RADIOTAP_HE_MU_FLAGS2_BW_FROM_SIG_A_BW_160MHZ = 0x0003,
|
||||||
|
IEEE80211_RADIOTAP_HE_MU_FLAGS2_BW_FROM_SIG_A_BW_KNOWN = 0x0004,
|
||||||
|
IEEE80211_RADIOTAP_HE_MU_FLAGS2_SIG_B_COMP = 0x0008,
|
||||||
|
IEEE80211_RADIOTAP_HE_MU_FLAGS2_SIG_B_SYMS_USERS = 0x00f0,
|
||||||
|
IEEE80211_RADIOTAP_HE_MU_FLAGS2_PUNC_FROM_SIG_A_BW = 0x0300,
|
||||||
|
IEEE80211_RADIOTAP_HE_MU_FLAGS2_PUNC_FROM_SIG_A_BW_KNOWN= 0x0400,
|
||||||
|
IEEE80211_RADIOTAP_HE_MU_FLAGS2_CH2_CTR_26T_RU = 0x0800,
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 12, 0)
|
||||||
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 1, 0)
|
||||||
|
#define rwnx_cfg80211_add_iface(wiphy, name, name_assign_type, type, params) \
|
||||||
|
rwnx_cfg80211_add_iface(wiphy, name, type, u32 *flags, params)
|
||||||
|
#else
|
||||||
|
#define rwnx_cfg80211_add_iface(wiphy, name, name_assign_type, type, params) \
|
||||||
|
rwnx_cfg80211_add_iface(wiphy, name, name_assign_type, type, u32 *flags, params)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define rwnx_cfg80211_change_iface(wiphy, dev, type, params) \
|
||||||
|
rwnx_cfg80211_change_iface(wiphy, dev, type, u32 *flags, params)
|
||||||
|
|
||||||
|
#define CCFS0(vht) vht->center_freq_seg1_idx
|
||||||
|
#define CCFS1(vht) vht->center_freq_seg2_idx
|
||||||
|
|
||||||
|
#else
|
||||||
|
#define CCFS0(vht) vht->center_freq_seg0_idx
|
||||||
|
#define CCFS1(vht) vht->center_freq_seg1_idx
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 11, 0)
|
||||||
|
#define cfg80211_cqm_rssi_notify(dev, event, level, gfp) \
|
||||||
|
cfg80211_cqm_rssi_notify(dev, event, gfp)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 9, 0)
|
||||||
|
#define ieee80211_amsdu_to_8023s(skb, list, addr, iftype, extra_headroom, check_da, check_sa) \
|
||||||
|
ieee80211_amsdu_to_8023s(skb, list, addr, iftype, extra_headroom, false)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 7, 0)
|
||||||
|
#define NUM_NL80211_BANDS IEEE80211_NUM_BANDS
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 2, 0)
|
||||||
|
#define cfg80211_disconnected(dev, reason, ie, len, local, gfp) \
|
||||||
|
cfg80211_disconnected(dev, reason, ie, len, gfp)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 1, 0)) && !(defined CONFIG_VENDOR_RWNX)
|
||||||
|
#define ieee80211_chandef_to_operating_class(chan_def, op_class) 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)
|
||||||
|
#define SURVEY_INFO_TIME SURVEY_INFO_CHANNEL_TIME
|
||||||
|
#define SURVEY_INFO_TIME_BUSY SURVEY_INFO_CHANNEL_TIME_BUSY
|
||||||
|
#define SURVEY_INFO_TIME_EXT_BUSY SURVEY_INFO_CHANNEL_TIME_EXT_BUSY
|
||||||
|
#define SURVEY_INFO_TIME_RX SURVEY_INFO_CHANNEL_TIME_RX
|
||||||
|
#define SURVEY_INFO_TIME_TX SURVEY_INFO_CHANNEL_TIME_TX
|
||||||
|
|
||||||
|
#define SURVEY_TIME(s) s->channel_time
|
||||||
|
#define SURVEY_TIME_BUSY(s) s->channel_time_busy
|
||||||
|
#else
|
||||||
|
#define SURVEY_TIME(s) s->time
|
||||||
|
#define SURVEY_TIME_BUSY(s) s->time_busy
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 19, 0)
|
||||||
|
#define cfg80211_ch_switch_started_notify(dev, chandef, count)
|
||||||
|
|
||||||
|
#define WLAN_BSS_COEX_INFORMATION_REQUEST BIT(0)
|
||||||
|
#define WLAN_EXT_CAPA1_EXT_CHANNEL_SWITCHING BIT(2)
|
||||||
|
#define WLAN_EXT_CAPA4_TDLS_BUFFER_STA BIT(4)
|
||||||
|
#define WLAN_EXT_CAPA4_TDLS_PEER_PSM BIT(5)
|
||||||
|
#define WLAN_EXT_CAPA4_TDLS_CHAN_SWITCH BIT(6)
|
||||||
|
#define WLAN_EXT_CAPA5_TDLS_CH_SW_PROHIBITED BIT(7)
|
||||||
|
#define NL80211_FEATURE_TDLS_CHANNEL_SWITCH 0
|
||||||
|
|
||||||
|
#define STA_TDLS_INITIATOR(sta) 0
|
||||||
|
|
||||||
|
#define REGULATORY_IGNORE_STALE_KICKOFF 0
|
||||||
|
#else
|
||||||
|
#define STA_TDLS_INITIATOR(sta) sta->tdls_initiator
|
||||||
|
|
||||||
|
#ifndef REGULATORY_IGNORE_STALE_KICKOFF
|
||||||
|
#define REGULATORY_IGNORE_STALE_KICKOFF 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 18, 0)) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 12, 0))
|
||||||
|
#define cfg80211_rx_mgmt(wdev, freq, rssi, buf, len, flags) \
|
||||||
|
cfg80211_rx_mgmt(wdev, freq, rssi, buf, len, flags, GFP_ATOMIC)
|
||||||
|
#elif LINUX_VERSION_CODE < KERNEL_VERSION(3, 11, 0)
|
||||||
|
#define cfg80211_rx_mgmt(wdev, freq, rssi, buf, len, flags) \
|
||||||
|
cfg80211_rx_mgmt(wdev, freq, rssi, buf, len, GFP_ATOMIC)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 17, 0)
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0)
|
||||||
|
#define rwnx_cfg80211_tdls_mgmt(wiphy, dev, peer, act, tok, status, peer_capability, initiator, buf, len) \
|
||||||
|
rwnx_cfg80211_tdls_mgmt(wiphy, dev, peer, act, tok, status, peer_capability, buf, len)
|
||||||
|
#else
|
||||||
|
#define rwnx_cfg80211_tdls_mgmt(wiphy, dev, peer, act, tok, status, peer_capability, initiator, buf, len) \
|
||||||
|
rwnx_cfg80211_tdls_mgmt(wiphy, dev, peer, act, tok, status, buf, len)
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <linux/types.h>
|
||||||
|
|
||||||
|
struct ieee80211_wmm_ac_param {
|
||||||
|
u8 aci_aifsn; /* AIFSN, ACM, ACI */
|
||||||
|
u8 cw; /* ECWmin, ECWmax (CW = 2^ECW - 1) */
|
||||||
|
__le16 txop_limit;
|
||||||
|
} __packed;
|
||||||
|
|
||||||
|
struct ieee80211_wmm_param_ie {
|
||||||
|
u8 element_id; /* Element ID: 221 (0xdd); */
|
||||||
|
u8 len; /* Length: 24 */
|
||||||
|
/* required fields for WMM version 1 */
|
||||||
|
u8 oui[3]; /* 00:50:f2 */
|
||||||
|
u8 oui_type; /* 2 */
|
||||||
|
u8 oui_subtype; /* 1 */
|
||||||
|
u8 version; /* 1 for WMM version 1.0 */
|
||||||
|
u8 qos_info; /* AP/STA specific QoS info */
|
||||||
|
u8 reserved; /* 0 */
|
||||||
|
/* AC_BE, AC_BK, AC_VI, AC_VO */
|
||||||
|
struct ieee80211_wmm_ac_param ac[4];
|
||||||
|
} __packed;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 19, 0)
|
||||||
|
enum {
|
||||||
|
IEEE80211_HE_MCS_SUPPORT_0_7 = 0,
|
||||||
|
IEEE80211_HE_MCS_SUPPORT_0_9 = 1,
|
||||||
|
IEEE80211_HE_MCS_SUPPORT_0_11 = 2,
|
||||||
|
IEEE80211_HE_MCS_NOT_SUPPORTED = 3,
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* MAC80211 */
|
||||||
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 18, 0)
|
||||||
|
#define rwnx_ops_mgd_prepare_tx(hw, vif, duration) \
|
||||||
|
rwnx_ops_mgd_prepare_tx(hw, vif)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 12, 0)
|
||||||
|
|
||||||
|
#define RX_ENC_HT(s) s->flag |= RX_FLAG_HT
|
||||||
|
#define RX_ENC_HT_GF(s) s->flag |= (RX_FLAG_HT | RX_FLAG_HT_GF)
|
||||||
|
#define RX_ENC_VHT(s) s->flag |= RX_FLAG_HT
|
||||||
|
#define RX_ENC_HE(s) s->flag |= RX_FLAG_HT
|
||||||
|
#define RX_ENC_FLAG_SHORT_GI(s) s->flag |= RX_FLAG_SHORT_GI
|
||||||
|
#define RX_ENC_FLAG_SHORT_PRE(s) s->flag |= RX_FLAG_SHORTPRE
|
||||||
|
#define RX_ENC_FLAG_LDPC(s) s->flag |= RX_FLAG_LDPC
|
||||||
|
#define RX_BW_40MHZ(s) s->flag |= RX_FLAG_40MHZ
|
||||||
|
#define RX_BW_80MHZ(s) s->vht_flag |= RX_VHT_FLAG_80MHZ
|
||||||
|
#define RX_BW_160MHZ(s) s->vht_flag |= RX_VHT_FLAG_160MHZ
|
||||||
|
#define RX_NSS(s) s->vht_nss
|
||||||
|
|
||||||
|
#else
|
||||||
|
#define RX_ENC_HT(s) s->encoding = RX_ENC_HT
|
||||||
|
#define RX_ENC_HT_GF(s) { s->encoding = RX_ENC_HT; \
|
||||||
|
s->enc_flags |= RX_ENC_FLAG_HT_GF; }
|
||||||
|
#define RX_ENC_VHT(s) s->encoding = RX_ENC_VHT
|
||||||
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 19, 0)
|
||||||
|
#define RX_ENC_HE(s) s->encoding = RX_ENC_VHT
|
||||||
|
#else
|
||||||
|
#define RX_ENC_HE(s) s->encoding = RX_ENC_HE
|
||||||
|
#endif
|
||||||
|
#define RX_ENC_FLAG_SHORT_GI(s) s->enc_flags |= RX_ENC_FLAG_SHORT_GI
|
||||||
|
#define RX_ENC_FLAG_SHORT_PRE(s) s->enc_flags |= RX_ENC_FLAG_SHORTPRE
|
||||||
|
#define RX_ENC_FLAG_LDPC(s) s->enc_flags |= RX_ENC_FLAG_LDPC
|
||||||
|
#define RX_BW_40MHZ(s) s->bw = RATE_INFO_BW_40
|
||||||
|
#define RX_BW_80MHZ(s) s->bw = RATE_INFO_BW_80
|
||||||
|
#define RX_BW_160MHZ(s) s->bw = RATE_INFO_BW_160
|
||||||
|
#define RX_NSS(s) s->nss
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 11, 0)
|
||||||
|
#define ieee80211_cqm_rssi_notify(vif, event, level, gfp) \
|
||||||
|
ieee80211_cqm_rssi_notify(vif, event, gfp)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef CONFIG_VENDOR_RWNX_AMSDUS_TX
|
||||||
|
#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 4, 0))
|
||||||
|
#define rwnx_ops_ampdu_action(hw, vif, params) \
|
||||||
|
rwnx_ops_ampdu_action(hw, vif, enum ieee80211_ampdu_mlme_action action, \
|
||||||
|
struct ieee80211_sta *sta, u16 tid, u16 *ssn, u8 buf_size)
|
||||||
|
#elif (LINUX_VERSION_CODE < KERNEL_VERSION(4, 6, 0))
|
||||||
|
#define rwnx_ops_ampdu_action(hw, vif, params) \
|
||||||
|
rwnx_ops_ampdu_action(hw, vif, enum ieee80211_ampdu_mlme_action action, \
|
||||||
|
struct ieee80211_sta *sta, u16 tid, u16 *ssn, u8 buf_size, \
|
||||||
|
bool amsdu)
|
||||||
|
#endif
|
||||||
|
#endif /* CONFIG_VENDOR_RWNX_AMSDUS_TX */
|
||||||
|
|
||||||
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 2, 0)
|
||||||
|
#define IEEE80211_HW_SUPPORT_FAST_XMIT 0
|
||||||
|
#define ieee80211_hw_check(hw, feat) (hw->flags & IEEE80211_HW_##feat)
|
||||||
|
#define ieee80211_hw_set(hw, feat) {hw->flags |= IEEE80211_HW_##feat;}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 19, 0)
|
||||||
|
#define rwnx_ops_sw_scan_start(hw, vif, mac_addr) \
|
||||||
|
rwnx_ops_sw_scan_start(hw)
|
||||||
|
#define rwnx_ops_sw_scan_complete(hw, vif) \
|
||||||
|
rwnx_ops_sw_scan_complete(hw)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 17, 0)
|
||||||
|
#define rwnx_ops_hw_scan(hw, vif, hw_req) \
|
||||||
|
rwnx_ops_hw_scan(hw, vif, struct cfg80211_scan_request *req)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* NET */
|
||||||
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 13, 0)
|
||||||
|
#define rwnx_select_queue(dev, skb, sb_dev) \
|
||||||
|
rwnx_select_queue(dev, skb)
|
||||||
|
#elif LINUX_VERSION_CODE < KERNEL_VERSION(4, 19, 0)
|
||||||
|
#define rwnx_select_queue(dev, skb, sb_dev) \
|
||||||
|
rwnx_select_queue(dev, skb, void *accel_priv, select_queue_fallback_t fallback)
|
||||||
|
#elif LINUX_VERSION_CODE < KERNEL_VERSION(5, 2, 0)
|
||||||
|
#define rwnx_select_queue(dev, skb, sb_dev) \
|
||||||
|
rwnx_select_queue(dev, skb, sb_dev, select_queue_fallback_t fallback)
|
||||||
|
#else
|
||||||
|
#define rwnx_select_queue(dev, skb, sb_dev) \
|
||||||
|
rwnx_select_queue(dev, skb, sb_dev)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 16, 0)) && !(defined CONFIG_VENDOR_RWNX)
|
||||||
|
#define sk_pacing_shift_update(sk, shift)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 17, 0)
|
||||||
|
#define alloc_netdev_mqs(size, name, assign, setup, txqs, rxqs) \
|
||||||
|
alloc_netdev_mqs(size, name, setup, txqs, rxqs)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 17, 0)
|
||||||
|
#define NET_NAME_UNKNOWN 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* TRACE */
|
||||||
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 2, 0)
|
||||||
|
#define trace_print_symbols_seq ftrace_print_symbols_seq
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 17, 0)
|
||||||
|
#define trace_seq_buffer_ptr(p) p->buffer + p->len
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* TIME */
|
||||||
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 8, 0)
|
||||||
|
#define time64_to_tm(t, o, tm) time_to_tm((time_t)t, o, tm)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 19, 0)
|
||||||
|
#define ktime_get_real_seconds get_seconds
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 17, 0)
|
||||||
|
typedef __s64 time64_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* _RWNX_COMPAT_H_ */
|
||||||
2739
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/rwnx_debugfs.c
Normal file
2739
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/rwnx_debugfs.c
Normal file
File diff suppressed because it is too large
Load diff
203
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/rwnx_debugfs.h
Normal file
203
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/rwnx_debugfs.h
Normal file
|
|
@ -0,0 +1,203 @@
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
*
|
||||||
|
* @file rwnx_debugfs.h
|
||||||
|
*
|
||||||
|
* @brief Miscellaneous utility function definitions
|
||||||
|
*
|
||||||
|
* Copyright (C) RivieraWaves 2012-2019
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef _RWNX_DEBUGFS_H_
|
||||||
|
#define _RWNX_DEBUGFS_H_
|
||||||
|
|
||||||
|
#include <linux/workqueue.h>
|
||||||
|
#include <linux/if_ether.h>
|
||||||
|
#include <linux/version.h>
|
||||||
|
#include "rwnx_fw_trace.h"
|
||||||
|
|
||||||
|
struct rwnx_hw;
|
||||||
|
struct rwnx_sta;
|
||||||
|
|
||||||
|
/* some macros taken from iwlwifi */
|
||||||
|
/* TODO: replace with generic read and fill read buffer in open to avoid double
|
||||||
|
* reads */
|
||||||
|
#define DEBUGFS_ADD_FILE(name, parent, mode) do { \
|
||||||
|
if (!debugfs_create_file(#name, mode, parent, rwnx_hw, \
|
||||||
|
&rwnx_dbgfs_##name##_ops)) \
|
||||||
|
goto err; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define DEBUGFS_ADD_BOOL(name, parent, ptr) do { \
|
||||||
|
struct dentry *__tmp; \
|
||||||
|
__tmp = debugfs_create_bool(#name, S_IWUSR | S_IRUSR, \
|
||||||
|
parent, ptr); \
|
||||||
|
if (IS_ERR(__tmp) || !__tmp) \
|
||||||
|
goto err; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define DEBUGFS_ADD_X64(name, parent, ptr) do { \
|
||||||
|
struct dentry *__tmp; \
|
||||||
|
__tmp = debugfs_create_x64(#name, S_IWUSR | S_IRUSR, \
|
||||||
|
parent, ptr); \
|
||||||
|
if (IS_ERR(__tmp) || !__tmp) \
|
||||||
|
goto err; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define DEBUGFS_ADD_U64(name, parent, ptr, mode) do { \
|
||||||
|
struct dentry *__tmp; \
|
||||||
|
__tmp = debugfs_create_u64(#name, mode, \
|
||||||
|
parent, ptr); \
|
||||||
|
if (IS_ERR(__tmp) || !__tmp) \
|
||||||
|
goto err; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define DEBUGFS_ADD_X32(name, parent, ptr) do { \
|
||||||
|
struct dentry *__tmp; \
|
||||||
|
__tmp = debugfs_create_x32(#name, S_IWUSR | S_IRUSR, \
|
||||||
|
parent, ptr); \
|
||||||
|
if (IS_ERR(__tmp) || !__tmp) \
|
||||||
|
goto err; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 7, 0)
|
||||||
|
#define DEBUGFS_ADD_U32(name, parent, ptr, mode) do { \
|
||||||
|
debugfs_create_u32(#name, mode, \
|
||||||
|
parent, ptr); \
|
||||||
|
} while (0)
|
||||||
|
#else
|
||||||
|
#define DEBUGFS_ADD_U32(name, parent, ptr, mode) do { \
|
||||||
|
struct dentry *__tmp; \
|
||||||
|
__tmp = debugfs_create_u32(#name, mode, \
|
||||||
|
parent, ptr); \
|
||||||
|
if (IS_ERR(__tmp) || !__tmp) \
|
||||||
|
goto err; \
|
||||||
|
} while (0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* file operation */
|
||||||
|
#define DEBUGFS_READ_FUNC(name) \
|
||||||
|
static ssize_t rwnx_dbgfs_##name##_read(struct file *file, \
|
||||||
|
char __user *user_buf, \
|
||||||
|
size_t count, loff_t *ppos);
|
||||||
|
|
||||||
|
#define DEBUGFS_WRITE_FUNC(name) \
|
||||||
|
static ssize_t rwnx_dbgfs_##name##_write(struct file *file, \
|
||||||
|
const char __user *user_buf,\
|
||||||
|
size_t count, loff_t *ppos);
|
||||||
|
|
||||||
|
#define DEBUGFS_OPEN_FUNC(name) \
|
||||||
|
static int rwnx_dbgfs_##name##_open(struct inode *inode, \
|
||||||
|
struct file *file);
|
||||||
|
|
||||||
|
#define DEBUGFS_RELEASE_FUNC(name) \
|
||||||
|
static int rwnx_dbgfs_##name##_release(struct inode *inode, \
|
||||||
|
struct file *file);
|
||||||
|
|
||||||
|
#define DEBUGFS_READ_FILE_OPS(name) \
|
||||||
|
DEBUGFS_READ_FUNC(name); \
|
||||||
|
static const struct file_operations rwnx_dbgfs_##name##_ops = { \
|
||||||
|
.read = rwnx_dbgfs_##name##_read, \
|
||||||
|
.open = simple_open, \
|
||||||
|
.llseek = generic_file_llseek, \
|
||||||
|
};
|
||||||
|
|
||||||
|
#define DEBUGFS_WRITE_FILE_OPS(name) \
|
||||||
|
DEBUGFS_WRITE_FUNC(name); \
|
||||||
|
static const struct file_operations rwnx_dbgfs_##name##_ops = { \
|
||||||
|
.write = rwnx_dbgfs_##name##_write, \
|
||||||
|
.open = simple_open, \
|
||||||
|
.llseek = generic_file_llseek, \
|
||||||
|
};
|
||||||
|
|
||||||
|
#define DEBUGFS_READ_WRITE_FILE_OPS(name) \
|
||||||
|
DEBUGFS_READ_FUNC(name); \
|
||||||
|
DEBUGFS_WRITE_FUNC(name); \
|
||||||
|
static const struct file_operations rwnx_dbgfs_##name##_ops = { \
|
||||||
|
.write = rwnx_dbgfs_##name##_write, \
|
||||||
|
.read = rwnx_dbgfs_##name##_read, \
|
||||||
|
.open = simple_open, \
|
||||||
|
.llseek = generic_file_llseek, \
|
||||||
|
};
|
||||||
|
|
||||||
|
#define DEBUGFS_READ_WRITE_OPEN_RELEASE_FILE_OPS(name) \
|
||||||
|
DEBUGFS_READ_FUNC(name); \
|
||||||
|
DEBUGFS_WRITE_FUNC(name); \
|
||||||
|
DEBUGFS_OPEN_FUNC(name); \
|
||||||
|
DEBUGFS_RELEASE_FUNC(name); \
|
||||||
|
static const struct file_operations rwnx_dbgfs_##name##_ops = { \
|
||||||
|
.write = rwnx_dbgfs_##name##_write, \
|
||||||
|
.read = rwnx_dbgfs_##name##_read, \
|
||||||
|
.open = rwnx_dbgfs_##name##_open, \
|
||||||
|
.release = rwnx_dbgfs_##name##_release, \
|
||||||
|
.llseek = generic_file_llseek, \
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef CONFIG_RWNX_DEBUGFS
|
||||||
|
|
||||||
|
struct rwnx_debugfs {
|
||||||
|
unsigned long long rateidx;
|
||||||
|
struct dentry *dir;
|
||||||
|
bool trace_prst;
|
||||||
|
|
||||||
|
char helper_cmd[64];
|
||||||
|
//struct work_struct helper_work;
|
||||||
|
bool helper_scheduled;
|
||||||
|
spinlock_t umh_lock;
|
||||||
|
bool unregistering;
|
||||||
|
|
||||||
|
#ifndef CONFIG_RWNX_FHOST
|
||||||
|
struct rwnx_fw_log fw_log;
|
||||||
|
#endif /* CONFIG_RWNX_FHOST */
|
||||||
|
|
||||||
|
#ifdef CONFIG_RWNX_FULLMAC
|
||||||
|
struct work_struct rc_stat_work;
|
||||||
|
uint8_t rc_sta[NX_REMOTE_STA_MAX];
|
||||||
|
uint8_t rc_write;
|
||||||
|
uint8_t rc_read;
|
||||||
|
struct dentry *dir_rc;
|
||||||
|
struct dentry *dir_sta[NX_REMOTE_STA_MAX];
|
||||||
|
int rc_config[NX_REMOTE_STA_MAX];
|
||||||
|
struct list_head rc_config_save;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef CONFIG_RWNX_FULLMAC
|
||||||
|
|
||||||
|
// Max duration in msecs to save rate config for a sta after disconnection
|
||||||
|
#define RC_CONFIG_DUR 600000
|
||||||
|
|
||||||
|
struct rwnx_rc_config_save {
|
||||||
|
struct list_head list;
|
||||||
|
unsigned long timestamp;
|
||||||
|
int rate;
|
||||||
|
u8 mac_addr[ETH_ALEN];
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int rwnx_dbgfs_register(struct rwnx_hw *rwnx_hw, const char *name);
|
||||||
|
void rwnx_dbgfs_unregister(struct rwnx_hw *rwnx_hw);
|
||||||
|
#ifdef CONFIG_RWNX_FULLMAC
|
||||||
|
void rwnx_dbgfs_register_rc_stat(struct rwnx_hw *rwnx_hw, struct rwnx_sta *sta);
|
||||||
|
void rwnx_dbgfs_unregister_rc_stat(struct rwnx_hw *rwnx_hw, struct rwnx_sta *sta);
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
|
||||||
|
struct rwnx_debugfs {
|
||||||
|
};
|
||||||
|
|
||||||
|
static inline int rwnx_dbgfs_register(struct rwnx_hw *rwnx_hw, const char *name) { return 0; }
|
||||||
|
static inline void rwnx_dbgfs_unregister(struct rwnx_hw *rwnx_hw) {}
|
||||||
|
#ifdef CONFIG_RWNX_FULLMAC
|
||||||
|
static inline void rwnx_dbgfs_register_rc_stat(struct rwnx_hw *rwnx_hw, struct rwnx_sta *sta) {}
|
||||||
|
static inline void rwnx_dbgfs_unregister_rc_stat(struct rwnx_hw *rwnx_hw, struct rwnx_sta *sta) {}
|
||||||
|
#endif
|
||||||
|
#endif /* CONFIG_RWNX_DEBUGFS */
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* _RWNX_DEBUGFS_H_ */
|
||||||
928
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/rwnx_defs.h
Normal file
928
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/rwnx_defs.h
Normal file
|
|
@ -0,0 +1,928 @@
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
*
|
||||||
|
* @file rwnx_defs.h
|
||||||
|
*
|
||||||
|
* @brief Main driver structure declarations for fullmac driver
|
||||||
|
*
|
||||||
|
* Copyright (C) RivieraWaves 2012-2019
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _RWNX_DEFS_H_
|
||||||
|
#define _RWNX_DEFS_H_
|
||||||
|
|
||||||
|
#include <linux/interrupt.h>
|
||||||
|
#include <linux/device.h>
|
||||||
|
#include <linux/dmapool.h>
|
||||||
|
#include <linux/skbuff.h>
|
||||||
|
#include <net/cfg80211.h>
|
||||||
|
#include <linux/slab.h>
|
||||||
|
|
||||||
|
#include "rwnx_mod_params.h"
|
||||||
|
#include "rwnx_debugfs.h"
|
||||||
|
#include "rwnx_tx.h"
|
||||||
|
#include "rwnx_rx.h"
|
||||||
|
#include "rwnx_radar.h"
|
||||||
|
#include "rwnx_utils.h"
|
||||||
|
#include "rwnx_mu_group.h"
|
||||||
|
#include "rwnx_platform.h"
|
||||||
|
#include "rwnx_cmds.h"
|
||||||
|
#include "rwnx_compat.h"
|
||||||
|
#ifdef CONFIG_FILTER_TCP_ACK
|
||||||
|
#include "aicwf_tcp_ack.h"
|
||||||
|
#endif
|
||||||
|
#ifdef CONFIG_BAND_STEERING
|
||||||
|
#include "aicwf_steering.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef AICWF_SDIO_SUPPORT
|
||||||
|
#include "aicwf_sdio.h"
|
||||||
|
#include "sdio_host.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef AICWF_USB_SUPPORT
|
||||||
|
#include "usb_host.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_BR_SUPPORT
|
||||||
|
#include "aic_br_ext.h"
|
||||||
|
#endif /* CONFIG_BR_SUPPORT */
|
||||||
|
|
||||||
|
#define WPI_HDR_LEN 18
|
||||||
|
#define WPI_PN_LEN 16
|
||||||
|
#define WPI_PN_OFST 2
|
||||||
|
#define WPI_MIC_LEN 16
|
||||||
|
#define WPI_KEY_LEN 32
|
||||||
|
#define WPI_SUBKEY_LEN 16 // WPI key is actually two 16bytes key
|
||||||
|
|
||||||
|
#define LEGACY_PS_ID 0
|
||||||
|
#define UAPSD_ID 1
|
||||||
|
|
||||||
|
#define PS_SP_INTERRUPTED 255
|
||||||
|
#define MAC_ADDR_LEN 6
|
||||||
|
|
||||||
|
//because android kernel 5.15 uses kernel 6.0 or 6.1 kernel api
|
||||||
|
#ifdef ANDROID_PLATFORM
|
||||||
|
#define HIGH_KERNEL_VERSION KERNEL_VERSION(5, 15, 41)
|
||||||
|
#define HIGH_KERNEL_VERSION2 KERNEL_VERSION(5, 15, 41)
|
||||||
|
#define HIGH_KERNEL_VERSION3 KERNEL_VERSION(5, 15, 104)
|
||||||
|
#define HIGH_KERNEL_VERSION4 KERNEL_VERSION(6, 1, 0)
|
||||||
|
#else
|
||||||
|
#define HIGH_KERNEL_VERSION KERNEL_VERSION(6, 0, 0)
|
||||||
|
#define HIGH_KERNEL_VERSION2 KERNEL_VERSION(6, 1, 0)
|
||||||
|
#define HIGH_KERNEL_VERSION3 KERNEL_VERSION(6, 3, 0)
|
||||||
|
#define HIGH_KERNEL_VERSION4 KERNEL_VERSION(6, 3, 0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#if LINUX_VERSION_CODE >= HIGH_KERNEL_VERSION
|
||||||
|
#define IEEE80211_MAX_AMPDU_BUF IEEE80211_MAX_AMPDU_BUF_HE
|
||||||
|
#define IEEE80211_HE_PHY_CAP6_TRIG_MU_BEAMFORMER_FB IEEE80211_HE_PHY_CAP6_TRIG_MU_BEAMFORMING_PARTIAL_BW_FB
|
||||||
|
#define IEEE80211_HE_PHY_CAP6_TRIG_SU_BEAMFORMER_FB IEEE80211_HE_PHY_CAP6_TRIG_SU_BEAMFORMING_FB
|
||||||
|
#define IEEE80211_HE_PHY_CAP3_RX_HE_MU_PPDU_FROM_NON_AP_STA IEEE80211_HE_PHY_CAP3_RX_PARTIAL_BW_SU_IN_20MHZ_MU
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef IEEE80211_MAX_AMPDU_BUF
|
||||||
|
#define IEEE80211_MAX_AMPDU_BUF 0x100
|
||||||
|
#endif
|
||||||
|
#ifndef IEEE80211_HE_PHY_CAP6_TRIG_MU_BEAMFORMER_FB
|
||||||
|
#define IEEE80211_HE_PHY_CAP6_TRIG_MU_BEAMFORMER_FB 0x08
|
||||||
|
#endif
|
||||||
|
#ifndef IEEE80211_HE_PHY_CAP6_TRIG_SU_BEAMFORMER_FB
|
||||||
|
#define IEEE80211_HE_PHY_CAP6_TRIG_SU_BEAMFORMER_FB 0x04
|
||||||
|
#endif
|
||||||
|
#ifndef IEEE80211_HE_PHY_CAP3_RX_HE_MU_PPDU_FROM_NON_AP_STA
|
||||||
|
#define IEEE80211_HE_PHY_CAP3_RX_HE_MU_PPDU_FROM_NON_AP_STA 0x40
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 5, 0) || defined(CONFIG_VHT_FOR_OLD_KERNEL)
|
||||||
|
enum nl80211_ac {
|
||||||
|
NL80211_AC_VO,
|
||||||
|
NL80211_AC_VI,
|
||||||
|
NL80211_AC_BE,
|
||||||
|
NL80211_AC_BK,
|
||||||
|
NL80211_NUM_ACS
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 6, 0) || defined(CONFIG_VHT_FOR_OLD_KERNEL)
|
||||||
|
struct ieee80211_vht_operation {
|
||||||
|
u8 vht_op_info_chwidth;
|
||||||
|
u8 vht_op_info_chan_center_freq_seg1_idx;
|
||||||
|
u8 vht_op_info_chan_center_freq_seg2_idx;
|
||||||
|
__le16 vht_basic_mcs_set;
|
||||||
|
} __packed;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 7, 0)
|
||||||
|
#define NL80211_IFTYPE_P2P_DEVICE 10
|
||||||
|
#define IEEE80211_RADIOTAP_AMPDU_STATUS 20
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0) || defined(CONFIG_VHT_FOR_OLD_KERNEL)
|
||||||
|
#define IEEE80211_RADIOTAP_VHT 21
|
||||||
|
#define IEEE80211_RADIOTAP_VHT_KNOWN_GI 0x0004
|
||||||
|
#define IEEE80211_RADIOTAP_VHT_KNOWN_BANDWIDTH 0x0040
|
||||||
|
|
||||||
|
#define IEEE80211_RADIOTAP_VHT_FLAG_STBC 0x01
|
||||||
|
#define IEEE80211_RADIOTAP_VHT_FLAG_SGI 0x04
|
||||||
|
|
||||||
|
#define NL80211_FEATURE_CELL_BASE_REG_HINTS 1 << 3
|
||||||
|
#define NL80211_FEATURE_P2P_DEVICE_NEEDS_CHANNEL 1 << 4
|
||||||
|
#define NL80211_FEATURE_SAE 1 << 5
|
||||||
|
#define NL80211_FEATURE_LOW_PRIORITY_SCAN 1 << 6
|
||||||
|
#define NL80211_FEATURE_SCAN_FLUSH 1 << 7
|
||||||
|
#define NL80211_FEATURE_AP_SCAN 1 << 8
|
||||||
|
#define NL80211_FEATURE_VIF_TXPOWER 1 << 9
|
||||||
|
#define NL80211_FEATURE_NEED_OBSS_SCAN 1 << 10
|
||||||
|
#define NL80211_FEATURE_P2P_GO_CTWIN 1 << 11
|
||||||
|
#define NL80211_FEATURE_P2P_GO_OPPPS 1 << 12
|
||||||
|
|
||||||
|
/* 802.11ac VHT Capabilities */
|
||||||
|
#define IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_3895 0x00000000
|
||||||
|
#define IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_7991 0x00000001
|
||||||
|
#define IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454 0x00000002
|
||||||
|
#define IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ 0x00000004
|
||||||
|
#define IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ 0x00000008
|
||||||
|
#define IEEE80211_VHT_CAP_RXLDPC 0x00000010
|
||||||
|
#define IEEE80211_VHT_CAP_SHORT_GI_80 0x00000020
|
||||||
|
#define IEEE80211_VHT_CAP_SHORT_GI_160 0x00000040
|
||||||
|
#define IEEE80211_VHT_CAP_TXSTBC 0x00000080
|
||||||
|
#define IEEE80211_VHT_CAP_RXSTBC_1 0x00000100
|
||||||
|
#define IEEE80211_VHT_CAP_RXSTBC_2 0x00000200
|
||||||
|
#define IEEE80211_VHT_CAP_RXSTBC_3 0x00000300
|
||||||
|
#define IEEE80211_VHT_CAP_RXSTBC_4 0x00000400
|
||||||
|
#define IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE 0x00000800
|
||||||
|
#define IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE 0x00001000
|
||||||
|
#define IEEE80211_VHT_CAP_BEAMFORMER_ANTENNAS_MAX 0x00006000
|
||||||
|
#define IEEE80211_VHT_CAP_SOUNDING_DIMENTION_MAX 0x00030000
|
||||||
|
#define IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE 0x00080000
|
||||||
|
#define IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE 0x00100000
|
||||||
|
#define IEEE80211_VHT_CAP_VHT_TXOP_PS 0x00200000
|
||||||
|
#define IEEE80211_VHT_CAP_HTC_VHT 0x00400000
|
||||||
|
#define IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_SHIFT 23
|
||||||
|
#define IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK \
|
||||||
|
(7 << IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_SHIFT)
|
||||||
|
#define IEEE80211_VHT_CAP_VHT_LINK_ADAPTATION_VHT_UNSOL_MFB 0x08000000
|
||||||
|
#define IEEE80211_VHT_CAP_VHT_LINK_ADAPTATION_VHT_MRQ_MFB 0x0c000000
|
||||||
|
#define IEEE80211_VHT_CAP_RX_ANTENNA_PATTERN 0x10000000
|
||||||
|
#define IEEE80211_VHT_CAP_TX_ANTENNA_PATTERN 0x20000000
|
||||||
|
|
||||||
|
enum ieee80211_vht_mcs_support {
|
||||||
|
IEEE80211_VHT_MCS_SUPPORT_0_7 = 0,
|
||||||
|
IEEE80211_VHT_MCS_SUPPORT_0_8 = 1,
|
||||||
|
IEEE80211_VHT_MCS_SUPPORT_0_9 = 2,
|
||||||
|
IEEE80211_VHT_MCS_NOT_SUPPORTED = 3,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum nl80211_chan_width {
|
||||||
|
NL80211_CHAN_WIDTH_20_NOHT,
|
||||||
|
NL80211_CHAN_WIDTH_20,
|
||||||
|
NL80211_CHAN_WIDTH_40,
|
||||||
|
NL80211_CHAN_WIDTH_80,
|
||||||
|
NL80211_CHAN_WIDTH_80P80,
|
||||||
|
NL80211_CHAN_WIDTH_160,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct cfg80211_chan_def {
|
||||||
|
struct ieee80211_channel *chan;
|
||||||
|
enum nl80211_chan_width width;
|
||||||
|
u32 center_freq1;
|
||||||
|
u32 center_freq2;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum nl80211_mesh_power_mode {
|
||||||
|
NL80211_MESH_POWER_UNKNOWN,
|
||||||
|
NL80211_MESH_POWER_ACTIVE,
|
||||||
|
NL80211_MESH_POWER_LIGHT_SLEEP,
|
||||||
|
NL80211_MESH_POWER_DEEP_SLEEP,
|
||||||
|
__NL80211_MESH_POWER_AFTER_LAST,
|
||||||
|
NL80211_MESH_POWER_MAX = __NL80211_MESH_POWER_AFTER_LAST - 1
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_BAND_STEERING
|
||||||
|
enum band_type {
|
||||||
|
BAND_ON_24G = 0,
|
||||||
|
BAND_ON_5G = 1,
|
||||||
|
BAND_ON_60G = 2,
|
||||||
|
BAND_ON_6G = 3,
|
||||||
|
BAND_MAX,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum WIFI_FRAME_TYPE {
|
||||||
|
WIFI_MGT_TYPE = (0),
|
||||||
|
};
|
||||||
|
|
||||||
|
enum WIFI_FRAME_SUBTYPE {
|
||||||
|
WIFI_ASSOCREQ = (0 | WIFI_MGT_TYPE),
|
||||||
|
WIFI_PROBEREQ = (BIT(6) | WIFI_MGT_TYPE),
|
||||||
|
WIFI_AUTH = (BIT(7) | BIT(5) | BIT(4) | WIFI_MGT_TYPE),
|
||||||
|
};
|
||||||
|
|
||||||
|
struct tmp_feature_sta {
|
||||||
|
u8_l sta_idx;
|
||||||
|
u8_l supported_band;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define MAX_PENDING_PROBES 3
|
||||||
|
struct ap_probe_rsp {
|
||||||
|
u8_l da[6];
|
||||||
|
struct work_struct rsp_work;
|
||||||
|
bool in_use;
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 9, 0)
|
||||||
|
#define NL80211_MESHCONF_POWER_MODE 26
|
||||||
|
|
||||||
|
/*
|
||||||
|
* TDLS capabililites to be enabled in the 5th byte of the
|
||||||
|
* @WLAN_EID_EXT_CAPABILITY information element
|
||||||
|
*/
|
||||||
|
#define WLAN_EXT_CAPA5_TDLS_ENABLED BIT(5)
|
||||||
|
#define WLAN_EXT_CAPA5_TDLS_PROHIBITED BIT(6)
|
||||||
|
|
||||||
|
#define WLAN_EXT_CAPA8_OPMODE_NOTIF BIT(6)
|
||||||
|
|
||||||
|
/* TDLS specific payload type in the LLC/SNAP header */
|
||||||
|
#define WLAN_TDLS_SNAP_RFTYPE 0x2
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct rwnx_bcn - Information of the beacon in used (AP mode)
|
||||||
|
*
|
||||||
|
* @head: head portion of beacon (before TIM IE)
|
||||||
|
* @tail: tail portion of beacon (after TIM IE)
|
||||||
|
* @ies: extra IEs (not used ?)
|
||||||
|
* @head_len: length of head data
|
||||||
|
* @tail_len: length of tail data
|
||||||
|
* @ies_len: length of extra IEs data
|
||||||
|
* @tim_len: length of TIM IE
|
||||||
|
* @len: Total beacon len (head + tim + tail + extra)
|
||||||
|
* @dtim: dtim period
|
||||||
|
*/
|
||||||
|
struct rwnx_bcn {
|
||||||
|
u8 *head;
|
||||||
|
u8 *tail;
|
||||||
|
u8 *ies;
|
||||||
|
size_t head_len;
|
||||||
|
size_t tail_len;
|
||||||
|
size_t ies_len;
|
||||||
|
size_t tim_len;
|
||||||
|
size_t len;
|
||||||
|
u8 dtim;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct rwnx_key - Key information
|
||||||
|
*
|
||||||
|
* @hw_idx: Idx of the key from hardware point of view
|
||||||
|
*/
|
||||||
|
struct rwnx_key {
|
||||||
|
u8 hw_idx;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Structure containing information about a Mesh Path
|
||||||
|
*/
|
||||||
|
struct rwnx_mesh_path {
|
||||||
|
struct list_head list; /* For rwnx_vif.mesh_paths */
|
||||||
|
u8 path_idx; /* Path Index */
|
||||||
|
struct mac_addr tgt_mac_addr; /* Target MAC Address */
|
||||||
|
struct rwnx_sta *p_nhop_sta; /* Pointer to the Next Hop STA */
|
||||||
|
};
|
||||||
|
|
||||||
|
struct rwnx_mesh_proxy {
|
||||||
|
struct list_head list; /* For rwnx_vif.mesh_proxy */
|
||||||
|
struct mac_addr ext_sta_addr; /* Address of the External STA */
|
||||||
|
struct mac_addr proxy_addr; /* Proxy MAC Address */
|
||||||
|
bool local; /* Indicate if interface is a proxy for the device */
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct rwnx_csa - Information for CSA (Channel Switch Announcement)
|
||||||
|
*
|
||||||
|
* @vif: Pointer to the vif doing the CSA
|
||||||
|
* @bcn: Beacon to use after CSA
|
||||||
|
* @elem: IPC buffer to send the new beacon to the fw
|
||||||
|
* @chandef: defines the channel to use after the switch
|
||||||
|
* @count: Current csa counter
|
||||||
|
* @status: Status of the CSA at fw level
|
||||||
|
* @ch_idx: Index of the new channel context
|
||||||
|
* @work: work scheduled at the end of CSA
|
||||||
|
*/
|
||||||
|
struct rwnx_csa {
|
||||||
|
struct rwnx_vif *vif;
|
||||||
|
struct rwnx_bcn bcn;
|
||||||
|
struct rwnx_ipc_elem_var elem;
|
||||||
|
struct cfg80211_chan_def chandef;
|
||||||
|
int count;
|
||||||
|
int status;
|
||||||
|
int ch_idx;
|
||||||
|
struct work_struct work;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct apm_probe_sta {
|
||||||
|
u8 sta_mac_addr[6];
|
||||||
|
u8 vif_idx;
|
||||||
|
u64 probe_id;
|
||||||
|
struct work_struct apmprobestaWork;
|
||||||
|
struct workqueue_struct *apmprobesta_wq;
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Possible States of the TDLS link.
|
||||||
|
enum tdls_status_tag {
|
||||||
|
/// TDLS link is not active (no TDLS peer connected)
|
||||||
|
TDLS_LINK_IDLE,
|
||||||
|
/// TDLS Setup Request transmitted
|
||||||
|
TDLS_SETUP_REQ_TX,
|
||||||
|
/// TDLS Setup Response transmitted
|
||||||
|
TDLS_SETUP_RSP_TX,
|
||||||
|
/// TDLS link is active (TDLS peer connected)
|
||||||
|
TDLS_LINK_ACTIVE,
|
||||||
|
/// TDLS Max Number of states.
|
||||||
|
TDLS_STATE_MAX
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Structure used to save information relative to the TDLS peer.
|
||||||
|
* This is also linked within the rwnx_hw vifs list.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
struct rwnx_tdls {
|
||||||
|
bool active; /* Indicate if TDLS link is active */
|
||||||
|
bool initiator; /* Indicate if TDLS peer is the TDLS initiator */
|
||||||
|
bool chsw_en; /* Indicate if channel switch is enabled */
|
||||||
|
u8 last_tid; /* TID of the latest MPDU transmitted over the
|
||||||
|
TDLS direct link to the TDLS STA */
|
||||||
|
u16 last_sn; /* Sequence number of the latest MPDU transmitted
|
||||||
|
over the TDLS direct link to the TDLS STA */
|
||||||
|
bool ps_on; /* Indicate if the power save is enabled on the
|
||||||
|
TDLS STA */
|
||||||
|
bool chsw_allowed; /* Indicate if TDLS channel switch is allowed */
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* enum rwnx_ap_flags - AP flags
|
||||||
|
*
|
||||||
|
* @RWNX_AP_ISOLATE Isolate clients (i.e. Don't brige packets transmitted by
|
||||||
|
* one client for another one)
|
||||||
|
*/
|
||||||
|
enum rwnx_ap_flags {
|
||||||
|
RWNX_AP_ISOLATE = BIT(0),
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Structure used to save information relative to the managed interfaces.
|
||||||
|
* This is also linked within the rwnx_hw vifs list.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
struct rwnx_vif {
|
||||||
|
struct list_head list;
|
||||||
|
struct rwnx_hw *rwnx_hw;
|
||||||
|
struct wireless_dev wdev;
|
||||||
|
struct net_device *ndev;
|
||||||
|
struct net_device_stats net_stats;
|
||||||
|
struct rwnx_key key[6];
|
||||||
|
unsigned long drv_flags;
|
||||||
|
atomic_t drv_conn_state;
|
||||||
|
u8 drv_vif_index; /* Identifier of the VIF in driver */
|
||||||
|
u8 vif_index; /* Identifier of the station in FW */
|
||||||
|
u8 ch_index; /* Channel context identifier */
|
||||||
|
bool up; /* Indicate if associated netdev is up
|
||||||
|
(i.e. Interface is created at fw level) */
|
||||||
|
bool use_4addr; /* Should we use 4addresses mode */
|
||||||
|
bool is_resending; /* Indicate if a frame is being resent on this interface */
|
||||||
|
bool user_mpm; /* In case of Mesh Point VIF, indicate if MPM is handled by userspace */
|
||||||
|
bool roc_tdls; /* Indicate if the ROC has been called by a
|
||||||
|
TDLS station */
|
||||||
|
u8 tdls_status; /* Status of the TDLS link */
|
||||||
|
bool tdls_chsw_prohibited; /* Indicate if TDLS Channel Switch is prohibited */
|
||||||
|
bool wep_enabled; /* 1 if WEP is enabled */
|
||||||
|
bool wep_auth_err; /* 1 if auth status code is not supported auth alg when WEP enabled */
|
||||||
|
enum nl80211_auth_type last_auth_type; /* Authentication type (algorithm) sent in the last connection
|
||||||
|
when WEP enabled */
|
||||||
|
union
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
struct rwnx_sta *ap; /* Pointer to the peer STA entry allocated for
|
||||||
|
the AP */
|
||||||
|
struct rwnx_sta *tdls_sta; /* Pointer to the TDLS station */
|
||||||
|
bool external_auth; /* Indicate if external authentication is in progress */
|
||||||
|
u32 group_cipher_type;
|
||||||
|
u32 paired_cipher_type;
|
||||||
|
//connected network info start
|
||||||
|
char ssid[33];//ssid max is 32, but this has one spare for '\0'
|
||||||
|
int ssid_len;
|
||||||
|
u8 bssid[ETH_ALEN];
|
||||||
|
u32 conn_owner_nlportid;
|
||||||
|
bool is_roam;
|
||||||
|
//connected network info end
|
||||||
|
} sta;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
u16 flags; /* see rwnx_ap_flags */
|
||||||
|
struct list_head sta_list; /* List of STA connected to the AP */
|
||||||
|
struct rwnx_bcn bcn; /* beacon */
|
||||||
|
u8 bcmc_index; /* Index of the BCMC sta to use */
|
||||||
|
#if (defined CONFIG_HE_FOR_OLD_KERNEL) || (defined CONFIG_VHT_FOR_OLD_KERNEL)
|
||||||
|
u8 aic_index;
|
||||||
|
#endif
|
||||||
|
struct rwnx_csa *csa;
|
||||||
|
|
||||||
|
struct list_head mpath_list; /* List of Mesh Paths used on this interface */
|
||||||
|
struct list_head proxy_list; /* List of Proxies Information used on this interface */
|
||||||
|
bool create_path; /* Indicate if we are waiting for a MESH_CREATE_PATH_CFM
|
||||||
|
message */
|
||||||
|
int generation; /* Increased each time the list of Mesh Paths is updated */
|
||||||
|
#ifdef CONFIG_BAND_STEERING
|
||||||
|
u8_l tmp_sta_idx;
|
||||||
|
enum band_type band;
|
||||||
|
u32_l freq;
|
||||||
|
bool start;
|
||||||
|
#endif
|
||||||
|
enum nl80211_mesh_power_mode mesh_pm; /* mesh power save mode currently set in firmware */
|
||||||
|
enum nl80211_mesh_power_mode next_mesh_pm; /* mesh power save mode for next peer */
|
||||||
|
} ap;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
struct rwnx_vif *master; /* pointer on master interface */
|
||||||
|
struct rwnx_sta *sta_4a;
|
||||||
|
} ap_vlan;
|
||||||
|
};
|
||||||
|
|
||||||
|
u8_l key_has_add;
|
||||||
|
u8_l is_p2p_vif;
|
||||||
|
struct apm_probe_sta sta_probe;
|
||||||
|
|
||||||
|
#ifdef CONFIG_BR_SUPPORT
|
||||||
|
spinlock_t br_ext_lock;
|
||||||
|
/* unsigned int macclone_completed; */
|
||||||
|
struct nat25_network_db_entry *nethash[NAT25_HASH_SIZE];
|
||||||
|
int pppoe_connection_in_progress;
|
||||||
|
unsigned char pppoe_addr[MACADDRLEN];
|
||||||
|
unsigned char scdb_mac[MACADDRLEN];
|
||||||
|
unsigned char scdb_ip[4];
|
||||||
|
struct nat25_network_db_entry *scdb_entry;
|
||||||
|
unsigned char br_mac[MACADDRLEN];
|
||||||
|
unsigned char br_ip[4];
|
||||||
|
|
||||||
|
struct br_ext_info ethBrExtInfo;
|
||||||
|
#endif /* CONFIG_BR_SUPPORT */
|
||||||
|
#ifdef CONFIG_BAND_STEERING
|
||||||
|
struct workqueue_struct *rsp_wq;
|
||||||
|
struct timer_list steer_timer;
|
||||||
|
struct work_struct steer_work;
|
||||||
|
struct b_steer_priv bsteerpriv;
|
||||||
|
struct ap_probe_rsp pb_pool[MAX_PENDING_PROBES];
|
||||||
|
#endif
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#define RWNX_VIF_TYPE(rwnx_vif) (rwnx_vif->wdev.iftype)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Structure used to store information relative to PS mode.
|
||||||
|
*
|
||||||
|
* @active: True when the sta is in PS mode.
|
||||||
|
* If false, other values should be ignored
|
||||||
|
* @pkt_ready: Number of packets buffered for the sta in drv's txq
|
||||||
|
* (1 counter for Legacy PS and 1 for U-APSD)
|
||||||
|
* @sp_cnt: Number of packets that remain to be pushed in the service period.
|
||||||
|
* 0 means that no service period is in progress
|
||||||
|
* (1 counter for Legacy PS and 1 for U-APSD)
|
||||||
|
*/
|
||||||
|
struct rwnx_sta_ps {
|
||||||
|
bool active;
|
||||||
|
u16 pkt_ready[2];
|
||||||
|
u16 sp_cnt[2];
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct rwnx_rx_rate_stats - Store statistics for RX rates
|
||||||
|
*
|
||||||
|
* @table: Table indicating how many frame has been receive which each
|
||||||
|
* rate index. Rate index is the same as the one used by RC algo for TX
|
||||||
|
* @size: Size of the table array
|
||||||
|
* @cpt: number of frames received
|
||||||
|
*/
|
||||||
|
struct rwnx_rx_rate_stats {
|
||||||
|
int *table;
|
||||||
|
int size;
|
||||||
|
int cpt;
|
||||||
|
int rate_cnt;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct rwnx_sta_stats - Structure Used to store statistics specific to a STA
|
||||||
|
*
|
||||||
|
* @last_rx: Hardware vector of the last received frame
|
||||||
|
* @rx_rate: Statistics of the received rates
|
||||||
|
*/
|
||||||
|
struct rwnx_sta_stats {
|
||||||
|
u32 rx_pkts;
|
||||||
|
u32 tx_pkts;
|
||||||
|
u64 rx_bytes;
|
||||||
|
u64 tx_bytes;
|
||||||
|
unsigned long last_act;
|
||||||
|
struct hw_vect last_rx;
|
||||||
|
struct rwnx_rx_rate_stats rx_rate;
|
||||||
|
u32 last_chan_time;
|
||||||
|
u32 last_chan_busy_time;
|
||||||
|
u32 tx_ack_succ_stat;
|
||||||
|
u32 tx_ack_fail_stat;
|
||||||
|
u32 last_chan_tx_busy_time;
|
||||||
|
};
|
||||||
|
|
||||||
|
#if (defined CONFIG_HE_FOR_OLD_KERNEL) || (defined CONFIG_VHT_FOR_OLD_KERNEL)
|
||||||
|
struct aic_sta {
|
||||||
|
u8 sta_idx; /* Identifier of the station */
|
||||||
|
bool he; /* Flag indicating if the station supports HE */
|
||||||
|
bool vht; /* Flag indicating if the station supports VHT */
|
||||||
|
|
||||||
|
struct ieee80211_he_cap_elem he_cap_elem;
|
||||||
|
struct ieee80211_he_mcs_nss_supp he_mcs_nss_supp;
|
||||||
|
|
||||||
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0) || defined(CONFIG_VHT_FOR_OLD_KERNEL)
|
||||||
|
__le32 vht_cap_info;
|
||||||
|
struct ieee80211_vht_mcs_info supp_mcs;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Structure used to save information relative to the managed stations.
|
||||||
|
*/
|
||||||
|
struct rwnx_sta {
|
||||||
|
struct list_head list;
|
||||||
|
u16 aid; /* association ID */
|
||||||
|
u8 sta_idx; /* Identifier of the station */
|
||||||
|
u8 vif_idx; /* Identifier of the VIF (fw id) the station
|
||||||
|
belongs to */
|
||||||
|
u8 vlan_idx; /* Identifier of the VLAN VIF (fw id) the station
|
||||||
|
belongs to (= vif_idx if no vlan in used) */
|
||||||
|
enum nl80211_band band; /* Band */
|
||||||
|
enum nl80211_chan_width width; /* Channel width */
|
||||||
|
u16 center_freq; /* Center frequency */
|
||||||
|
u32 center_freq1; /* Center frequency 1 */
|
||||||
|
u32 center_freq2; /* Center frequency 2 */
|
||||||
|
u8 ch_idx; /* Identifier of the channel
|
||||||
|
context the station belongs to */
|
||||||
|
bool qos; /* Flag indicating if the station
|
||||||
|
supports QoS */
|
||||||
|
u8 acm; /* Bitfield indicating which queues
|
||||||
|
have AC mandatory */
|
||||||
|
u16 uapsd_tids; /* Bitfield indicating which tids are subject to
|
||||||
|
UAPSD */
|
||||||
|
u8 mac_addr[ETH_ALEN]; /* MAC address of the station */
|
||||||
|
struct rwnx_key key;
|
||||||
|
bool valid; /* Flag indicating if the entry is valid */
|
||||||
|
struct rwnx_sta_ps ps; /* Information when STA is in PS (AP only) */
|
||||||
|
#ifdef CONFIG_RWNX_BFMER
|
||||||
|
struct rwnx_bfmer_report *bfm_report; /* Beamforming report to be used for
|
||||||
|
VHT TX Beamforming */
|
||||||
|
#ifdef CONFIG_RWNX_MUMIMO_TX
|
||||||
|
struct rwnx_sta_group_info group_info; /* MU grouping information for the STA */
|
||||||
|
#endif /* CONFIG_RWNX_MUMIMO_TX */
|
||||||
|
#endif /* CONFIG_RWNX_BFMER */
|
||||||
|
|
||||||
|
bool ht; /* Flag indicating if the station
|
||||||
|
supports HT */
|
||||||
|
bool vht; /* Flag indicating if the station
|
||||||
|
supports VHT */
|
||||||
|
u32 ac_param[AC_MAX]; /* EDCA parameters */
|
||||||
|
struct rwnx_tdls tdls; /* TDLS station information */
|
||||||
|
struct rwnx_sta_stats stats;
|
||||||
|
enum nl80211_mesh_power_mode mesh_pm; /* link-specific mesh power save mode */
|
||||||
|
#ifdef CONFIG_DYNAMIC_PERPWR
|
||||||
|
s8_l rssi_save;
|
||||||
|
s8_l per_pwrloss;
|
||||||
|
struct work_struct per_pwr_work;
|
||||||
|
unsigned long last_jiffies;
|
||||||
|
#endif
|
||||||
|
#ifdef CONFIG_BAND_STEERING
|
||||||
|
u32_l link_time;
|
||||||
|
s8_l rssi;
|
||||||
|
u8_l support_band;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
static inline const u8 *rwnx_sta_addr(struct rwnx_sta *rwnx_sta) {
|
||||||
|
return rwnx_sta->mac_addr;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_RWNX_SPLIT_TX_BUF
|
||||||
|
struct rwnx_amsdu_stats {
|
||||||
|
int done;
|
||||||
|
int failed;
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct rwnx_stats {
|
||||||
|
int cfm_balance[NX_TXQ_CNT];
|
||||||
|
unsigned long last_rx, last_tx; /* jiffies */
|
||||||
|
int ampdus_tx[IEEE80211_MAX_AMPDU_BUF];
|
||||||
|
int ampdus_rx[IEEE80211_MAX_AMPDU_BUF];
|
||||||
|
int ampdus_rx_map[4];
|
||||||
|
int ampdus_rx_miss;
|
||||||
|
#ifdef CONFIG_RWNX_SPLIT_TX_BUF
|
||||||
|
struct rwnx_amsdu_stats amsdus[NX_TX_PAYLOAD_MAX];
|
||||||
|
#endif
|
||||||
|
int amsdus_rx[64];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct rwnx_sec_phy_chan {
|
||||||
|
u16 prim20_freq;
|
||||||
|
u16 center_freq1;
|
||||||
|
u16 center_freq2;
|
||||||
|
enum nl80211_band band;
|
||||||
|
u8 type;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Structure that will contains all RoC information received from cfg80211 */
|
||||||
|
struct rwnx_roc_elem {
|
||||||
|
struct wireless_dev *wdev;
|
||||||
|
struct ieee80211_channel *chan;
|
||||||
|
unsigned int duration;
|
||||||
|
/* Used to avoid call of CFG80211 callback upon expiration of RoC */
|
||||||
|
bool mgmt_roc;
|
||||||
|
/* Indicate if we have switch on the RoC channel */
|
||||||
|
bool on_chan;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Structure containing channel survey information received from MAC */
|
||||||
|
struct rwnx_survey_info {
|
||||||
|
// Filled
|
||||||
|
u32 filled;
|
||||||
|
// Amount of time in ms the radio spent on the channel
|
||||||
|
u32 chan_time_ms;
|
||||||
|
// Amount of time the primary channel was sensed busy
|
||||||
|
u32 chan_time_busy_ms;
|
||||||
|
// Noise in dbm
|
||||||
|
s8 noise_dbm;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define RWNX_CH_NOT_SET 0xFF
|
||||||
|
#define RWNX_INVALID_VIF 0xFF
|
||||||
|
#define RWNX_INVALID_STA 0xFF
|
||||||
|
|
||||||
|
/* Structure containing channel context information */
|
||||||
|
struct rwnx_chanctx {
|
||||||
|
struct cfg80211_chan_def chan_def; /* channel description */
|
||||||
|
u8 count; /* number of vif using this ctxt */
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* rwnx_phy_info - Phy information
|
||||||
|
*
|
||||||
|
* @phy_cnt: Number of phy interface
|
||||||
|
* @cfg: Configuration send to firmware
|
||||||
|
* @sec_chan: Channel configuration of the second phy interface (if phy_cnt > 1)
|
||||||
|
* @limit_bw: Set to true to limit BW on requested channel. Only set to use
|
||||||
|
* VHT with old radio that don't support 80MHz (deprecated)
|
||||||
|
*/
|
||||||
|
struct rwnx_phy_info {
|
||||||
|
u8 cnt;
|
||||||
|
struct phy_cfg_tag cfg;
|
||||||
|
struct rwnx_sec_phy_chan sec_chan;
|
||||||
|
bool limit_bw;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct defrag_ctrl_info {
|
||||||
|
struct list_head list;
|
||||||
|
u8 sta_idx;
|
||||||
|
u8 tid;
|
||||||
|
u16 sn;
|
||||||
|
u8 next_fn;
|
||||||
|
u16 frm_len;
|
||||||
|
struct sk_buff *skb;
|
||||||
|
struct timer_list defrag_timer;
|
||||||
|
struct rwnx_hw *rwnx_hw;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct amsdu_subframe_hdr {
|
||||||
|
u8 da[6];
|
||||||
|
u8 sa[6];
|
||||||
|
u16 sublen;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* rwnx driver status */
|
||||||
|
void rwnx_set_conn_state(atomic_t *drv_conn_state, int state);
|
||||||
|
|
||||||
|
enum rwnx_drv_connect_status {
|
||||||
|
RWNX_DRV_STATUS_DISCONNECTED = 0,
|
||||||
|
RWNX_DRV_STATUS_DISCONNECTING,
|
||||||
|
RWNX_DRV_STATUS_CONNECTING,
|
||||||
|
RWNX_DRV_STATUS_CONNECTED,
|
||||||
|
RWNX_DRV_STATUS_ROAMING,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const char *const s_conn_state[] = {
|
||||||
|
"RWNX_DRV_STATUS_DISCONNECTED",
|
||||||
|
"RWNX_DRV_STATUS_DISCONNECTING",
|
||||||
|
"RWNX_DRV_STATUS_CONNECTING",
|
||||||
|
"RWNX_DRV_STATUS_CONNECTED",
|
||||||
|
"RWNX_DRV_STATUS_ROAMING",
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct sta_tx_flowctrl {
|
||||||
|
atomic_t tx_pending_cnt;
|
||||||
|
u8 flowctrl;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct rwnx_hw {
|
||||||
|
struct rwnx_mod_params *mod_params;
|
||||||
|
struct device *dev;
|
||||||
|
#ifdef AICWF_SDIO_SUPPORT
|
||||||
|
struct aic_sdio_dev *sdiodev;
|
||||||
|
#endif
|
||||||
|
#ifdef AICWF_USB_SUPPORT
|
||||||
|
struct aic_usb_dev *usbdev;
|
||||||
|
#endif
|
||||||
|
struct wiphy *wiphy;
|
||||||
|
struct list_head vifs;
|
||||||
|
struct rwnx_vif *vif_table[NX_VIRT_DEV_MAX + NX_REMOTE_STA_MAX]; /* indexed with fw id */
|
||||||
|
struct rwnx_sta sta_table[NX_REMOTE_STA_MAX + NX_VIRT_DEV_MAX];
|
||||||
|
#ifdef CONFIG_HE_FOR_OLD_KERNEL
|
||||||
|
struct aic_sta aic_table[NX_REMOTE_STA_MAX + NX_VIRT_DEV_MAX];
|
||||||
|
#endif
|
||||||
|
struct rwnx_survey_info survey[SCAN_CHANNEL_MAX];
|
||||||
|
struct cfg80211_scan_request *scan_request;
|
||||||
|
#ifdef CONFIG_SCHED_SCAN
|
||||||
|
struct cfg80211_sched_scan_request *sched_scan_req;
|
||||||
|
#endif
|
||||||
|
struct rwnx_chanctx chanctx_table[NX_CHAN_CTXT_CNT];
|
||||||
|
u8 cur_chanctx;
|
||||||
|
|
||||||
|
u8 monitor_vif; /* FW id of the monitor interface, RWNX_INVALID_VIF if no monitor vif at fw level */
|
||||||
|
#ifdef CONFIG_FILTER_TCP_ACK
|
||||||
|
/* tcp ack management */
|
||||||
|
struct tcp_ack_manage ack_m;
|
||||||
|
#endif
|
||||||
|
/* RoC Management */
|
||||||
|
struct rwnx_roc_elem *roc_elem; /* Information provided by cfg80211 in its remain on channel request */
|
||||||
|
u32 roc_cookie_cnt; /* Counter used to identify RoC request sent by cfg80211 */
|
||||||
|
|
||||||
|
struct rwnx_cmd_mgr *cmd_mgr;
|
||||||
|
|
||||||
|
struct rwnx_plat *plat;
|
||||||
|
|
||||||
|
spinlock_t tx_lock;
|
||||||
|
spinlock_t cb_lock;
|
||||||
|
struct mutex mutex; /* per-device perimeter lock */
|
||||||
|
|
||||||
|
struct tasklet_struct task;
|
||||||
|
struct mm_version_cfm version_cfm; /* Lower layers versions - obtained via MM_VERSION_REQ */
|
||||||
|
|
||||||
|
u32 tcp_pacing_shift;
|
||||||
|
|
||||||
|
/* IPC */
|
||||||
|
struct ipc_host_env_tag *ipc_env;
|
||||||
|
#ifdef AICWF_SDIO_SUPPORT
|
||||||
|
struct sdio_host_env_tag sdio_env;
|
||||||
|
#endif
|
||||||
|
#ifdef AICWF_USB_SUPPORT
|
||||||
|
struct usb_host_env_tag usb_env;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct rwnx_ipc_elem_pool e2amsgs_pool;
|
||||||
|
struct rwnx_ipc_elem_pool dbgmsgs_pool;
|
||||||
|
struct rwnx_ipc_elem_pool e2aradars_pool;
|
||||||
|
struct rwnx_ipc_elem_var pattern_elem;
|
||||||
|
struct rwnx_ipc_dbgdump_elem dbgdump_elem;
|
||||||
|
struct rwnx_ipc_elem_pool e2arxdesc_pool;
|
||||||
|
struct rwnx_ipc_skb_elem *e2aunsuprxvec_elems;
|
||||||
|
//struct rwnx_ipc_rxbuf_elems rxbuf_elems;
|
||||||
|
struct rwnx_ipc_elem_var scan_ie;
|
||||||
|
|
||||||
|
struct kmem_cache *sw_txhdr_cache;
|
||||||
|
|
||||||
|
struct rwnx_debugfs debugfs;
|
||||||
|
struct rwnx_stats stats;
|
||||||
|
|
||||||
|
#ifdef CONFIG_PREALLOC_TXQ
|
||||||
|
struct rwnx_txq *txq;
|
||||||
|
#else
|
||||||
|
struct rwnx_txq txq[NX_NB_TXQ];
|
||||||
|
#endif
|
||||||
|
struct rwnx_hwq hwq[NX_TXQ_CNT];
|
||||||
|
|
||||||
|
u64 avail_idx_map;
|
||||||
|
u8 vif_started;
|
||||||
|
bool adding_sta;
|
||||||
|
struct rwnx_phy_info phy;
|
||||||
|
|
||||||
|
struct rwnx_radar radar;
|
||||||
|
|
||||||
|
/* extended capabilities supported */
|
||||||
|
u8 ext_capa[8];
|
||||||
|
|
||||||
|
#ifdef CONFIG_RWNX_MUMIMO_TX
|
||||||
|
struct rwnx_mu_info mu;
|
||||||
|
#endif
|
||||||
|
u8 is_p2p_alive;
|
||||||
|
u8 is_p2p_connected;
|
||||||
|
struct timer_list p2p_alive_timer;
|
||||||
|
struct rwnx_vif *p2p_dev_vif;
|
||||||
|
atomic_t p2p_alive_timer_count;
|
||||||
|
bool band_5g_support;
|
||||||
|
bool fwlog_en;
|
||||||
|
bool scanning;
|
||||||
|
bool p2p_working;
|
||||||
|
|
||||||
|
struct list_head defrag_list;
|
||||||
|
spinlock_t defrag_lock;
|
||||||
|
|
||||||
|
struct work_struct apmStalossWork;
|
||||||
|
struct workqueue_struct *apmStaloss_wq;
|
||||||
|
u8 apm_vif_idx;
|
||||||
|
u8 sta_mac_addr[6];
|
||||||
|
|
||||||
|
struct wakeup_source *ws_rx;
|
||||||
|
struct wakeup_source *ws_irqrx;
|
||||||
|
struct wakeup_source *ws_tx;
|
||||||
|
struct wakeup_source *ws_pwrctrl;
|
||||||
|
|
||||||
|
#ifdef CONFIG_SCHED_SCAN
|
||||||
|
bool is_sched_scan;
|
||||||
|
#endif//CONFIG_SCHED_SCAN
|
||||||
|
|
||||||
|
struct sta_tx_flowctrl sta_flowctrl[NX_REMOTE_STA_MAX];
|
||||||
|
#if 0
|
||||||
|
bool he_flag;
|
||||||
|
#endif
|
||||||
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 6, 0)
|
||||||
|
struct mac_chan_op ap_chan;
|
||||||
|
struct ieee80211_channel set_chan;
|
||||||
|
#endif
|
||||||
|
#ifdef CONFIG_VHT_FOR_OLD_KERNEL
|
||||||
|
struct ieee80211_sta_vht_cap vht_cap_2G;
|
||||||
|
struct ieee80211_sta_vht_cap vht_cap_5G;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_USE_WIRELESS_EXT
|
||||||
|
bool wext_scan;
|
||||||
|
struct completion wext_scan_com;
|
||||||
|
struct list_head wext_scanre_list;
|
||||||
|
char wext_essid[33];
|
||||||
|
int support_freqs[SCAN_CHANNEL_MAX];
|
||||||
|
int support_freqs_number;
|
||||||
|
#ifdef CONFIG_DYNAMIC_PWR
|
||||||
|
struct timer_list pwrloss_timer;
|
||||||
|
struct work_struct pwrloss_work;
|
||||||
|
struct rwnx_vif *read_rssi_vif;
|
||||||
|
s8 pwrloss_lvl;
|
||||||
|
u8 sta_rssi_idx;
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#ifdef CONFIG_BAND_STEERING
|
||||||
|
u8_l iface_idx;
|
||||||
|
struct tmp_feature_sta feature_table[NX_REMOTE_STA_MAX + NX_VIRT_DEV_MAX];
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
u8 *rwnx_build_bcn(struct rwnx_bcn *bcn, struct cfg80211_beacon_data *new);
|
||||||
|
|
||||||
|
void rwnx_chanctx_link(struct rwnx_vif *vif, u8 idx,
|
||||||
|
struct cfg80211_chan_def *chandef);
|
||||||
|
void rwnx_chanctx_unlink(struct rwnx_vif *vif);
|
||||||
|
int rwnx_chanctx_valid(struct rwnx_hw *rwnx_hw, u8 idx);
|
||||||
|
|
||||||
|
extern u8 chip_id;
|
||||||
|
static inline bool is_multicast_sta(int sta_idx)
|
||||||
|
{
|
||||||
|
|
||||||
|
if((g_rwnx_plat->usbdev->chipid == PRODUCT_ID_AIC8801) ||
|
||||||
|
((g_rwnx_plat->usbdev->chipid == PRODUCT_ID_AIC8800DC ||
|
||||||
|
g_rwnx_plat->usbdev->chipid == PRODUCT_ID_AIC8800DW) && chip_id < 3)){
|
||||||
|
return (sta_idx >= NX_REMOTE_STA_MAX_FOR_OLD_IC);
|
||||||
|
}else{
|
||||||
|
return (sta_idx >= NX_REMOTE_STA_MAX);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
struct rwnx_sta *rwnx_get_sta(struct rwnx_hw *rwnx_hw, const u8 *mac_addr);
|
||||||
|
|
||||||
|
static inline uint8_t master_vif_idx(struct rwnx_vif *vif)
|
||||||
|
{
|
||||||
|
if (unlikely(vif->wdev.iftype == NL80211_IFTYPE_AP_VLAN)) {
|
||||||
|
return vif->ap_vlan.master->vif_index;
|
||||||
|
} else {
|
||||||
|
return vif->vif_index;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void rwnx_external_auth_enable(struct rwnx_vif *vif);
|
||||||
|
void rwnx_external_auth_disable(struct rwnx_vif *vif);
|
||||||
|
|
||||||
|
#endif /* _RWNX_DEFS_H_ */
|
||||||
294
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/rwnx_dini.c
Normal file
294
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/rwnx_dini.c
Normal file
|
|
@ -0,0 +1,294 @@
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
*
|
||||||
|
* @file rwnx_dini.c - Add support for dini platform
|
||||||
|
*
|
||||||
|
* Copyright (C) RivieraWaves 2012-2019
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "rwnx_dini.h"
|
||||||
|
#include "rwnx_defs.h"
|
||||||
|
#include "rwnx_irqs.h"
|
||||||
|
#include "reg_access.h"
|
||||||
|
|
||||||
|
/* Config FPGA is accessed via bar0 */
|
||||||
|
#define CFPGA_DMA0_CTRL_REG 0x02C
|
||||||
|
#define CFPGA_DMA1_CTRL_REG 0x04C
|
||||||
|
#define CFPGA_DMA2_CTRL_REG 0x06C
|
||||||
|
#define CFPGA_UINTR_SRC_REG 0x0E8
|
||||||
|
#define CFPGA_UINTR_MASK_REG 0x0EC
|
||||||
|
#define CFPGA_BAR4_HIADDR_REG 0x100
|
||||||
|
#define CFPGA_BAR4_LOADDR_REG 0x104
|
||||||
|
#define CFPGA_BAR4_LOADDR_MASK_REG 0x110
|
||||||
|
#define CFPGA_BAR_TOUT 0x120
|
||||||
|
|
||||||
|
#define CFPGA_DMA_CTRL_ENABLE 0x00001400
|
||||||
|
#define CFPGA_DMA_CTRL_DISABLE 0x00001000
|
||||||
|
#define CFPGA_DMA_CTRL_CLEAR 0x00001800
|
||||||
|
#define CFPGA_DMA_CTRL_REREAD_TIME_MASK (BIT(10) - 1)
|
||||||
|
|
||||||
|
#define CFPGA_BAR4_LOADDR_MASK_MAX 0xFF000000
|
||||||
|
|
||||||
|
#define CFPGA_PCIEX_IT 0x00000001
|
||||||
|
#define CFPGA_ALL_ITS 0x0000000F
|
||||||
|
|
||||||
|
/* Programmable BAR4 Window start address */
|
||||||
|
#define CPU_RAM_WINDOW_HIGH 0x00000000
|
||||||
|
#define CPU_RAM_WINDOW_LOW 0x00000000
|
||||||
|
#define AHB_BRIDGE_WINDOW_HIGH 0x00000000
|
||||||
|
#define AHB_BRIDGE_WINDOW_LOW 0x60000000
|
||||||
|
|
||||||
|
struct rwnx_dini
|
||||||
|
{
|
||||||
|
u8 *pci_bar0_vaddr;
|
||||||
|
u8 *pci_bar4_vaddr;
|
||||||
|
};
|
||||||
|
|
||||||
|
static const u32 mv_cfg_fpga_dma_ctrl_regs[] = {
|
||||||
|
CFPGA_DMA0_CTRL_REG,
|
||||||
|
CFPGA_DMA1_CTRL_REG,
|
||||||
|
CFPGA_DMA2_CTRL_REG
|
||||||
|
};
|
||||||
|
|
||||||
|
/* This also clears running transactions */
|
||||||
|
static void dini_dma_on(struct rwnx_dini *rwnx_dini)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
u32 reread_time;
|
||||||
|
volatile void *reg;
|
||||||
|
|
||||||
|
for (i = 0; i < ARRAY_SIZE(mv_cfg_fpga_dma_ctrl_regs); i++) {
|
||||||
|
reg = rwnx_dini->pci_bar0_vaddr + mv_cfg_fpga_dma_ctrl_regs[i];
|
||||||
|
reread_time = readl(reg) & CFPGA_DMA_CTRL_REREAD_TIME_MASK;
|
||||||
|
|
||||||
|
writel(CFPGA_DMA_CTRL_CLEAR | reread_time, reg);
|
||||||
|
writel(CFPGA_DMA_CTRL_ENABLE | reread_time, reg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This also clears running transactions */
|
||||||
|
static void dini_dma_off(struct rwnx_dini *rwnx_dini)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
u32 reread_time;
|
||||||
|
volatile void *reg;
|
||||||
|
|
||||||
|
for (i = 0; i < ARRAY_SIZE(mv_cfg_fpga_dma_ctrl_regs); i++) {
|
||||||
|
reg = rwnx_dini->pci_bar0_vaddr + mv_cfg_fpga_dma_ctrl_regs[i];
|
||||||
|
reread_time = readl(reg) & CFPGA_DMA_CTRL_REREAD_TIME_MASK;
|
||||||
|
|
||||||
|
writel(CFPGA_DMA_CTRL_DISABLE | reread_time, reg);
|
||||||
|
writel(CFPGA_DMA_CTRL_CLEAR | reread_time, reg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Configure address range for BAR4.
|
||||||
|
* By default BAR4_LOADDR_MASK value is 0xFF000000, then there is no need to
|
||||||
|
* change it because the addresses we need to access are covered by this mask
|
||||||
|
*/
|
||||||
|
static void dini_set_bar4_win(u32 low, u32 high, struct rwnx_dini *rwnx_dini)
|
||||||
|
{
|
||||||
|
writel(low, rwnx_dini->pci_bar0_vaddr + CFPGA_BAR4_LOADDR_REG);
|
||||||
|
writel(high, rwnx_dini->pci_bar0_vaddr + CFPGA_BAR4_HIADDR_REG);
|
||||||
|
writel(CFPGA_BAR4_LOADDR_MASK_MAX,
|
||||||
|
rwnx_dini->pci_bar0_vaddr + CFPGA_BAR4_LOADDR_MASK_REG);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enable User Interrupts of CFPGA that trigger PCIe IRQs on PCIE_10
|
||||||
|
* and request the corresponding IRQ line
|
||||||
|
*/
|
||||||
|
int rwnx_cfpga_irq_enable(struct rwnx_hw *rwnx_hw)
|
||||||
|
{
|
||||||
|
struct rwnx_plat *rwnx_plat = rwnx_hw->plat;
|
||||||
|
struct rwnx_dini *rwnx_dini = (struct rwnx_dini *)rwnx_plat->priv;
|
||||||
|
unsigned int cfpga_uintr_mask;
|
||||||
|
volatile void *reg;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
/* sched_setscheduler on ONESHOT threaded irq handler for BCNs ? */
|
||||||
|
if ((ret = request_irq(rwnx_hw->plat->pci_dev->irq, rwnx_irq_hdlr, 0,
|
||||||
|
"rwnx", rwnx_hw)))
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
reg = rwnx_dini->pci_bar0_vaddr + CFPGA_UINTR_MASK_REG;
|
||||||
|
cfpga_uintr_mask = readl(reg);
|
||||||
|
writel(cfpga_uintr_mask | CFPGA_PCIEX_IT, reg);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Disable User Interrupts of CFPGA that trigger PCIe IRQs on PCIE_10
|
||||||
|
* and free the corresponding IRQ line
|
||||||
|
*/
|
||||||
|
int rwnx_cfpga_irq_disable(struct rwnx_hw *rwnx_hw)
|
||||||
|
{
|
||||||
|
struct rwnx_plat *rwnx_plat = rwnx_hw->plat;
|
||||||
|
struct rwnx_dini *rwnx_dini = (struct rwnx_dini *)rwnx_plat->priv;
|
||||||
|
unsigned int cfpga_uintr_mask;
|
||||||
|
volatile void *reg;
|
||||||
|
|
||||||
|
reg = rwnx_dini->pci_bar0_vaddr + CFPGA_UINTR_MASK_REG;
|
||||||
|
cfpga_uintr_mask = readl(reg);
|
||||||
|
writel(cfpga_uintr_mask & ~CFPGA_PCIEX_IT, reg);
|
||||||
|
|
||||||
|
free_irq(rwnx_hw->plat->pci_dev->irq, rwnx_hw);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int rwnx_dini_platform_enable(struct rwnx_hw *rwnx_hw)
|
||||||
|
{
|
||||||
|
struct rwnx_plat *rwnx_plat = rwnx_hw->plat;
|
||||||
|
struct rwnx_dini *rwnx_dini = (struct rwnx_dini *)rwnx_plat->priv;
|
||||||
|
|
||||||
|
#ifdef CONFIG_RWNX_SDM
|
||||||
|
writel(0x0000FFFF, rwnx_dini->pci_bar0_vaddr + CFPGA_BAR_TOUT);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
dini_dma_on(rwnx_dini);
|
||||||
|
return rwnx_cfpga_irq_enable(rwnx_hw);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int rwnx_dini_platform_disable(struct rwnx_hw *rwnx_hw)
|
||||||
|
{
|
||||||
|
struct rwnx_plat *rwnx_plat = rwnx_hw->plat;
|
||||||
|
struct rwnx_dini *rwnx_dini = (struct rwnx_dini *)rwnx_plat->priv;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = rwnx_cfpga_irq_disable(rwnx_hw);
|
||||||
|
dini_dma_off(rwnx_dini);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rwnx_dini_platform_deinit(struct rwnx_plat *rwnx_plat)
|
||||||
|
{
|
||||||
|
struct rwnx_dini *rwnx_dini = (struct rwnx_dini *)rwnx_plat->priv;
|
||||||
|
|
||||||
|
pci_disable_device(rwnx_plat->pci_dev);
|
||||||
|
iounmap(rwnx_dini->pci_bar0_vaddr);
|
||||||
|
iounmap(rwnx_dini->pci_bar4_vaddr);
|
||||||
|
pci_release_regions(rwnx_plat->pci_dev);
|
||||||
|
|
||||||
|
kfree(rwnx_plat);
|
||||||
|
}
|
||||||
|
|
||||||
|
static u8* rwnx_dini_get_address(struct rwnx_plat *rwnx_plat, int addr_name,
|
||||||
|
unsigned int offset)
|
||||||
|
{
|
||||||
|
struct rwnx_dini *rwnx_dini = (struct rwnx_dini *)rwnx_plat->priv;
|
||||||
|
|
||||||
|
if (WARN(addr_name >= RWNX_ADDR_MAX, "Invalid address %d", addr_name))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (addr_name == RWNX_ADDR_CPU)
|
||||||
|
dini_set_bar4_win(CPU_RAM_WINDOW_LOW, CPU_RAM_WINDOW_HIGH, rwnx_dini);
|
||||||
|
else
|
||||||
|
dini_set_bar4_win(AHB_BRIDGE_WINDOW_LOW, AHB_BRIDGE_WINDOW_HIGH, rwnx_dini);
|
||||||
|
|
||||||
|
return rwnx_dini->pci_bar4_vaddr + offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rwnx_dini_ack_irq(struct rwnx_plat *rwnx_plat)
|
||||||
|
{
|
||||||
|
struct rwnx_dini *rwnx_dini = (struct rwnx_dini *)rwnx_plat->priv;
|
||||||
|
|
||||||
|
writel(CFPGA_ALL_ITS, rwnx_dini->pci_bar0_vaddr + CFPGA_UINTR_SRC_REG);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const u32 rwnx_dini_config_reg[] = {
|
||||||
|
NXMAC_DEBUG_PORT_SEL_ADDR,
|
||||||
|
SYSCTRL_DIAG_CONF_ADDR,
|
||||||
|
RF_V6_DIAGPORT_CONF1_ADDR,
|
||||||
|
RF_v6_PHYDIAG_CONF1_ADDR,
|
||||||
|
};
|
||||||
|
|
||||||
|
static int rwnx_dini_get_config_reg(struct rwnx_plat *rwnx_plat, const u32 **list)
|
||||||
|
{
|
||||||
|
if (!list)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
*list = rwnx_dini_config_reg;
|
||||||
|
return ARRAY_SIZE(rwnx_dini_config_reg);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* rwnx_dini_platform_init - Initialize the DINI platform
|
||||||
|
*
|
||||||
|
* @pci_dev PCI device
|
||||||
|
* @rwnx_plat Pointer on struct rwnx_stat * to be populated
|
||||||
|
*
|
||||||
|
* @return 0 on success, < 0 otherwise
|
||||||
|
*
|
||||||
|
* Allocate and initialize a rwnx_plat structure for the dini platform.
|
||||||
|
*/
|
||||||
|
int rwnx_dini_platform_init(struct pci_dev *pci_dev, struct rwnx_plat **rwnx_plat)
|
||||||
|
{
|
||||||
|
struct rwnx_dini *rwnx_dini;
|
||||||
|
u16 pci_cmd;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
*rwnx_plat = kzalloc(sizeof(struct rwnx_plat) + sizeof(struct rwnx_dini),
|
||||||
|
GFP_KERNEL);
|
||||||
|
if (!*rwnx_plat)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
rwnx_dini = (struct rwnx_dini *)(*rwnx_plat)->priv;
|
||||||
|
|
||||||
|
/* Hotplug fixups */
|
||||||
|
pci_read_config_word(pci_dev, PCI_COMMAND, &pci_cmd);
|
||||||
|
pci_cmd |= PCI_COMMAND_PARITY | PCI_COMMAND_SERR;
|
||||||
|
pci_write_config_word(pci_dev, PCI_COMMAND, pci_cmd);
|
||||||
|
pci_write_config_byte(pci_dev, PCI_CACHE_LINE_SIZE, L1_CACHE_BYTES >> 2);
|
||||||
|
|
||||||
|
if ((ret = pci_enable_device(pci_dev))) {
|
||||||
|
dev_err(&(pci_dev->dev), "pci_enable_device failed\n");
|
||||||
|
goto out_enable;
|
||||||
|
}
|
||||||
|
|
||||||
|
pci_set_master(pci_dev);
|
||||||
|
|
||||||
|
if ((ret = pci_request_regions(pci_dev, KBUILD_MODNAME))) {
|
||||||
|
dev_err(&(pci_dev->dev), "pci_request_regions failed\n");
|
||||||
|
goto out_request;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(rwnx_dini->pci_bar0_vaddr = (u8 *)pci_ioremap_bar(pci_dev, 0))) {
|
||||||
|
dev_err(&(pci_dev->dev), "pci_ioremap_bar(%d) failed\n", 0);
|
||||||
|
ret = -ENOMEM;
|
||||||
|
goto out_bar0;
|
||||||
|
}
|
||||||
|
if (!(rwnx_dini->pci_bar4_vaddr = (u8 *)pci_ioremap_bar(pci_dev, 4))) {
|
||||||
|
dev_err(&(pci_dev->dev), "pci_ioremap_bar(%d) failed\n", 4);
|
||||||
|
ret = -ENOMEM;
|
||||||
|
goto out_bar4;
|
||||||
|
}
|
||||||
|
|
||||||
|
(*rwnx_plat)->enable = rwnx_dini_platform_enable;
|
||||||
|
(*rwnx_plat)->disable = rwnx_dini_platform_disable;
|
||||||
|
(*rwnx_plat)->deinit = rwnx_dini_platform_deinit;
|
||||||
|
(*rwnx_plat)->get_address = rwnx_dini_get_address;
|
||||||
|
(*rwnx_plat)->ack_irq = rwnx_dini_ack_irq;
|
||||||
|
(*rwnx_plat)->get_config_reg = rwnx_dini_get_config_reg;
|
||||||
|
|
||||||
|
#ifdef CONFIG_RWNX_SDM
|
||||||
|
writel(0x0000FFFF, rwnx_dini->pci_bar0_vaddr + CFPGA_BAR_TOUT);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
out_bar4:
|
||||||
|
iounmap(rwnx_dini->pci_bar0_vaddr);
|
||||||
|
out_bar0:
|
||||||
|
pci_release_regions(pci_dev);
|
||||||
|
out_request:
|
||||||
|
pci_disable_device(pci_dev);
|
||||||
|
out_enable:
|
||||||
|
kfree(*rwnx_plat);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
20
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/rwnx_dini.h
Normal file
20
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/rwnx_dini.h
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
/**
|
||||||
|
****************************************************************************************
|
||||||
|
*
|
||||||
|
* @file rwnx_dini.h
|
||||||
|
*
|
||||||
|
* Copyright (C) RivieraWaves 2012-2019
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _RWNX_DINI_H_
|
||||||
|
#define _RWNX_DINI_H_
|
||||||
|
|
||||||
|
#include <linux/pci.h>
|
||||||
|
#include "rwnx_platform.h"
|
||||||
|
|
||||||
|
int rwnx_dini_platform_init(struct pci_dev *pci_dev,
|
||||||
|
struct rwnx_plat **rwnx_plat);
|
||||||
|
|
||||||
|
#endif /* _RWNX_DINI_H_ */
|
||||||
1243
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/rwnx_events.h
Normal file
1243
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/rwnx_events.h
Normal file
File diff suppressed because it is too large
Load diff
568
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/rwnx_fw_dump.c
Normal file
568
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/rwnx_fw_dump.c
Normal file
|
|
@ -0,0 +1,568 @@
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
*
|
||||||
|
* @file rwnx_fw_dump.c
|
||||||
|
*
|
||||||
|
* @brief Definition of debug fs entries to process fw dump
|
||||||
|
*
|
||||||
|
* Copyright (C) RivieraWaves 2012-2019
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <linux/kmod.h>
|
||||||
|
#include <linux/debugfs.h>
|
||||||
|
|
||||||
|
#include "rwnx_defs.h"
|
||||||
|
#include "rwnx_debugfs.h"
|
||||||
|
|
||||||
|
static ssize_t rwnx_dbgfs_rhd_read(struct file *file,
|
||||||
|
char __user *user_buf,
|
||||||
|
size_t count, loff_t *ppos)
|
||||||
|
{
|
||||||
|
struct rwnx_hw *priv = file->private_data;
|
||||||
|
struct dbg_debug_dump_tag *dump = priv->dbgdump_elem.buf.addr;
|
||||||
|
ssize_t read;
|
||||||
|
|
||||||
|
mutex_lock(&priv->dbgdump_elem.mutex);
|
||||||
|
if (!priv->debugfs.trace_prst) {
|
||||||
|
mutex_unlock(&priv->dbgdump_elem.mutex);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
read = simple_read_from_buffer(user_buf, count, ppos,
|
||||||
|
dump->rhd_mem,
|
||||||
|
dump->dbg_info.rhd_len);
|
||||||
|
|
||||||
|
mutex_unlock(&priv->dbgdump_elem.mutex);
|
||||||
|
return read;
|
||||||
|
}
|
||||||
|
|
||||||
|
DEBUGFS_READ_FILE_OPS(rhd);
|
||||||
|
|
||||||
|
static ssize_t rwnx_dbgfs_rbd_read(struct file *file,
|
||||||
|
char __user *user_buf,
|
||||||
|
size_t count, loff_t *ppos)
|
||||||
|
{
|
||||||
|
struct rwnx_hw *priv = file->private_data;
|
||||||
|
struct dbg_debug_dump_tag *dump = priv->dbgdump_elem.buf.addr;
|
||||||
|
ssize_t read;
|
||||||
|
|
||||||
|
mutex_lock(&priv->dbgdump_elem.mutex);
|
||||||
|
if (!priv->debugfs.trace_prst) {
|
||||||
|
mutex_unlock(&priv->dbgdump_elem.mutex);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
read = simple_read_from_buffer(user_buf, count, ppos,
|
||||||
|
dump->rbd_mem,
|
||||||
|
dump->dbg_info.rbd_len);
|
||||||
|
|
||||||
|
mutex_unlock(&priv->dbgdump_elem.mutex);
|
||||||
|
return read;
|
||||||
|
}
|
||||||
|
|
||||||
|
DEBUGFS_READ_FILE_OPS(rbd);
|
||||||
|
|
||||||
|
static ssize_t rwnx_dbgfs_thdx_read(struct file *file, char __user *user_buf,
|
||||||
|
size_t count, loff_t *ppos, int idx)
|
||||||
|
{
|
||||||
|
struct rwnx_hw *priv = file->private_data;
|
||||||
|
struct dbg_debug_dump_tag *dump = priv->dbgdump_elem.buf.addr;
|
||||||
|
ssize_t read;
|
||||||
|
|
||||||
|
mutex_lock(&priv->dbgdump_elem.mutex);
|
||||||
|
if (!priv->debugfs.trace_prst) {
|
||||||
|
mutex_unlock(&priv->dbgdump_elem.mutex);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
read = simple_read_from_buffer(user_buf, count, ppos,
|
||||||
|
&dump->thd_mem[idx],
|
||||||
|
dump->dbg_info.thd_len[idx]);
|
||||||
|
|
||||||
|
mutex_unlock(&priv->dbgdump_elem.mutex);
|
||||||
|
return read;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t rwnx_dbgfs_thd0_read(struct file *file,
|
||||||
|
char __user *user_buf,
|
||||||
|
size_t count, loff_t *ppos)
|
||||||
|
{
|
||||||
|
return rwnx_dbgfs_thdx_read(file, user_buf, count, ppos, 0);
|
||||||
|
}
|
||||||
|
DEBUGFS_READ_FILE_OPS(thd0);
|
||||||
|
|
||||||
|
static ssize_t rwnx_dbgfs_thd1_read(struct file *file,
|
||||||
|
char __user *user_buf,
|
||||||
|
size_t count, loff_t *ppos)
|
||||||
|
{
|
||||||
|
return rwnx_dbgfs_thdx_read(file, user_buf, count, ppos, 1);
|
||||||
|
}
|
||||||
|
DEBUGFS_READ_FILE_OPS(thd1);
|
||||||
|
|
||||||
|
static ssize_t rwnx_dbgfs_thd2_read(struct file *file,
|
||||||
|
char __user *user_buf,
|
||||||
|
size_t count, loff_t *ppos)
|
||||||
|
{
|
||||||
|
return rwnx_dbgfs_thdx_read(file, user_buf, count, ppos, 2);
|
||||||
|
}
|
||||||
|
DEBUGFS_READ_FILE_OPS(thd2);
|
||||||
|
|
||||||
|
static ssize_t rwnx_dbgfs_thd3_read(struct file *file,
|
||||||
|
char __user *user_buf,
|
||||||
|
size_t count, loff_t *ppos)
|
||||||
|
{
|
||||||
|
return rwnx_dbgfs_thdx_read(file, user_buf, count, ppos, 3);
|
||||||
|
}
|
||||||
|
DEBUGFS_READ_FILE_OPS(thd3);
|
||||||
|
|
||||||
|
#if (NX_TXQ_CNT == 5)
|
||||||
|
static ssize_t rwnx_dbgfs_thd4_read(struct file *file,
|
||||||
|
char __user *user_buf,
|
||||||
|
size_t count, loff_t *ppos)
|
||||||
|
{
|
||||||
|
return rwnx_dbgfs_thdx_read(file, user_buf, count, ppos, 4);
|
||||||
|
}
|
||||||
|
DEBUGFS_READ_FILE_OPS(thd4);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static ssize_t rwnx_dbgfs_mactrace_read(struct file *file,
|
||||||
|
char __user *user_buf,
|
||||||
|
size_t count, loff_t *ppos)
|
||||||
|
{
|
||||||
|
struct rwnx_hw *priv = file->private_data;
|
||||||
|
struct dbg_debug_dump_tag *dump = priv->dbgdump_elem.buf.addr;
|
||||||
|
ssize_t read;
|
||||||
|
|
||||||
|
mutex_lock(&priv->dbgdump_elem.mutex);
|
||||||
|
if (!priv->debugfs.trace_prst) {
|
||||||
|
char msg[64];
|
||||||
|
|
||||||
|
scnprintf(msg, sizeof(msg), "Force trigger\n");
|
||||||
|
rwnx_dbgfs_trigger_fw_dump(priv, msg);
|
||||||
|
|
||||||
|
mutex_unlock(&priv->dbgdump_elem.mutex);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
read = simple_read_from_buffer(user_buf, count, ppos,
|
||||||
|
dump->la_mem,
|
||||||
|
dump->dbg_info.la_conf.trace_len);
|
||||||
|
|
||||||
|
mutex_unlock(&priv->dbgdump_elem.mutex);
|
||||||
|
|
||||||
|
return read;
|
||||||
|
}
|
||||||
|
DEBUGFS_READ_FILE_OPS(mactrace);
|
||||||
|
|
||||||
|
static ssize_t rwnx_dbgfs_macdiags_read(struct file *file,
|
||||||
|
char __user *user_buf,
|
||||||
|
size_t count, loff_t *ppos)
|
||||||
|
{
|
||||||
|
struct rwnx_hw *priv = file->private_data;
|
||||||
|
struct dbg_debug_dump_tag *dump = priv->dbgdump_elem.buf.addr;
|
||||||
|
ssize_t read;
|
||||||
|
|
||||||
|
mutex_lock(&priv->dbgdump_elem.mutex);
|
||||||
|
if (!priv->debugfs.trace_prst) {
|
||||||
|
mutex_unlock(&priv->dbgdump_elem.mutex);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
read = simple_read_from_buffer(user_buf, count, ppos,
|
||||||
|
dump->dbg_info.diags_mac,
|
||||||
|
DBG_DIAGS_MAC_MAX * 2);
|
||||||
|
|
||||||
|
mutex_unlock(&priv->dbgdump_elem.mutex);
|
||||||
|
return read;
|
||||||
|
}
|
||||||
|
|
||||||
|
DEBUGFS_READ_FILE_OPS(macdiags);
|
||||||
|
|
||||||
|
static ssize_t rwnx_dbgfs_phydiags_read(struct file *file,
|
||||||
|
char __user *user_buf,
|
||||||
|
size_t count, loff_t *ppos)
|
||||||
|
{
|
||||||
|
struct rwnx_hw *priv = file->private_data;
|
||||||
|
struct dbg_debug_dump_tag *dump = priv->dbgdump_elem.buf.addr;
|
||||||
|
ssize_t read;
|
||||||
|
|
||||||
|
mutex_lock(&priv->dbgdump_elem.mutex);
|
||||||
|
if (!priv->debugfs.trace_prst) {
|
||||||
|
mutex_unlock(&priv->dbgdump_elem.mutex);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
read = simple_read_from_buffer(user_buf, count, ppos,
|
||||||
|
dump->dbg_info.diags_phy,
|
||||||
|
DBG_DIAGS_PHY_MAX * 2);
|
||||||
|
|
||||||
|
mutex_unlock(&priv->dbgdump_elem.mutex);
|
||||||
|
return read;
|
||||||
|
}
|
||||||
|
|
||||||
|
DEBUGFS_READ_FILE_OPS(phydiags);
|
||||||
|
|
||||||
|
static ssize_t rwnx_dbgfs_hwdiags_read(struct file *file,
|
||||||
|
char __user *user_buf,
|
||||||
|
size_t count, loff_t *ppos)
|
||||||
|
{
|
||||||
|
struct rwnx_hw *priv = file->private_data;
|
||||||
|
struct dbg_debug_dump_tag *dump = priv->dbgdump_elem.buf.addr;
|
||||||
|
char buf[16];
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
mutex_lock(&priv->dbgdump_elem.mutex);
|
||||||
|
if (!priv->debugfs.trace_prst) {
|
||||||
|
mutex_unlock(&priv->dbgdump_elem.mutex);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = scnprintf(buf, min_t(size_t, sizeof(buf) - 1, count),
|
||||||
|
"%08X\n", dump->dbg_info.hw_diag);
|
||||||
|
|
||||||
|
mutex_unlock(&priv->dbgdump_elem.mutex);
|
||||||
|
return simple_read_from_buffer(user_buf, count, ppos, buf, ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
DEBUGFS_READ_FILE_OPS(hwdiags);
|
||||||
|
|
||||||
|
static ssize_t rwnx_dbgfs_plfdiags_read(struct file *file,
|
||||||
|
char __user *user_buf,
|
||||||
|
size_t count, loff_t *ppos)
|
||||||
|
{
|
||||||
|
struct rwnx_hw *priv = file->private_data;
|
||||||
|
struct dbg_debug_dump_tag *dump = priv->dbgdump_elem.buf.addr;
|
||||||
|
char buf[16];
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
mutex_lock(&priv->dbgdump_elem.mutex);
|
||||||
|
if (!priv->debugfs.trace_prst) {
|
||||||
|
mutex_unlock(&priv->dbgdump_elem.mutex);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = scnprintf(buf, min_t(size_t, sizeof(buf) - 1, count),
|
||||||
|
"%08X\n", dump->dbg_info.la_conf.diag_conf);
|
||||||
|
|
||||||
|
mutex_unlock(&priv->dbgdump_elem.mutex);
|
||||||
|
return simple_read_from_buffer(user_buf, count, ppos, buf, ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
DEBUGFS_READ_FILE_OPS(plfdiags);
|
||||||
|
|
||||||
|
static ssize_t rwnx_dbgfs_swdiags_read(struct file *file,
|
||||||
|
char __user *user_buf,
|
||||||
|
size_t count, loff_t *ppos)
|
||||||
|
{
|
||||||
|
struct rwnx_hw *priv = file->private_data;
|
||||||
|
struct dbg_debug_dump_tag *dump = priv->dbgdump_elem.buf.addr;
|
||||||
|
ssize_t read;
|
||||||
|
|
||||||
|
mutex_lock(&priv->dbgdump_elem.mutex);
|
||||||
|
if (!priv->debugfs.trace_prst) {
|
||||||
|
mutex_unlock(&priv->dbgdump_elem.mutex);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
read = simple_read_from_buffer(user_buf, count, ppos,
|
||||||
|
&dump->dbg_info.sw_diag,
|
||||||
|
dump->dbg_info.sw_diag_len);
|
||||||
|
|
||||||
|
mutex_unlock(&priv->dbgdump_elem.mutex);
|
||||||
|
return read;
|
||||||
|
}
|
||||||
|
|
||||||
|
DEBUGFS_READ_FILE_OPS(swdiags);
|
||||||
|
|
||||||
|
static ssize_t rwnx_dbgfs_error_read(struct file *file,
|
||||||
|
char __user *user_buf,
|
||||||
|
size_t count, loff_t *ppos)
|
||||||
|
{
|
||||||
|
struct rwnx_hw *priv = file->private_data;
|
||||||
|
struct dbg_debug_dump_tag *dump = priv->dbgdump_elem.buf.addr;
|
||||||
|
ssize_t read;
|
||||||
|
|
||||||
|
mutex_lock(&priv->dbgdump_elem.mutex);
|
||||||
|
if (!priv->debugfs.trace_prst) {
|
||||||
|
mutex_unlock(&priv->dbgdump_elem.mutex);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
read = simple_read_from_buffer(user_buf, count, ppos,
|
||||||
|
dump->dbg_info.error,
|
||||||
|
strlen((char *)dump->dbg_info.error));
|
||||||
|
|
||||||
|
mutex_unlock(&priv->dbgdump_elem.mutex);
|
||||||
|
return read;
|
||||||
|
}
|
||||||
|
|
||||||
|
DEBUGFS_READ_FILE_OPS(error);
|
||||||
|
|
||||||
|
static ssize_t rwnx_dbgfs_rxdesc_read(struct file *file,
|
||||||
|
char __user *user_buf,
|
||||||
|
size_t count, loff_t *ppos)
|
||||||
|
{
|
||||||
|
struct rwnx_hw *priv = file->private_data;
|
||||||
|
struct dbg_debug_dump_tag *dump = priv->dbgdump_elem.buf.addr;
|
||||||
|
char buf[32];
|
||||||
|
int ret;
|
||||||
|
ssize_t read;
|
||||||
|
|
||||||
|
mutex_lock(&priv->dbgdump_elem.mutex);
|
||||||
|
if (!priv->debugfs.trace_prst) {
|
||||||
|
mutex_unlock(&priv->dbgdump_elem.mutex);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = scnprintf(buf, min_t(size_t, sizeof(buf) - 1, count),
|
||||||
|
"%08X\n%08X\n", dump->dbg_info.rhd,
|
||||||
|
dump->dbg_info.rbd);
|
||||||
|
read = simple_read_from_buffer(user_buf, count, ppos, buf, ret);
|
||||||
|
|
||||||
|
mutex_unlock(&priv->dbgdump_elem.mutex);
|
||||||
|
return read;
|
||||||
|
}
|
||||||
|
|
||||||
|
DEBUGFS_READ_FILE_OPS(rxdesc);
|
||||||
|
|
||||||
|
static ssize_t rwnx_dbgfs_txdesc_read(struct file *file,
|
||||||
|
char __user *user_buf,
|
||||||
|
size_t count, loff_t *ppos)
|
||||||
|
{
|
||||||
|
struct rwnx_hw *priv = file->private_data;
|
||||||
|
struct dbg_debug_dump_tag *dump = priv->dbgdump_elem.buf.addr;
|
||||||
|
char buf[64];
|
||||||
|
int len = 0;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
mutex_lock(&priv->dbgdump_elem.mutex);
|
||||||
|
if (!priv->debugfs.trace_prst) {
|
||||||
|
mutex_unlock(&priv->dbgdump_elem.mutex);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < NX_TXQ_CNT; i++) {
|
||||||
|
len += scnprintf(&buf[len], min_t(size_t, sizeof(buf) - len - 1, count),
|
||||||
|
"%08X\n", dump->dbg_info.thd[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
mutex_unlock(&priv->dbgdump_elem.mutex);
|
||||||
|
return simple_read_from_buffer(user_buf, count, ppos, buf, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
DEBUGFS_READ_FILE_OPS(txdesc);
|
||||||
|
|
||||||
|
static ssize_t rwnx_dbgfs_macrxptr_read(struct file *file,
|
||||||
|
char __user *user_buf,
|
||||||
|
size_t count, loff_t *ppos)
|
||||||
|
{
|
||||||
|
struct rwnx_hw *priv = file->private_data;
|
||||||
|
struct dbg_debug_dump_tag *dump = priv->dbgdump_elem.buf.addr;
|
||||||
|
ssize_t read;
|
||||||
|
|
||||||
|
mutex_lock(&priv->dbgdump_elem.mutex);
|
||||||
|
if (!priv->debugfs.trace_prst) {
|
||||||
|
mutex_unlock(&priv->dbgdump_elem.mutex);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
read = simple_read_from_buffer(user_buf, count, ppos,
|
||||||
|
&dump->dbg_info.rhd_hw_ptr,
|
||||||
|
2 * sizeof(dump->dbg_info.rhd_hw_ptr));
|
||||||
|
|
||||||
|
mutex_unlock(&priv->dbgdump_elem.mutex);
|
||||||
|
return read;
|
||||||
|
}
|
||||||
|
|
||||||
|
DEBUGFS_READ_FILE_OPS(macrxptr);
|
||||||
|
|
||||||
|
static ssize_t rwnx_dbgfs_lamacconf_read(struct file *file,
|
||||||
|
char __user *user_buf,
|
||||||
|
size_t count, loff_t *ppos)
|
||||||
|
{
|
||||||
|
struct rwnx_hw *priv = file->private_data;
|
||||||
|
struct dbg_debug_dump_tag *dump = priv->dbgdump_elem.buf.addr;
|
||||||
|
ssize_t read;
|
||||||
|
|
||||||
|
mutex_lock(&priv->dbgdump_elem.mutex);
|
||||||
|
if (!priv->debugfs.trace_prst) {
|
||||||
|
mutex_unlock(&priv->dbgdump_elem.mutex);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
read = simple_read_from_buffer(user_buf, count, ppos,
|
||||||
|
dump->dbg_info.la_conf.conf,
|
||||||
|
LA_CONF_LEN * 4);
|
||||||
|
|
||||||
|
mutex_unlock(&priv->dbgdump_elem.mutex);
|
||||||
|
return read;
|
||||||
|
}
|
||||||
|
DEBUGFS_READ_FILE_OPS(lamacconf);
|
||||||
|
|
||||||
|
static ssize_t rwnx_dbgfs_chaninfo_read(struct file *file,
|
||||||
|
char __user *user_buf,
|
||||||
|
size_t count, loff_t *ppos)
|
||||||
|
{
|
||||||
|
struct rwnx_hw *priv = file->private_data;
|
||||||
|
struct dbg_debug_dump_tag *dump = priv->dbgdump_elem.buf.addr;
|
||||||
|
char buf[4 * 32];
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
mutex_lock(&priv->dbgdump_elem.mutex);
|
||||||
|
if (!priv->debugfs.trace_prst) {
|
||||||
|
mutex_unlock(&priv->dbgdump_elem.mutex);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = scnprintf(buf, min_t(size_t, sizeof(buf) - 1, count),
|
||||||
|
"type: %d\n"
|
||||||
|
"prim20_freq: %d MHz\n"
|
||||||
|
"center1_freq: %d MHz\n"
|
||||||
|
"center2_freq: %d MHz\n",
|
||||||
|
(dump->dbg_info.chan_info.info1 >> 8) & 0xFF,
|
||||||
|
(dump->dbg_info.chan_info.info1 >> 16) & 0xFFFF,
|
||||||
|
(dump->dbg_info.chan_info.info2 >> 0) & 0xFFFF,
|
||||||
|
(dump->dbg_info.chan_info.info2 >> 16) & 0xFFFF);
|
||||||
|
|
||||||
|
mutex_unlock(&priv->dbgdump_elem.mutex);
|
||||||
|
return simple_read_from_buffer(user_buf, count, ppos, buf, ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
DEBUGFS_READ_FILE_OPS(chaninfo);
|
||||||
|
|
||||||
|
static ssize_t rwnx_dbgfs_um_helper_read(struct file *file,
|
||||||
|
char __user *user_buf,
|
||||||
|
size_t count, loff_t *ppos)
|
||||||
|
{
|
||||||
|
struct rwnx_hw *priv = file->private_data;
|
||||||
|
char buf[sizeof(priv->debugfs.helper_cmd)];
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = scnprintf(buf, min_t(size_t, sizeof(buf) - 1, count),
|
||||||
|
"%s", priv->debugfs.helper_cmd);
|
||||||
|
|
||||||
|
return simple_read_from_buffer(user_buf, count, ppos, buf, ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t rwnx_dbgfs_um_helper_write(struct file *file,
|
||||||
|
const char __user *user_buf,
|
||||||
|
size_t count, loff_t *ppos)
|
||||||
|
{
|
||||||
|
struct rwnx_hw *priv = file->private_data;
|
||||||
|
int eobuf = min_t(size_t, sizeof(priv->debugfs.helper_cmd) - 1, count);
|
||||||
|
|
||||||
|
priv->debugfs.helper_cmd[eobuf] = '\0';
|
||||||
|
if (copy_from_user(priv->debugfs.helper_cmd, user_buf, eobuf))
|
||||||
|
return -EFAULT;
|
||||||
|
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
DEBUGFS_READ_WRITE_FILE_OPS(um_helper);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Calls a userspace pgm
|
||||||
|
*/
|
||||||
|
int rwnx_um_helper(struct rwnx_debugfs *rwnx_debugfs, const char *cmd)
|
||||||
|
{
|
||||||
|
char *envp[] = { "PATH=/sbin:/usr/sbin:/bin:/usr/bin", NULL };
|
||||||
|
char **argv;
|
||||||
|
int argc, ret;
|
||||||
|
|
||||||
|
if (!rwnx_debugfs->dir ||
|
||||||
|
!strlen((cmd = cmd ? cmd : rwnx_debugfs->helper_cmd)))
|
||||||
|
return 0;
|
||||||
|
argv = argv_split(in_interrupt() ? GFP_ATOMIC : GFP_KERNEL, cmd, &argc);
|
||||||
|
if (!argc)
|
||||||
|
return PTR_ERR(argv);
|
||||||
|
|
||||||
|
if ((ret = call_usermodehelper(argv[0], argv, envp,
|
||||||
|
UMH_WAIT_PROC | UMH_KILLABLE)))
|
||||||
|
printk(KERN_CRIT "Failed to call %s (%s returned %d)\n",
|
||||||
|
argv[0], cmd, ret);
|
||||||
|
argv_free(argv);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rwnx_um_helper_work(struct work_struct *ws)
|
||||||
|
{
|
||||||
|
struct rwnx_debugfs *rwnx_debugfs = container_of(ws, struct rwnx_debugfs,
|
||||||
|
helper_work);
|
||||||
|
struct rwnx_hw *rwnx_hw = container_of(rwnx_debugfs, struct rwnx_hw,
|
||||||
|
debugfs);
|
||||||
|
rwnx_um_helper(rwnx_debugfs, NULL);
|
||||||
|
if (!rwnx_debugfs->unregistering)
|
||||||
|
rwnx_umh_done(rwnx_hw);
|
||||||
|
rwnx_debugfs->helper_scheduled = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int rwnx_trigger_um_helper(struct rwnx_debugfs *rwnx_debugfs)
|
||||||
|
{
|
||||||
|
struct rwnx_hw *rwnx_hw = container_of(rwnx_debugfs, struct rwnx_hw,
|
||||||
|
debugfs);
|
||||||
|
|
||||||
|
if (rwnx_debugfs->helper_scheduled == true) {
|
||||||
|
dev_err(rwnx_hw->dev, "%s: Already scheduled\n", __func__);
|
||||||
|
return -EBUSY;
|
||||||
|
}
|
||||||
|
|
||||||
|
spin_lock_bh(&rwnx_debugfs->umh_lock);
|
||||||
|
if (rwnx_debugfs->unregistering) {
|
||||||
|
spin_unlock_bh(&rwnx_debugfs->umh_lock);
|
||||||
|
dev_err(rwnx_hw->dev, "%s: unregistering\n", __func__);
|
||||||
|
return -ENOENT;
|
||||||
|
}
|
||||||
|
rwnx_debugfs->helper_scheduled = true;
|
||||||
|
schedule_work(&rwnx_debugfs->helper_work);
|
||||||
|
spin_unlock_bh(&rwnx_debugfs->umh_lock);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int rwnx_dbgfs_register_fw_dump(struct rwnx_hw *rwnx_hw,
|
||||||
|
struct dentry *dir_drv,
|
||||||
|
struct dentry *dir_diags)
|
||||||
|
{
|
||||||
|
|
||||||
|
struct rwnx_debugfs *rwnx_debugfs = &rwnx_hw->debugfs;
|
||||||
|
|
||||||
|
BUILD_BUG_ON(sizeof(CONFIG_RWNX_UM_HELPER_DFLT) >=
|
||||||
|
sizeof(rwnx_debugfs->helper_cmd));
|
||||||
|
strncpy(rwnx_debugfs->helper_cmd,
|
||||||
|
CONFIG_RWNX_UM_HELPER_DFLT, sizeof(rwnx_debugfs->helper_cmd));
|
||||||
|
INIT_WORK(&rwnx_debugfs->helper_work, rwnx_um_helper_work);
|
||||||
|
DEBUGFS_ADD_FILE(um_helper, dir_drv, S_IWUSR | S_IRUSR);
|
||||||
|
|
||||||
|
rwnx_debugfs->trace_prst = rwnx_debugfs->helper_scheduled = false;
|
||||||
|
spin_lock_init(&rwnx_debugfs->umh_lock);
|
||||||
|
DEBUGFS_ADD_FILE(rhd, dir_diags, S_IRUSR);
|
||||||
|
DEBUGFS_ADD_FILE(rbd, dir_diags, S_IRUSR);
|
||||||
|
DEBUGFS_ADD_FILE(thd0, dir_diags, S_IRUSR);
|
||||||
|
DEBUGFS_ADD_FILE(thd1, dir_diags, S_IRUSR);
|
||||||
|
DEBUGFS_ADD_FILE(thd2, dir_diags, S_IRUSR);
|
||||||
|
DEBUGFS_ADD_FILE(thd3, dir_diags, S_IRUSR);
|
||||||
|
#if (NX_TXQ_CNT == 5)
|
||||||
|
DEBUGFS_ADD_FILE(thd4, dir_diags, S_IRUSR);
|
||||||
|
#endif
|
||||||
|
DEBUGFS_ADD_FILE(mactrace, dir_diags, S_IRUSR);
|
||||||
|
DEBUGFS_ADD_FILE(macdiags, dir_diags, S_IRUSR);
|
||||||
|
DEBUGFS_ADD_FILE(phydiags, dir_diags, S_IRUSR);
|
||||||
|
DEBUGFS_ADD_FILE(plfdiags, dir_diags, S_IRUSR);
|
||||||
|
DEBUGFS_ADD_FILE(hwdiags, dir_diags, S_IRUSR);
|
||||||
|
DEBUGFS_ADD_FILE(swdiags, dir_diags, S_IRUSR);
|
||||||
|
DEBUGFS_ADD_FILE(error, dir_diags, S_IRUSR);
|
||||||
|
DEBUGFS_ADD_FILE(rxdesc, dir_diags, S_IRUSR);
|
||||||
|
DEBUGFS_ADD_FILE(txdesc, dir_diags, S_IRUSR);
|
||||||
|
DEBUGFS_ADD_FILE(macrxptr, dir_diags, S_IRUSR);
|
||||||
|
DEBUGFS_ADD_FILE(lamacconf, dir_diags, S_IRUSR);
|
||||||
|
DEBUGFS_ADD_FILE(chaninfo, dir_diags, S_IRUSR);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
err:
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
47
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/rwnx_fw_trace.c
Normal file
47
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/rwnx_fw_trace.c
Normal file
|
|
@ -0,0 +1,47 @@
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
*
|
||||||
|
* @file rwnx_fw_trace.c
|
||||||
|
*
|
||||||
|
* Copyright (C) RivieraWaves 2017-2019
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
#include <linux/types.h>
|
||||||
|
#include <linux/kernel.h>
|
||||||
|
#include <linux/slab.h>
|
||||||
|
#include <linux/uaccess.h>
|
||||||
|
#include <linux/sched.h>
|
||||||
|
#include <linux/fs.h>
|
||||||
|
#include <linux/delay.h>
|
||||||
|
#include "rwnx_fw_trace.h"
|
||||||
|
|
||||||
|
int rwnx_fw_log_init(struct rwnx_fw_log *fw_log)
|
||||||
|
{
|
||||||
|
u8 *buf = kmalloc(FW_LOG_SIZE, GFP_KERNEL);
|
||||||
|
if (!buf)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
fw_log->buf.data = buf;
|
||||||
|
fw_log->buf.start = fw_log->buf.data;
|
||||||
|
fw_log->buf.size = 0;
|
||||||
|
fw_log->buf.end = fw_log->buf.data;
|
||||||
|
fw_log->buf.dataend = fw_log->buf.data + FW_LOG_SIZE;
|
||||||
|
spin_lock_init(&fw_log->lock);
|
||||||
|
|
||||||
|
printk("fw_log_init: %lx, %lx\n", (unsigned long)fw_log->buf.start, (unsigned long)(fw_log->buf.dataend));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void rwnx_fw_log_deinit(struct rwnx_fw_log *fw_log)
|
||||||
|
{
|
||||||
|
if (!fw_log)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (fw_log->buf.data)
|
||||||
|
kfree(fw_log->buf.data);
|
||||||
|
fw_log->buf.start = NULL;
|
||||||
|
fw_log->buf.end = NULL;
|
||||||
|
fw_log->buf.size = 0;
|
||||||
|
}
|
||||||
|
|
||||||
35
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/rwnx_fw_trace.h
Normal file
35
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/rwnx_fw_trace.h
Normal file
|
|
@ -0,0 +1,35 @@
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
*
|
||||||
|
* rwnx_fw_trace.h
|
||||||
|
*
|
||||||
|
* Copyright (C) RivieraWaves 2017-2019
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _RWNX_FW_TRACE_H_
|
||||||
|
#define _RWNX_FW_TRACE_H_
|
||||||
|
|
||||||
|
#include <linux/mutex.h>
|
||||||
|
#include <linux/wait.h>
|
||||||
|
#include <linux/workqueue.h>
|
||||||
|
|
||||||
|
#define FW_LOG_SIZE (10240)
|
||||||
|
|
||||||
|
struct rwnx_fw_log_buf {
|
||||||
|
uint8_t *data;
|
||||||
|
uint8_t *start;
|
||||||
|
uint8_t *end;
|
||||||
|
uint8_t *dataend;
|
||||||
|
uint32_t size;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct rwnx_fw_log {
|
||||||
|
struct rwnx_fw_log_buf buf;
|
||||||
|
spinlock_t lock;
|
||||||
|
};
|
||||||
|
|
||||||
|
int rwnx_fw_log_init(struct rwnx_fw_log *fw_log);
|
||||||
|
void rwnx_fw_log_deinit(struct rwnx_fw_log *fw_log);
|
||||||
|
#endif /* _RWNX_FW_TRACE_H_ */
|
||||||
18
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/rwnx_gki.c
Normal file
18
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/rwnx_gki.c
Normal file
|
|
@ -0,0 +1,18 @@
|
||||||
|
#include <linux/version.h>
|
||||||
|
#include <linux/skbuff.h>
|
||||||
|
|
||||||
|
|
||||||
|
void rwnx_gki_skb_append(struct sk_buff *old, struct sk_buff *newsk, struct sk_buff_head *list)
|
||||||
|
{
|
||||||
|
unsigned long flags;
|
||||||
|
struct sk_buff *prev = old;
|
||||||
|
struct sk_buff *next = prev->next;
|
||||||
|
spin_lock_irqsave(&list->lock, flags);
|
||||||
|
WRITE_ONCE(newsk->next, next);
|
||||||
|
WRITE_ONCE(newsk->prev, prev);
|
||||||
|
WRITE_ONCE(next->prev, newsk);
|
||||||
|
WRITE_ONCE(prev->next, newsk);
|
||||||
|
list->qlen++;
|
||||||
|
spin_unlock_irqrestore(&list->lock, flags);
|
||||||
|
}
|
||||||
|
|
||||||
11
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/rwnx_gki.h
Normal file
11
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/rwnx_gki.h
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
#ifndef __RWNX_GKI_H
|
||||||
|
#define __RWNX_GKI_H
|
||||||
|
|
||||||
|
#ifdef CONFIG_GKI
|
||||||
|
void rwnx_gki_skb_append(struct sk_buff *old, struct sk_buff *newsk, struct sk_buff_head *list);
|
||||||
|
#define rwnx_skb_append rwnx_gki_skb_append
|
||||||
|
#else
|
||||||
|
#define rwnx_skb_append skb_append
|
||||||
|
#endif//CONFIG_GKI
|
||||||
|
|
||||||
|
#endif
|
||||||
67
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/rwnx_irqs.c
Normal file
67
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/rwnx_irqs.c
Normal file
|
|
@ -0,0 +1,67 @@
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
*
|
||||||
|
* @file rwnx_irqs.c
|
||||||
|
*
|
||||||
|
* Copyright (C) RivieraWaves 2012-2019
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
#include <linux/interrupt.h>
|
||||||
|
|
||||||
|
#include "rwnx_defs.h"
|
||||||
|
#include "ipc_host.h"
|
||||||
|
#include "rwnx_prof.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* rwnx_irq_hdlr - IRQ handler
|
||||||
|
*
|
||||||
|
* Handler registerd by the platform driver
|
||||||
|
*/
|
||||||
|
irqreturn_t rwnx_irq_hdlr(int irq, void *dev_id)
|
||||||
|
{
|
||||||
|
struct rwnx_hw *rwnx_hw = (struct rwnx_hw *)dev_id;
|
||||||
|
disable_irq_nosync(irq);
|
||||||
|
tasklet_schedule(&rwnx_hw->task);
|
||||||
|
return IRQ_HANDLED;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* rwnx_task - Bottom half for IRQ handler
|
||||||
|
*
|
||||||
|
* Read irq status and process accordingly
|
||||||
|
*/
|
||||||
|
void rwnx_task(unsigned long data)
|
||||||
|
{
|
||||||
|
struct rwnx_hw *rwnx_hw = (struct rwnx_hw *)data;
|
||||||
|
REG_SW_SET_PROFILING(rwnx_hw, SW_PROF_RWNX_IPC_IRQ_HDLR);
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
struct rwnx_plat *rwnx_plat = rwnx_hw->plat;
|
||||||
|
u32 status, statuses = 0;
|
||||||
|
|
||||||
|
/* Ack unconditionnally in case ipc_host_get_status does not see the irq */
|
||||||
|
rwnx_plat->ack_irq(rwnx_plat);
|
||||||
|
|
||||||
|
while ((status = ipc_host_get_status(rwnx_hw->ipc_env))) {
|
||||||
|
statuses |= status;
|
||||||
|
/* All kinds of IRQs will be handled in one shot (RX, MSG, DBG, ...)
|
||||||
|
* this will ack IPC irqs not the cfpga irqs */
|
||||||
|
ipc_host_irq(rwnx_hw->ipc_env, status);
|
||||||
|
|
||||||
|
rwnx_plat->ack_irq(rwnx_plat);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
//if (statuses & IPC_IRQ_E2A_RXDESC)
|
||||||
|
// rwnx_hw->stats.last_rx = now;
|
||||||
|
//if (statuses & IPC_IRQ_E2A_TXCFM)
|
||||||
|
// rwnx_hw->stats.last_tx = now;
|
||||||
|
AICWFDBG(LOGTRACE, "rwnx_task\n");
|
||||||
|
spin_lock_bh(&rwnx_hw->tx_lock);
|
||||||
|
rwnx_hwq_process_all(rwnx_hw);
|
||||||
|
spin_unlock_bh(&rwnx_hw->tx_lock);
|
||||||
|
#if 0
|
||||||
|
enable_irq(rwnx_platform_get_irq(rwnx_plat));
|
||||||
|
#endif
|
||||||
|
REG_SW_CLEAR_PROFILING(rwnx_hw, SW_PROF_RWNX_IPC_IRQ_HDLR);
|
||||||
|
}
|
||||||
20
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/rwnx_irqs.h
Normal file
20
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/rwnx_irqs.h
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
*
|
||||||
|
* @file rwnx_irqs.h
|
||||||
|
*
|
||||||
|
* Copyright (C) RivieraWaves 2012-2019
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
#ifndef _RWNX_IRQS_H_
|
||||||
|
#define _RWNX_IRQS_H_
|
||||||
|
|
||||||
|
#include <linux/interrupt.h>
|
||||||
|
|
||||||
|
/* IRQ handler to be registered by platform driver */
|
||||||
|
irqreturn_t rwnx_irq_hdlr(int irq, void *dev_id);
|
||||||
|
|
||||||
|
void rwnx_task(unsigned long data);
|
||||||
|
|
||||||
|
#endif /* _RWNX_IRQS_H_ */
|
||||||
9150
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/rwnx_main.c
Executable file
9150
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/rwnx_main.c
Executable file
File diff suppressed because it is too large
Load diff
65
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/rwnx_main.h
Normal file
65
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/rwnx_main.h
Normal file
|
|
@ -0,0 +1,65 @@
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
*
|
||||||
|
* @file rwnx_main.h
|
||||||
|
*
|
||||||
|
* Copyright (C) RivieraWaves 2012-2019
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _RWNX_MAIN_H_
|
||||||
|
#define _RWNX_MAIN_H_
|
||||||
|
|
||||||
|
#include "rwnx_defs.h"
|
||||||
|
|
||||||
|
int rwnx_cfg80211_init(struct rwnx_plat *rwnx_plat, void **platform_data);
|
||||||
|
void rwnx_cfg80211_deinit(struct rwnx_hw *rwnx_hw);
|
||||||
|
int rwnx_fill_station_info(struct rwnx_sta *sta, struct rwnx_vif *vif,
|
||||||
|
struct station_info *sinfo, u8 *phymode, u32 *tx_phyrate, u32 *rx_phyrate);
|
||||||
|
|
||||||
|
extern int testmode;
|
||||||
|
extern u8 chip_id;
|
||||||
|
extern u8 chip_sub_id;
|
||||||
|
extern u8 chip_mcu_id;
|
||||||
|
|
||||||
|
#define CHIP_ID_H_MASK 0xC0
|
||||||
|
#define IS_CHIP_ID_H() ((chip_id & CHIP_ID_H_MASK) == CHIP_ID_H_MASK)
|
||||||
|
|
||||||
|
#define RSSI_GET_INTERVAL (10 * 1000) //time interval
|
||||||
|
#define RSSI_THD_0 (-20) //rssi 0 (dBm)
|
||||||
|
#define RSSI_THD_1 (-30) //rssi 1 (dBm)
|
||||||
|
#define RSSI_THD_2 (-75) //rssi 2 (dBm)
|
||||||
|
|
||||||
|
#define PWR_LOSS_LVL0 (-10) //RSSI > RSSI_THD_0
|
||||||
|
#define PWR_LOSS_LVL1 (-5 ) //RSSI_THD_1 < RSSI <RSSI_THD_0
|
||||||
|
#define PWR_LOSS_LVL2 (0) //RSSI_THD_2 < RSSI <RSSI_THD_1
|
||||||
|
#define PWR_LOSS_LVL3 (0)//(2) //RSSI <RSSI_THD_2
|
||||||
|
|
||||||
|
#define PWR_DELAY_TIME (10 * 1000) //pwr reduced latency time (ms)
|
||||||
|
|
||||||
|
struct rwnx_sta *rwnx_retrieve_sta(struct rwnx_hw *rwnx_hw,
|
||||||
|
struct rwnx_vif *rwnx_vif, u8 *addr,
|
||||||
|
__le16 fc, bool ap);
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef CONFIG_BAND_STEERING
|
||||||
|
void aicwf_steering_work(struct work_struct *work);
|
||||||
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 14, 0)
|
||||||
|
void aicwf_steering_timeout(ulong data);
|
||||||
|
#else
|
||||||
|
void aicwf_steering_timeout(struct timer_list *t);
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_DYNAMIC_PERPWR
|
||||||
|
void rssi_update_txpwrloss(struct rwnx_sta *sta, s8_l rssi);
|
||||||
|
void aicwf_txpwer_per_sta_worker(struct work_struct *work);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_DYNAMIC_PWR
|
||||||
|
void set_txpwrloss_ctrl(struct rwnx_hw *rwnx_hw, s8 value);
|
||||||
|
void aicwf_pwrloss_worker(struct work_struct *work);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* _RWNX_MAIN_H_ */
|
||||||
42
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/rwnx_mesh.c
Normal file
42
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/rwnx_mesh.c
Normal file
|
|
@ -0,0 +1,42 @@
|
||||||
|
/**
|
||||||
|
****************************************************************************************
|
||||||
|
*
|
||||||
|
* @file rwnx_mesh.c
|
||||||
|
*
|
||||||
|
* Copyright (C) RivieraWaves 2016-2019
|
||||||
|
*
|
||||||
|
****************************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* INCLUDE FILES
|
||||||
|
****************************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "rwnx_mesh.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* FUNCTION DEFINITIONS
|
||||||
|
****************************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
struct rwnx_mesh_proxy *rwnx_get_mesh_proxy_info(struct rwnx_vif *p_rwnx_vif, u8 *p_sta_addr, bool local)
|
||||||
|
{
|
||||||
|
struct rwnx_mesh_proxy *p_mesh_proxy = NULL;
|
||||||
|
struct rwnx_mesh_proxy *p_cur_proxy;
|
||||||
|
|
||||||
|
/* Look for proxied devices with provided address */
|
||||||
|
list_for_each_entry(p_cur_proxy, &p_rwnx_vif->ap.proxy_list, list) {
|
||||||
|
if (p_cur_proxy->local != local) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!memcmp(&p_cur_proxy->ext_sta_addr, p_sta_addr, ETH_ALEN)) {
|
||||||
|
p_mesh_proxy = p_cur_proxy;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return the found information */
|
||||||
|
return p_mesh_proxy;
|
||||||
|
}
|
||||||
45
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/rwnx_mesh.h
Normal file
45
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/rwnx_mesh.h
Normal file
|
|
@ -0,0 +1,45 @@
|
||||||
|
/**
|
||||||
|
****************************************************************************************
|
||||||
|
*
|
||||||
|
* @file rwnx_mesh.h
|
||||||
|
*
|
||||||
|
* @brief VHT Beamformer function declarations
|
||||||
|
*
|
||||||
|
* Copyright (C) RivieraWaves 2016-2019
|
||||||
|
*
|
||||||
|
****************************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _RWNX_MESH_H_
|
||||||
|
#define _RWNX_MESH_H_
|
||||||
|
|
||||||
|
/**
|
||||||
|
* INCLUDE FILES
|
||||||
|
****************************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "rwnx_defs.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DEFINES
|
||||||
|
****************************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TYPE DEFINITIONS
|
||||||
|
****************************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* FUNCTION DECLARATIONS
|
||||||
|
****************************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
****************************************************************************************
|
||||||
|
* @brief TODO [LT]
|
||||||
|
****************************************************************************************
|
||||||
|
*/
|
||||||
|
struct rwnx_mesh_proxy *rwnx_get_mesh_proxy_info(struct rwnx_vif *p_rwnx_vif, u8 *p_sta_addr, bool local);
|
||||||
|
|
||||||
|
#endif /* _RWNX_MESH_H_ */
|
||||||
1863
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/rwnx_mod_params.c
Normal file
1863
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/rwnx_mod_params.c
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -0,0 +1,76 @@
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
*
|
||||||
|
* @file rwnx_mod_params.h
|
||||||
|
*
|
||||||
|
* @brief Declaration of module parameters
|
||||||
|
*
|
||||||
|
* Copyright (C) RivieraWaves 2012-2019
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _RWNX_MOD_PARAM_H_
|
||||||
|
#define _RWNX_MOD_PARAM_H_
|
||||||
|
|
||||||
|
struct rwnx_mod_params {
|
||||||
|
bool ht_on;
|
||||||
|
bool vht_on;
|
||||||
|
bool he_on;
|
||||||
|
int mcs_map;
|
||||||
|
int he_mcs_map;
|
||||||
|
bool he_ul_on;
|
||||||
|
bool ldpc_on;
|
||||||
|
bool stbc_on;
|
||||||
|
bool gf_rx_on;
|
||||||
|
int phy_cfg;
|
||||||
|
int uapsd_timeout;
|
||||||
|
bool ap_uapsd_on;
|
||||||
|
bool sgi;
|
||||||
|
bool sgi80;
|
||||||
|
bool use_2040;
|
||||||
|
bool use_80;
|
||||||
|
bool custregd;
|
||||||
|
bool custchan;
|
||||||
|
int nss;
|
||||||
|
int amsdu_rx_max;
|
||||||
|
bool bfmee;
|
||||||
|
bool bfmer;
|
||||||
|
bool mesh;
|
||||||
|
bool murx;
|
||||||
|
bool mutx;
|
||||||
|
bool mutx_on;
|
||||||
|
unsigned int roc_dur_max;
|
||||||
|
int listen_itv;
|
||||||
|
bool listen_bcmc;
|
||||||
|
int lp_clk_ppm;
|
||||||
|
bool ps_on;
|
||||||
|
int tx_lft;
|
||||||
|
int amsdu_maxnb;
|
||||||
|
int uapsd_queues;
|
||||||
|
bool tdls;
|
||||||
|
bool uf;
|
||||||
|
bool auto_reply;
|
||||||
|
char *ftl;
|
||||||
|
bool dpsm;
|
||||||
|
#ifdef CONFIG_RWNX_FULLMAC
|
||||||
|
bool ant_div;
|
||||||
|
#endif /* CONFIG_RWNX_FULLMAC */
|
||||||
|
};
|
||||||
|
|
||||||
|
extern struct rwnx_mod_params rwnx_mod_params;
|
||||||
|
|
||||||
|
struct rwnx_hw;
|
||||||
|
struct wiphy;
|
||||||
|
int rwnx_handle_dynparams(struct rwnx_hw *rwnx_hw, struct wiphy *wiphy);
|
||||||
|
void rwnx_custregd(struct rwnx_hw *rwnx_hw, struct wiphy *wiphy);
|
||||||
|
void rwnx_enable_wapi(struct rwnx_hw *rwnx_hw);
|
||||||
|
void rwnx_enable_mfp(struct rwnx_hw *rwnx_hw);
|
||||||
|
struct ieee80211_regdomain *getRegdomainFromRwnxDB(struct wiphy *wiphy,
|
||||||
|
char *alpha2);
|
||||||
|
|
||||||
|
struct ieee80211_regdomain *getRegdomainFromRwnxDBIndex(struct wiphy *wiphy,
|
||||||
|
int index);
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* _RWNX_MOD_PARAM_H_ */
|
||||||
1712
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/rwnx_msg_rx.c
Executable file
1712
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/rwnx_msg_rx.c
Executable file
File diff suppressed because it is too large
Load diff
19
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/rwnx_msg_rx.h
Normal file
19
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/rwnx_msg_rx.h
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
/**
|
||||||
|
****************************************************************************************
|
||||||
|
*
|
||||||
|
* @file rwnx_msg_rx.h
|
||||||
|
*
|
||||||
|
* @brief RX function declarations
|
||||||
|
*
|
||||||
|
* Copyright (C) RivieraWaves 2012-2019
|
||||||
|
*
|
||||||
|
****************************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _RWNX_MSG_RX_H_
|
||||||
|
#define _RWNX_MSG_RX_H_
|
||||||
|
|
||||||
|
void rwnx_rx_handle_msg(struct rwnx_hw *rwnx_hw, struct ipc_e2a_msg *msg);
|
||||||
|
void rwnx_rx_handle_print(struct rwnx_hw *rwnx_hw, u8 *msg, u32 len);
|
||||||
|
|
||||||
|
#endif /* _RWNX_MSG_RX_H_ */
|
||||||
5064
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/rwnx_msg_tx.c
Executable file
5064
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/rwnx_msg_tx.c
Executable file
File diff suppressed because it is too large
Load diff
206
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/rwnx_msg_tx.h
Normal file
206
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/rwnx_msg_tx.h
Normal file
|
|
@ -0,0 +1,206 @@
|
||||||
|
/**
|
||||||
|
****************************************************************************************
|
||||||
|
*
|
||||||
|
* @file rwnx_msg_tx.h
|
||||||
|
*
|
||||||
|
* @brief TX function declarations
|
||||||
|
*
|
||||||
|
* Copyright (C) RivieraWaves 2012-2019
|
||||||
|
*
|
||||||
|
****************************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _RWNX_MSG_TX_H_
|
||||||
|
#define _RWNX_MSG_TX_H_
|
||||||
|
|
||||||
|
#include "rwnx_defs.h"
|
||||||
|
|
||||||
|
#ifdef RF_WRITE_FILE
|
||||||
|
#define FW_RF_CALIB_FILE "aic_rf_calib.bin"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
int rwnx_send_reset(struct rwnx_hw *rwnx_hw);
|
||||||
|
int rwnx_send_start(struct rwnx_hw *rwnx_hw);
|
||||||
|
int rwnx_send_version_req(struct rwnx_hw *rwnx_hw, struct mm_version_cfm *cfm);
|
||||||
|
int rwnx_send_add_if(struct rwnx_hw *rwnx_hw, const unsigned char *mac,
|
||||||
|
enum nl80211_iftype iftype, bool p2p, struct mm_add_if_cfm *cfm);
|
||||||
|
int rwnx_send_remove_if(struct rwnx_hw *rwnx_hw, u8 vif_index, bool defer);
|
||||||
|
int rwnx_send_set_channel(struct rwnx_hw *rwnx_hw, int phy_idx,
|
||||||
|
struct mm_set_channel_cfm *cfm);
|
||||||
|
int rwnx_send_key_add(struct rwnx_hw *rwnx_hw, u8 vif_idx, u8 sta_idx, bool pairwise,
|
||||||
|
u8 *key, u8 key_len, u8 key_idx, u8 cipher_suite,
|
||||||
|
struct mm_key_add_cfm *cfm);
|
||||||
|
int rwnx_send_key_del(struct rwnx_hw *rwnx_hw, uint8_t hw_key_idx);
|
||||||
|
int rwnx_send_bcn(struct rwnx_hw *rwnx_hw,u8 *buf, u8 vif_idx, u16 bcn_len);
|
||||||
|
|
||||||
|
int rwnx_send_bcn_change(struct rwnx_hw *rwnx_hw, u8 vif_idx, u32 bcn_addr,
|
||||||
|
u16 bcn_len, u16 tim_oft, u16 tim_len, u16 *csa_oft);
|
||||||
|
int rwnx_send_tim_update(struct rwnx_hw *rwnx_hw, u8 vif_idx, u16 aid,
|
||||||
|
u8 tx_status);
|
||||||
|
int rwnx_send_roc(struct rwnx_hw *rwnx_hw, struct rwnx_vif *vif,
|
||||||
|
struct ieee80211_channel *chan, unsigned int duration, struct mm_remain_on_channel_cfm *roc_cfm);
|
||||||
|
int rwnx_send_cancel_roc(struct rwnx_hw *rwnx_hw);
|
||||||
|
int rwnx_send_set_power(struct rwnx_hw *rwnx_hw, u8 vif_idx, s8 pwr,
|
||||||
|
struct mm_set_power_cfm *cfm);
|
||||||
|
int rwnx_send_set_edca(struct rwnx_hw *rwnx_hw, u8 hw_queue, u32 param,
|
||||||
|
bool uapsd, u8 inst_nbr);
|
||||||
|
int rwnx_send_tdls_chan_switch_req(struct rwnx_hw *rwnx_hw, struct rwnx_vif *rwnx_vif,
|
||||||
|
struct rwnx_sta *rwnx_sta, bool sta_initiator,
|
||||||
|
u8 oper_class, struct cfg80211_chan_def *chandef,
|
||||||
|
struct tdls_chan_switch_cfm *cfm);
|
||||||
|
int rwnx_send_tdls_cancel_chan_switch_req(struct rwnx_hw *rwnx_hw,
|
||||||
|
struct rwnx_vif *rwnx_vif,
|
||||||
|
struct rwnx_sta *rwnx_sta,
|
||||||
|
struct tdls_cancel_chan_switch_cfm *cfm);
|
||||||
|
|
||||||
|
#ifdef CONFIG_RWNX_P2P_DEBUGFS
|
||||||
|
int rwnx_send_p2p_oppps_req(struct rwnx_hw *rwnx_hw, struct rwnx_vif *rwnx_vif,
|
||||||
|
u8 ctw, struct mm_set_p2p_oppps_cfm *cfm);
|
||||||
|
int rwnx_send_p2p_noa_req(struct rwnx_hw *rwnx_hw, struct rwnx_vif *rwnx_vif,
|
||||||
|
int count, int interval, int duration,
|
||||||
|
bool dyn_noa, struct mm_set_p2p_noa_cfm *cfm);
|
||||||
|
#endif /* CONFIG_RWNX_P2P_DEBUGFS */
|
||||||
|
|
||||||
|
#ifdef AICWF_ARP_OFFLOAD
|
||||||
|
int rwnx_send_arpoffload_en_req(struct rwnx_hw *rwnx_hw, struct rwnx_vif *rwnx_vif,
|
||||||
|
u32_l ipaddr, u8_l enable);
|
||||||
|
#endif
|
||||||
|
int rwnx_send_rf_config_req(struct rwnx_hw *rwnx_hw, u8_l ofst, u8_l sel, u8_l *tbl, u16_l len);
|
||||||
|
int rwnx_send_rf_calib_req(struct rwnx_hw *rwnx_hw, struct mm_set_rf_calib_cfm *cfm);
|
||||||
|
int rwnx_send_get_macaddr_req(struct rwnx_hw *rwnx_hw, struct mm_get_mac_addr_cfm *cfm);
|
||||||
|
|
||||||
|
#ifdef CONFIG_RWNX_FULLMAC
|
||||||
|
int rwnx_send_me_config_req(struct rwnx_hw *rwnx_hw);
|
||||||
|
int rwnx_send_me_chan_config_req(struct rwnx_hw *rwnx_hw, char *ccode);
|
||||||
|
int rwnx_send_me_set_control_port_req(struct rwnx_hw *rwnx_hw, bool opened,
|
||||||
|
u8 sta_idx);
|
||||||
|
int rwnx_send_me_sta_add(struct rwnx_hw *rwnx_hw, struct station_parameters *params,
|
||||||
|
const u8 *mac, u8 inst_nbr, struct me_sta_add_cfm *cfm);
|
||||||
|
int rwnx_send_me_sta_del(struct rwnx_hw *rwnx_hw, u8 sta_idx, bool tdls_sta);
|
||||||
|
int rwnx_send_me_traffic_ind(struct rwnx_hw *rwnx_hw, u8 sta_idx, bool uapsd, u8 tx_status);
|
||||||
|
int rwnx_send_me_rc_stats(struct rwnx_hw *rwnx_hw, u8 sta_idx,
|
||||||
|
struct me_rc_stats_cfm *cfm);
|
||||||
|
int rwnx_send_me_rc_set_rate(struct rwnx_hw *rwnx_hw,
|
||||||
|
u8 sta_idx,
|
||||||
|
u16 rate_idx);
|
||||||
|
int rwnx_send_me_set_ps_mode(struct rwnx_hw *rwnx_hw, u8 ps_mode);
|
||||||
|
int rwnx_send_me_set_lp_level(struct rwnx_hw *rwnx_hw, u8 lp_level);
|
||||||
|
int rwnx_send_sm_connect_req(struct rwnx_hw *rwnx_hw,
|
||||||
|
struct rwnx_vif *rwnx_vif,
|
||||||
|
struct cfg80211_connect_params *sme,
|
||||||
|
struct sm_connect_cfm *cfm);
|
||||||
|
int rwnx_send_sm_disconnect_req(struct rwnx_hw *rwnx_hw,
|
||||||
|
struct rwnx_vif *rwnx_vif,
|
||||||
|
u16 reason);
|
||||||
|
int rwnx_send_sm_external_auth_required_rsp(struct rwnx_hw *rwnx_hw,
|
||||||
|
struct rwnx_vif *rwnx_vif,
|
||||||
|
u16 status);
|
||||||
|
int rwnx_send_apm_start_req(struct rwnx_hw *rwnx_hw, struct rwnx_vif *vif,
|
||||||
|
struct cfg80211_ap_settings *settings,
|
||||||
|
struct apm_start_cfm *cfm,
|
||||||
|
struct rwnx_ipc_elem_var *elem);
|
||||||
|
int rwnx_send_apm_stop_req(struct rwnx_hw *rwnx_hw, struct rwnx_vif *vif);
|
||||||
|
int rwnx_send_scanu_req(struct rwnx_hw *rwnx_hw, struct rwnx_vif *rwnx_vif,
|
||||||
|
struct cfg80211_scan_request *param);
|
||||||
|
int rwnx_send_scanu_cancel_req(struct rwnx_hw *rwnx_hw,
|
||||||
|
struct scan_cancel_cfm *cfm);
|
||||||
|
|
||||||
|
int rwnx_send_apm_start_cac_req(struct rwnx_hw *rwnx_hw, struct rwnx_vif *vif,
|
||||||
|
struct cfg80211_chan_def *chandef,
|
||||||
|
struct apm_start_cac_cfm *cfm);
|
||||||
|
int rwnx_send_apm_stop_cac_req(struct rwnx_hw *rwnx_hw, struct rwnx_vif *vif);
|
||||||
|
int rwnx_send_tdls_peer_traffic_ind_req(struct rwnx_hw *rwnx_hw, struct rwnx_vif *rwnx_vif);
|
||||||
|
int rwnx_send_config_monitor_req(struct rwnx_hw *rwnx_hw,
|
||||||
|
struct cfg80211_chan_def *chandef,
|
||||||
|
struct me_config_monitor_cfm *cfm);
|
||||||
|
int rwnx_send_mesh_start_req(struct rwnx_hw *rwnx_hw, struct rwnx_vif *vif,
|
||||||
|
const struct mesh_config *conf, const struct mesh_setup *setup,
|
||||||
|
struct mesh_start_cfm *cfm);
|
||||||
|
int rwnx_send_mesh_stop_req(struct rwnx_hw *rwnx_hw, struct rwnx_vif *vif,
|
||||||
|
struct mesh_stop_cfm *cfm);
|
||||||
|
int rwnx_send_mesh_update_req(struct rwnx_hw *rwnx_hw, struct rwnx_vif *vif,
|
||||||
|
u32 mask, const struct mesh_config *p_mconf, struct mesh_update_cfm *cfm);
|
||||||
|
int rwnx_send_mesh_peer_info_req(struct rwnx_hw *rwnx_hw, struct rwnx_vif *vif,
|
||||||
|
u8 sta_idx, struct mesh_peer_info_cfm *cfm);
|
||||||
|
void rwnx_send_mesh_peer_update_ntf(struct rwnx_hw *rwnx_hw, struct rwnx_vif *vif,
|
||||||
|
u8 sta_idx, u8 mlink_state);
|
||||||
|
void rwnx_send_mesh_path_create_req(struct rwnx_hw *rwnx_hw, struct rwnx_vif *vif, u8 *tgt_addr);
|
||||||
|
int rwnx_send_mesh_path_update_req(struct rwnx_hw *rwnx_hw, struct rwnx_vif *vif, const u8 *tgt_addr,
|
||||||
|
const u8 *p_nhop_addr, struct mesh_path_update_cfm *cfm);
|
||||||
|
void rwnx_send_mesh_proxy_add_req(struct rwnx_hw *rwnx_hw, struct rwnx_vif *vif, u8 *ext_addr);
|
||||||
|
#endif /* CONFIG_RWNX_FULLMAC */
|
||||||
|
|
||||||
|
#ifdef CONFIG_RWNX_BFMER
|
||||||
|
#ifdef CONFIG_RWNX_FULLMAC
|
||||||
|
void rwnx_send_bfmer_enable(struct rwnx_hw *rwnx_hw, struct rwnx_sta *rwnx_sta,
|
||||||
|
const struct ieee80211_vht_cap *vht_cap);
|
||||||
|
#endif /* CONFIG_RWNX_FULLMAC */
|
||||||
|
#ifdef CONFIG_RWNX_MUMIMO_TX
|
||||||
|
int rwnx_send_mu_group_update_req(struct rwnx_hw *rwnx_hw, struct rwnx_sta *rwnx_sta);
|
||||||
|
#endif /* CONFIG_RWNX_MUMIMO_TX */
|
||||||
|
#endif /* CONFIG_RWNX_BFMER */
|
||||||
|
|
||||||
|
/* Debug messages */
|
||||||
|
int rwnx_send_dbg_trigger_req(struct rwnx_hw *rwnx_hw, char *msg);
|
||||||
|
int rwnx_send_dbg_mem_read_req(struct rwnx_hw *rwnx_hw, u32 mem_addr,
|
||||||
|
struct dbg_mem_read_cfm *cfm);
|
||||||
|
int rwnx_send_dbg_mem_write_req(struct rwnx_hw *rwnx_hw, u32 mem_addr,
|
||||||
|
u32 mem_data);
|
||||||
|
int rwnx_send_dbg_mem_mask_write_req(struct rwnx_hw *rwnx_hw, u32 mem_addr,
|
||||||
|
u32 mem_mask, u32 mem_data);
|
||||||
|
int rwnx_send_dbg_set_mod_filter_req(struct rwnx_hw *rwnx_hw, u32 filter);
|
||||||
|
#ifdef CONFIG_RFTEST
|
||||||
|
int rwnx_send_rftest_req(struct rwnx_hw *rwnx_hw, u32_l cmd, u32_l argc, u8_l *argv, struct dbg_rftest_cmd_cfm *cfm);
|
||||||
|
#endif
|
||||||
|
int rwnx_send_dbg_set_sev_filter_req(struct rwnx_hw *rwnx_hw, u32 filter);
|
||||||
|
int rwnx_send_dbg_get_sys_stat_req(struct rwnx_hw *rwnx_hw,
|
||||||
|
struct dbg_get_sys_stat_cfm *cfm);
|
||||||
|
int rwnx_send_dbg_mem_block_write_req(struct rwnx_hw *rwnx_hw, u32 mem_addr,
|
||||||
|
u32 mem_size, u32 *mem_data);
|
||||||
|
int rwnx_send_dbg_mem_block_read_req(struct rwnx_hw *rwnx_hw, u32 mem_addr,
|
||||||
|
u32 mem_size, struct dbg_mem_block_read_cfm *cfm);
|
||||||
|
int rwnx_send_dbg_start_app_req(struct rwnx_hw *rwnx_hw, u32 boot_addr,
|
||||||
|
u32 boot_type);
|
||||||
|
int rwnx_send_dbg_gpio_write_req(struct rwnx_hw *rwnx_hw, u8_l gpio_idx, u8_l gpio_val);
|
||||||
|
int rwnx_send_dbg_gpio_read_req(struct rwnx_hw *rwnx_hw, u8_l gpio_idx, struct dbg_gpio_read_cfm *cfm);
|
||||||
|
int rwnx_send_dbg_gpio_init_req(struct rwnx_hw *rwnx_hw, u8_l gpio_idx, u8_l gpio_dir, u8_l gpio_val);
|
||||||
|
int rwnx_send_cfg_rssi_req(struct rwnx_hw *rwnx_hw, u8 vif_index, int rssi_thold, u32 rssi_hyst);
|
||||||
|
int rwnx_send_disable_agg_req(struct rwnx_hw *rwnx_hw, u8_l agg_disable, u8_l agg_disable_rx, u8_l sta_idx);
|
||||||
|
int rwnx_send_coex_req(struct rwnx_hw *rwnx_hw, u8_l disable_coexnull, u8_l enable_nullcts);
|
||||||
|
int rwnx_send_get_sta_info_req(struct rwnx_hw *rwnx_hw, u8_l sta_idx, struct mm_get_sta_info_cfm *cfm);
|
||||||
|
int rwnx_send_set_stack_start_req(struct rwnx_hw *rwnx_hw, u8_l on, u8_l efuse_valid, u8_l set_vendor_info,
|
||||||
|
u8_l fwtrace_redir_en, struct mm_set_stack_start_cfm *cfm);
|
||||||
|
int rwnx_send_txop_req(struct rwnx_hw *rwnx_hw, uint16_t *txop, u8_l long_nav_en, u8_l cfe_en);
|
||||||
|
int rwnx_send_set_temp_comp_req(struct rwnx_hw *rwnx_hw, struct mm_set_vendor_swconfig_cfm *cfm);
|
||||||
|
int rwnx_send_vendor_hwconfig_req(struct rwnx_hw *rwnx_hw, uint32_t hwconfig_id, int32_t *param, int32_t *param_out);
|
||||||
|
int rwnx_send_vendor_swconfig_req(struct rwnx_hw *rwnx_hw, uint32_t swconfig_id, int32_t *param_in, int32_t *param_out);
|
||||||
|
int rwnx_send_mask_set_ext_flags_req(struct rwnx_hw *rwnx_hw, uint32_t flags_mask, uint32_t flags_val, struct mm_set_vendor_swconfig_cfm *cfm);
|
||||||
|
int rwnx_send_vendor_hwconfig_req_x2(struct rwnx_hw *rwnx_hw, uint32_t hwconfig_id, int32_t *param, int32_t *param_out);
|
||||||
|
int rwnx_send_vendor_swconfig_req_x2(struct rwnx_hw *rwnx_hw, uint32_t swconfig_id, int32_t *param_in, int32_t *param_out);
|
||||||
|
|
||||||
|
int rwnx_send_get_fw_version_req(struct rwnx_hw *rwnx_hw, struct mm_get_fw_version_cfm *cfm);
|
||||||
|
int rwnx_send_txpwr_idx_req(struct rwnx_hw *rwnx_hw);
|
||||||
|
int rwnx_send_txpwr_ofst_req(struct rwnx_hw *rwnx_hw);
|
||||||
|
int rwnx_send_txpwr_ofst2x_req(struct rwnx_hw *rwnx_hw);
|
||||||
|
int rwnx_send_txpwr_ofst2x_v2_req(struct rwnx_hw *rwnx_hw);
|
||||||
|
int rwnx_send_set_filter(struct rwnx_hw *rwnx_hw, uint32_t filter);
|
||||||
|
int rwnx_send_txpwr_lvl_req(struct rwnx_hw *rwnx_hw);
|
||||||
|
int rwnx_send_txpwr_lvl_v3_req(struct rwnx_hw *rwnx_hw);
|
||||||
|
int rwnx_send_txpwr_lvl_v4_req(struct rwnx_hw *rwnx_hw);
|
||||||
|
int rwnx_send_txpwr_lvl_adj_req(struct rwnx_hw *rwnx_hw);
|
||||||
|
#ifdef CONFIG_WOWLAN
|
||||||
|
int rwnx_send_set_pkt_filter_req(struct rwnx_hw *rwnx_hw, u8_l *param);
|
||||||
|
int rwnx_send_dummy_reboot(struct rwnx_hw *rwnx_hw);
|
||||||
|
#endif
|
||||||
|
#ifdef CONFIG_DYNAMIC_PERPWR
|
||||||
|
int rwnx_send_txpwr_per_sta_req(struct rwnx_hw *rwnx_hw, struct rwnx_sta *sta);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
//#ifdef CONFIG_USB_BT
|
||||||
|
int rwnx_send_reboot(struct rwnx_hw *rwnx_hw);
|
||||||
|
//#endif // CONFIG_USB_BT
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* _RWNX_MSG_TX_H_ */
|
||||||
659
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/rwnx_mu_group.c
Normal file
659
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/rwnx_mu_group.c
Normal file
|
|
@ -0,0 +1,659 @@
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
*
|
||||||
|
* @file rwnx_mu_group.c
|
||||||
|
*
|
||||||
|
* Copyright (C) RivieraWaves 2016-2019
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "rwnx_defs.h"
|
||||||
|
#include "rwnx_msg_tx.h"
|
||||||
|
#include "rwnx_events.h"
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* rwnx_mu_group_sta_init - Initialize group information for a STA
|
||||||
|
*
|
||||||
|
* @sta: Sta to initialize
|
||||||
|
*/
|
||||||
|
void rwnx_mu_group_sta_init(struct rwnx_sta *sta,
|
||||||
|
const struct ieee80211_vht_cap *vht_cap)
|
||||||
|
{
|
||||||
|
sta->group_info.map = 0;
|
||||||
|
sta->group_info.cnt = 0;
|
||||||
|
sta->group_info.active.next = LIST_POISON1;
|
||||||
|
sta->group_info.update.next = LIST_POISON1;
|
||||||
|
sta->group_info.last_update = 0;
|
||||||
|
sta->group_info.traffic = 0;
|
||||||
|
sta->group_info.group = 0;
|
||||||
|
|
||||||
|
if (!vht_cap ||
|
||||||
|
!(vht_cap->vht_cap_info & IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE)) {
|
||||||
|
sta->group_info.map = RWNX_SU_GROUP;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* rwnx_mu_group_sta_del - Remove a sta from all MU group
|
||||||
|
*
|
||||||
|
* @rwnx_hw: main driver data
|
||||||
|
* @sta: STA to remove
|
||||||
|
*
|
||||||
|
* Remove one sta from all the MU groups it belongs to.
|
||||||
|
*/
|
||||||
|
void rwnx_mu_group_sta_del(struct rwnx_hw *rwnx_hw, struct rwnx_sta *sta)
|
||||||
|
{
|
||||||
|
struct rwnx_mu_info *mu = &rwnx_hw->mu;
|
||||||
|
int i, j, group_id;
|
||||||
|
bool lock_taken;
|
||||||
|
u64 map;
|
||||||
|
|
||||||
|
lock_taken = (down_interruptible(&mu->lock) == 0);
|
||||||
|
|
||||||
|
group_sta_for_each(sta, group_id, map) {
|
||||||
|
struct rwnx_mu_group *group = rwnx_mu_group_from_id(mu, group_id);
|
||||||
|
|
||||||
|
for (i = 0; i < CONFIG_USER_MAX; i++) {
|
||||||
|
if (group->users[i] == sta) {
|
||||||
|
group->users[i] = NULL;
|
||||||
|
group->user_cnt --;
|
||||||
|
/* Don't keep group with only one user */
|
||||||
|
if (group->user_cnt == 1) {
|
||||||
|
for (j = 0; j < CONFIG_USER_MAX; j++) {
|
||||||
|
if (group->users[j]) {
|
||||||
|
group->users[j]->group_info.cnt--;
|
||||||
|
group->users[j]->group_info.map &= ~BIT_ULL(group->group_id);
|
||||||
|
if (group->users[j]->group_info.group == group_id)
|
||||||
|
group->users[j]->group_info.group = 0;
|
||||||
|
group->user_cnt --;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mu->group_cnt--;
|
||||||
|
trace_mu_group_delete(group->group_id);
|
||||||
|
} else {
|
||||||
|
trace_mu_group_update(group);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
WARN((i == CONFIG_USER_MAX), "sta %d doesn't belongs to group %d",
|
||||||
|
sta->sta_idx, group_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
sta->group_info.map = 0;
|
||||||
|
sta->group_info.cnt = 0;
|
||||||
|
sta->group_info.traffic = 0;
|
||||||
|
|
||||||
|
if (sta->group_info.active.next != LIST_POISON1)
|
||||||
|
list_del(&sta->group_info.active);
|
||||||
|
|
||||||
|
if (sta->group_info.update.next != LIST_POISON1)
|
||||||
|
list_del(&sta->group_info.update);
|
||||||
|
|
||||||
|
if (lock_taken)
|
||||||
|
up(&mu->lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* rwnx_mu_group_sta_get_map - Get the list of group a STA belongs to
|
||||||
|
*
|
||||||
|
* @sta: pointer to the sta
|
||||||
|
*
|
||||||
|
* @return the list of group a STA belongs to as a bitfield
|
||||||
|
*/
|
||||||
|
u64 rwnx_mu_group_sta_get_map(struct rwnx_sta *sta)
|
||||||
|
{
|
||||||
|
if (sta)
|
||||||
|
return sta->group_info.map;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* rwnx_mu_group_sta_get_pos - Get sta position in a group
|
||||||
|
*
|
||||||
|
* @rwnx_hw: main driver data
|
||||||
|
* @sta: pointer to the sta
|
||||||
|
* @group_id: Group id
|
||||||
|
*
|
||||||
|
* @return the positon of @sta in group @group_id or -1 if the sta
|
||||||
|
* doesn't belongs to the group (or group id is invalid)
|
||||||
|
*/
|
||||||
|
int rwnx_mu_group_sta_get_pos(struct rwnx_hw *rwnx_hw, struct rwnx_sta *sta,
|
||||||
|
int group_id)
|
||||||
|
{
|
||||||
|
struct rwnx_mu_group *group;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
group = rwnx_mu_group_from_id(&rwnx_hw->mu, group_id);
|
||||||
|
if (!group)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
for (i = 0; i < CONFIG_USER_MAX; i++) {
|
||||||
|
if (group->users[i] == sta)
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
WARN(1, "sta %d doesn't belongs to group %d",
|
||||||
|
sta->sta_idx, group_id);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* rwnx_mu_group_move_head - Move (or add) one element at the top of a list
|
||||||
|
*
|
||||||
|
* @list: list pointer
|
||||||
|
* @elem: element to move (or add) at the top of @list
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
static inline
|
||||||
|
void rwnx_mu_group_move_head(struct list_head *list, struct list_head *elem)
|
||||||
|
{
|
||||||
|
if (elem->next != LIST_POISON1) {
|
||||||
|
__list_del_entry(elem);
|
||||||
|
}
|
||||||
|
list_add(elem, list);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* rwnx_mu_group_remove_users - Remove all the users of a group
|
||||||
|
*
|
||||||
|
* @mu: pointer on MU info
|
||||||
|
* @group: pointer on group to remove users from
|
||||||
|
*
|
||||||
|
* Loop over all users one one group and remove this group from their
|
||||||
|
* map (and count).
|
||||||
|
* Each users is also added to the update_sta list, so that group info
|
||||||
|
* will be resent to fw for this user.
|
||||||
|
*/
|
||||||
|
static inline
|
||||||
|
void rwnx_mu_group_remove_users(struct rwnx_mu_info *mu,
|
||||||
|
struct rwnx_mu_group *group)
|
||||||
|
{
|
||||||
|
struct rwnx_sta *sta;
|
||||||
|
int i, group_id = group->group_id;
|
||||||
|
|
||||||
|
for (i = 0; i < CONFIG_USER_MAX; i++) {
|
||||||
|
if (group->users[i]) {
|
||||||
|
sta = group->users[i];
|
||||||
|
group->users[i] = NULL;
|
||||||
|
sta->group_info.cnt--;
|
||||||
|
sta->group_info.map &= ~BIT_ULL(group_id);
|
||||||
|
rwnx_mu_group_move_head(&mu->update_sta,
|
||||||
|
&sta->group_info.update);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (group->user_cnt)
|
||||||
|
mu->group_cnt--;
|
||||||
|
group->user_cnt = 0;
|
||||||
|
trace_mu_group_delete(group_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* rwnx_mu_group_add_users - Add users to a group
|
||||||
|
*
|
||||||
|
* @mu: pointer on MU info
|
||||||
|
* @group: pointer on group to add users in
|
||||||
|
* @nb_user: number of users to ad
|
||||||
|
* @users: table of user to add
|
||||||
|
*
|
||||||
|
* Add @nb_users to @group (which may already have users)
|
||||||
|
* Each new users is added to the first free position.
|
||||||
|
* It is assume that @group has at least @nb_user free position. If it is not
|
||||||
|
* case it only add the number of users needed to complete the group.
|
||||||
|
* Each users (effectively added to @group) is also added to the update_sta
|
||||||
|
* list, so that group info will be resent to fw for this user.
|
||||||
|
*/
|
||||||
|
static inline
|
||||||
|
void rwnx_mu_group_add_users(struct rwnx_mu_info *mu,
|
||||||
|
struct rwnx_mu_group *group,
|
||||||
|
int nb_user, struct rwnx_sta **users)
|
||||||
|
{
|
||||||
|
int i, j, group_id = group->group_id;
|
||||||
|
|
||||||
|
if (!group->user_cnt)
|
||||||
|
mu->group_cnt++;
|
||||||
|
|
||||||
|
j = 0;
|
||||||
|
for (i = 0; i < nb_user ; i++) {
|
||||||
|
for (; j < CONFIG_USER_MAX ; j++) {
|
||||||
|
if (group->users[j] == NULL) {
|
||||||
|
group->users[j] = users[i];
|
||||||
|
users[i]->group_info.cnt ++;
|
||||||
|
users[i]->group_info.map |= BIT_ULL(group_id);
|
||||||
|
|
||||||
|
rwnx_mu_group_move_head(&(mu->update_sta),
|
||||||
|
&(users[i]->group_info.update));
|
||||||
|
group->user_cnt ++;
|
||||||
|
j ++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
WARN(j == (CONFIG_USER_MAX - 1),
|
||||||
|
"Too many user for group %d (nb_user=%d)",
|
||||||
|
group_id, group->user_cnt + nb_user - i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
trace_mu_group_update(group);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* rwnx_mu_group_create_one - create on group with a specific group of user
|
||||||
|
*
|
||||||
|
* @mu: pointer on MU info
|
||||||
|
* @nb_user: number of user to include in the group (<= CONFIG_USER_MAX)
|
||||||
|
* @users: table of users
|
||||||
|
*
|
||||||
|
* Try to create a new group with a specific group of users.
|
||||||
|
* 1- First it checks if a group containing all this users already exists.
|
||||||
|
*
|
||||||
|
* 2- Then it checks if it is possible to complete a group which already
|
||||||
|
* contains at least one user.
|
||||||
|
*
|
||||||
|
* 3- Finally it create a new group. To do so, it take take the last group of
|
||||||
|
* the active_groups list, remove all its current users and add the new ones
|
||||||
|
*
|
||||||
|
* In all cases, the group selected is moved at the top of the active_groups
|
||||||
|
* list
|
||||||
|
*
|
||||||
|
* @return 1 if a new group has been created and 0 otherwise
|
||||||
|
*/
|
||||||
|
static
|
||||||
|
int rwnx_mu_group_create_one(struct rwnx_mu_info *mu, int nb_user,
|
||||||
|
struct rwnx_sta **users, int *nb_group_left)
|
||||||
|
{
|
||||||
|
int i, group_id;
|
||||||
|
struct rwnx_mu_group *group;
|
||||||
|
u64 group_match;
|
||||||
|
u64 group_avail;
|
||||||
|
|
||||||
|
group_match = users[0]->group_info.map;
|
||||||
|
group_avail = users[0]->group_info.map;
|
||||||
|
for (i = 1; i < nb_user ; i++) {
|
||||||
|
group_match &= users[i]->group_info.map;
|
||||||
|
group_avail |= users[i]->group_info.map;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (group_match) {
|
||||||
|
/* a group (or more) with all the users already exist */
|
||||||
|
group_id = RWNX_GET_FIRST_GROUP_ID(group_match);
|
||||||
|
group = rwnx_mu_group_from_id(mu, group_id);
|
||||||
|
rwnx_mu_group_move_head(&mu->active_groups, &group->list);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if CONFIG_USER_MAX > 2
|
||||||
|
if (group_avail) {
|
||||||
|
/* check if we can complete a group */
|
||||||
|
struct rwnx_sta *users2[CONFIG_USER_MAX];
|
||||||
|
int nb_user2;
|
||||||
|
|
||||||
|
group_for_each(group_id, group_avail) {
|
||||||
|
group = rwnx_mu_group_from_id(mu, group_id);
|
||||||
|
if (group->user_cnt == CONFIG_USER_MAX)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
nb_user2 = 0;
|
||||||
|
for (i = 0; i < nb_user ; i++) {
|
||||||
|
if (!(users[i]->group_info.map & BIT_ULL(group_id))) {
|
||||||
|
users2[nb_user2] = users[i];
|
||||||
|
nb_user2++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((group->user_cnt + nb_user2) <= CONFIG_USER_MAX) {
|
||||||
|
rwnx_mu_group_add_users(mu, group, nb_user2, users2);
|
||||||
|
rwnx_mu_group_move_head(&mu->active_groups, &group->list);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_USER_MAX > 2*/
|
||||||
|
|
||||||
|
/* create a new group */
|
||||||
|
group = list_last_entry(&mu->active_groups, struct rwnx_mu_group, list);
|
||||||
|
rwnx_mu_group_remove_users(mu, group);
|
||||||
|
rwnx_mu_group_add_users(mu, group, nb_user, users);
|
||||||
|
rwnx_mu_group_move_head(&mu->active_groups, &group->list);
|
||||||
|
(*nb_group_left)--;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* rwnx_mu_group_create - Create new groups containing one specific sta
|
||||||
|
*
|
||||||
|
* @mu: pointer on MU info
|
||||||
|
* @sta: sta to add in each group
|
||||||
|
* @nb_group_left: maximum number to new group allowed. (updated on exit)
|
||||||
|
*
|
||||||
|
* This will try to create "all the possible" group with a specific sta being
|
||||||
|
* a member of all these group.
|
||||||
|
* The function simply loops over the @active_sta list (starting from @sta).
|
||||||
|
* When it has (CONFIG_USER_MAX - 1) users it try to create a new group with
|
||||||
|
* these users (plus @sta).
|
||||||
|
* Loops end when there is no more users, or no more new group is allowed
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
static
|
||||||
|
void rwnx_mu_group_create(struct rwnx_mu_info *mu, struct rwnx_sta *sta,
|
||||||
|
int *nb_group_left)
|
||||||
|
{
|
||||||
|
struct rwnx_sta *user_sta = sta;
|
||||||
|
struct rwnx_sta *users[CONFIG_USER_MAX];
|
||||||
|
int nb_user = 1;
|
||||||
|
|
||||||
|
users[0] = sta;
|
||||||
|
while (*nb_group_left) {
|
||||||
|
|
||||||
|
list_for_each_entry_continue(user_sta, &mu->active_sta, group_info.active) {
|
||||||
|
users[nb_user] = user_sta;
|
||||||
|
if (++nb_user == CONFIG_USER_MAX) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nb_user > 1) {
|
||||||
|
if (rwnx_mu_group_create_one(mu, nb_user, users, nb_group_left))
|
||||||
|
(*nb_group_left)--;
|
||||||
|
|
||||||
|
if (nb_user < CONFIG_USER_MAX)
|
||||||
|
break;
|
||||||
|
else
|
||||||
|
nb_user = 1;
|
||||||
|
} else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* rwnx_mu_group_work - process function of the "group_work"
|
||||||
|
*
|
||||||
|
* The work is scheduled when several sta (MU beamformee capable) are active.
|
||||||
|
* When called, the @active_sta contains the list of the active sta (starting
|
||||||
|
* from the most recent one), and @active_groups is the list of all possible
|
||||||
|
* groups ordered so that the first one is the most recently used.
|
||||||
|
*
|
||||||
|
* This function will create new groups, starting from group containing the
|
||||||
|
* most "active" sta.
|
||||||
|
* For example if the list of sta is :
|
||||||
|
* sta8 -> sta3 -> sta4 -> sta7 -> sta1
|
||||||
|
* and the number of user per group is 3, it will create grooups :
|
||||||
|
* - sta8 / sta3 / sta4
|
||||||
|
* - sta8 / sta7 / sta1
|
||||||
|
* - sta3 / sta4 / sta7
|
||||||
|
* - sta3 / sta1
|
||||||
|
* - sta4 / sta7 / sta1
|
||||||
|
* - sta7 / sta1
|
||||||
|
*
|
||||||
|
* To create new group, the least used group are first selected.
|
||||||
|
* It is only allowed to create NX_MU_GROUP_MAX per iteration.
|
||||||
|
*
|
||||||
|
* Once groups have been updated, mu group information is update to the fw.
|
||||||
|
* To do so it use the @update_sta list to know which sta has been affected.
|
||||||
|
* As it is necessary to wait for fw confirmation before using this new group
|
||||||
|
* MU is temporarily disabled during group update
|
||||||
|
*
|
||||||
|
* Work is then rescheduled.
|
||||||
|
*
|
||||||
|
* At the end of the function, both @active_sta and @update_sta list are empty.
|
||||||
|
*
|
||||||
|
* Note:
|
||||||
|
* - This is still a WIP, and will require more tuning
|
||||||
|
* - not all combinations are created, to avoid to much processing.
|
||||||
|
* - reschedule delay should be adaptative
|
||||||
|
*/
|
||||||
|
void rwnx_mu_group_work(struct work_struct *ws)
|
||||||
|
{
|
||||||
|
struct delayed_work *dw = container_of(ws, struct delayed_work, work);
|
||||||
|
struct rwnx_mu_info *mu = container_of(dw, struct rwnx_mu_info, group_work);
|
||||||
|
struct rwnx_hw *rwnx_hw = container_of(mu, struct rwnx_hw, mu);
|
||||||
|
struct rwnx_sta *sta, *next;
|
||||||
|
int nb_group_left = NX_MU_GROUP_MAX;
|
||||||
|
|
||||||
|
if (WARN(!rwnx_hw->mod_params->mutx,
|
||||||
|
"In group formation work, but mutx disabled"))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (down_interruptible(&mu->lock) != 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
mu->update_count++;
|
||||||
|
if (!mu->update_count)
|
||||||
|
mu->update_count++;
|
||||||
|
|
||||||
|
list_for_each_entry_safe(sta, next, &mu->active_sta, group_info.active) {
|
||||||
|
if (nb_group_left)
|
||||||
|
rwnx_mu_group_create(mu, sta, &nb_group_left);
|
||||||
|
|
||||||
|
sta->group_info.last_update = mu->update_count;
|
||||||
|
list_del(&sta->group_info.active);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (! list_empty(&mu->update_sta)) {
|
||||||
|
list_for_each_entry_safe(sta, next, &mu->update_sta, group_info.update) {
|
||||||
|
rwnx_send_mu_group_update_req(rwnx_hw, sta);
|
||||||
|
list_del(&sta->group_info.update);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mu->next_group_select = jiffies;
|
||||||
|
rwnx_mu_group_sta_select(rwnx_hw);
|
||||||
|
up(&mu->lock);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* rwnx_mu_group_init - Initialize MU groups
|
||||||
|
*
|
||||||
|
* @rwnx_hw: main driver data
|
||||||
|
*
|
||||||
|
* Initialize all MU group
|
||||||
|
*/
|
||||||
|
void rwnx_mu_group_init(struct rwnx_hw *rwnx_hw)
|
||||||
|
{
|
||||||
|
struct rwnx_mu_info *mu = &rwnx_hw->mu;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
INIT_LIST_HEAD(&mu->active_groups);
|
||||||
|
INIT_LIST_HEAD(&mu->active_sta);
|
||||||
|
INIT_LIST_HEAD(&mu->update_sta);
|
||||||
|
|
||||||
|
for (i = 0; i < NX_MU_GROUP_MAX; i++) {
|
||||||
|
int j;
|
||||||
|
mu->groups[i].user_cnt = 0;
|
||||||
|
mu->groups[i].group_id = i + 1;
|
||||||
|
for (j = 0; j < CONFIG_USER_MAX; j++) {
|
||||||
|
mu->groups[i].users[j] = NULL;
|
||||||
|
}
|
||||||
|
list_add(&mu->groups[i].list, &mu->active_groups);
|
||||||
|
}
|
||||||
|
|
||||||
|
mu->update_count = 1;
|
||||||
|
mu->group_cnt = 0;
|
||||||
|
mu->next_group_select = jiffies;
|
||||||
|
INIT_DELAYED_WORK(&mu->group_work, rwnx_mu_group_work);
|
||||||
|
sema_init(&mu->lock, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* rwnx_mu_set_active_sta - mark a STA as active
|
||||||
|
*
|
||||||
|
* @rwnx_hw: main driver data
|
||||||
|
* @sta: pointer to the sta
|
||||||
|
* @traffic: Number of buffers to add in the sta's traffic counter
|
||||||
|
*
|
||||||
|
* If @sta is MU beamformee capable (and MU-MIMO tx is enabled) move the
|
||||||
|
* sta at the top of the @active_sta list.
|
||||||
|
* It also schedule the group_work if not already scheduled and the list
|
||||||
|
* contains more than one sta.
|
||||||
|
*
|
||||||
|
* If a STA was already in the list during the last group update
|
||||||
|
* (i.e. sta->group_info.last_update == mu->update_count) it is not added
|
||||||
|
* back to the list until a sta that wasn't active during the last update is
|
||||||
|
* added. This is to avoid scheduling group update with a list of sta that
|
||||||
|
* were all already in the list during previous update.
|
||||||
|
*
|
||||||
|
* It is called with mu->lock taken.
|
||||||
|
*/
|
||||||
|
void rwnx_mu_set_active_sta(struct rwnx_hw *rwnx_hw, struct rwnx_sta *sta,
|
||||||
|
int traffic)
|
||||||
|
{
|
||||||
|
struct rwnx_mu_info *mu = &rwnx_hw->mu;
|
||||||
|
|
||||||
|
if (!sta || (sta->group_info.map & RWNX_SU_GROUP))
|
||||||
|
return;
|
||||||
|
|
||||||
|
sta->group_info.traffic += traffic;
|
||||||
|
|
||||||
|
if ((sta->group_info.last_update != mu->update_count) ||
|
||||||
|
!list_empty(&mu->active_sta)) {
|
||||||
|
|
||||||
|
rwnx_mu_group_move_head(&mu->active_sta, &sta->group_info.active);
|
||||||
|
|
||||||
|
if (!delayed_work_pending(&mu->group_work) &&
|
||||||
|
!list_is_singular(&mu->active_sta)) {
|
||||||
|
schedule_delayed_work(&mu->group_work,
|
||||||
|
msecs_to_jiffies(RWNX_MU_GROUP_INTERVAL));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* rwnx_mu_set_active_group - mark a MU group as active
|
||||||
|
*
|
||||||
|
* @rwnx_hw: main driver data
|
||||||
|
* @group_id: Group id
|
||||||
|
*
|
||||||
|
* move a group at the top of the @active_groups list
|
||||||
|
*/
|
||||||
|
void rwnx_mu_set_active_group(struct rwnx_hw *rwnx_hw, int group_id)
|
||||||
|
{
|
||||||
|
struct rwnx_mu_info *mu = &rwnx_hw->mu;
|
||||||
|
struct rwnx_mu_group *group = rwnx_mu_group_from_id(mu, group_id);
|
||||||
|
|
||||||
|
rwnx_mu_group_move_head(&mu->active_groups, &group->list);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* rwnx_mu_group_sta_select - Select the best group for MU stas
|
||||||
|
*
|
||||||
|
* @rwnx_hw: main driver data
|
||||||
|
*
|
||||||
|
* For each MU capable client of AP interfaces this function tries to select
|
||||||
|
* the best group to use.
|
||||||
|
*
|
||||||
|
* In first pass, gather information from all stations to form statistics
|
||||||
|
* for each group for the previous @RWNX_MU_GROUP_SELECT_INTERVAL interval:
|
||||||
|
* - number of buffers transmitted
|
||||||
|
* - number of user
|
||||||
|
*
|
||||||
|
* Then groups with more than 2 active users, are assigned after being ordered
|
||||||
|
* by traffic :
|
||||||
|
* - group with highest traffic is selected: set this group for all its users
|
||||||
|
* - update nb_users for all others group (as one sta may be in several groups)
|
||||||
|
* - select the next group that have still mor than 2 users and assign it.
|
||||||
|
* - continue until all group are processed
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void rwnx_mu_group_sta_select(struct rwnx_hw *rwnx_hw)
|
||||||
|
{
|
||||||
|
struct rwnx_mu_info *mu = &rwnx_hw->mu;
|
||||||
|
int nb_users[NX_MU_GROUP_MAX + 1];
|
||||||
|
int traffic[NX_MU_GROUP_MAX + 1];
|
||||||
|
int order[NX_MU_GROUP_MAX + 1];
|
||||||
|
struct rwnx_sta *sta;
|
||||||
|
struct rwnx_vif *vif;
|
||||||
|
struct list_head *head;
|
||||||
|
u64 map;
|
||||||
|
int i, j, update, group_id, tmp, cnt = 0;
|
||||||
|
|
||||||
|
if (!mu->group_cnt || time_before(jiffies, mu->next_group_select))
|
||||||
|
return;
|
||||||
|
|
||||||
|
list_for_each_entry(vif, &rwnx_hw->vifs, list) {
|
||||||
|
|
||||||
|
if (RWNX_VIF_TYPE(vif) != NL80211_IFTYPE_AP)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
#ifdef CONFIG_RWNX_FULLMAC
|
||||||
|
head = &vif->ap.sta_list;
|
||||||
|
#else
|
||||||
|
head = &vif->stations;
|
||||||
|
#endif /* CONFIG_RWNX_FULLMAC */
|
||||||
|
|
||||||
|
memset(nb_users, 0, sizeof(nb_users));
|
||||||
|
memset(traffic, 0, sizeof(traffic));
|
||||||
|
list_for_each_entry(sta, head, list) {
|
||||||
|
int sta_traffic = sta->group_info.traffic;
|
||||||
|
|
||||||
|
/* reset statistics for next selection */
|
||||||
|
sta->group_info.traffic = 0;
|
||||||
|
if (sta->group_info.group)
|
||||||
|
trace_mu_group_selection(sta, 0);
|
||||||
|
sta->group_info.group = 0;
|
||||||
|
|
||||||
|
if (sta->group_info.cnt == 0 ||
|
||||||
|
sta_traffic < RWNX_MU_GROUP_MIN_TRAFFIC)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
group_sta_for_each(sta, group_id, map) {
|
||||||
|
nb_users[group_id]++;
|
||||||
|
traffic[group_id] += sta_traffic;
|
||||||
|
|
||||||
|
/* list group with 2 users or more */
|
||||||
|
if (nb_users[group_id] == 2)
|
||||||
|
order[cnt++] = group_id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* reorder list of group with more that 2 users */
|
||||||
|
update = 1;
|
||||||
|
while(update) {
|
||||||
|
update = 0;
|
||||||
|
for (i = 0; i < cnt - 1; i++) {
|
||||||
|
if (traffic[order[i]] < traffic[order[i + 1]]) {
|
||||||
|
tmp = order[i];
|
||||||
|
order[i] = order[i + 1];
|
||||||
|
order[i + 1] = tmp;
|
||||||
|
update = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* now assign group in traffic order */
|
||||||
|
for (i = 0; i < cnt ; i ++) {
|
||||||
|
struct rwnx_mu_group *group;
|
||||||
|
group_id = order[i];
|
||||||
|
|
||||||
|
if (nb_users[group_id] < 2)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
group = rwnx_mu_group_from_id(mu, group_id);
|
||||||
|
for (j = 0; j < CONFIG_USER_MAX ; j++) {
|
||||||
|
if (group->users[j]) {
|
||||||
|
trace_mu_group_selection(group->users[j], group_id);
|
||||||
|
group->users[j]->group_info.group = group_id;
|
||||||
|
|
||||||
|
group_sta_for_each(group->users[j], tmp, map) {
|
||||||
|
if (group_id != tmp)
|
||||||
|
nb_users[tmp]--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mu->next_group_select = jiffies +
|
||||||
|
msecs_to_jiffies(RWNX_MU_GROUP_SELECT_INTERVAL);
|
||||||
|
mu->next_group_select |= 1;
|
||||||
|
}
|
||||||
179
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/rwnx_mu_group.h
Normal file
179
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/rwnx_mu_group.h
Normal file
|
|
@ -0,0 +1,179 @@
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
*
|
||||||
|
* @file rwnx_mu_group.h
|
||||||
|
*
|
||||||
|
* Copyright (C) RivieraWaves 2016-2019
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
#ifndef _RWNX_MU_GROUP_H_
|
||||||
|
#define _RWNX_MU_GROUP_H_
|
||||||
|
|
||||||
|
#include <linux/workqueue.h>
|
||||||
|
#include <linux/semaphore.h>
|
||||||
|
|
||||||
|
struct rwnx_hw;
|
||||||
|
struct rwnx_sta;
|
||||||
|
|
||||||
|
#ifdef CONFIG_RWNX_MUMIMO_TX
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct rwnx_sta_group_info - Group Information for a STA
|
||||||
|
*
|
||||||
|
* @active: node for @mu->active_sta list
|
||||||
|
* @update: node for @mu->update_sta list
|
||||||
|
* @cnt: Number of groups the STA belongs to
|
||||||
|
* @map: Bitfield of groups the sta belongs to
|
||||||
|
* @traffic: Number of buffers sent since previous group selection
|
||||||
|
* @group: Id of the group selected by previous group selection
|
||||||
|
* (cf @rwnx_mu_group_sta_select)
|
||||||
|
*/
|
||||||
|
struct rwnx_sta_group_info {
|
||||||
|
struct list_head active;
|
||||||
|
struct list_head update;
|
||||||
|
u16 last_update;
|
||||||
|
int cnt;
|
||||||
|
u64 map;
|
||||||
|
int traffic;
|
||||||
|
u8 group;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct mu_group_info - Information about the users of a group
|
||||||
|
*
|
||||||
|
* @list: node for mu->active_groups
|
||||||
|
* @group_id: Group identifier
|
||||||
|
* @user_cnt: Number of the users in the group
|
||||||
|
* @users: Pointer to the sta, ordered by user position
|
||||||
|
*/
|
||||||
|
struct rwnx_mu_group {
|
||||||
|
struct list_head list;
|
||||||
|
int group_id;
|
||||||
|
int user_cnt;
|
||||||
|
struct rwnx_sta *users[CONFIG_USER_MAX];
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct rwnx_mu_info - Information about all MU group
|
||||||
|
*
|
||||||
|
* @active_groups: List of all possible groups. Ordered from the most recently
|
||||||
|
* used one to the least one (and possibly never used)
|
||||||
|
* @active_sta: List of MU beamformee sta that have been active (since previous
|
||||||
|
* group update). Ordered from the most recently active.
|
||||||
|
* @update_sta: List of sta whose group information has changed and need to be
|
||||||
|
* updated at fw level
|
||||||
|
* @groups: Table of all groups
|
||||||
|
* @group_work: Work item used to schedule group update
|
||||||
|
* @update_count: Counter used to identify the last group formation update.
|
||||||
|
* (cf rwnx_sta_group_info.last_update)
|
||||||
|
* @lock: Lock taken during group update. If tx happens lock is taken, then tx
|
||||||
|
* will not used MU.
|
||||||
|
* @next_group_assign: Next time the group selection should be run
|
||||||
|
* (ref @rwnx_mu_group_sta_select)
|
||||||
|
* @group_cnt: Number of group created
|
||||||
|
*/
|
||||||
|
struct rwnx_mu_info {
|
||||||
|
struct list_head active_groups;
|
||||||
|
struct list_head active_sta;
|
||||||
|
struct list_head update_sta;
|
||||||
|
struct rwnx_mu_group groups[NX_MU_GROUP_MAX];
|
||||||
|
struct delayed_work group_work;
|
||||||
|
u16 update_count;
|
||||||
|
struct semaphore lock;
|
||||||
|
unsigned long next_group_select;
|
||||||
|
u8 group_cnt;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define RWNX_SU_GROUP BIT_ULL(0)
|
||||||
|
#define RWNX_MU_GROUP_MASK 0x7ffffffffffffffeULL
|
||||||
|
#define RWNX_MU_GROUP_INTERVAL 200 /* in ms */
|
||||||
|
#define RWNX_MU_GROUP_SELECT_INTERVAL 100 /* in ms */
|
||||||
|
// minimum traffic in a RWNX_MU_GROUP_SELECT_INTERVAL to consider the sta
|
||||||
|
#define RWNX_MU_GROUP_MIN_TRAFFIC 50 /* in number of packet */
|
||||||
|
|
||||||
|
|
||||||
|
#define RWNX_GET_FIRST_GROUP_ID(map) (fls64(map) - 1)
|
||||||
|
|
||||||
|
#define group_sta_for_each(sta, id, map) \
|
||||||
|
map = sta->group_info.map & RWNX_MU_GROUP_MASK; \
|
||||||
|
for (id = (fls64(map) - 1) ; id > 0 ; \
|
||||||
|
map &= ~(u64)BIT_ULL(id), id = (fls64(map) - 1))
|
||||||
|
|
||||||
|
#define group_for_each(id, map) \
|
||||||
|
for (id = (fls64(map) - 1) ; id > 0 ; \
|
||||||
|
map &= ~(u64)BIT_ULL(id), id = (fls64(map) - 1))
|
||||||
|
|
||||||
|
#define RWNX_MUMIMO_INFO_POS_ID(info) (((info) >> 6) & 0x3)
|
||||||
|
#define RWNX_MUMIMO_INFO_GROUP_ID(info) ((info) & 0x3f)
|
||||||
|
|
||||||
|
static inline
|
||||||
|
struct rwnx_mu_group *rwnx_mu_group_from_id(struct rwnx_mu_info *mu, int id)
|
||||||
|
{
|
||||||
|
if (id > NX_MU_GROUP_MAX)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
return &mu->groups[id - 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void rwnx_mu_group_sta_init(struct rwnx_sta *sta,
|
||||||
|
const struct ieee80211_vht_cap *vht_cap);
|
||||||
|
void rwnx_mu_group_sta_del(struct rwnx_hw *rwnx_hw, struct rwnx_sta *sta);
|
||||||
|
u64 rwnx_mu_group_sta_get_map(struct rwnx_sta *sta);
|
||||||
|
int rwnx_mu_group_sta_get_pos(struct rwnx_hw *rwnx_hw, struct rwnx_sta *sta,
|
||||||
|
int group_id);
|
||||||
|
|
||||||
|
void rwnx_mu_group_init(struct rwnx_hw *rwnx_hw);
|
||||||
|
|
||||||
|
void rwnx_mu_set_active_sta(struct rwnx_hw *rwnx_hw, struct rwnx_sta *sta,
|
||||||
|
int traffic);
|
||||||
|
void rwnx_mu_set_active_group(struct rwnx_hw *rwnx_hw, int group_id);
|
||||||
|
void rwnx_mu_group_sta_select(struct rwnx_hw *rwnx_hw);
|
||||||
|
|
||||||
|
|
||||||
|
#else /* ! CONFIG_RWNX_MUMIMO_TX */
|
||||||
|
|
||||||
|
static inline
|
||||||
|
void rwnx_mu_group_sta_init(struct rwnx_sta *sta,
|
||||||
|
const struct ieee80211_vht_cap *vht_cap)
|
||||||
|
{}
|
||||||
|
|
||||||
|
static inline
|
||||||
|
void rwnx_mu_group_sta_del(struct rwnx_hw *rwnx_hw, struct rwnx_sta *sta)
|
||||||
|
{}
|
||||||
|
|
||||||
|
static inline
|
||||||
|
u64 rwnx_mu_group_sta_get_map(struct rwnx_sta *sta)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline
|
||||||
|
int rwnx_mu_group_sta_get_pos(struct rwnx_hw *rwnx_hw, struct rwnx_sta *sta,
|
||||||
|
int group_id)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline
|
||||||
|
void rwnx_mu_group_init(struct rwnx_hw *rwnx_hw)
|
||||||
|
{}
|
||||||
|
|
||||||
|
static inline
|
||||||
|
void rwnx_mu_set_active_sta(struct rwnx_hw *rwnx_hw, struct rwnx_sta *sta,
|
||||||
|
int traffic)
|
||||||
|
{}
|
||||||
|
|
||||||
|
static inline
|
||||||
|
void rwnx_mu_set_active_group(struct rwnx_hw *rwnx_hw, int group_id)
|
||||||
|
{}
|
||||||
|
|
||||||
|
static inline
|
||||||
|
void rwnx_mu_group_sta_select(struct rwnx_hw *rwnx_hw)
|
||||||
|
{}
|
||||||
|
|
||||||
|
#endif /* CONFIG_RWNX_MUMIMO_TX */
|
||||||
|
|
||||||
|
#endif /* _RWNX_MU_GROUP_H_ */
|
||||||
|
|
||||||
94
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/rwnx_pci.c
Normal file
94
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/rwnx_pci.c
Normal file
|
|
@ -0,0 +1,94 @@
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
*
|
||||||
|
* @file rwnx_pci.c
|
||||||
|
*
|
||||||
|
* Copyright (C) RivieraWaves 2012-2019
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
#include <linux/pci.h>
|
||||||
|
#include <linux/module.h>
|
||||||
|
|
||||||
|
#include "rwnx_defs.h"
|
||||||
|
#include "rwnx_dini.h"
|
||||||
|
#include "rwnx_v7.h"
|
||||||
|
|
||||||
|
#define PCI_VENDOR_ID_DINIGROUP 0x17DF
|
||||||
|
#define PCI_DEVICE_ID_DINIGROUP_DNV6_F2PCIE 0x1907
|
||||||
|
|
||||||
|
#define PCI_DEVICE_ID_XILINX_CEVA_VIRTEX7 0x7011
|
||||||
|
|
||||||
|
static const struct pci_device_id rwnx_pci_ids[] = {
|
||||||
|
{PCI_DEVICE(PCI_VENDOR_ID_DINIGROUP, PCI_DEVICE_ID_DINIGROUP_DNV6_F2PCIE)},
|
||||||
|
{PCI_DEVICE(PCI_VENDOR_ID_XILINX, PCI_DEVICE_ID_XILINX_CEVA_VIRTEX7)},
|
||||||
|
{0,}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/* Uncomment this for depmod to create module alias */
|
||||||
|
/* We don't want this on development platform */
|
||||||
|
//MODULE_DEVICE_TABLE(pci, rwnx_pci_ids);
|
||||||
|
|
||||||
|
static int rwnx_pci_probe(struct pci_dev *pci_dev,
|
||||||
|
const struct pci_device_id *pci_id)
|
||||||
|
{
|
||||||
|
struct rwnx_plat *rwnx_plat = NULL;
|
||||||
|
void *drvdata;
|
||||||
|
int ret = -ENODEV;
|
||||||
|
|
||||||
|
RWNX_DBG(RWNX_FN_ENTRY_STR);
|
||||||
|
|
||||||
|
if (pci_id->vendor == PCI_VENDOR_ID_DINIGROUP) {
|
||||||
|
ret = rwnx_dini_platform_init(pci_dev, &rwnx_plat);
|
||||||
|
} else if (pci_id->vendor == PCI_VENDOR_ID_XILINX) {
|
||||||
|
ret = rwnx_v7_platform_init(pci_dev, &rwnx_plat);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
rwnx_plat->pci_dev = pci_dev;
|
||||||
|
|
||||||
|
ret = rwnx_platform_init(rwnx_plat, &drvdata);
|
||||||
|
pci_set_drvdata(pci_dev, drvdata);
|
||||||
|
|
||||||
|
if (ret)
|
||||||
|
rwnx_plat->deinit(rwnx_plat);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rwnx_pci_remove(struct pci_dev *pci_dev)
|
||||||
|
{
|
||||||
|
struct rwnx_hw *rwnx_hw;
|
||||||
|
struct rwnx_plat *rwnx_plat;
|
||||||
|
|
||||||
|
RWNX_DBG(RWNX_FN_ENTRY_STR);
|
||||||
|
|
||||||
|
rwnx_hw = pci_get_drvdata(pci_dev);
|
||||||
|
rwnx_plat = rwnx_hw->plat;
|
||||||
|
|
||||||
|
rwnx_platform_deinit(rwnx_hw);
|
||||||
|
rwnx_plat->deinit(rwnx_plat);
|
||||||
|
|
||||||
|
pci_set_drvdata(pci_dev, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct pci_driver rwnx_pci_drv = {
|
||||||
|
.name = KBUILD_MODNAME,
|
||||||
|
.id_table = rwnx_pci_ids,
|
||||||
|
.probe = rwnx_pci_probe,
|
||||||
|
.remove = rwnx_pci_remove
|
||||||
|
};
|
||||||
|
|
||||||
|
int rwnx_pci_register_drv(void)
|
||||||
|
{
|
||||||
|
return pci_register_driver(&rwnx_pci_drv);
|
||||||
|
}
|
||||||
|
|
||||||
|
void rwnx_pci_unregister_drv(void)
|
||||||
|
{
|
||||||
|
pci_unregister_driver(&rwnx_pci_drv);
|
||||||
|
}
|
||||||
|
|
||||||
17
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/rwnx_pci.h
Normal file
17
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/rwnx_pci.h
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
*
|
||||||
|
* @file rwnx_pci.h
|
||||||
|
*
|
||||||
|
* Copyright (C) RivieraWaves 2012-2019
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _RWNX_PCI_H_
|
||||||
|
#define _RWNX_PCI_H_
|
||||||
|
|
||||||
|
int rwnx_pci_register_drv(void);
|
||||||
|
void rwnx_pci_unregister_drv(void);
|
||||||
|
|
||||||
|
#endif /* _RWNX_PCI_H_ */
|
||||||
3723
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/rwnx_platform.c
Normal file
3723
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/rwnx_platform.c
Normal file
File diff suppressed because it is too large
Load diff
186
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/rwnx_platform.h
Normal file
186
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/rwnx_platform.h
Normal file
|
|
@ -0,0 +1,186 @@
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
*
|
||||||
|
* @file rwnx_platorm.h
|
||||||
|
*
|
||||||
|
* Copyright (C) RivieraWaves 2012-2019
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _RWNX_PLATFORM_H_
|
||||||
|
#define _RWNX_PLATFORM_H_
|
||||||
|
|
||||||
|
#include <linux/pci.h>
|
||||||
|
#include "lmac_msg.h"
|
||||||
|
|
||||||
|
|
||||||
|
#define RWNX_CONFIG_FW_NAME "rwnx_settings.ini"
|
||||||
|
#define RWNX_PHY_CONFIG_TRD_NAME "rwnx_trident.ini"
|
||||||
|
#define RWNX_PHY_CONFIG_KARST_NAME "rwnx_karst.ini"
|
||||||
|
#define RWNX_AGC_FW_NAME "agcram.bin"
|
||||||
|
#define RWNX_LDPC_RAM_NAME "ldpcram.bin"
|
||||||
|
#ifdef CONFIG_RWNX_FULLMAC
|
||||||
|
#define RWNX_MAC_FW_BASE_NAME "fmacfw"
|
||||||
|
#elif defined CONFIG_RWNX_FHOST
|
||||||
|
#define RWNX_MAC_FW_BASE_NAME "fhostfw"
|
||||||
|
#endif /* CONFIG_RWNX_FULLMAC */
|
||||||
|
|
||||||
|
#ifdef CONFIG_RWNX_TL4
|
||||||
|
#define RWNX_MAC_FW_NAME RWNX_MAC_FW_BASE_NAME".hex"
|
||||||
|
#else
|
||||||
|
#define RWNX_MAC_FW_NAME RWNX_MAC_FW_BASE_NAME".ihex"
|
||||||
|
#define RWNX_MAC_FW_NAME2 RWNX_MAC_FW_BASE_NAME".bin"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define RWNX_FCU_FW_NAME "fcuram.bin"
|
||||||
|
#if (defined(CONFIG_DPD) && !defined(CONFIG_FORCE_DPD_CALIB))
|
||||||
|
#define FW_DPDRESULT_NAME_8800DC "aic_dpdresult_lite_8800dc.bin"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define POWER_LEVEL_INVALID_VAL (127)
|
||||||
|
|
||||||
|
enum {
|
||||||
|
FW_NORMAL_MODE = 0,
|
||||||
|
FW_RFTEST_MODE = 1,
|
||||||
|
FW_BLE_SCAN_WAKEUP_MODE = 2,
|
||||||
|
FW_M2D_OTA_MODE = 3,
|
||||||
|
FW_DPDCALIB_MODE = 4,
|
||||||
|
FW_BLE_SCAN_AD_FILTER_MODE = 5,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Type of memory to access (cf rwnx_plat.get_address)
|
||||||
|
*
|
||||||
|
* @RWNX_ADDR_CPU To access memory of the embedded CPU
|
||||||
|
* @RWNX_ADDR_SYSTEM To access memory/registers of one subsystem of the
|
||||||
|
* embedded system
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
enum rwnx_platform_addr {
|
||||||
|
RWNX_ADDR_CPU,
|
||||||
|
RWNX_ADDR_SYSTEM,
|
||||||
|
RWNX_ADDR_MAX,
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
txpwr_lvl_conf_t txpwr_lvl;
|
||||||
|
txpwr_lvl_conf_v2_t txpwr_lvl_v2;
|
||||||
|
txpwr_lvl_conf_v3_t txpwr_lvl_v3;
|
||||||
|
txpwr_lvl_conf_v4_t txpwr_lvl_v4;
|
||||||
|
txpwr_lvl_adj_conf_t txpwr_lvl_adj;
|
||||||
|
txpwr_loss_conf_t txpwr_loss;
|
||||||
|
txpwr_ofst_conf_t txpwr_ofst;
|
||||||
|
txpwr_ofst2x_conf_t txpwr_ofst2x;
|
||||||
|
txpwr_ofst2x_conf_v2_t txpwr_ofst2x_v2;
|
||||||
|
xtal_cap_conf_t xtal_cap;
|
||||||
|
} userconfig_info_t;
|
||||||
|
|
||||||
|
extern userconfig_info_t userconfig_info;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
REGIONS_SRRC,
|
||||||
|
REGIONS_FCC,
|
||||||
|
REGIONS_ETSI,
|
||||||
|
REGIONS_JP,
|
||||||
|
REGIONS_DEFAULT,
|
||||||
|
} Regions_code;
|
||||||
|
|
||||||
|
|
||||||
|
struct rwnx_hw;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct rwnx_plat - Operation pointers for RWNX PCI platform
|
||||||
|
*
|
||||||
|
* @pci_dev: pointer to pci dev
|
||||||
|
* @enabled: Set if embedded platform has been enabled (i.e. fw loaded and
|
||||||
|
* ipc started)
|
||||||
|
* @enable: Configure communication with the fw (i.e. configure the transfers
|
||||||
|
* enable and register interrupt)
|
||||||
|
* @disable: Stop communication with the fw
|
||||||
|
* @deinit: Free all ressources allocated for the embedded platform
|
||||||
|
* @get_address: Return the virtual address to access the requested address on
|
||||||
|
* the platform.
|
||||||
|
* @ack_irq: Acknowledge the irq at link level.
|
||||||
|
* @get_config_reg: Return the list (size + pointer) of registers to restore in
|
||||||
|
* order to reload the platform while keeping the current configuration.
|
||||||
|
*
|
||||||
|
* @priv Private data for the link driver
|
||||||
|
*/
|
||||||
|
struct rwnx_plat {
|
||||||
|
struct pci_dev *pci_dev;
|
||||||
|
|
||||||
|
#ifdef AICWF_SDIO_SUPPORT
|
||||||
|
struct aic_sdio_dev *sdiodev;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef AICWF_USB_SUPPORT
|
||||||
|
struct aic_usb_dev *usbdev;
|
||||||
|
#endif
|
||||||
|
bool enabled;
|
||||||
|
bool wait_disconnect_cb;
|
||||||
|
|
||||||
|
int (*enable)(struct rwnx_hw *rwnx_hw);
|
||||||
|
int (*disable)(struct rwnx_hw *rwnx_hw);
|
||||||
|
void (*deinit)(struct rwnx_plat *rwnx_plat);
|
||||||
|
u8* (*get_address)(struct rwnx_plat *rwnx_plat, int addr_name,
|
||||||
|
unsigned int offset);
|
||||||
|
void (*ack_irq)(struct rwnx_plat *rwnx_plat);
|
||||||
|
int (*get_config_reg)(struct rwnx_plat *rwnx_plat, const u32 **list);
|
||||||
|
|
||||||
|
u8 priv[0] __aligned(sizeof(void *));
|
||||||
|
};
|
||||||
|
|
||||||
|
#define RWNX_ADDR(plat, base, offset) \
|
||||||
|
plat->get_address(plat, base, offset)
|
||||||
|
|
||||||
|
#define RWNX_REG_READ(plat, base, offset) \
|
||||||
|
readl(plat->get_address(plat, base, offset))
|
||||||
|
|
||||||
|
#define RWNX_REG_WRITE(val, plat, base, offset) \
|
||||||
|
writel(val, plat->get_address(plat, base, offset))
|
||||||
|
|
||||||
|
extern struct rwnx_plat *g_rwnx_plat;
|
||||||
|
|
||||||
|
int rwnx_platform_init(struct rwnx_plat *rwnx_plat, void **platform_data);
|
||||||
|
void rwnx_platform_deinit(struct rwnx_hw *rwnx_hw);
|
||||||
|
|
||||||
|
int rwnx_platform_on(struct rwnx_hw *rwnx_hw, void *config);
|
||||||
|
void rwnx_platform_off(struct rwnx_hw *rwnx_hw, void **config);
|
||||||
|
|
||||||
|
int is_file_exist(char* name);
|
||||||
|
void get_userconfig_txpwr_lvl_in_fdrv(txpwr_lvl_conf_t *txpwr_lvl);
|
||||||
|
void get_userconfig_txpwr_lvl_v2_in_fdrv(txpwr_lvl_conf_v2_t *txpwr_lvl_v2);
|
||||||
|
void get_userconfig_txpwr_lvl_v3_in_fdrv(txpwr_lvl_conf_v3_t *txpwr_lvl_v3);
|
||||||
|
void get_userconfig_txpwr_lvl_v4_in_fdrv(txpwr_lvl_conf_v4_t *txpwr_lvl_v4);
|
||||||
|
void get_userconfig_txpwr_lvl_adj_in_fdrv(txpwr_lvl_adj_conf_t *txpwr_lvl_adj);
|
||||||
|
void get_userconfig_txpwr_ofst_in_fdrv(txpwr_ofst_conf_t *txpwr_ofst);
|
||||||
|
void get_userconfig_txpwr_ofst2x_in_fdrv(txpwr_ofst2x_conf_t *txpwr_ofst2x);
|
||||||
|
void get_userconfig_txpwr_ofst2x_v2_in_fdrv(txpwr_ofst2x_conf_v2_t *txpwr_ofst2x_v2);
|
||||||
|
void get_userconfig_txpwr_loss(txpwr_loss_conf_t *txpwr_loss);
|
||||||
|
void set_txpwr_loss_ofst(s8_l value);
|
||||||
|
void rwnx_plat_userconfig_parsing(char *buffer, int size);
|
||||||
|
|
||||||
|
uint8_t get_ccode_region(char * ccode);
|
||||||
|
u8 get_region_index(char * name);
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef CONFIG_POWER_LIMIT
|
||||||
|
int8_t rwnx_plat_powerlimit_save(u8_l band, char *channel, u8_l bw, char *limit, char *name);
|
||||||
|
void rwnx_plat_powerlimit_parsing(char *buffer, int size, char *cc);
|
||||||
|
int8_t get_powerlimit_by_freq(uint8_t band, uint16_t freq, uint8_t r_idx);
|
||||||
|
int8_t get_powerlimit_by_chnum(uint8_t chnum, uint8_t r_idx, uint8_t bw);
|
||||||
|
#endif
|
||||||
|
int rwnx_platform_register_drv(void);
|
||||||
|
void rwnx_platform_unregister_drv(void);
|
||||||
|
|
||||||
|
extern struct device *rwnx_platform_get_dev(struct rwnx_plat *rwnx_plat);
|
||||||
|
|
||||||
|
static inline unsigned int rwnx_platform_get_irq(struct rwnx_plat *rwnx_plat)
|
||||||
|
{
|
||||||
|
return rwnx_plat->pci_dev->irq;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* _RWNX_PLATFORM_H_ */
|
||||||
133
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/rwnx_prof.h
Normal file
133
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/rwnx_prof.h
Normal file
|
|
@ -0,0 +1,133 @@
|
||||||
|
/**
|
||||||
|
****************************************************************************************
|
||||||
|
*
|
||||||
|
* @file rwnx_prof.h
|
||||||
|
*
|
||||||
|
* Copyright (C) RivieraWaves 2012-2019
|
||||||
|
*
|
||||||
|
****************************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _RWNX_PROF_H_
|
||||||
|
#define _RWNX_PROF_H_
|
||||||
|
|
||||||
|
#include "reg_access.h"
|
||||||
|
#include "rwnx_platform.h"
|
||||||
|
|
||||||
|
static inline void rwnx_prof_set(struct rwnx_hw *rwnx_hw, int val)
|
||||||
|
{
|
||||||
|
struct rwnx_plat *rwnx_plat = rwnx_hw->plat;
|
||||||
|
RWNX_REG_WRITE(val, rwnx_plat, RWNX_ADDR_SYSTEM, NXMAC_SW_SET_PROFILING_ADDR);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void rwnx_prof_clear(struct rwnx_hw *rwnx_hw, int val)
|
||||||
|
{
|
||||||
|
struct rwnx_plat *rwnx_plat = rwnx_hw->plat;
|
||||||
|
RWNX_REG_WRITE(val, rwnx_plat, RWNX_ADDR_SYSTEM, NXMAC_SW_CLEAR_PROFILING_ADDR);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
/* Defines for SW Profiling registers values */
|
||||||
|
enum {
|
||||||
|
TX_IPC_IRQ,
|
||||||
|
TX_IPC_EVT,
|
||||||
|
TX_PREP_EVT,
|
||||||
|
TX_DMA_IRQ,
|
||||||
|
TX_MAC_IRQ,
|
||||||
|
TX_PAYL_HDL,
|
||||||
|
TX_CFM_EVT,
|
||||||
|
TX_IPC_CFM,
|
||||||
|
RX_MAC_IRQ, // 8
|
||||||
|
RX_TRIGGER_EVT,
|
||||||
|
RX_DMA_IRQ,
|
||||||
|
RX_DMA_EVT,
|
||||||
|
RX_IPC_IND,
|
||||||
|
RX_MPDU_XFER,
|
||||||
|
DBG_PROF_MAX
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
enum {
|
||||||
|
SW_PROF_HOSTBUF_IDX = 12,
|
||||||
|
/****** IPC IRQs related signals ******/
|
||||||
|
/* E2A direction */
|
||||||
|
SW_PROF_IRQ_E2A_RXDESC = 16, // to make sure we let 16 bits available for LMAC FW
|
||||||
|
SW_PROF_IRQ_E2A_TXCFM,
|
||||||
|
SW_PROF_IRQ_E2A_DBG,
|
||||||
|
SW_PROF_IRQ_E2A_MSG,
|
||||||
|
SW_PROF_IPC_MSGPUSH,
|
||||||
|
SW_PROF_MSGALLOC,
|
||||||
|
SW_PROF_MSGIND,
|
||||||
|
SW_PROF_DBGIND,
|
||||||
|
|
||||||
|
/* A2E direction */
|
||||||
|
SW_PROF_IRQ_A2E_TXCFM_BACK,
|
||||||
|
|
||||||
|
/****** Driver functions related signals ******/
|
||||||
|
SW_PROF_WAIT_QUEUE_STOP,
|
||||||
|
SW_PROF_WAIT_QUEUE_WAKEUP,
|
||||||
|
SW_PROF_RWNXDATAIND,
|
||||||
|
SW_PROF_RWNX_IPC_IRQ_HDLR,
|
||||||
|
SW_PROF_RWNX_IPC_THR_IRQ_HDLR,
|
||||||
|
SW_PROF_IEEE80211RX,
|
||||||
|
SW_PROF_RWNX_PATTERN,
|
||||||
|
SW_PROF_MAX
|
||||||
|
};
|
||||||
|
|
||||||
|
// [LT]For debug purpose only
|
||||||
|
#if (0)
|
||||||
|
#define SW_PROF_CHAN_CTXT_CFM_HDL_BIT (21)
|
||||||
|
#define SW_PROF_CHAN_CTXT_CFM_BIT (22)
|
||||||
|
#define SW_PROF_CHAN_CTXT_CFM_SWDONE_BIT (23)
|
||||||
|
#define SW_PROF_CHAN_CTXT_PUSH_BIT (24)
|
||||||
|
#define SW_PROF_CHAN_CTXT_QUEUE_BIT (25)
|
||||||
|
#define SW_PROF_CHAN_CTXT_TX_BIT (26)
|
||||||
|
#define SW_PROF_CHAN_CTXT_TX_PAUSE_BIT (27)
|
||||||
|
#define SW_PROF_CHAN_CTXT_PSWTCH_BIT (28)
|
||||||
|
#define SW_PROF_CHAN_CTXT_SWTCH_BIT (29)
|
||||||
|
|
||||||
|
// TO DO: update this
|
||||||
|
|
||||||
|
#define REG_SW_SET_PROFILING_CHAN(env, bit) \
|
||||||
|
rwnx_prof_set((struct rwnx_hw*)env, BIT(bit))
|
||||||
|
|
||||||
|
#define REG_SW_CLEAR_PROFILING_CHAN(env, bit) \
|
||||||
|
rwnx_prof_clear((struct rwnx_hw*)env, BIT(bit))
|
||||||
|
|
||||||
|
#else
|
||||||
|
#define SW_PROF_CHAN_CTXT_CFM_HDL_BIT (0)
|
||||||
|
#define SW_PROF_CHAN_CTXT_CFM_BIT (0)
|
||||||
|
#define SW_PROF_CHAN_CTXT_CFM_SWDONE_BIT (0)
|
||||||
|
#define SW_PROF_CHAN_CTXT_PUSH_BIT (0)
|
||||||
|
#define SW_PROF_CHAN_CTXT_QUEUE_BIT (0)
|
||||||
|
#define SW_PROF_CHAN_CTXT_TX_BIT (0)
|
||||||
|
#define SW_PROF_CHAN_CTXT_TX_PAUSE_BIT (0)
|
||||||
|
#define SW_PROF_CHAN_CTXT_PSWTCH_BIT (0)
|
||||||
|
#define SW_PROF_CHAN_CTXT_SWTCH_BIT (0)
|
||||||
|
|
||||||
|
#define REG_SW_SET_PROFILING_CHAN(env, bit) do {} while (0)
|
||||||
|
#define REG_SW_CLEAR_PROFILING_CHAN(env, bit) do {} while (0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_RWNX_SW_PROFILING
|
||||||
|
/* Macros for SW PRofiling registers access */
|
||||||
|
#define REG_SW_SET_PROFILING(env, bit) \
|
||||||
|
rwnx_prof_set((struct rwnx_hw*)env, BIT(bit))
|
||||||
|
|
||||||
|
#define REG_SW_SET_HOSTBUF_IDX_PROFILING(env, val) \
|
||||||
|
rwnx_prof_set((struct rwnx_hw*)env, val<<(SW_PROF_HOSTBUF_IDX))
|
||||||
|
|
||||||
|
#define REG_SW_CLEAR_PROFILING(env, bit) \
|
||||||
|
rwnx_prof_clear((struct rwnx_hw*)env, BIT(bit))
|
||||||
|
|
||||||
|
#define REG_SW_CLEAR_HOSTBUF_IDX_PROFILING(env) \
|
||||||
|
rwnx_prof_clear((struct rwnx_hw*)env,0x0F<<(SW_PROF_HOSTBUF_IDX))
|
||||||
|
|
||||||
|
#else
|
||||||
|
#define REG_SW_SET_PROFILING(env, value) do {} while (0)
|
||||||
|
#define REG_SW_CLEAR_PROFILING(env, value) do {} while (0)
|
||||||
|
#define REG_SW_SET_HOSTBUF_IDX_PROFILING(env, val) do {} while (0)
|
||||||
|
#define REG_SW_CLEAR_HOSTBUF_IDX_PROFILING(env) do {} while (0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* _RWNX_PROF_H_ */
|
||||||
1793
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/rwnx_radar.c
Normal file
1793
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/rwnx_radar.c
Normal file
File diff suppressed because it is too large
Load diff
186
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/rwnx_radar.h
Normal file
186
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/rwnx_radar.h
Normal file
|
|
@ -0,0 +1,186 @@
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
*
|
||||||
|
* @file rwnx_radar.h
|
||||||
|
*
|
||||||
|
* @brief Functions to handle radar detection
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Copyright (C) RivieraWaves 2012-2019
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
#ifndef _RWNX_RADAR_H_
|
||||||
|
#define _RWNX_RADAR_H_
|
||||||
|
|
||||||
|
#include <linux/nl80211.h>
|
||||||
|
|
||||||
|
struct rwnx_vif;
|
||||||
|
struct rwnx_hw;
|
||||||
|
|
||||||
|
enum rwnx_radar_chain {
|
||||||
|
RWNX_RADAR_RIU = 0,
|
||||||
|
RWNX_RADAR_FCU,
|
||||||
|
RWNX_RADAR_LAST
|
||||||
|
};
|
||||||
|
|
||||||
|
enum rwnx_radar_detector {
|
||||||
|
RWNX_RADAR_DETECT_DISABLE = 0, /* Ignore radar pulses */
|
||||||
|
RWNX_RADAR_DETECT_ENABLE = 1, /* Process pattern detection but do not
|
||||||
|
report radar to upper layer (for test) */
|
||||||
|
RWNX_RADAR_DETECT_REPORT = 2 /* Process pattern detection and report
|
||||||
|
radar to upper layer. */
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef CONFIG_RWNX_RADAR
|
||||||
|
#include <linux/workqueue.h>
|
||||||
|
#include <linux/spinlock.h>
|
||||||
|
|
||||||
|
#define RWNX_RADAR_PULSE_MAX 32
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct rwnx_radar_pulses - List of pulses reported by HW
|
||||||
|
* @index: write index
|
||||||
|
* @count: number of valid pulses
|
||||||
|
* @buffer: buffer of pulses
|
||||||
|
*/
|
||||||
|
struct rwnx_radar_pulses {
|
||||||
|
/* Last radar pulses received */
|
||||||
|
int index;
|
||||||
|
int count;
|
||||||
|
u32 buffer[RWNX_RADAR_PULSE_MAX];
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct dfs_pattern_detector - DFS pattern detector
|
||||||
|
* @region: active DFS region, NL80211_DFS_UNSET until set
|
||||||
|
* @num_radar_types: number of different radar types
|
||||||
|
* @last_pulse_ts: time stamp of last valid pulse in usecs
|
||||||
|
* @prev_jiffies:
|
||||||
|
* @radar_detector_specs: array of radar detection specs
|
||||||
|
* @channel_detectors: list connecting channel_detector elements
|
||||||
|
*/
|
||||||
|
struct dfs_pattern_detector {
|
||||||
|
u8 enabled;
|
||||||
|
enum nl80211_dfs_regions region;
|
||||||
|
u8 num_radar_types;
|
||||||
|
u64 last_pulse_ts;
|
||||||
|
u32 prev_jiffies;
|
||||||
|
const struct radar_detector_specs *radar_spec;
|
||||||
|
struct list_head detectors[];
|
||||||
|
};
|
||||||
|
|
||||||
|
#define NX_NB_RADAR_DETECTED 4
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct rwnx_radar_detected - List of radar detected
|
||||||
|
*/
|
||||||
|
struct rwnx_radar_detected {
|
||||||
|
u16 index;
|
||||||
|
u16 count;
|
||||||
|
s64 time[NX_NB_RADAR_DETECTED];
|
||||||
|
s16 freq[NX_NB_RADAR_DETECTED];
|
||||||
|
};
|
||||||
|
|
||||||
|
#define RWNX_RADAR_DUMP_EN 1
|
||||||
|
#ifdef RWNX_RADAR_DUMP_EN
|
||||||
|
#define RWNX_RADARR_DUMP_NB 32
|
||||||
|
struct rwnx_radar_dump {
|
||||||
|
u32 cnt;
|
||||||
|
u32 idx;
|
||||||
|
u32 ps[RWNX_RADARR_DUMP_NB];
|
||||||
|
u64 tm[RWNX_RADARR_DUMP_NB];
|
||||||
|
u64 ts[RWNX_RADARR_DUMP_NB];
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
enum rwnx_radar_status {
|
||||||
|
RWNX_RADAR_IDLE = 0,
|
||||||
|
RWNX_RADAR_CAC_BUSY = 1,
|
||||||
|
RWNX_RADAR_CAC_DONE = 2,
|
||||||
|
RWNX_RADAR_INSERVICE_BUSY = 3,
|
||||||
|
RWNX_RADAR_INSERVICE_DONE = 4
|
||||||
|
};
|
||||||
|
struct rwnx_radar {
|
||||||
|
struct rwnx_radar_pulses pulses[RWNX_RADAR_LAST];
|
||||||
|
struct dfs_pattern_detector *dpd[RWNX_RADAR_LAST];
|
||||||
|
struct rwnx_radar_detected detected[RWNX_RADAR_LAST];
|
||||||
|
#ifdef RWNX_RADAR_DUMP_EN
|
||||||
|
struct rwnx_radar_dump *rmem;
|
||||||
|
#endif
|
||||||
|
u16 status;
|
||||||
|
u16 sta_num;
|
||||||
|
struct work_struct detection_work; /* Work used to process radar pulses */
|
||||||
|
spinlock_t lock; /* lock for pulses processing */
|
||||||
|
|
||||||
|
/* In softmac cac is handled by mac80211 */
|
||||||
|
#ifdef CONFIG_RWNX_FULLMAC
|
||||||
|
struct delayed_work cac_work; /* Work used to handle CAC */
|
||||||
|
struct rwnx_vif *cac_vif; /* vif on which we started CAC */
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
void rwnx_radar_reset_rmem(struct rwnx_radar *radar);
|
||||||
|
void rwnx_radar_init_rmem(struct rwnx_radar *radar);
|
||||||
|
void rwnx_radar_deinit_rmem(struct rwnx_radar *radar);
|
||||||
|
|
||||||
|
bool rwnx_radar_detection_init(struct rwnx_radar *radar);
|
||||||
|
void rwnx_radar_detection_deinit(struct rwnx_radar *radar);
|
||||||
|
bool rwnx_radar_set_domain(struct rwnx_radar *radar,
|
||||||
|
enum nl80211_dfs_regions region);
|
||||||
|
void rwnx_radar_detection_enable(struct rwnx_radar *radar, u8 enable, u8 chain);
|
||||||
|
bool rwnx_radar_detection_is_enable(struct rwnx_radar *radar, u8 chain);
|
||||||
|
void rwnx_radar_start_cac(struct rwnx_radar *radar, u32 cac_time_ms,
|
||||||
|
struct rwnx_vif *vif);
|
||||||
|
void rwnx_radar_cancel_cac(struct rwnx_radar *radar);
|
||||||
|
void rwnx_radar_detection_enable_on_cur_channel(struct rwnx_hw *rwnx_hw);
|
||||||
|
int rwnx_radar_dump_pattern_detector(char *buf, size_t len,
|
||||||
|
struct rwnx_radar *radar, u8 chain);
|
||||||
|
int rwnx_radar_dump_radar_detected(char *buf, size_t len,
|
||||||
|
struct rwnx_radar *radar, u8 chain);
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
struct rwnx_radar {
|
||||||
|
};
|
||||||
|
|
||||||
|
static inline bool rwnx_radar_detection_init(struct rwnx_radar *radar)
|
||||||
|
{return true;}
|
||||||
|
|
||||||
|
static inline void rwnx_radar_detection_deinit(struct rwnx_radar *radar)
|
||||||
|
{}
|
||||||
|
|
||||||
|
static inline bool rwnx_radar_set_domain(struct rwnx_radar *radar,
|
||||||
|
enum nl80211_dfs_regions region)
|
||||||
|
{return true;}
|
||||||
|
|
||||||
|
static inline void rwnx_radar_detection_enable(struct rwnx_radar *radar,
|
||||||
|
u8 enable, u8 chain)
|
||||||
|
{}
|
||||||
|
|
||||||
|
static inline bool rwnx_radar_detection_is_enable(struct rwnx_radar *radar,
|
||||||
|
u8 chain)
|
||||||
|
{return false;}
|
||||||
|
|
||||||
|
static inline void rwnx_radar_start_cac(struct rwnx_radar *radar,
|
||||||
|
u32 cac_time_ms, struct rwnx_vif *vif)
|
||||||
|
{}
|
||||||
|
|
||||||
|
static inline void rwnx_radar_cancel_cac(struct rwnx_radar *radar)
|
||||||
|
{}
|
||||||
|
|
||||||
|
static inline void rwnx_radar_detection_enable_on_cur_channel(struct rwnx_hw *rwnx_hw)
|
||||||
|
{}
|
||||||
|
|
||||||
|
static inline int rwnx_radar_dump_pattern_detector(char *buf, size_t len,
|
||||||
|
struct rwnx_radar *radar,
|
||||||
|
u8 chain)
|
||||||
|
{return 0;}
|
||||||
|
|
||||||
|
static inline int rwnx_radar_dump_radar_detected(char *buf, size_t len,
|
||||||
|
struct rwnx_radar *radar,
|
||||||
|
u8 chain)
|
||||||
|
{return 0;}
|
||||||
|
|
||||||
|
#endif /* CONFIG_RWNX_RADAR */
|
||||||
|
|
||||||
|
#endif // _RWNX_RADAR_H_
|
||||||
2794
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/rwnx_rx.c
Executable file
2794
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/rwnx_rx.c
Executable file
File diff suppressed because it is too large
Load diff
408
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/rwnx_rx.h
Normal file
408
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/rwnx_rx.h
Normal file
|
|
@ -0,0 +1,408 @@
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
*
|
||||||
|
* @file rwnx_rx.h
|
||||||
|
*
|
||||||
|
* Copyright (C) RivieraWaves 2012-2019
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
#ifndef _RWNX_RX_H_
|
||||||
|
#define _RWNX_RX_H_
|
||||||
|
|
||||||
|
#include "aicwf_txrxif.h"
|
||||||
|
|
||||||
|
#define SERVER_PORT 67
|
||||||
|
#define CLIENT_PORT 68
|
||||||
|
#define DHCP_MAGIC 0x63825363
|
||||||
|
#define DHCP_ACK 5
|
||||||
|
#define DHCP_OPTION_MESSAGE_TYPE 53 /* RFC 2132 9.6, important for DHCP */
|
||||||
|
#define DHCP_OPTION_END 255
|
||||||
|
|
||||||
|
enum rx_status_bits
|
||||||
|
{
|
||||||
|
/// The buffer can be forwarded to the networking stack
|
||||||
|
RX_STAT_FORWARD = 1 << 0,
|
||||||
|
/// A new buffer has to be allocated
|
||||||
|
RX_STAT_ALLOC = 1 << 1,
|
||||||
|
/// The buffer has to be deleted
|
||||||
|
RX_STAT_DELETE = 1 << 2,
|
||||||
|
/// The length of the buffer has to be updated
|
||||||
|
RX_STAT_LEN_UPDATE = 1 << 3,
|
||||||
|
/// The length in the Ethernet header has to be updated
|
||||||
|
RX_STAT_ETH_LEN_UPDATE = 1 << 4,
|
||||||
|
/// Simple copy
|
||||||
|
RX_STAT_COPY = 1 << 5,
|
||||||
|
/// Spurious frame (inform upper layer and discard)
|
||||||
|
RX_STAT_SPURIOUS = 1 << 6,
|
||||||
|
/// packet for monitor interface
|
||||||
|
RX_STAT_MONITOR = 1 << 7,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Decryption status subfields.
|
||||||
|
* {
|
||||||
|
*/
|
||||||
|
#define RWNX_RX_HD_DECR_UNENC 0 // ENCRYPTION TYPE NONE
|
||||||
|
#define RWNX_RX_HD_DECR_WEP 1 // ENCRYPTION TYPE WEP
|
||||||
|
#define RWNX_RX_HD_DECR_TKIP 2 // ENCRYPTION TYPE TKIP
|
||||||
|
#define RWNX_RX_HD_DECR_CCMP128 3 // ENCRYPTION TYPE CCMP128
|
||||||
|
#define RWNX_RX_HD_DECR_CCMP256 4 // ENCRYPTION TYPE CCMP256
|
||||||
|
#define RWNX_RX_HD_DECR_GCMP128 5 // ENCRYPTION TYPE GCMP128
|
||||||
|
#define RWNX_RX_HD_DECR_GCMP256 6 // ENCRYPTION TYPE GCMP256
|
||||||
|
#define RWNX_RX_HD_DECR_WAPI 7 // ENCRYPTION TYPE WAPI
|
||||||
|
// @}
|
||||||
|
|
||||||
|
//#ifdef CONFIG_RWNX_MON_DATA
|
||||||
|
#if 0
|
||||||
|
#define RX_MACHDR_BACKUP_LEN 64
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct rx_vector_1_old {
|
||||||
|
/** Receive Vector 1a */
|
||||||
|
u32 leg_length :12;
|
||||||
|
u32 leg_rate : 4;
|
||||||
|
u32 ht_length :16;
|
||||||
|
|
||||||
|
/** Receive Vector 1b */
|
||||||
|
u32 _ht_length : 4; // FIXME
|
||||||
|
u32 short_gi : 1;
|
||||||
|
u32 stbc : 2;
|
||||||
|
u32 smoothing : 1;
|
||||||
|
u32 mcs : 7;
|
||||||
|
u32 pre_type : 1;
|
||||||
|
u32 format_mod : 3;
|
||||||
|
u32 ch_bw : 2;
|
||||||
|
u32 n_sts : 3;
|
||||||
|
u32 lsig_valid : 1;
|
||||||
|
u32 sounding : 1;
|
||||||
|
u32 num_extn_ss : 2;
|
||||||
|
u32 aggregation : 1;
|
||||||
|
u32 fec_coding : 1;
|
||||||
|
u32 dyn_bw : 1;
|
||||||
|
u32 doze_not_allowed : 1;
|
||||||
|
|
||||||
|
/** Receive Vector 1c */
|
||||||
|
u32 antenna_set : 8;
|
||||||
|
u32 partial_aid : 9;
|
||||||
|
u32 group_id : 6;
|
||||||
|
u32 first_user : 1;
|
||||||
|
s32 rssi1 : 8;
|
||||||
|
|
||||||
|
/** Receive Vector 1d */
|
||||||
|
s32 rssi2 : 8;
|
||||||
|
s32 rssi3 : 8;
|
||||||
|
s32 rssi4 : 8;
|
||||||
|
u32 reserved_1d : 8;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct rx_leg_vect
|
||||||
|
{
|
||||||
|
u8 dyn_bw_in_non_ht : 1;
|
||||||
|
u8 chn_bw_in_non_ht : 2;
|
||||||
|
u8 rsvd_nht : 4;
|
||||||
|
u8 lsig_valid : 1;
|
||||||
|
} __packed;
|
||||||
|
|
||||||
|
struct rx_ht_vect
|
||||||
|
{
|
||||||
|
u16 sounding : 1;
|
||||||
|
u16 smoothing : 1;
|
||||||
|
u16 short_gi : 1;
|
||||||
|
u16 aggregation : 1;
|
||||||
|
u16 stbc : 1;
|
||||||
|
u16 num_extn_ss : 2;
|
||||||
|
u16 lsig_valid : 1;
|
||||||
|
u16 mcs : 7;
|
||||||
|
u16 fec : 1;
|
||||||
|
u16 length :16;
|
||||||
|
} __packed;
|
||||||
|
|
||||||
|
struct rx_vht_vect
|
||||||
|
{
|
||||||
|
u8 sounding : 1;
|
||||||
|
u8 beamformed : 1;
|
||||||
|
u8 short_gi : 1;
|
||||||
|
u8 rsvd_vht1 : 1;
|
||||||
|
u8 stbc : 1;
|
||||||
|
u8 doze_not_allowed : 1;
|
||||||
|
u8 first_user : 1;
|
||||||
|
u8 rsvd_vht2 : 1;
|
||||||
|
u16 partial_aid : 9;
|
||||||
|
u16 group_id : 6;
|
||||||
|
u16 rsvd_vht3 : 1;
|
||||||
|
u32 mcs : 4;
|
||||||
|
u32 nss : 3;
|
||||||
|
u32 fec : 1;
|
||||||
|
u32 length :20;
|
||||||
|
u32 rsvd_vht4 : 4;
|
||||||
|
} __packed;
|
||||||
|
|
||||||
|
struct rx_he_vect
|
||||||
|
{
|
||||||
|
u8 sounding : 1;
|
||||||
|
u8 beamformed : 1;
|
||||||
|
u8 gi_type : 2;
|
||||||
|
u8 stbc : 1;
|
||||||
|
u8 rsvd_he1 : 3;
|
||||||
|
|
||||||
|
u8 uplink_flag : 1;
|
||||||
|
u8 beam_change : 1;
|
||||||
|
u8 dcm : 1;
|
||||||
|
u8 he_ltf_type : 2;
|
||||||
|
u8 doppler : 1;
|
||||||
|
u8 rsvd_he2 : 2;
|
||||||
|
|
||||||
|
u8 bss_color : 6;
|
||||||
|
u8 rsvd_he3 : 2;
|
||||||
|
|
||||||
|
u8 txop_duration : 7;
|
||||||
|
u8 rsvd_he4 : 1;
|
||||||
|
|
||||||
|
u8 pe_duration : 4;
|
||||||
|
u8 spatial_reuse : 4;
|
||||||
|
|
||||||
|
u8 sig_b_comp_mode : 1;
|
||||||
|
u8 dcm_sig_b : 1;
|
||||||
|
u8 mcs_sig_b : 3;
|
||||||
|
u8 ru_size : 3;
|
||||||
|
|
||||||
|
u32 mcs : 4;
|
||||||
|
u32 nss : 3;
|
||||||
|
u32 fec : 1;
|
||||||
|
u32 length :20;
|
||||||
|
u32 rsvd_he6 : 4;
|
||||||
|
} __packed;
|
||||||
|
|
||||||
|
struct rx_vector_1 {
|
||||||
|
u8 format_mod : 4;
|
||||||
|
u8 ch_bw : 3;
|
||||||
|
u8 pre_type : 1;
|
||||||
|
u8 antenna_set : 8;
|
||||||
|
s32 rssi_leg : 8;
|
||||||
|
u32 leg_length :12;
|
||||||
|
u32 leg_rate : 4;
|
||||||
|
s32 rssi1 : 8;
|
||||||
|
|
||||||
|
union
|
||||||
|
{
|
||||||
|
struct rx_leg_vect leg;
|
||||||
|
struct rx_ht_vect ht;
|
||||||
|
struct rx_vht_vect vht;
|
||||||
|
struct rx_he_vect he;
|
||||||
|
};
|
||||||
|
} __packed;
|
||||||
|
|
||||||
|
struct rx_vector_2_old {
|
||||||
|
/** Receive Vector 2a */
|
||||||
|
u32 rcpi : 8;
|
||||||
|
u32 evm1 : 8;
|
||||||
|
u32 evm2 : 8;
|
||||||
|
u32 evm3 : 8;
|
||||||
|
|
||||||
|
/** Receive Vector 2b */
|
||||||
|
u32 evm4 : 8;
|
||||||
|
u32 reserved2b_1 : 8;
|
||||||
|
u32 reserved2b_2 : 8;
|
||||||
|
u32 reserved2b_3 : 8;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
struct rx_vector_2 {
|
||||||
|
/** Receive Vector 2a */
|
||||||
|
u32 rcpi1 : 8;
|
||||||
|
u32 rcpi2 : 8;
|
||||||
|
u32 rcpi3 : 8;
|
||||||
|
u32 rcpi4 : 8;
|
||||||
|
|
||||||
|
/** Receive Vector 2b */
|
||||||
|
u32 evm1 : 8;
|
||||||
|
u32 evm2 : 8;
|
||||||
|
u32 evm3 : 8;
|
||||||
|
u32 evm4 : 8;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct phy_channel_info_desc {
|
||||||
|
/** PHY channel information 1 */
|
||||||
|
u32 phy_band : 8;
|
||||||
|
u32 phy_channel_type : 8;
|
||||||
|
u32 phy_prim20_freq : 16;
|
||||||
|
/** PHY channel information 2 */
|
||||||
|
u32 phy_center1_freq : 16;
|
||||||
|
u32 phy_center2_freq : 16;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct hw_vect {
|
||||||
|
/** Total length for the MPDU transfer */
|
||||||
|
u32 len :16;
|
||||||
|
|
||||||
|
u32 reserved : 8;//data type is included
|
||||||
|
/** AMPDU Status Information */
|
||||||
|
u32 mpdu_cnt : 6;
|
||||||
|
u32 ampdu_cnt : 2;
|
||||||
|
|
||||||
|
/** TSF Low */
|
||||||
|
__le32 tsf_lo;
|
||||||
|
/** TSF High */
|
||||||
|
__le32 tsf_hi;
|
||||||
|
|
||||||
|
/** Receive Vector 1 */
|
||||||
|
struct rx_vector_1 rx_vect1;
|
||||||
|
/** Receive Vector 2 */
|
||||||
|
struct rx_vector_2 rx_vect2;
|
||||||
|
|
||||||
|
/** Status **/
|
||||||
|
u32 rx_vect2_valid : 1;
|
||||||
|
u32 resp_frame : 1;
|
||||||
|
/** Decryption Status */
|
||||||
|
u32 decr_status : 3;
|
||||||
|
u32 rx_fifo_oflow : 1;
|
||||||
|
|
||||||
|
/** Frame Unsuccessful */
|
||||||
|
u32 undef_err : 1;
|
||||||
|
u32 phy_err : 1;
|
||||||
|
u32 fcs_err : 1;
|
||||||
|
u32 addr_mismatch : 1;
|
||||||
|
u32 ga_frame : 1;
|
||||||
|
u32 current_ac : 2;
|
||||||
|
|
||||||
|
u32 frm_successful_rx : 1;
|
||||||
|
/** Descriptor Done */
|
||||||
|
u32 desc_done_rx : 1;
|
||||||
|
/** Key Storage RAM Index */
|
||||||
|
u32 key_sram_index : 10;
|
||||||
|
/** Key Storage RAM Index Valid */
|
||||||
|
u32 key_sram_v : 1;
|
||||||
|
u32 type : 2;
|
||||||
|
u32 subtype : 4;
|
||||||
|
};
|
||||||
|
|
||||||
|
//#ifdef CONFIG_RWNX_MON_DATA
|
||||||
|
#if 0
|
||||||
|
/// MAC header backup descriptor
|
||||||
|
struct mon_machdrdesc
|
||||||
|
{
|
||||||
|
/// Length of the buffer
|
||||||
|
u32 buf_len;
|
||||||
|
/// Buffer containing mac header, LLC and SNAP
|
||||||
|
u8 buffer[RX_MACHDR_BACKUP_LEN];
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct hw_rxhdr {
|
||||||
|
/** RX vector */
|
||||||
|
struct hw_vect hwvect;
|
||||||
|
|
||||||
|
/** PHY channel information */
|
||||||
|
struct phy_channel_info_desc phy_info;
|
||||||
|
|
||||||
|
/** RX flags */
|
||||||
|
u32 flags_is_amsdu : 1;
|
||||||
|
u32 flags_is_80211_mpdu: 1;
|
||||||
|
u32 flags_is_4addr : 1;
|
||||||
|
u32 flags_new_peer : 1;
|
||||||
|
#if defined(AICWF_SDIO_SUPPORT) || defined(AICWF_USB_SUPPORT)
|
||||||
|
u32 flags_user_prio : 1; // aic: fw not fill any more
|
||||||
|
u32 flags_need_reord : 1;
|
||||||
|
u32 flags_upload : 1;
|
||||||
|
#else
|
||||||
|
u32 flags_user_prio : 3;
|
||||||
|
#endif
|
||||||
|
#ifndef AICWF_RX_REORDER
|
||||||
|
u32 flags_rsvd0 : 1;
|
||||||
|
#else
|
||||||
|
u32 is_monitor_vif : 1;
|
||||||
|
#endif
|
||||||
|
u32 flags_vif_idx : 8; // 0xFF if invalid VIF index
|
||||||
|
u32 flags_sta_idx : 8; // 0xFF if invalid STA index
|
||||||
|
u32 flags_dst_idx : 8; // 0xFF if unknown destination STA
|
||||||
|
//#ifdef CONFIG_RWNX_MON_DATA
|
||||||
|
#if 0
|
||||||
|
/// MAC header backup descriptor (used only for MSDU when there is a monitor and a data interface)
|
||||||
|
struct mon_machdrdesc mac_hdr_backup;
|
||||||
|
#endif
|
||||||
|
/** Pattern indicating if the buffer is available for the driver */
|
||||||
|
u32 pattern;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct rwnx_legrate {
|
||||||
|
int idx;
|
||||||
|
int rate;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern struct rwnx_legrate legrates_lut[];
|
||||||
|
extern u16 tx_legrates_lut_rate[];
|
||||||
|
|
||||||
|
struct DHCPInfo {
|
||||||
|
u8 op;
|
||||||
|
u8 htype;
|
||||||
|
u8 hlen;
|
||||||
|
u8 hops;
|
||||||
|
u32 xid;
|
||||||
|
u16 secs;
|
||||||
|
u16 flags;
|
||||||
|
u32 ciaddr;
|
||||||
|
u32 yiaddr;
|
||||||
|
u32 siaddr;
|
||||||
|
u32 giaddr;
|
||||||
|
u8 chaddr[16];
|
||||||
|
u8 sname[64];
|
||||||
|
u8 file[128];
|
||||||
|
u32 cookie;
|
||||||
|
u8 options[308]; /* 312 - cookie */
|
||||||
|
};
|
||||||
|
|
||||||
|
u8 rwnx_unsup_rx_vec_ind(void *pthis, void *hostid);
|
||||||
|
u8 rwnx_rxdataind(void *pthis, void *hostid);
|
||||||
|
u8 rwnx_rxdataind_aicwf(struct rwnx_hw *rwnx_hw, void *hostid, void *rx_priv);
|
||||||
|
int aicwf_process_rxframes(struct aicwf_rx_priv *rx_priv);
|
||||||
|
#ifdef CONFIG_USB_MSG_IN_EP
|
||||||
|
int aicwf_process_msg_rxframes(struct aicwf_rx_priv *rx_priv);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef AICWF_ARP_OFFLOAD
|
||||||
|
void arpoffload_proc(struct sk_buff *skb, struct rwnx_vif *rwnx_vif);
|
||||||
|
#endif
|
||||||
|
#ifdef AICWF_RX_REORDER
|
||||||
|
struct recv_msdu *reord_rxframe_alloc(spinlock_t *lock, struct list_head *q);
|
||||||
|
void reord_rxframe_free(spinlock_t *lock, struct list_head *q, struct list_head *list);
|
||||||
|
struct reord_ctrl_info *reord_init_sta( struct aicwf_rx_priv *rx_priv, const u8 *mac_addr);
|
||||||
|
void reord_deinit_sta(struct aicwf_rx_priv *rx_priv, struct reord_ctrl_info *reord_info);
|
||||||
|
int reord_need_check(struct reord_ctrl *preorder_ctrl, u16 seq_num);
|
||||||
|
int reord_rxframe_enqueue(struct reord_ctrl *preorder_ctrl, struct recv_msdu *prframe);
|
||||||
|
void reord_timeout_worker(struct work_struct *work);
|
||||||
|
int reord_single_frame_ind(struct aicwf_rx_priv *rx_priv, struct recv_msdu *prframe);
|
||||||
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(4,14,0)
|
||||||
|
void reord_timeout_handler (ulong data);
|
||||||
|
#else
|
||||||
|
void reord_timeout_handler (struct timer_list *t);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
void rwnx_rxdata_process_amsdu(struct rwnx_hw *rwnx_hw, struct sk_buff *skb, u8 vif_idx,
|
||||||
|
struct sk_buff_head *list);
|
||||||
|
|
||||||
|
#ifdef CONFIG_HE_FOR_OLD_KERNEL
|
||||||
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 4, 197)
|
||||||
|
struct element {
|
||||||
|
u8 id;
|
||||||
|
u8 datalen;
|
||||||
|
u8 data[];
|
||||||
|
};
|
||||||
|
/* element iteration helpers */
|
||||||
|
#define for_each_element(_elem, _data, _datalen) \
|
||||||
|
for (_elem = (const struct element *)(_data); \
|
||||||
|
(const u8 *)(_data) + (_datalen) - (const u8 *)_elem >= \
|
||||||
|
(int)sizeof(*_elem) && \
|
||||||
|
(const u8 *)(_data) + (_datalen) - (const u8 *)_elem >= \
|
||||||
|
(int)sizeof(*_elem) + _elem->datalen; \
|
||||||
|
_elem = (const struct element *)(_elem->data + _elem->datalen))
|
||||||
|
|
||||||
|
#define for_each_element_id(element, _id, data, datalen) \
|
||||||
|
for_each_element(element, data, datalen) \
|
||||||
|
if (element->id == (_id))
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* _RWNX_RX_H_ */
|
||||||
269
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/rwnx_strs.c
Normal file
269
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/rwnx_strs.c
Normal file
|
|
@ -0,0 +1,269 @@
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
*
|
||||||
|
* @file rwnx_strs.c
|
||||||
|
*
|
||||||
|
* @brief Miscellaneous debug strings
|
||||||
|
*
|
||||||
|
* Copyright (C) RivieraWaves 2014-2019
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "lmac_msg.h"
|
||||||
|
|
||||||
|
static const char *const rwnx_mmid2str[MSG_I(MM_MAX)] = {
|
||||||
|
[MSG_I(MM_RESET_REQ)] = "MM_RESET_REQ",
|
||||||
|
[MSG_I(MM_RESET_CFM)] = "MM_RESET_CFM",
|
||||||
|
[MSG_I(MM_START_REQ)] = "MM_START_REQ",
|
||||||
|
[MSG_I(MM_START_CFM)] = "MM_START_CFM",
|
||||||
|
[MSG_I(MM_VERSION_REQ)] = "MM_VERSION_REQ",
|
||||||
|
[MSG_I(MM_VERSION_CFM)] = "MM_VERSION_CFM",
|
||||||
|
[MSG_I(MM_ADD_IF_REQ)] = "MM_ADD_IF_REQ",
|
||||||
|
[MSG_I(MM_ADD_IF_CFM)] = "MM_ADD_IF_CFM",
|
||||||
|
[MSG_I(MM_REMOVE_IF_REQ)] = "MM_REMOVE_IF_REQ",
|
||||||
|
[MSG_I(MM_REMOVE_IF_CFM)] = "MM_REMOVE_IF_CFM",
|
||||||
|
[MSG_I(MM_STA_ADD_REQ)] = "MM_STA_ADD_REQ",
|
||||||
|
[MSG_I(MM_STA_ADD_CFM)] = "MM_STA_ADD_CFM",
|
||||||
|
[MSG_I(MM_STA_DEL_REQ)] = "MM_STA_DEL_REQ",
|
||||||
|
[MSG_I(MM_STA_DEL_CFM)] = "MM_STA_DEL_CFM",
|
||||||
|
[MSG_I(MM_SET_FILTER_REQ)] = "MM_SET_FILTER_REQ",
|
||||||
|
[MSG_I(MM_SET_FILTER_CFM)] = "MM_SET_FILTER_CFM",
|
||||||
|
[MSG_I(MM_SET_CHANNEL_REQ)] = "MM_SET_CHANNEL_REQ",
|
||||||
|
[MSG_I(MM_SET_CHANNEL_CFM)] = "MM_SET_CHANNEL_CFM",
|
||||||
|
[MSG_I(MM_SET_DTIM_REQ)] = "MM_SET_DTIM_REQ",
|
||||||
|
[MSG_I(MM_SET_DTIM_CFM)] = "MM_SET_DTIM_CFM",
|
||||||
|
[MSG_I(MM_SET_BEACON_INT_REQ)] = "MM_SET_BEACON_INT_REQ",
|
||||||
|
[MSG_I(MM_SET_BEACON_INT_CFM)] = "MM_SET_BEACON_INT_CFM",
|
||||||
|
[MSG_I(MM_SET_BASIC_RATES_REQ)] = "MM_SET_BASIC_RATES_REQ",
|
||||||
|
[MSG_I(MM_SET_BASIC_RATES_CFM)] = "MM_SET_BASIC_RATES_CFM",
|
||||||
|
[MSG_I(MM_SET_BSSID_REQ)] = "MM_SET_BSSID_REQ",
|
||||||
|
[MSG_I(MM_SET_BSSID_CFM)] = "MM_SET_BSSID_CFM",
|
||||||
|
[MSG_I(MM_SET_EDCA_REQ)] = "MM_SET_EDCA_REQ",
|
||||||
|
[MSG_I(MM_SET_EDCA_CFM)] = "MM_SET_EDCA_CFM",
|
||||||
|
[MSG_I(MM_SET_MODE_REQ)] = "MM_SET_MODE_REQ",
|
||||||
|
[MSG_I(MM_SET_MODE_CFM)] = "MM_SET_MODE_CFM",
|
||||||
|
[MSG_I(MM_SET_VIF_STATE_REQ)] = "MM_SET_VIF_STATE_REQ",
|
||||||
|
[MSG_I(MM_SET_VIF_STATE_CFM)] = "MM_SET_VIF_STATE_CFM",
|
||||||
|
[MSG_I(MM_SET_SLOTTIME_REQ)] = "MM_SET_SLOTTIME_REQ",
|
||||||
|
[MSG_I(MM_SET_SLOTTIME_CFM)] = "MM_SET_SLOTTIME_CFM",
|
||||||
|
[MSG_I(MM_SET_IDLE_REQ)] = "MM_SET_IDLE_REQ",
|
||||||
|
[MSG_I(MM_SET_IDLE_CFM)] = "MM_SET_IDLE_CFM",
|
||||||
|
[MSG_I(MM_KEY_ADD_REQ)] = "MM_KEY_ADD_REQ",
|
||||||
|
[MSG_I(MM_KEY_ADD_CFM)] = "MM_KEY_ADD_CFM",
|
||||||
|
[MSG_I(MM_KEY_DEL_REQ)] = "MM_KEY_DEL_REQ",
|
||||||
|
[MSG_I(MM_KEY_DEL_CFM)] = "MM_KEY_DEL_CFM",
|
||||||
|
[MSG_I(MM_BA_ADD_REQ)] = "MM_BA_ADD_REQ",
|
||||||
|
[MSG_I(MM_BA_ADD_CFM)] = "MM_BA_ADD_CFM",
|
||||||
|
[MSG_I(MM_BA_DEL_REQ)] = "MM_BA_DEL_REQ",
|
||||||
|
[MSG_I(MM_BA_DEL_CFM)] = "MM_BA_DEL_CFM",
|
||||||
|
[MSG_I(MM_PRIMARY_TBTT_IND)] = "MM_PRIMARY_TBTT_IND",
|
||||||
|
[MSG_I(MM_SECONDARY_TBTT_IND)] = "MM_SECONDARY_TBTT_IND",
|
||||||
|
[MSG_I(MM_SET_POWER_REQ)] = "MM_SET_POWER_REQ",
|
||||||
|
[MSG_I(MM_SET_POWER_CFM)] = "MM_SET_POWER_CFM",
|
||||||
|
[MSG_I(MM_DBG_TRIGGER_REQ)] = "MM_DBG_TRIGGER_REQ",
|
||||||
|
[MSG_I(MM_SET_PS_MODE_REQ)] = "MM_SET_PS_MODE_REQ",
|
||||||
|
[MSG_I(MM_SET_PS_MODE_CFM)] = "MM_SET_PS_MODE_CFM",
|
||||||
|
[MSG_I(MM_CHAN_CTXT_ADD_REQ)] = "MM_CHAN_CTXT_ADD_REQ",
|
||||||
|
[MSG_I(MM_CHAN_CTXT_ADD_CFM)] = "MM_CHAN_CTXT_ADD_CFM",
|
||||||
|
[MSG_I(MM_CHAN_CTXT_DEL_REQ)] = "MM_CHAN_CTXT_DEL_REQ",
|
||||||
|
[MSG_I(MM_CHAN_CTXT_DEL_CFM)] = "MM_CHAN_CTXT_DEL_CFM",
|
||||||
|
[MSG_I(MM_CHAN_CTXT_LINK_REQ)] = "MM_CHAN_CTXT_LINK_REQ",
|
||||||
|
[MSG_I(MM_CHAN_CTXT_LINK_CFM)] = "MM_CHAN_CTXT_LINK_CFM",
|
||||||
|
[MSG_I(MM_CHAN_CTXT_UNLINK_REQ)] = "MM_CHAN_CTXT_UNLINK_REQ",
|
||||||
|
[MSG_I(MM_CHAN_CTXT_UNLINK_CFM)] = "MM_CHAN_CTXT_UNLINK_CFM",
|
||||||
|
[MSG_I(MM_CHAN_CTXT_UPDATE_REQ)] = "MM_CHAN_CTXT_UPDATE_REQ",
|
||||||
|
[MSG_I(MM_CHAN_CTXT_UPDATE_CFM)] = "MM_CHAN_CTXT_UPDATE_CFM",
|
||||||
|
[MSG_I(MM_CHAN_CTXT_SCHED_REQ)] = "MM_CHAN_CTXT_SCHED_REQ",
|
||||||
|
[MSG_I(MM_CHAN_CTXT_SCHED_CFM)] = "MM_CHAN_CTXT_SCHED_CFM",
|
||||||
|
[MSG_I(MM_BCN_CHANGE_REQ)] = "MM_BCN_CHANGE_REQ",
|
||||||
|
[MSG_I(MM_BCN_CHANGE_CFM)] = "MM_BCN_CHANGE_CFM",
|
||||||
|
[MSG_I(MM_TIM_UPDATE_REQ)] = "MM_TIM_UPDATE_REQ",
|
||||||
|
[MSG_I(MM_TIM_UPDATE_CFM)] = "MM_TIM_UPDATE_CFM",
|
||||||
|
[MSG_I(MM_CONNECTION_LOSS_IND)] = "MM_CONNECTION_LOSS_IND",
|
||||||
|
[MSG_I(MM_CHANNEL_SWITCH_IND)] = "MM_CHANNEL_SWITCH_IND",
|
||||||
|
[MSG_I(MM_CHANNEL_PRE_SWITCH_IND)] = "MM_CHANNEL_PRE_SWITCH_IND",
|
||||||
|
[MSG_I(MM_REMAIN_ON_CHANNEL_REQ)] = "MM_REMAIN_ON_CHANNEL_REQ",
|
||||||
|
[MSG_I(MM_REMAIN_ON_CHANNEL_CFM)] = "MM_REMAIN_ON_CHANNEL_CFM",
|
||||||
|
[MSG_I(MM_REMAIN_ON_CHANNEL_EXP_IND)] = "MM_REMAIN_ON_CHANNEL_EXP_IND",
|
||||||
|
[MSG_I(MM_PS_CHANGE_IND)] = "MM_PS_CHANGE_IND",
|
||||||
|
[MSG_I(MM_TRAFFIC_REQ_IND)] = "MM_TRAFFIC_REQ_IND",
|
||||||
|
[MSG_I(MM_SET_PS_OPTIONS_REQ)] = "MM_SET_PS_OPTIONS_REQ",
|
||||||
|
[MSG_I(MM_SET_PS_OPTIONS_CFM)] = "MM_SET_PS_OPTIONS_CFM",
|
||||||
|
[MSG_I(MM_P2P_VIF_PS_CHANGE_IND)] = "MM_P2P_VIF_PS_CHANGE_IND",
|
||||||
|
[MSG_I(MM_CSA_COUNTER_IND)] = "MM_CSA_COUNTER_IND",
|
||||||
|
[MSG_I(MM_CHANNEL_SURVEY_IND)] = "MM_CHANNEL_SURVEY_IND",
|
||||||
|
[MSG_I(MM_SET_P2P_NOA_REQ)] = "MM_SET_P2P_NOA_REQ",
|
||||||
|
[MSG_I(MM_SET_P2P_OPPPS_REQ)] = "MM_SET_P2P_OPPPS_REQ",
|
||||||
|
[MSG_I(MM_SET_P2P_NOA_CFM)] = "MM_SET_P2P_NOA_CFM",
|
||||||
|
[MSG_I(MM_SET_P2P_OPPPS_CFM)] = "MM_SET_P2P_OPPPS_CFM",
|
||||||
|
[MSG_I(MM_CFG_RSSI_REQ)] = "MM_CFG_RSSI_REQ",
|
||||||
|
[MSG_I(MM_RSSI_STATUS_IND)] = "MM_RSSI_STATUS_IND",
|
||||||
|
[MSG_I(MM_CSA_FINISH_IND)] = "MM_CSA_FINISH_IND",
|
||||||
|
[MSG_I(MM_CSA_TRAFFIC_IND)] = "MM_CSA_TRAFFIC_IND",
|
||||||
|
[MSG_I(MM_MU_GROUP_UPDATE_REQ)] = "MM_MU_GROUP_UPDATE_REQ",
|
||||||
|
[MSG_I(MM_MU_GROUP_UPDATE_CFM)] = "MM_MU_GROUP_UPDATE_CFM",
|
||||||
|
|
||||||
|
[MSG_I(MM_SET_ARPOFFLOAD_REQ)] = "MM_SET_ARPOFFLOAD_REQ",
|
||||||
|
[MSG_I(MM_SET_ARPOFFLOAD_CFM)] = "MM_SET_ARPOFFLOAD_CFM",
|
||||||
|
[MSG_I(MM_SET_AGG_DISABLE_REQ)] = "MM_SET_AGG_DISABLE_REQ",
|
||||||
|
[MSG_I(MM_SET_AGG_DISABLE_CFM)] = "MM_SET_AGG_DISABLE_CFM",
|
||||||
|
[MSG_I(MM_SET_COEX_REQ)] = "MM_SET_COEX_REQ",
|
||||||
|
[MSG_I(MM_SET_COEX_CFM)] = "MM_SET_COEX_CFM",
|
||||||
|
[MSG_I(MM_SET_RF_CONFIG_REQ)] = "MM_SET_RF_CONFIG_REQ",
|
||||||
|
[MSG_I(MM_SET_RF_CONFIG_CFM)] = "MM_SET_RF_CONFIG_CFM",
|
||||||
|
[MSG_I(MM_SET_RF_CALIB_REQ)] = "MM_SET_RF_CALIB_REQ",
|
||||||
|
[MSG_I(MM_SET_RF_CALIB_CFM)] = "MM_SET_RF_CALIB_CFM",
|
||||||
|
|
||||||
|
[MSG_I(MM_GET_MAC_ADDR_REQ)] = "MM_GET_MAC_ADDR_REQ",
|
||||||
|
[MSG_I(MM_GET_MAC_ADDR_CFM)] = "MM_GET_MAC_ADDR_CFM",
|
||||||
|
[MSG_I(MM_GET_STA_INFO_REQ)] = "MM_GET_STA_INFO_REQ",
|
||||||
|
[MSG_I(MM_GET_STA_INFO_CFM)] = "MM_GET_STA_INFO_CFM",
|
||||||
|
[MSG_I(MM_SET_TXPWR_IDX_LVL_REQ)] = "MM_SET_TXPWR_IDX_LVL_REQ",
|
||||||
|
[MSG_I(MM_SET_TXPWR_IDX_LVL_CFM)] = "MM_SET_TXPWR_IDX_LVL_CFM",
|
||||||
|
[MSG_I(MM_SET_TXPWR_OFST_REQ)] = "MM_SET_TXPWR_OFST_REQ",
|
||||||
|
[MSG_I(MM_SET_TXPWR_OFST_CFM)] = "MM_SET_TXPWR_OFST_CFM",
|
||||||
|
[MSG_I(MM_SET_STACK_START_REQ)] = "MM_SET_STACK_START_REQ",
|
||||||
|
[MSG_I(MM_SET_STACK_START_CFM)] = "MM_SET_STACK_START_CFM",
|
||||||
|
[MSG_I(MM_APM_STALOSS_IND)] = "MM_APM_STALOSS_IND",
|
||||||
|
[MSG_I(MM_SET_VENDOR_HWCONFIG_REQ)] = "MM_SET_VENDOR_HWCONFIG_REQ",
|
||||||
|
[MSG_I(MM_SET_VENDOR_HWCONFIG_CFM)] = "MM_SET_VENDOR_HWCONFIG_CFM",
|
||||||
|
[MSG_I(MM_GET_FW_VERSION_REQ)] = "MM_GET_FW_VERSION_REQ",
|
||||||
|
[MSG_I(MM_GET_FW_VERSION_CFM)] = "MM_GET_FW_VERSION_CFM",
|
||||||
|
[MSG_I(MM_SET_RESUME_RESTORE_REQ)] = "MM_SET_RESUME_RESTORE_REQ",
|
||||||
|
[MSG_I(MM_SET_RESUME_RESTORE_CFM)] = "MM_SET_RESUME_RESTORE_CFM",
|
||||||
|
[MSG_I(MM_GET_WIFI_DISABLE_REQ)] = "MM_GET_WIFI_DISABLE_REQ",
|
||||||
|
[MSG_I(MM_GET_WIFI_DISABLE_CFM)] = "MM_GET_WIFI_DISABLE_CFM",
|
||||||
|
[MSG_I(MM_CFG_RSSI_CFM)] = "MM_CFG_RSSI_CFM",
|
||||||
|
[MSG_I(MM_SET_TXPWR_PER_STA_REQ)] = "MM_SET_TXPWR_PER_STA_REQ",
|
||||||
|
[MSG_I(MM_SET_TXPWR_PER_STA_CFM)] = "MM_SET_TXPWR_PER_STA_CFM",
|
||||||
|
};
|
||||||
|
|
||||||
|
static const char *const rwnx_dbgid2str[MSG_I(DBG_MAX)] = {
|
||||||
|
[MSG_I(DBG_MEM_READ_REQ)] = "DBG_MEM_READ_REQ",
|
||||||
|
[MSG_I(DBG_MEM_READ_CFM)] = "DBG_MEM_READ_CFM",
|
||||||
|
[MSG_I(DBG_MEM_WRITE_REQ)] = "DBG_MEM_WRITE_REQ",
|
||||||
|
[MSG_I(DBG_MEM_WRITE_CFM)] = "DBG_MEM_WRITE_CFM",
|
||||||
|
[MSG_I(DBG_SET_MOD_FILTER_REQ)] = "DBG_SET_MOD_FILTER_REQ",
|
||||||
|
[MSG_I(DBG_SET_MOD_FILTER_CFM)] = "DBG_SET_MOD_FILTER_CFM",
|
||||||
|
[MSG_I(DBG_SET_SEV_FILTER_REQ)] = "DBG_SET_SEV_FILTER_REQ",
|
||||||
|
[MSG_I(DBG_SET_SEV_FILTER_CFM)] = "DBG_SET_SEV_FILTER_CFM",
|
||||||
|
[MSG_I(DBG_ERROR_IND)] = "DBG_ERROR_IND",
|
||||||
|
[MSG_I(DBG_GET_SYS_STAT_REQ)] = "DBG_GET_SYS_STAT_REQ",
|
||||||
|
[MSG_I(DBG_GET_SYS_STAT_CFM)] = "DBG_GET_SYS_STAT_CFM",
|
||||||
|
};
|
||||||
|
|
||||||
|
static const char *const rwnx_scanid2str[MSG_I(SCAN_MAX)] = {
|
||||||
|
[MSG_I(SCAN_START_REQ)] = "SCAN_START_REQ",
|
||||||
|
[MSG_I(SCAN_START_CFM)] = "SCAN_START_CFM",
|
||||||
|
[MSG_I(SCAN_DONE_IND)] = "SCAN_DONE_IND",
|
||||||
|
};
|
||||||
|
|
||||||
|
static const char *const rwnx_tdlsid2str[MSG_I(TDLS_MAX)] = {
|
||||||
|
[MSG_I(TDLS_CHAN_SWITCH_CFM)] = "TDLS_CHAN_SWITCH_CFM",
|
||||||
|
[MSG_I(TDLS_CHAN_SWITCH_REQ)] = "TDLS_CHAN_SWITCH_REQ",
|
||||||
|
[MSG_I(TDLS_CHAN_SWITCH_IND)] = "TDLS_CHAN_SWITCH_IND",
|
||||||
|
[MSG_I(TDLS_CHAN_SWITCH_BASE_IND)] = "TDLS_CHAN_SWITCH_BASE_IND",
|
||||||
|
[MSG_I(TDLS_CANCEL_CHAN_SWITCH_REQ)] = "TDLS_CANCEL_CHAN_SWITCH_REQ",
|
||||||
|
[MSG_I(TDLS_CANCEL_CHAN_SWITCH_CFM)] = "TDLS_CANCEL_CHAN_SWITCH_CFM",
|
||||||
|
[MSG_I(TDLS_PEER_PS_IND)] = "TDLS_PEER_PS_IND",
|
||||||
|
[MSG_I(TDLS_PEER_TRAFFIC_IND_REQ)] = "TDLS_PEER_TRAFFIC_IND_REQ",
|
||||||
|
[MSG_I(TDLS_PEER_TRAFFIC_IND_CFM)] = "TDLS_PEER_TRAFFIC_IND_CFM",
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef CONFIG_RWNX_FULLMAC
|
||||||
|
|
||||||
|
static const char *const rwnx_scanuid2str[MSG_I(SCANU_MAX)] = {
|
||||||
|
[MSG_I(SCANU_START_REQ)] = "SCANU_START_REQ",
|
||||||
|
[MSG_I(SCANU_START_CFM)] = "SCANU_START_CFM",
|
||||||
|
[MSG_I(SCANU_JOIN_REQ)] = "SCANU_JOIN_REQ",
|
||||||
|
[MSG_I(SCANU_JOIN_CFM)] = "SCANU_JOIN_CFM",
|
||||||
|
[MSG_I(SCANU_RESULT_IND)] = "SCANU_RESULT_IND",
|
||||||
|
[MSG_I(SCANU_FAST_REQ)] = "SCANU_FAST_REQ",
|
||||||
|
[MSG_I(SCANU_FAST_CFM)] = "SCANU_FAST_CFM",
|
||||||
|
[MSG_I(SCANU_VENDOR_IE_REQ)] = "SCANU_VENDOR_IE_REQ",
|
||||||
|
[MSG_I(SCANU_VENDOR_IE_CFM)] = "SCANU_VENDOR_IE_CFM",
|
||||||
|
[MSG_I(SCANU_START_CFM_ADDTIONAL)] = "SCANU_START_CFM_ADDTIONAL",
|
||||||
|
[MSG_I(SCANU_CANCEL_REQ)] = "SCANU_CANCEL_REQ",
|
||||||
|
[MSG_I(SCANU_CANCEL_CFM)] = "SCANU_CANCEL_CFM",
|
||||||
|
};
|
||||||
|
|
||||||
|
static const char *const rwnx_meid2str[MSG_I(ME_MAX)] = {
|
||||||
|
[MSG_I(ME_CONFIG_REQ)] = "ME_CONFIG_REQ",
|
||||||
|
[MSG_I(ME_CONFIG_CFM)] = "ME_CONFIG_CFM",
|
||||||
|
[MSG_I(ME_CHAN_CONFIG_REQ)] = "ME_CHAN_CONFIG_REQ",
|
||||||
|
[MSG_I(ME_CHAN_CONFIG_CFM)] = "ME_CHAN_CONFIG_CFM",
|
||||||
|
[MSG_I(ME_SET_CONTROL_PORT_REQ)] = "ME_SET_CONTROL_PORT_REQ",
|
||||||
|
[MSG_I(ME_SET_CONTROL_PORT_CFM)] = "ME_SET_CONTROL_PORT_CFM",
|
||||||
|
[MSG_I(ME_TKIP_MIC_FAILURE_IND)] = "ME_TKIP_MIC_FAILURE_IND",
|
||||||
|
[MSG_I(ME_STA_ADD_REQ)] = "ME_STA_ADD_REQ",
|
||||||
|
[MSG_I(ME_STA_ADD_CFM)] = "ME_STA_ADD_CFM",
|
||||||
|
[MSG_I(ME_STA_DEL_REQ)] = "ME_STA_DEL_REQ",
|
||||||
|
[MSG_I(ME_STA_DEL_CFM)] = "ME_STA_DEL_CFM",
|
||||||
|
[MSG_I(ME_TX_CREDITS_UPDATE_IND)]= "ME_TX_CREDITS_UPDATE_IND",
|
||||||
|
[MSG_I(ME_RC_STATS_REQ)] = "ME_RC_STATS_REQ",
|
||||||
|
[MSG_I(ME_RC_STATS_CFM)] = "ME_RC_STATS_CFM",
|
||||||
|
[MSG_I(ME_RC_SET_RATE_REQ)] = "ME_RC_SET_RATE_REQ",
|
||||||
|
[MSG_I(ME_TRAFFIC_IND_REQ)] = "ME_TRAFFIC_IND_REQ",
|
||||||
|
[MSG_I(ME_TRAFFIC_IND_CFM)] = "ME_TRAFFIC_IND_CFM",
|
||||||
|
[MSG_I(ME_SET_PS_MODE_REQ)] = "ME_SET_PS_MODE_REQ",
|
||||||
|
[MSG_I(ME_SET_PS_MODE_CFM)] = "ME_SET_PS_MODE_CFM",
|
||||||
|
};
|
||||||
|
|
||||||
|
static const char *const rwnx_smid2str[MSG_I(SM_MAX)] = {
|
||||||
|
[MSG_I(SM_CONNECT_REQ)] = "SM_CONNECT_REQ",
|
||||||
|
[MSG_I(SM_CONNECT_CFM)] = "SM_CONNECT_CFM",
|
||||||
|
[MSG_I(SM_CONNECT_IND)] = "SM_CONNECT_IND",
|
||||||
|
[MSG_I(SM_DISCONNECT_REQ)] = "SM_DISCONNECT_REQ",
|
||||||
|
[MSG_I(SM_DISCONNECT_CFM)] = "SM_DISCONNECT_CFM",
|
||||||
|
[MSG_I(SM_DISCONNECT_IND)] = "SM_DISCONNECT_IND",
|
||||||
|
[MSG_I(SM_EXTERNAL_AUTH_REQUIRED_IND)] = "SM_EXTERNAL_AUTH_REQUIRED_IND",
|
||||||
|
[MSG_I(SM_EXTERNAL_AUTH_REQUIRED_RSP)] = "SM_EXTERNAL_AUTH_REQUIRED_RSP",
|
||||||
|
[MSG_I(SM_EXTERNAL_AUTH_REQUIRED_RSP_CFM)] = "SM_EXTERNAL_AUTH_REQUIRED_RSP_CFM",
|
||||||
|
};
|
||||||
|
|
||||||
|
static const char *const rwnx_apmid2str[MSG_I(APM_MAX)] = {
|
||||||
|
[MSG_I(APM_START_REQ)] = "APM_START_REQ",
|
||||||
|
[MSG_I(APM_START_CFM)] = "APM_START_CFM",
|
||||||
|
[MSG_I(APM_STOP_REQ)] = "APM_STOP_REQ",
|
||||||
|
[MSG_I(APM_STOP_CFM)] = "APM_STOP_CFM",
|
||||||
|
[MSG_I(APM_START_CAC_REQ)] = "APM_START_CAC_REQ",
|
||||||
|
[MSG_I(APM_START_CAC_CFM)] = "APM_START_CAC_CFM",
|
||||||
|
[MSG_I(APM_STOP_CAC_REQ)] = "APM_STOP_CAC_REQ",
|
||||||
|
[MSG_I(APM_STOP_CAC_CFM)] = "APM_STOP_CAC_CFM",
|
||||||
|
[MSG_I(APM_SET_BEACON_IE_REQ)] = "APM_SET_BEACON_IE_REQ",
|
||||||
|
[MSG_I(APM_SET_BEACON_IE_CFM)] = "APM_SET_BEACON_IE_CFM",
|
||||||
|
};
|
||||||
|
|
||||||
|
static const char *const rwnx_meshid2str[MSG_I(MESH_MAX)] = {
|
||||||
|
[MSG_I(MESH_START_REQ)] = "MESH_START_REQ",
|
||||||
|
[MSG_I(MESH_START_CFM)] = "MESH_START_CFM",
|
||||||
|
[MSG_I(MESH_STOP_REQ)] = "MESH_STOP_REQ",
|
||||||
|
[MSG_I(MESH_STOP_CFM)] = "MESH_STOP_CFM",
|
||||||
|
[MSG_I(MESH_UPDATE_REQ)] = "MESH_UPDATE_REQ",
|
||||||
|
[MSG_I(MESH_UPDATE_CFM)] = "MESH_UPDATE_CFM",
|
||||||
|
[MSG_I(MESH_PATH_CREATE_REQ)] = "MESH_PATH_CREATE_REQ",
|
||||||
|
[MSG_I(MESH_PATH_CREATE_CFM)] = "MESH_PATH_CREATE_CFM",
|
||||||
|
[MSG_I(MESH_PATH_UPDATE_REQ)] = "MESH_PATH_UPDATE_REQ",
|
||||||
|
[MSG_I(MESH_PATH_UPDATE_CFM)] = "MESH_PATH_UPDATE_CFM",
|
||||||
|
[MSG_I(MESH_PROXY_ADD_REQ)] = "MESH_PROXY_ADD_REQ",
|
||||||
|
[MSG_I(MESH_PEER_UPDATE_IND)] = "MESH_PEER_UPDATE_IND",
|
||||||
|
[MSG_I(MESH_PATH_UPDATE_IND)] = "MESH_PATH_UPDATE_IND",
|
||||||
|
[MSG_I(MESH_PROXY_UPDATE_IND)] = "MESH_PROXY_UPDATE_IND",
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* CONFIG_RWNX_FULLMAC */
|
||||||
|
|
||||||
|
const char *const *rwnx_id2str[TASK_LAST_EMB + 1] = {
|
||||||
|
[TASK_MM] = rwnx_mmid2str,
|
||||||
|
[TASK_DBG] = rwnx_dbgid2str,
|
||||||
|
[TASK_SCAN] = rwnx_scanid2str,
|
||||||
|
[TASK_TDLS] = rwnx_tdlsid2str,
|
||||||
|
#ifdef CONFIG_RWNX_FULLMAC
|
||||||
|
[TASK_SCANU] = rwnx_scanuid2str,
|
||||||
|
[TASK_ME] = rwnx_meid2str,
|
||||||
|
[TASK_SM] = rwnx_smid2str,
|
||||||
|
[TASK_APM] = rwnx_apmid2str,
|
||||||
|
[TASK_MESH] = rwnx_meshid2str,
|
||||||
|
#endif
|
||||||
|
};
|
||||||
31
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/rwnx_strs.h
Normal file
31
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/rwnx_strs.h
Normal file
|
|
@ -0,0 +1,31 @@
|
||||||
|
/**
|
||||||
|
****************************************************************************************
|
||||||
|
*
|
||||||
|
* @file rwnx_strs.h
|
||||||
|
*
|
||||||
|
* @brief Miscellaneous debug strings
|
||||||
|
*
|
||||||
|
* Copyright (C) RivieraWaves 2014-2019
|
||||||
|
*
|
||||||
|
****************************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _RWNX_STRS_H_
|
||||||
|
#define _RWNX_STRS_H_
|
||||||
|
|
||||||
|
#ifdef CONFIG_RWNX_FHOST
|
||||||
|
|
||||||
|
#define RWNX_ID2STR(tag) "Cmd"
|
||||||
|
|
||||||
|
#else
|
||||||
|
#include "lmac_msg.h"
|
||||||
|
|
||||||
|
#define RWNX_ID2STR(tag) (((MSG_T(tag) < ARRAY_SIZE(rwnx_id2str)) && \
|
||||||
|
(rwnx_id2str[MSG_T(tag)]) && \
|
||||||
|
((rwnx_id2str[MSG_T(tag)])[MSG_I(tag)])) ? \
|
||||||
|
(rwnx_id2str[MSG_T(tag)])[MSG_I(tag)] : "unknown")
|
||||||
|
|
||||||
|
extern const char *const *rwnx_id2str[TASK_LAST_EMB + 1];
|
||||||
|
#endif /* CONFIG_RWNX_FHOST */
|
||||||
|
|
||||||
|
#endif /* _RWNX_STRS_H_ */
|
||||||
796
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/rwnx_tdls.c
Normal file
796
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/rwnx_tdls.c
Normal file
|
|
@ -0,0 +1,796 @@
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
*
|
||||||
|
* @file rwnx_tx.c
|
||||||
|
*
|
||||||
|
* Copyright (C) RivieraWaves 2012-2019
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* INCLUDE FILES
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "rwnx_tdls.h"
|
||||||
|
#include "rwnx_compat.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* FUNCTION DEFINITIONS
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
static u16
|
||||||
|
rwnx_get_tdls_sta_capab(struct rwnx_vif *rwnx_vif, u16 status_code)
|
||||||
|
{
|
||||||
|
u16 capab = 0;
|
||||||
|
|
||||||
|
/* The capability will be 0 when sending a failure code */
|
||||||
|
if (status_code != 0)
|
||||||
|
return capab;
|
||||||
|
|
||||||
|
if (rwnx_vif->sta.ap->band != NL80211_BAND_2GHZ)
|
||||||
|
return capab;
|
||||||
|
|
||||||
|
capab |= WLAN_CAPABILITY_SHORT_SLOT_TIME;
|
||||||
|
capab |= WLAN_CAPABILITY_SHORT_PREAMBLE;
|
||||||
|
|
||||||
|
return capab;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
rwnx_tdls_prepare_encap_data(struct rwnx_hw *rwnx_hw, struct rwnx_vif *rwnx_vif,
|
||||||
|
const u8 *peer, u8 action_code, u8 dialog_token,
|
||||||
|
u16 status_code, struct sk_buff *skb)
|
||||||
|
{
|
||||||
|
struct ieee80211_tdls_data *tf;
|
||||||
|
tf = (void *)skb_put(skb, sizeof(struct ieee80211_tdls_data) - sizeof(tf->u));
|
||||||
|
|
||||||
|
// set eth header
|
||||||
|
memcpy(tf->da, peer, ETH_ALEN);
|
||||||
|
memcpy(tf->sa, rwnx_hw->wiphy->perm_addr, ETH_ALEN);
|
||||||
|
tf->ether_type = cpu_to_be16(ETH_P_TDLS);
|
||||||
|
|
||||||
|
// set common TDLS info
|
||||||
|
tf->payload_type = WLAN_TDLS_SNAP_RFTYPE;
|
||||||
|
tf->category = WLAN_CATEGORY_TDLS;
|
||||||
|
tf->action_code = action_code;
|
||||||
|
|
||||||
|
// set action specific TDLS info
|
||||||
|
switch (action_code) {
|
||||||
|
case WLAN_TDLS_SETUP_REQUEST:
|
||||||
|
skb_put(skb, sizeof(tf->u.setup_req));
|
||||||
|
tf->u.setup_req.dialog_token = dialog_token;
|
||||||
|
tf->u.setup_req.capability =
|
||||||
|
cpu_to_le16(rwnx_get_tdls_sta_capab(rwnx_vif, status_code));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WLAN_TDLS_SETUP_RESPONSE:
|
||||||
|
skb_put(skb, sizeof(tf->u.setup_resp));
|
||||||
|
tf->u.setup_resp.status_code = cpu_to_le16(status_code);
|
||||||
|
tf->u.setup_resp.dialog_token = dialog_token;
|
||||||
|
tf->u.setup_resp.capability =
|
||||||
|
cpu_to_le16(rwnx_get_tdls_sta_capab(rwnx_vif, status_code));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WLAN_TDLS_SETUP_CONFIRM:
|
||||||
|
skb_put(skb, sizeof(tf->u.setup_cfm));
|
||||||
|
tf->u.setup_cfm.status_code = cpu_to_le16(status_code);
|
||||||
|
tf->u.setup_cfm.dialog_token = dialog_token;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WLAN_TDLS_TEARDOWN:
|
||||||
|
skb_put(skb, sizeof(tf->u.teardown));
|
||||||
|
tf->u.teardown.reason_code = cpu_to_le16(status_code);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WLAN_TDLS_DISCOVERY_REQUEST:
|
||||||
|
skb_put(skb, sizeof(tf->u.discover_req));
|
||||||
|
tf->u.discover_req.dialog_token = dialog_token;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
rwnx_prep_tdls_direct(struct rwnx_hw *rwnx_hw, struct rwnx_vif *rwnx_vif,
|
||||||
|
const u8 *peer, u8 action_code, u8 dialog_token,
|
||||||
|
u16 status_code, struct sk_buff *skb)
|
||||||
|
{
|
||||||
|
struct ieee80211_mgmt *mgmt;
|
||||||
|
|
||||||
|
mgmt = (void *)skb_put(skb, 24);
|
||||||
|
memset(mgmt, 0, 24);
|
||||||
|
memcpy(mgmt->da, peer, ETH_ALEN);
|
||||||
|
memcpy(mgmt->sa, rwnx_hw->wiphy->perm_addr, ETH_ALEN);
|
||||||
|
memcpy(mgmt->bssid, rwnx_vif->sta.ap->mac_addr, ETH_ALEN);
|
||||||
|
|
||||||
|
mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
|
||||||
|
IEEE80211_STYPE_ACTION);
|
||||||
|
|
||||||
|
switch (action_code) {
|
||||||
|
case WLAN_PUB_ACTION_TDLS_DISCOVER_RES:
|
||||||
|
skb_put(skb, 1 + sizeof(mgmt->u.action.u.tdls_discover_resp));
|
||||||
|
mgmt->u.action.category = WLAN_CATEGORY_PUBLIC;
|
||||||
|
mgmt->u.action.u.tdls_discover_resp.action_code = WLAN_PUB_ACTION_TDLS_DISCOVER_RES;
|
||||||
|
mgmt->u.action.u.tdls_discover_resp.dialog_token = dialog_token;
|
||||||
|
mgmt->u.action.u.tdls_discover_resp.capability =
|
||||||
|
cpu_to_le16(rwnx_get_tdls_sta_capab(rwnx_vif, status_code));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
rwnx_add_srates_ie(struct rwnx_hw *rwnx_hw, struct sk_buff *skb)
|
||||||
|
{
|
||||||
|
u8 i, rates, *pos;
|
||||||
|
int rate;
|
||||||
|
struct ieee80211_supported_band *rwnx_band_2GHz = rwnx_hw->wiphy->bands[NL80211_BAND_2GHZ];
|
||||||
|
|
||||||
|
rates = 8;
|
||||||
|
|
||||||
|
if (skb_tailroom(skb) < rates + 2)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
pos = skb_put(skb, rates + 2);
|
||||||
|
*pos++ = WLAN_EID_SUPP_RATES;
|
||||||
|
*pos++ = rates;
|
||||||
|
for (i = 0; i < rates; i++) {
|
||||||
|
rate = rwnx_band_2GHz->bitrates[i].bitrate;
|
||||||
|
rate = DIV_ROUND_UP(rate, 5);
|
||||||
|
*pos++ = (u8)rate;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
rwnx_add_ext_srates_ie(struct rwnx_hw *rwnx_hw, struct sk_buff *skb)
|
||||||
|
{
|
||||||
|
u8 i, exrates, *pos;
|
||||||
|
int rate;
|
||||||
|
struct ieee80211_supported_band *rwnx_band_2GHz = rwnx_hw->wiphy->bands[NL80211_BAND_2GHZ];
|
||||||
|
|
||||||
|
exrates = rwnx_band_2GHz->n_bitrates - 8;
|
||||||
|
|
||||||
|
if (skb_tailroom(skb) < exrates + 2)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
pos = skb_put(skb, exrates + 2);
|
||||||
|
*pos++ = WLAN_EID_EXT_SUPP_RATES;
|
||||||
|
*pos++ = exrates;
|
||||||
|
for (i = 8; i < (8+exrates); i++) {
|
||||||
|
rate = rwnx_band_2GHz->bitrates[i].bitrate;
|
||||||
|
rate = DIV_ROUND_UP(rate, 5);
|
||||||
|
*pos++ = (u8)rate;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
rwnx_tdls_add_supp_channels(struct rwnx_hw *rwnx_hw, struct sk_buff *skb)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Add possible channels for TDLS. These are channels that are allowed
|
||||||
|
* to be active.
|
||||||
|
*/
|
||||||
|
u8 subband_cnt = 0;
|
||||||
|
u8 *pos_subband;
|
||||||
|
u8 *pos = skb_put(skb, 2);
|
||||||
|
struct ieee80211_supported_band *rwnx_band_2GHz = rwnx_hw->wiphy->bands[NL80211_BAND_2GHZ];
|
||||||
|
//#ifdef USE_5G
|
||||||
|
struct ieee80211_supported_band *rwnx_band_5GHz = rwnx_hw->wiphy->bands[NL80211_BAND_5GHZ];
|
||||||
|
//#endif
|
||||||
|
|
||||||
|
*pos++ = WLAN_EID_SUPPORTED_CHANNELS;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 5GHz and 2GHz channels numbers can overlap. Ignore this for now, as
|
||||||
|
* this doesn't happen in real world scenarios.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* 2GHz, with 5MHz spacing */
|
||||||
|
pos_subband = skb_put(skb, 2);
|
||||||
|
if (rwnx_band_2GHz->n_channels > 0)
|
||||||
|
{
|
||||||
|
*pos_subband++ = ieee80211_frequency_to_channel(rwnx_band_2GHz->channels[0].center_freq);
|
||||||
|
*pos_subband++ = rwnx_band_2GHz->n_channels;
|
||||||
|
subband_cnt++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 5GHz, with 20MHz spacing */
|
||||||
|
pos_subband = skb_put(skb, 2);
|
||||||
|
//#ifdef USE_5G
|
||||||
|
if(rwnx_hw->band_5g_support){
|
||||||
|
if (rwnx_band_5GHz->n_channels > 0)
|
||||||
|
{
|
||||||
|
*pos_subband++ = ieee80211_frequency_to_channel(rwnx_band_5GHz->channels[0].center_freq);
|
||||||
|
*pos_subband++ = rwnx_band_5GHz->n_channels;
|
||||||
|
subband_cnt++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//#endif
|
||||||
|
/* length */
|
||||||
|
*pos = 2 * subband_cnt;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
rwnx_tdls_add_ext_capab(struct rwnx_hw *rwnx_hw, struct sk_buff *skb)
|
||||||
|
{
|
||||||
|
u8 *pos = (void *)skb_put(skb, 7);
|
||||||
|
bool chan_switch = rwnx_hw->wiphy->features &
|
||||||
|
NL80211_FEATURE_TDLS_CHANNEL_SWITCH;
|
||||||
|
|
||||||
|
*pos++ = WLAN_EID_EXT_CAPABILITY;
|
||||||
|
*pos++ = 5; /* len */
|
||||||
|
*pos++ = 0x0;
|
||||||
|
*pos++ = 0x0;
|
||||||
|
*pos++ = 0x0;
|
||||||
|
*pos++ = WLAN_EXT_CAPA4_TDLS_BUFFER_STA |
|
||||||
|
(chan_switch ? WLAN_EXT_CAPA4_TDLS_CHAN_SWITCH : 0);
|
||||||
|
*pos++ = WLAN_EXT_CAPA5_TDLS_ENABLED;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
rwnx_add_wmm_info_ie(struct sk_buff *skb, u8 qosinfo)
|
||||||
|
{
|
||||||
|
u8 *pos = (void *)skb_put(skb, 9);
|
||||||
|
|
||||||
|
*pos++ = WLAN_EID_VENDOR_SPECIFIC;
|
||||||
|
*pos++ = 7; /* len */
|
||||||
|
*pos++ = 0x00; /* Microsoft OUI 00:50:F2 */
|
||||||
|
*pos++ = 0x50;
|
||||||
|
*pos++ = 0xf2;
|
||||||
|
*pos++ = 2; /* WME */
|
||||||
|
*pos++ = 0; /* WME info */
|
||||||
|
*pos++ = 1; /* WME ver */
|
||||||
|
*pos++ = qosinfo; /* U-APSD no in use */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* translate numbering in the WMM parameter IE to the mac80211 notation */
|
||||||
|
static u8 rwnx_ac_from_wmm(int ac)
|
||||||
|
{
|
||||||
|
switch (ac) {
|
||||||
|
default:
|
||||||
|
WARN_ON_ONCE(1);
|
||||||
|
case 0:
|
||||||
|
return AC_BE;
|
||||||
|
case 1:
|
||||||
|
return AC_BK;
|
||||||
|
case 2:
|
||||||
|
return AC_VI;
|
||||||
|
case 3:
|
||||||
|
return AC_VO;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
rwnx_add_wmm_param_ie(struct sk_buff *skb, u8 acm_bits, u32 *ac_params)
|
||||||
|
{
|
||||||
|
struct ieee80211_wmm_param_ie *wmm;
|
||||||
|
int i, j;
|
||||||
|
u8 cw_min, cw_max;
|
||||||
|
bool acm;
|
||||||
|
|
||||||
|
wmm = (void *)skb_put(skb, sizeof(struct ieee80211_wmm_param_ie));
|
||||||
|
memset(wmm, 0, sizeof(*wmm));
|
||||||
|
|
||||||
|
wmm->element_id = WLAN_EID_VENDOR_SPECIFIC;
|
||||||
|
wmm->len = sizeof(*wmm) - 2;
|
||||||
|
|
||||||
|
wmm->oui[0] = 0x00; /* Microsoft OUI 00:50:F2 */
|
||||||
|
wmm->oui[1] = 0x50;
|
||||||
|
wmm->oui[2] = 0xf2;
|
||||||
|
wmm->oui_type = 2; /* WME */
|
||||||
|
wmm->oui_subtype = 1; /* WME param */
|
||||||
|
wmm->version = 1; /* WME ver */
|
||||||
|
wmm->qos_info = 0; /* U-APSD not in use */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Use the EDCA parameters defined for the BSS, or default if the AP
|
||||||
|
* doesn't support it, as mandated by 802.11-2012 section 10.22.4
|
||||||
|
*/
|
||||||
|
for (i = 0; i < AC_MAX; i++) {
|
||||||
|
j = rwnx_ac_from_wmm(i);
|
||||||
|
cw_min = (ac_params[j] & 0xF0 ) >> 4;
|
||||||
|
cw_max = (ac_params[j] & 0xF00 ) >> 8;
|
||||||
|
acm = (acm_bits & (1 << j)) != 0;
|
||||||
|
|
||||||
|
wmm->ac[i].aci_aifsn = (i << 5) | (acm << 4) | (ac_params[j] & 0xF);
|
||||||
|
wmm->ac[i].cw = (cw_max << 4) | cw_min;
|
||||||
|
wmm->ac[i].txop_limit = (ac_params[j] & 0x0FFFF000 ) >> 12;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
rwnx_tdls_add_oper_classes(struct rwnx_vif *rwnx_vif, struct sk_buff *skb)
|
||||||
|
{
|
||||||
|
u8 *pos;
|
||||||
|
u8 op_class;
|
||||||
|
struct cfg80211_chan_def chan_def;
|
||||||
|
struct ieee80211_channel chan;
|
||||||
|
|
||||||
|
chan.band = rwnx_vif->sta.ap->band;
|
||||||
|
chan.center_freq = rwnx_vif->sta.ap->center_freq;
|
||||||
|
chan_def.chan = &chan;
|
||||||
|
chan_def.width = rwnx_vif->sta.ap->width;
|
||||||
|
chan_def.center_freq1 = rwnx_vif->sta.ap->center_freq1;
|
||||||
|
chan_def.center_freq2 = rwnx_vif->sta.ap->center_freq2;
|
||||||
|
|
||||||
|
if (!ieee80211_chandef_to_operating_class(&chan_def, &op_class))
|
||||||
|
return;
|
||||||
|
|
||||||
|
pos = skb_put(skb, 4);
|
||||||
|
*pos++ = WLAN_EID_SUPPORTED_REGULATORY_CLASSES;
|
||||||
|
*pos++ = 2; /* len */
|
||||||
|
|
||||||
|
// current op class
|
||||||
|
*pos++ = op_class;
|
||||||
|
*pos++ = op_class; /* give current operating class as alternate too */
|
||||||
|
|
||||||
|
// need to add 5GHz classes?
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
rwnx_ie_build_ht_cap(struct sk_buff *skb, struct ieee80211_sta_ht_cap *ht_cap,
|
||||||
|
u16 cap)
|
||||||
|
{
|
||||||
|
u8 *pos;
|
||||||
|
__le16 tmp;
|
||||||
|
|
||||||
|
pos = skb_put(skb, sizeof(struct ieee80211_ht_cap) + 2);
|
||||||
|
*pos++ = WLAN_EID_HT_CAPABILITY;
|
||||||
|
*pos++ = sizeof(struct ieee80211_ht_cap);
|
||||||
|
memset(pos, 0, sizeof(struct ieee80211_ht_cap));
|
||||||
|
|
||||||
|
/* capability flags */
|
||||||
|
tmp = cpu_to_le16(cap);
|
||||||
|
memcpy(pos, &tmp, sizeof(u16));
|
||||||
|
pos += sizeof(u16);
|
||||||
|
|
||||||
|
/* AMPDU parameters */
|
||||||
|
*pos++ = ht_cap->ampdu_factor |
|
||||||
|
(ht_cap->ampdu_density <<
|
||||||
|
IEEE80211_HT_AMPDU_PARM_DENSITY_SHIFT);
|
||||||
|
|
||||||
|
/* MCS set */
|
||||||
|
memcpy(pos, &ht_cap->mcs, sizeof(ht_cap->mcs));
|
||||||
|
pos += sizeof(ht_cap->mcs);
|
||||||
|
|
||||||
|
/* extended capabilities */
|
||||||
|
pos += sizeof(__le16);
|
||||||
|
|
||||||
|
/* BF capabilities */
|
||||||
|
pos += sizeof(__le32);
|
||||||
|
|
||||||
|
/* antenna selection */
|
||||||
|
pos += sizeof(u8);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
rwnx_ie_build_vht_cap(struct sk_buff *skb, struct ieee80211_sta_vht_cap *vht_cap,
|
||||||
|
u32 cap)
|
||||||
|
{
|
||||||
|
u8 *pos;
|
||||||
|
__le32 tmp;
|
||||||
|
|
||||||
|
pos = skb_put(skb, 14);
|
||||||
|
|
||||||
|
*pos++ = WLAN_EID_VHT_CAPABILITY;
|
||||||
|
*pos++ = sizeof(struct ieee80211_vht_cap);
|
||||||
|
memset(pos, 0, sizeof(struct ieee80211_vht_cap));
|
||||||
|
|
||||||
|
/* capability flags */
|
||||||
|
tmp = cpu_to_le32(cap);
|
||||||
|
memcpy(pos, &tmp, sizeof(u32));
|
||||||
|
pos += sizeof(u32);
|
||||||
|
|
||||||
|
/* VHT MCS set */
|
||||||
|
memcpy(pos, &vht_cap->vht_mcs, sizeof(vht_cap->vht_mcs));
|
||||||
|
pos += sizeof(vht_cap->vht_mcs);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
rwnx_tdls_add_bss_coex_ie(struct sk_buff *skb)
|
||||||
|
{
|
||||||
|
u8 *pos = (void *)skb_put(skb, 3);
|
||||||
|
|
||||||
|
*pos++ = WLAN_EID_BSS_COEX_2040;
|
||||||
|
*pos++ = 1; /* len */
|
||||||
|
|
||||||
|
*pos++ = WLAN_BSS_COEX_INFORMATION_REQUEST;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
rwnx_tdls_add_link_ie(struct rwnx_hw *rwnx_hw, struct rwnx_vif *rwnx_vif,
|
||||||
|
struct sk_buff *skb, const u8 *peer,
|
||||||
|
bool initiator)
|
||||||
|
{
|
||||||
|
struct ieee80211_tdls_lnkie *lnkid;
|
||||||
|
const u8 *init_addr, *rsp_addr;
|
||||||
|
|
||||||
|
if (initiator) {
|
||||||
|
init_addr = rwnx_hw->wiphy->perm_addr;
|
||||||
|
rsp_addr = peer;
|
||||||
|
} else {
|
||||||
|
init_addr = peer;
|
||||||
|
rsp_addr = rwnx_hw->wiphy->perm_addr;
|
||||||
|
}
|
||||||
|
|
||||||
|
lnkid = (void *)skb_put(skb, sizeof(struct ieee80211_tdls_lnkie));
|
||||||
|
|
||||||
|
lnkid->ie_type = WLAN_EID_LINK_ID;
|
||||||
|
lnkid->ie_len = sizeof(struct ieee80211_tdls_lnkie) - 2;
|
||||||
|
|
||||||
|
memcpy(lnkid->bssid, rwnx_vif->sta.ap->mac_addr, ETH_ALEN);
|
||||||
|
memcpy(lnkid->init_sta, init_addr, ETH_ALEN);
|
||||||
|
memcpy(lnkid->resp_sta, rsp_addr, ETH_ALEN);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
rwnx_tdls_add_aid_ie(struct rwnx_vif *rwnx_vif, struct sk_buff *skb)
|
||||||
|
{
|
||||||
|
u8 *pos = (void *)skb_put(skb, 4);
|
||||||
|
|
||||||
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 12, 0)
|
||||||
|
*pos++ = WLAN_EID_AID;
|
||||||
|
#else
|
||||||
|
*pos++ = 197;
|
||||||
|
#endif
|
||||||
|
*pos++ = 2; /* len */
|
||||||
|
*pos++ = rwnx_vif->sta.ap->aid;
|
||||||
|
}
|
||||||
|
|
||||||
|
static u8 *
|
||||||
|
rwnx_ie_build_ht_oper(struct rwnx_hw *rwnx_hw, struct rwnx_vif *rwnx_vif,
|
||||||
|
u8 *pos, struct ieee80211_sta_ht_cap *ht_cap,
|
||||||
|
u16 prot_mode)
|
||||||
|
{
|
||||||
|
struct ieee80211_ht_operation *ht_oper;
|
||||||
|
/* Build HT Information */
|
||||||
|
*pos++ = WLAN_EID_HT_OPERATION;
|
||||||
|
*pos++ = sizeof(struct ieee80211_ht_operation);
|
||||||
|
ht_oper = (struct ieee80211_ht_operation *)pos;
|
||||||
|
ht_oper->primary_chan = ieee80211_frequency_to_channel(
|
||||||
|
rwnx_vif->sta.ap->center_freq);
|
||||||
|
switch (rwnx_vif->sta.ap->width) {
|
||||||
|
case NL80211_CHAN_WIDTH_160:
|
||||||
|
case NL80211_CHAN_WIDTH_80P80:
|
||||||
|
case NL80211_CHAN_WIDTH_80:
|
||||||
|
case NL80211_CHAN_WIDTH_40:
|
||||||
|
if (rwnx_vif->sta.ap->center_freq1 > rwnx_vif->sta.ap->center_freq)
|
||||||
|
ht_oper->ht_param = IEEE80211_HT_PARAM_CHA_SEC_ABOVE;
|
||||||
|
else
|
||||||
|
ht_oper->ht_param = IEEE80211_HT_PARAM_CHA_SEC_BELOW;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ht_oper->ht_param = IEEE80211_HT_PARAM_CHA_SEC_NONE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (ht_cap->cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40 &&
|
||||||
|
rwnx_vif->sta.ap->width != NL80211_CHAN_WIDTH_20_NOHT &&
|
||||||
|
rwnx_vif->sta.ap->width != NL80211_CHAN_WIDTH_20)
|
||||||
|
ht_oper->ht_param |= IEEE80211_HT_PARAM_CHAN_WIDTH_ANY;
|
||||||
|
|
||||||
|
ht_oper->operation_mode = cpu_to_le16(prot_mode);
|
||||||
|
ht_oper->stbc_param = 0x0000;
|
||||||
|
|
||||||
|
/* It seems that Basic MCS set and Supported MCS set
|
||||||
|
are identical for the first 10 bytes */
|
||||||
|
memset(&ht_oper->basic_set, 0, 16);
|
||||||
|
memcpy(&ht_oper->basic_set, &ht_cap->mcs, 10);
|
||||||
|
|
||||||
|
return pos + sizeof(struct ieee80211_ht_operation);
|
||||||
|
}
|
||||||
|
|
||||||
|
static u8 *
|
||||||
|
rwnx_ie_build_vht_oper(struct rwnx_hw *rwnx_hw, struct rwnx_vif *rwnx_vif,
|
||||||
|
u8 *pos, struct ieee80211_sta_ht_cap *ht_cap,
|
||||||
|
u16 prot_mode)
|
||||||
|
{
|
||||||
|
struct ieee80211_vht_operation *vht_oper;
|
||||||
|
/* Build HT Information */
|
||||||
|
*pos++ = WLAN_EID_VHT_OPERATION;
|
||||||
|
*pos++ = sizeof(struct ieee80211_vht_operation);
|
||||||
|
vht_oper = (struct ieee80211_vht_operation *)pos;
|
||||||
|
|
||||||
|
switch (rwnx_vif->sta.ap->width) {
|
||||||
|
case NL80211_CHAN_WIDTH_80:
|
||||||
|
vht_oper->chan_width = IEEE80211_VHT_CHANWIDTH_80MHZ; // Channel Width
|
||||||
|
CCFS0(vht_oper) =
|
||||||
|
ieee80211_frequency_to_channel(rwnx_vif->sta.ap->center_freq); // Channel Center Frequency Segment 0
|
||||||
|
CCFS1(vht_oper) = 0; // Channel Center Frequency Segment 1 (N.A.)
|
||||||
|
break;
|
||||||
|
case NL80211_CHAN_WIDTH_160:
|
||||||
|
vht_oper->chan_width = IEEE80211_VHT_CHANWIDTH_160MHZ; // Channel Width
|
||||||
|
CCFS0(vht_oper) =
|
||||||
|
ieee80211_frequency_to_channel(rwnx_vif->sta.ap->center_freq); // Channel Center Frequency Segment 0
|
||||||
|
CCFS1(vht_oper) = 0; // Channel Center Frequency Segment 1 (N.A.)
|
||||||
|
break;
|
||||||
|
case NL80211_CHAN_WIDTH_80P80:
|
||||||
|
vht_oper->chan_width = IEEE80211_VHT_CHANWIDTH_80P80MHZ; // Channel Width
|
||||||
|
CCFS0(vht_oper) =
|
||||||
|
ieee80211_frequency_to_channel(rwnx_vif->sta.ap->center_freq1); // Channel Center Frequency Segment 0
|
||||||
|
CCFS1(vht_oper) =
|
||||||
|
ieee80211_frequency_to_channel(rwnx_vif->sta.ap->center_freq2); // Channel Center Frequency Segment 1
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
vht_oper->chan_width = IEEE80211_VHT_CHANWIDTH_USE_HT;
|
||||||
|
CCFS0(vht_oper) = 0;
|
||||||
|
CCFS1(vht_oper) = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
vht_oper->basic_mcs_set = cpu_to_le16(rwnx_hw->mod_params->mcs_map);
|
||||||
|
|
||||||
|
return pos + sizeof(struct ieee80211_vht_operation);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
rwnx_tdls_add_setup_start_ies(struct rwnx_hw *rwnx_hw, struct rwnx_vif *rwnx_vif,
|
||||||
|
struct sk_buff *skb, const u8 *peer,
|
||||||
|
u8 action_code, bool initiator,
|
||||||
|
const u8 *extra_ies, size_t extra_ies_len)
|
||||||
|
{
|
||||||
|
enum nl80211_band band = rwnx_vif->sta.ap->band;
|
||||||
|
struct ieee80211_supported_band *sband;
|
||||||
|
struct ieee80211_sta_ht_cap ht_cap;
|
||||||
|
struct ieee80211_sta_vht_cap vht_cap;
|
||||||
|
size_t offset = 0, noffset;
|
||||||
|
u8 *pos;
|
||||||
|
|
||||||
|
rcu_read_lock();
|
||||||
|
|
||||||
|
rwnx_add_srates_ie(rwnx_hw, skb);
|
||||||
|
rwnx_add_ext_srates_ie(rwnx_hw, skb);
|
||||||
|
rwnx_tdls_add_supp_channels(rwnx_hw, skb);
|
||||||
|
rwnx_tdls_add_ext_capab(rwnx_hw, skb);
|
||||||
|
|
||||||
|
/* add the QoS element if we support it */
|
||||||
|
if (/*local->hw.queues >= IEEE80211_NUM_ACS &&*/
|
||||||
|
action_code != WLAN_PUB_ACTION_TDLS_DISCOVER_RES)
|
||||||
|
rwnx_add_wmm_info_ie(skb, 0); /* no U-APSD */
|
||||||
|
|
||||||
|
rwnx_tdls_add_oper_classes(rwnx_vif, skb);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* with TDLS we can switch channels, and HT-caps are not necessarily
|
||||||
|
* the same on all bands. The specification limits the setup to a
|
||||||
|
* single HT-cap, so use the current band for now.
|
||||||
|
*/
|
||||||
|
sband = rwnx_hw->wiphy->bands[band];
|
||||||
|
memcpy(&ht_cap, &sband->ht_cap, sizeof(ht_cap));
|
||||||
|
if (((action_code == WLAN_TDLS_SETUP_REQUEST) ||
|
||||||
|
(action_code == WLAN_TDLS_SETUP_RESPONSE) ||
|
||||||
|
(action_code == WLAN_PUB_ACTION_TDLS_DISCOVER_RES)) &&
|
||||||
|
ht_cap.ht_supported /* (!sta || sta->sta.ht_cap.ht_supported)*/) {
|
||||||
|
rwnx_ie_build_ht_cap(skb, &ht_cap, ht_cap.cap);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ht_cap.ht_supported &&
|
||||||
|
(ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40))
|
||||||
|
rwnx_tdls_add_bss_coex_ie(skb);
|
||||||
|
|
||||||
|
rwnx_tdls_add_link_ie(rwnx_hw, rwnx_vif, skb, peer, initiator);
|
||||||
|
|
||||||
|
memcpy(&vht_cap, &sband->vht_cap, sizeof(vht_cap));
|
||||||
|
if (vht_cap.vht_supported) {
|
||||||
|
rwnx_tdls_add_aid_ie(rwnx_vif, skb);
|
||||||
|
rwnx_ie_build_vht_cap(skb, &vht_cap, vht_cap.cap);
|
||||||
|
// Operating mode Notification (optional)
|
||||||
|
}
|
||||||
|
|
||||||
|
/* add any remaining IEs */
|
||||||
|
if (extra_ies_len) {
|
||||||
|
noffset = extra_ies_len;
|
||||||
|
pos = skb_put(skb, noffset - offset);
|
||||||
|
memcpy(pos, extra_ies + offset, noffset - offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
rcu_read_unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
rwnx_tdls_add_setup_cfm_ies(struct rwnx_hw *rwnx_hw, struct rwnx_vif *rwnx_vif,
|
||||||
|
struct sk_buff *skb, const u8 *peer, bool initiator,
|
||||||
|
const u8 *extra_ies, size_t extra_ies_len)
|
||||||
|
{
|
||||||
|
struct ieee80211_supported_band *sband;
|
||||||
|
enum nl80211_band band = rwnx_vif->sta.ap->band;
|
||||||
|
struct ieee80211_sta_ht_cap ht_cap;
|
||||||
|
struct ieee80211_sta_vht_cap vht_cap;
|
||||||
|
|
||||||
|
size_t offset = 0, noffset;
|
||||||
|
struct rwnx_sta *sta, *ap_sta;
|
||||||
|
u8 *pos;
|
||||||
|
|
||||||
|
rcu_read_lock();
|
||||||
|
|
||||||
|
sta = rwnx_get_sta(rwnx_hw, peer);
|
||||||
|
ap_sta = rwnx_vif->sta.ap;
|
||||||
|
if (WARN_ON_ONCE(!sta || !ap_sta)) {
|
||||||
|
rcu_read_unlock();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* add the QoS param IE if both the peer and we support it */
|
||||||
|
if (sta->qos)
|
||||||
|
rwnx_add_wmm_param_ie(skb, ap_sta->acm, ap_sta->ac_param);
|
||||||
|
|
||||||
|
/* if HT support is only added in TDLS, we need an HT-operation IE */
|
||||||
|
sband = rwnx_hw->wiphy->bands[band];
|
||||||
|
memcpy(&ht_cap, &sband->ht_cap, sizeof(ht_cap));
|
||||||
|
if (ht_cap.ht_supported && !ap_sta->ht && sta->ht) {
|
||||||
|
pos = skb_put(skb, 2 + sizeof(struct ieee80211_ht_operation));
|
||||||
|
/* send an empty HT operation IE */
|
||||||
|
rwnx_ie_build_ht_oper(rwnx_hw, rwnx_vif, pos, &ht_cap, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
rwnx_tdls_add_link_ie(rwnx_hw, rwnx_vif, skb, peer, initiator);
|
||||||
|
|
||||||
|
memcpy(&vht_cap, &sband->vht_cap, sizeof(vht_cap));
|
||||||
|
if (vht_cap.vht_supported && !ap_sta->vht && sta->vht) {
|
||||||
|
pos = skb_put(skb, 2 + sizeof(struct ieee80211_vht_operation));
|
||||||
|
rwnx_ie_build_vht_oper(rwnx_hw, rwnx_vif, pos, &ht_cap, 0);
|
||||||
|
// Operating mode Notification (optional)
|
||||||
|
}
|
||||||
|
|
||||||
|
/* add any remaining IEs */
|
||||||
|
if (extra_ies_len) {
|
||||||
|
noffset = extra_ies_len;
|
||||||
|
pos = skb_put(skb, noffset - offset);
|
||||||
|
memcpy(pos, extra_ies + offset, noffset - offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
rcu_read_unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
rwnx_tdls_add_ies(struct rwnx_hw *rwnx_hw, struct rwnx_vif *rwnx_vif,
|
||||||
|
struct sk_buff *skb, const u8 *peer,
|
||||||
|
u8 action_code, u16 status_code,
|
||||||
|
bool initiator, const u8 *extra_ies,
|
||||||
|
size_t extra_ies_len, u8 oper_class,
|
||||||
|
struct cfg80211_chan_def *chandef)
|
||||||
|
{
|
||||||
|
switch (action_code) {
|
||||||
|
case WLAN_TDLS_SETUP_REQUEST:
|
||||||
|
case WLAN_TDLS_SETUP_RESPONSE:
|
||||||
|
case WLAN_PUB_ACTION_TDLS_DISCOVER_RES:
|
||||||
|
if (status_code == 0)
|
||||||
|
rwnx_tdls_add_setup_start_ies(rwnx_hw, rwnx_vif, skb, peer, action_code,
|
||||||
|
initiator, extra_ies, extra_ies_len);
|
||||||
|
break;
|
||||||
|
case WLAN_TDLS_SETUP_CONFIRM:
|
||||||
|
if (status_code == 0)
|
||||||
|
rwnx_tdls_add_setup_cfm_ies(rwnx_hw, rwnx_vif, skb, peer, initiator,
|
||||||
|
extra_ies, extra_ies_len);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WLAN_TDLS_TEARDOWN:
|
||||||
|
case WLAN_TDLS_DISCOVERY_REQUEST:
|
||||||
|
if (extra_ies_len)
|
||||||
|
memcpy(skb_put(skb, extra_ies_len), extra_ies,
|
||||||
|
extra_ies_len);
|
||||||
|
if (status_code == 0 || action_code == WLAN_TDLS_TEARDOWN)
|
||||||
|
rwnx_tdls_add_link_ie(rwnx_hw, rwnx_vif, skb, peer, initiator);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
rwnx_tdls_send_mgmt_packet_data(struct rwnx_hw *rwnx_hw, struct rwnx_vif *rwnx_vif,
|
||||||
|
const u8 *peer, u8 action_code, u8 dialog_token,
|
||||||
|
u16 status_code, u32 peer_capability, bool initiator,
|
||||||
|
const u8 *extra_ies, size_t extra_ies_len, u8 oper_class,
|
||||||
|
struct cfg80211_chan_def *chandef)
|
||||||
|
{
|
||||||
|
struct sk_buff *skb;
|
||||||
|
int ret = 0;
|
||||||
|
struct ieee80211_supported_band *rwnx_band_2GHz = rwnx_hw->wiphy->bands[NL80211_BAND_2GHZ];
|
||||||
|
//#ifdef USE_5G
|
||||||
|
struct ieee80211_supported_band *rwnx_band_5GHz = rwnx_hw->wiphy->bands[NL80211_BAND_5GHZ];
|
||||||
|
//#endif
|
||||||
|
int channels = rwnx_band_2GHz->n_channels;
|
||||||
|
|
||||||
|
if (rwnx_hw->band_5g_support){
|
||||||
|
channels += rwnx_band_5GHz->n_channels;
|
||||||
|
}
|
||||||
|
|
||||||
|
skb = netdev_alloc_skb(rwnx_vif->ndev,
|
||||||
|
sizeof(struct ieee80211_tdls_data) + // ethhdr + TDLS info
|
||||||
|
10 + /* supported rates */
|
||||||
|
6 + /* extended supported rates */
|
||||||
|
(2 + channels) + /* supported channels */
|
||||||
|
//#ifdef USE_5G
|
||||||
|
//(2 + rwnx_band_2GHz->n_channels + rwnx_band_5GHz->n_channels) + /* supported channels */
|
||||||
|
//#else
|
||||||
|
//(2 + rwnx_band_2GHz->n_channels) + /* supported channels */
|
||||||
|
//#endif
|
||||||
|
sizeof(struct ieee_types_extcap) +
|
||||||
|
sizeof(struct ieee80211_wmm_param_ie) +
|
||||||
|
4 + /* oper classes */
|
||||||
|
28 + //sizeof(struct ieee80211_ht_cap) +
|
||||||
|
sizeof(struct ieee_types_bss_co_2040) +
|
||||||
|
sizeof(struct ieee80211_tdls_lnkie) +
|
||||||
|
(2 + sizeof(struct ieee80211_vht_cap)) +
|
||||||
|
4 + /*AID*/
|
||||||
|
(2 + sizeof(struct ieee80211_ht_operation)) +
|
||||||
|
extra_ies_len);
|
||||||
|
|
||||||
|
if (!skb)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
switch (action_code) {
|
||||||
|
case WLAN_TDLS_SETUP_REQUEST:
|
||||||
|
case WLAN_TDLS_SETUP_RESPONSE:
|
||||||
|
case WLAN_TDLS_SETUP_CONFIRM:
|
||||||
|
case WLAN_TDLS_TEARDOWN:
|
||||||
|
case WLAN_TDLS_DISCOVERY_REQUEST:
|
||||||
|
ret = rwnx_tdls_prepare_encap_data(rwnx_hw, rwnx_vif, peer, action_code,
|
||||||
|
dialog_token, status_code, skb);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WLAN_PUB_ACTION_TDLS_DISCOVER_RES:
|
||||||
|
ret = rwnx_prep_tdls_direct(rwnx_hw, rwnx_vif, peer, action_code,
|
||||||
|
dialog_token, status_code, skb);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
ret = -ENOTSUPP;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ret < 0)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
rwnx_tdls_add_ies(rwnx_hw, rwnx_vif, skb, peer, action_code, status_code,
|
||||||
|
initiator, extra_ies, extra_ies_len, oper_class, chandef);
|
||||||
|
|
||||||
|
if (action_code == WLAN_PUB_ACTION_TDLS_DISCOVER_RES) {
|
||||||
|
u64 cookie;
|
||||||
|
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
|
||||||
|
struct cfg80211_mgmt_tx_params params;
|
||||||
|
|
||||||
|
params.len = skb->len;
|
||||||
|
params.buf = skb->data;
|
||||||
|
ret = rwnx_start_mgmt_xmit(rwnx_vif, NULL, ¶ms, false, &cookie);
|
||||||
|
#else
|
||||||
|
ret = rwnx_start_mgmt_xmit(rwnx_vif, NULL, NULL, false, 0, skb->data, skb->len, false, false, &cookie);
|
||||||
|
#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0) */
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (action_code) {
|
||||||
|
case WLAN_TDLS_SETUP_REQUEST:
|
||||||
|
case WLAN_TDLS_SETUP_RESPONSE:
|
||||||
|
case WLAN_TDLS_SETUP_CONFIRM:
|
||||||
|
skb->priority = 2;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
skb->priority = 5;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = rwnx_select_txq(rwnx_vif, skb);
|
||||||
|
ret = rwnx_start_xmit(skb, rwnx_vif->ndev);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
dev_kfree_skb(skb);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
54
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/rwnx_tdls.h
Normal file
54
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/rwnx_tdls.h
Normal file
|
|
@ -0,0 +1,54 @@
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
*
|
||||||
|
* @file rwnx_tdls.h
|
||||||
|
*
|
||||||
|
* @brief TDLS function declarations
|
||||||
|
*
|
||||||
|
* Copyright (C) RivieraWaves 2012-2019
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef RWNX_TDLS_H_
|
||||||
|
#define RWNX_TDLS_H_
|
||||||
|
|
||||||
|
#include "rwnx_defs.h"
|
||||||
|
|
||||||
|
struct ieee_types_header {
|
||||||
|
u8 element_id;
|
||||||
|
u8 len;
|
||||||
|
} __packed;
|
||||||
|
|
||||||
|
struct ieee_types_bss_co_2040 {
|
||||||
|
struct ieee_types_header ieee_hdr;
|
||||||
|
u8 bss_2040co;
|
||||||
|
} __packed;
|
||||||
|
|
||||||
|
struct ieee_types_extcap {
|
||||||
|
struct ieee_types_header ieee_hdr;
|
||||||
|
u8 ext_capab[8];
|
||||||
|
} __packed;
|
||||||
|
|
||||||
|
struct ieee_types_vht_cap {
|
||||||
|
struct ieee_types_header ieee_hdr;
|
||||||
|
struct ieee80211_vht_cap vhtcap;
|
||||||
|
} __packed;
|
||||||
|
|
||||||
|
struct ieee_types_vht_oper {
|
||||||
|
struct ieee_types_header ieee_hdr;
|
||||||
|
struct ieee80211_vht_operation vhtoper;
|
||||||
|
} __packed;
|
||||||
|
|
||||||
|
struct ieee_types_aid {
|
||||||
|
struct ieee_types_header ieee_hdr;
|
||||||
|
u16 aid;
|
||||||
|
} __packed;
|
||||||
|
|
||||||
|
int rwnx_tdls_send_mgmt_packet_data(struct rwnx_hw *rwnx_hw, struct rwnx_vif *rwnx_vif,
|
||||||
|
const u8 *peer, u8 action_code, u8 dialog_token,
|
||||||
|
u16 status_code, u32 peer_capability, bool initiator,
|
||||||
|
const u8 *extra_ies, size_t extra_ies_len, u8 oper_class,
|
||||||
|
struct cfg80211_chan_def *chandef);
|
||||||
|
|
||||||
|
#endif /* RWNX_TDLS_H_ */
|
||||||
226
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/rwnx_testmode.c
Normal file
226
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/rwnx_testmode.c
Normal file
|
|
@ -0,0 +1,226 @@
|
||||||
|
/**
|
||||||
|
****************************************************************************************
|
||||||
|
*
|
||||||
|
* @file rwnx_testmode.c
|
||||||
|
*
|
||||||
|
* @brief Test mode function definitions
|
||||||
|
*
|
||||||
|
* Copyright (C) RivieraWaves 2012-2019
|
||||||
|
*
|
||||||
|
****************************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <net/mac80211.h>
|
||||||
|
#include <net/netlink.h>
|
||||||
|
|
||||||
|
#include "rwnx_testmode.h"
|
||||||
|
#include "rwnx_msg_tx.h"
|
||||||
|
#include "rwnx_dini.h"
|
||||||
|
#include "reg_access.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This function handles the user application commands for register access.
|
||||||
|
*
|
||||||
|
* It retrieves command ID carried with RWNX_TM_ATTR_COMMAND and calls to the
|
||||||
|
* handlers respectively.
|
||||||
|
*
|
||||||
|
* If it's an unknown commdn ID, -ENOSYS is returned; or -ENOMSG if the
|
||||||
|
* mandatory fields(RWNX_TM_ATTR_REG_OFFSET,RWNX_TM_ATTR_REG_VALUE32)
|
||||||
|
* are missing; Otherwise 0 is replied indicating the success of the command execution.
|
||||||
|
*
|
||||||
|
* If RWNX_TM_ATTR_COMMAND is RWNX_TM_CMD_APP2DEV_REG_READ, the register read
|
||||||
|
* value is returned with RWNX_TM_ATTR_REG_VALUE32.
|
||||||
|
*
|
||||||
|
* @hw: ieee80211_hw object that represents the device
|
||||||
|
* @tb: general message fields from the user space
|
||||||
|
*/
|
||||||
|
int rwnx_testmode_reg(struct ieee80211_hw *hw, struct nlattr **tb)
|
||||||
|
{
|
||||||
|
struct rwnx_hw *rwnx_hw = hw->priv;
|
||||||
|
u32 mem_addr, val32;
|
||||||
|
struct sk_buff *skb;
|
||||||
|
int status = 0;
|
||||||
|
|
||||||
|
/* First check if register address is there */
|
||||||
|
if (!tb[RWNX_TM_ATTR_REG_OFFSET]) {
|
||||||
|
printk("Error finding register offset\n");
|
||||||
|
return -ENOMSG;
|
||||||
|
}
|
||||||
|
|
||||||
|
mem_addr = nla_get_u32(tb[RWNX_TM_ATTR_REG_OFFSET]);
|
||||||
|
|
||||||
|
switch (nla_get_u32(tb[RWNX_TM_ATTR_COMMAND])) {
|
||||||
|
case RWNX_TM_CMD_APP2DEV_REG_READ:
|
||||||
|
{
|
||||||
|
struct dbg_mem_read_cfm mem_read_cfm;
|
||||||
|
|
||||||
|
/*** Send the command to the LMAC ***/
|
||||||
|
if ((status = rwnx_send_dbg_mem_read_req(rwnx_hw, mem_addr, &mem_read_cfm)))
|
||||||
|
return status;
|
||||||
|
|
||||||
|
/* Allocate the answer message */
|
||||||
|
skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, 20);
|
||||||
|
if (!skb) {
|
||||||
|
printk("Error allocating memory\n");
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
val32 = mem_read_cfm.memdata;
|
||||||
|
if (nla_put_u32(skb, RWNX_TM_ATTR_REG_VALUE32, val32))
|
||||||
|
goto nla_put_failure;
|
||||||
|
|
||||||
|
/* Send the answer to upper layer */
|
||||||
|
status = cfg80211_testmode_reply(skb);
|
||||||
|
if (status < 0)
|
||||||
|
printk("Error sending msg : %d\n", status);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RWNX_TM_CMD_APP2DEV_REG_WRITE:
|
||||||
|
{
|
||||||
|
if (!tb[RWNX_TM_ATTR_REG_VALUE32]) {
|
||||||
|
printk("Error finding value to write\n");
|
||||||
|
return -ENOMSG;
|
||||||
|
} else {
|
||||||
|
val32 = nla_get_u32(tb[RWNX_TM_ATTR_REG_VALUE32]);
|
||||||
|
/* Send the command to the LMAC */
|
||||||
|
if ((status = rwnx_send_dbg_mem_write_req(rwnx_hw, mem_addr, val32)))
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
printk("Unknown testmode register command ID\n");
|
||||||
|
return -ENOSYS;
|
||||||
|
}
|
||||||
|
|
||||||
|
return status;
|
||||||
|
|
||||||
|
nla_put_failure:
|
||||||
|
kfree_skb(skb);
|
||||||
|
return -EMSGSIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This function handles the user application commands for Debug filter settings.
|
||||||
|
*
|
||||||
|
* @hw: ieee80211_hw object that represents the device
|
||||||
|
* @tb: general message fields from the user space
|
||||||
|
*/
|
||||||
|
int rwnx_testmode_dbg_filter(struct ieee80211_hw *hw, struct nlattr **tb)
|
||||||
|
{
|
||||||
|
struct rwnx_hw *rwnx_hw = hw->priv;
|
||||||
|
u32 filter;
|
||||||
|
int status = 0;
|
||||||
|
|
||||||
|
/* First check if the filter is there */
|
||||||
|
if (!tb[RWNX_TM_ATTR_REG_FILTER]) {
|
||||||
|
printk("Error finding filter value\n");
|
||||||
|
return -ENOMSG;
|
||||||
|
}
|
||||||
|
|
||||||
|
filter = nla_get_u32(tb[RWNX_TM_ATTR_REG_FILTER]);
|
||||||
|
RWNX_DBG("testmode debug filter, setting: 0x%x\n", filter);
|
||||||
|
|
||||||
|
switch (nla_get_u32(tb[RWNX_TM_ATTR_COMMAND])) {
|
||||||
|
case RWNX_TM_CMD_APP2DEV_SET_DBGMODFILTER:
|
||||||
|
{
|
||||||
|
/* Send the command to the LMAC */
|
||||||
|
if ((status = rwnx_send_dbg_set_mod_filter_req(rwnx_hw, filter)))
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case RWNX_TM_CMD_APP2DEV_SET_DBGSEVFILTER:
|
||||||
|
{
|
||||||
|
/* Send the command to the LMAC */
|
||||||
|
if ((status = rwnx_send_dbg_set_sev_filter_req(rwnx_hw, filter)))
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
printk("Unknown testmode register command ID\n");
|
||||||
|
return -ENOSYS;
|
||||||
|
}
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This function handles the user application commands for register access without using
|
||||||
|
* the normal LMAC messaging way.
|
||||||
|
* This time register access will be done through direct PCI BAR windows. This can be used
|
||||||
|
* to access registers even when the :AMC FW is stuck.
|
||||||
|
*
|
||||||
|
* @hw: ieee80211_hw object that represents the device
|
||||||
|
* @tb: general message fields from the user space
|
||||||
|
*/
|
||||||
|
int rwnx_testmode_reg_dbg(struct ieee80211_hw *hw, struct nlattr **tb)
|
||||||
|
{
|
||||||
|
struct rwnx_hw *rwnx_hw = hw->priv;
|
||||||
|
struct rwnx_plat *rwnx_plat = rwnx_hw->plat;
|
||||||
|
u32 mem_addr;
|
||||||
|
struct sk_buff *skb;
|
||||||
|
int status = 0;
|
||||||
|
volatile unsigned int reg_value = 0;
|
||||||
|
unsigned int offset;
|
||||||
|
|
||||||
|
/* First check if register address is there */
|
||||||
|
if (!tb[RWNX_TM_ATTR_REG_OFFSET]) {
|
||||||
|
printk("Error finding register offset\n");
|
||||||
|
return -ENOMSG;
|
||||||
|
}
|
||||||
|
|
||||||
|
mem_addr = nla_get_u32(tb[RWNX_TM_ATTR_REG_OFFSET]);
|
||||||
|
offset = mem_addr & 0x00FFFFFF;
|
||||||
|
|
||||||
|
switch (nla_get_u32(tb[RWNX_TM_ATTR_COMMAND])) {
|
||||||
|
case RWNX_TM_CMD_APP2DEV_REG_READ_DBG:
|
||||||
|
{
|
||||||
|
/*** Send the command to the LMAC ***/
|
||||||
|
reg_value = RWNX_REG_READ(rwnx_plat, RWNX_ADDR_SYSTEM, offset);
|
||||||
|
|
||||||
|
/* Allocate the answer message */
|
||||||
|
skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, 20);
|
||||||
|
if (!skb) {
|
||||||
|
printk("Error allocating memory\n");
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nla_put_u32(skb, RWNX_TM_ATTR_REG_VALUE32, reg_value))
|
||||||
|
goto nla_put_failure;
|
||||||
|
|
||||||
|
/* Send the answer to upper layer */
|
||||||
|
status = cfg80211_testmode_reply(skb);
|
||||||
|
if (status < 0)
|
||||||
|
printk("Error sending msg : %d\n", status);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RWNX_TM_CMD_APP2DEV_REG_WRITE_DBG:
|
||||||
|
{
|
||||||
|
if (!tb[RWNX_TM_ATTR_REG_VALUE32]) {
|
||||||
|
printk("Error finding value to write\n");
|
||||||
|
return -ENOMSG;
|
||||||
|
} else {
|
||||||
|
reg_value = nla_get_u32(tb[RWNX_TM_ATTR_REG_VALUE32]);
|
||||||
|
|
||||||
|
/* Send the command to the LMAC */
|
||||||
|
RWNX_REG_WRITE(reg_value, rwnx_plat, RWNX_ADDR_SYSTEM,
|
||||||
|
offset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
printk("Unknown testmode register command ID\n");
|
||||||
|
return -ENOSYS;
|
||||||
|
}
|
||||||
|
|
||||||
|
return status;
|
||||||
|
|
||||||
|
nla_put_failure:
|
||||||
|
kfree_skb(skb);
|
||||||
|
return -EMSGSIZE;
|
||||||
|
}
|
||||||
64
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/rwnx_testmode.h
Normal file
64
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/rwnx_testmode.h
Normal file
|
|
@ -0,0 +1,64 @@
|
||||||
|
/**
|
||||||
|
****************************************************************************************
|
||||||
|
*
|
||||||
|
* @file rwnx_testmode.h
|
||||||
|
*
|
||||||
|
* @brief Test mode function declarations
|
||||||
|
*
|
||||||
|
* Copyright (C) RivieraWaves 2012-2019
|
||||||
|
*
|
||||||
|
****************************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef RWNX_TESTMODE_H_
|
||||||
|
#define RWNX_TESTMODE_H_
|
||||||
|
|
||||||
|
#include <net/mac80211.h>
|
||||||
|
#include <net/netlink.h>
|
||||||
|
|
||||||
|
/* Commands from user space to kernel space(RWNX_TM_CMD_APP2DEV_XX) and
|
||||||
|
* from and kernel space to user space(RWNX_TM_CMD_DEV2APP_XX).
|
||||||
|
* The command ID is carried with RWNX_TM_ATTR_COMMAND.
|
||||||
|
*/
|
||||||
|
enum rwnx_tm_cmd_t {
|
||||||
|
/* commands from user application to access register */
|
||||||
|
RWNX_TM_CMD_APP2DEV_REG_READ = 1,
|
||||||
|
RWNX_TM_CMD_APP2DEV_REG_WRITE,
|
||||||
|
|
||||||
|
/* commands from user application to select the Debug levels */
|
||||||
|
RWNX_TM_CMD_APP2DEV_SET_DBGMODFILTER,
|
||||||
|
RWNX_TM_CMD_APP2DEV_SET_DBGSEVFILTER,
|
||||||
|
|
||||||
|
/* commands to access registers without sending messages to LMAC layer,
|
||||||
|
* this must be used when LMAC FW is stuck. */
|
||||||
|
RWNX_TM_CMD_APP2DEV_REG_READ_DBG,
|
||||||
|
RWNX_TM_CMD_APP2DEV_REG_WRITE_DBG,
|
||||||
|
|
||||||
|
RWNX_TM_CMD_MAX,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum rwnx_tm_attr_t {
|
||||||
|
RWNX_TM_ATTR_NOT_APPLICABLE = 0,
|
||||||
|
|
||||||
|
RWNX_TM_ATTR_COMMAND,
|
||||||
|
|
||||||
|
/* When RWNX_TM_ATTR_COMMAND is RWNX_TM_CMD_APP2DEV_REG_XXX,
|
||||||
|
* The mandatory fields are:
|
||||||
|
* RWNX_TM_ATTR_REG_OFFSET for the offset of the target register;
|
||||||
|
* RWNX_TM_ATTR_REG_VALUE32 for value */
|
||||||
|
RWNX_TM_ATTR_REG_OFFSET,
|
||||||
|
RWNX_TM_ATTR_REG_VALUE32,
|
||||||
|
|
||||||
|
/* When RWNX_TM_ATTR_COMMAND is RWNX_TM_CMD_APP2DEV_SET_DBGXXXFILTER,
|
||||||
|
* The mandatory field is RWNX_TM_ATTR_REG_FILTER. */
|
||||||
|
RWNX_TM_ATTR_REG_FILTER,
|
||||||
|
|
||||||
|
RWNX_TM_ATTR_MAX,
|
||||||
|
};
|
||||||
|
|
||||||
|
/***********************************************************************/
|
||||||
|
int rwnx_testmode_reg(struct ieee80211_hw *hw, struct nlattr **tb);
|
||||||
|
int rwnx_testmode_dbg_filter(struct ieee80211_hw *hw, struct nlattr **tb);
|
||||||
|
int rwnx_testmode_reg_dbg(struct ieee80211_hw *hw, struct nlattr **tb);
|
||||||
|
|
||||||
|
#endif /* RWNX_TESTMODE_H_ */
|
||||||
2492
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/rwnx_tx.c
Executable file
2492
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/rwnx_tx.c
Executable file
File diff suppressed because it is too large
Load diff
202
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/rwnx_tx.h
Normal file
202
usr/src/AIC8800/drivers/aic8800/aic8800_fdrv/rwnx_tx.h
Normal file
|
|
@ -0,0 +1,202 @@
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
*
|
||||||
|
* @file rwnx_tx.h
|
||||||
|
*
|
||||||
|
* Copyright (C) RivieraWaves 2012-2019
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
#ifndef _RWNX_TX_H_
|
||||||
|
#define _RWNX_TX_H_
|
||||||
|
|
||||||
|
#include <linux/ieee80211.h>
|
||||||
|
#include <net/cfg80211.h>
|
||||||
|
#include <linux/netdevice.h>
|
||||||
|
#include "lmac_types.h"
|
||||||
|
#include "ipc_shared.h"
|
||||||
|
#include "rwnx_txq.h"
|
||||||
|
#include "hal_desc.h"
|
||||||
|
|
||||||
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0)
|
||||||
|
#define IEEE80211_NUM_TIDS 16
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define RWNX_HWQ_BK 0
|
||||||
|
#define RWNX_HWQ_BE 1
|
||||||
|
#define RWNX_HWQ_VI 2
|
||||||
|
#define RWNX_HWQ_VO 3
|
||||||
|
#define RWNX_HWQ_BCMC 4
|
||||||
|
#define RWNX_HWQ_NB NX_TXQ_CNT
|
||||||
|
#define RWNX_HWQ_ALL_ACS (RWNX_HWQ_BK | RWNX_HWQ_BE | RWNX_HWQ_VI | RWNX_HWQ_VO)
|
||||||
|
#define RWNX_HWQ_ALL_ACS_BIT ( BIT(RWNX_HWQ_BK) | BIT(RWNX_HWQ_BE) | \
|
||||||
|
BIT(RWNX_HWQ_VI) | BIT(RWNX_HWQ_VO) )
|
||||||
|
|
||||||
|
#define RWNX_TX_LIFETIME_MS 1000
|
||||||
|
#define RWNX_TX_MAX_RATES NX_TX_MAX_RATES
|
||||||
|
|
||||||
|
#define RWNX_SWTXHDR_ALIGN_SZ 4
|
||||||
|
#define RWNX_SWTXHDR_ALIGN_MSK (RWNX_SWTXHDR_ALIGN_SZ - 1)
|
||||||
|
#define RWNX_SWTXHDR_ALIGN_PADS(x) \
|
||||||
|
((RWNX_SWTXHDR_ALIGN_SZ - ((x) & RWNX_SWTXHDR_ALIGN_MSK)) \
|
||||||
|
& RWNX_SWTXHDR_ALIGN_MSK)
|
||||||
|
#if RWNX_SWTXHDR_ALIGN_SZ & RWNX_SWTXHDR_ALIGN_MSK
|
||||||
|
#error bad RWNX_SWTXHDR_ALIGN_SZ
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define AMSDU_PADDING(x) ((4 - ((x) & 0x3)) & 0x3)
|
||||||
|
|
||||||
|
#define TXU_CNTRL_RETRY BIT(0)
|
||||||
|
#define TXU_CNTRL_MORE_DATA BIT(2)
|
||||||
|
#define TXU_CNTRL_MGMT BIT(3)
|
||||||
|
#define TXU_CNTRL_MGMT_NO_CCK BIT(4)
|
||||||
|
#define TXU_CNTRL_AMSDU BIT(6)
|
||||||
|
#define TXU_CNTRL_MGMT_ROBUST BIT(7)
|
||||||
|
#define TXU_CNTRL_USE_4ADDR BIT(8)
|
||||||
|
#define TXU_CNTRL_EOSP BIT(9)
|
||||||
|
#define TXU_CNTRL_MESH_FWD BIT(10)
|
||||||
|
#define TXU_CNTRL_TDLS BIT(11)
|
||||||
|
|
||||||
|
extern const int rwnx_tid2hwq[IEEE80211_NUM_TIDS];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct rwnx_amsdu_txhdr - Structure added in skb headroom (instead of
|
||||||
|
* rwnx_txhdr) for amsdu subframe buffer (except for the first subframe
|
||||||
|
* that has a normal rwnx_txhdr)
|
||||||
|
*
|
||||||
|
* @list List of other amsdu subframe (rwnx_sw_txhdr.amsdu.hdrs)
|
||||||
|
* @map_len Length to be downloaded for this subframe
|
||||||
|
* @dma_addr Buffer address form embedded point of view
|
||||||
|
* @skb skb
|
||||||
|
* @pad padding added before this subframe
|
||||||
|
* (only use when amsdu must be dismantled)
|
||||||
|
* @msdu_len Size, in bytes, of the MSDU (without padding nor amsdu header)
|
||||||
|
*/
|
||||||
|
struct rwnx_amsdu_txhdr {
|
||||||
|
struct list_head list;
|
||||||
|
size_t map_len;
|
||||||
|
dma_addr_t dma_addr;
|
||||||
|
struct sk_buff *skb;
|
||||||
|
u16 pad;
|
||||||
|
u16 msdu_len;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct rwnx_amsdu - Structure to manage creation of an A-MSDU, updated
|
||||||
|
* only In the first subframe of an A-MSDU
|
||||||
|
*
|
||||||
|
* @hdrs List of subframe of rwnx_amsdu_txhdr
|
||||||
|
* @len Current size for this A-MDSU (doesn't take padding into account)
|
||||||
|
* 0 means that no amsdu is in progress
|
||||||
|
* @nb Number of subframe in the amsdu
|
||||||
|
* @pad Padding to add before adding a new subframe
|
||||||
|
*/
|
||||||
|
struct rwnx_amsdu {
|
||||||
|
struct list_head hdrs;
|
||||||
|
u16 len;
|
||||||
|
u8 nb;
|
||||||
|
u8 pad;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct rwnx_sw_txhdr - Software part of tx header
|
||||||
|
*
|
||||||
|
* @rwnx_sta sta to which this buffer is addressed
|
||||||
|
* @rwnx_vif vif that send the buffer
|
||||||
|
* @txq pointer to TXQ used to send the buffer
|
||||||
|
* @hw_queue Index of the HWQ used to push the buffer.
|
||||||
|
* May be different than txq->hwq->id on confirmation.
|
||||||
|
* @frame_len Size of the frame (doesn't not include mac header)
|
||||||
|
* (Only used to update stat, can't we use skb->len instead ?)
|
||||||
|
* @headroom Headroom added in skb to add rwnx_txhdr
|
||||||
|
* (Only used to remove it before freeing skb, is it needed ?)
|
||||||
|
* @amsdu Description of amsdu whose first subframe is this buffer
|
||||||
|
* (amsdu.nb = 0 means this buffer is not part of amsdu)
|
||||||
|
* @skb skb received from transmission
|
||||||
|
* @map_len Length mapped for DMA (only rwnx_hw_txhdr and data are mapped)
|
||||||
|
* @dma_addr DMA address after mapping
|
||||||
|
* @desc Buffer description that will be copied in shared mem for FW
|
||||||
|
*/
|
||||||
|
struct rwnx_sw_txhdr {
|
||||||
|
struct rwnx_sta *rwnx_sta;
|
||||||
|
struct rwnx_vif *rwnx_vif;
|
||||||
|
struct rwnx_txq *txq;
|
||||||
|
u8 hw_queue;
|
||||||
|
u16 frame_len;
|
||||||
|
u16 headroom;
|
||||||
|
#ifdef CONFIG_RWNX_AMSDUS_TX
|
||||||
|
struct rwnx_amsdu amsdu;
|
||||||
|
#endif
|
||||||
|
u32 need_cfm;
|
||||||
|
struct sk_buff *skb;
|
||||||
|
|
||||||
|
size_t map_len;
|
||||||
|
dma_addr_t dma_addr;
|
||||||
|
struct txdesc_api desc;
|
||||||
|
u8 raw_frame;
|
||||||
|
u8 fixed_rate;
|
||||||
|
u16 rate_config;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct rwnx_txhdr - Stucture to control transimission of packet
|
||||||
|
* (Added in skb headroom)
|
||||||
|
*
|
||||||
|
* @sw_hdr: Information from driver
|
||||||
|
* @cache_guard:
|
||||||
|
* @hw_hdr: Information for/from hardware
|
||||||
|
*/
|
||||||
|
struct rwnx_txhdr {
|
||||||
|
struct rwnx_sw_txhdr *sw_hdr;
|
||||||
|
char cache_guard[L1_CACHE_BYTES];
|
||||||
|
struct rwnx_hw_txhdr hw_hdr;
|
||||||
|
};
|
||||||
|
|
||||||
|
u16 rwnx_select_txq(struct rwnx_vif *rwnx_vif, struct sk_buff *skb);
|
||||||
|
netdev_tx_t rwnx_start_xmit(struct sk_buff *skb, struct net_device *dev);
|
||||||
|
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
|
||||||
|
int rwnx_start_mgmt_xmit(struct rwnx_vif *vif, struct rwnx_sta *sta,
|
||||||
|
struct cfg80211_mgmt_tx_params *params, bool offchan,
|
||||||
|
u64 *cookie);
|
||||||
|
#else
|
||||||
|
int rwnx_start_mgmt_xmit(struct rwnx_vif *vif, struct rwnx_sta *sta,
|
||||||
|
struct ieee80211_channel *channel, bool offchan,
|
||||||
|
unsigned int wait, const u8* buf, size_t len,
|
||||||
|
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0))
|
||||||
|
bool no_cck,
|
||||||
|
#endif
|
||||||
|
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0))
|
||||||
|
bool dont_wait_for_ack,
|
||||||
|
#endif
|
||||||
|
u64 *cookie);
|
||||||
|
#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0) */
|
||||||
|
#ifdef CONFIG_RWNX_MON_XMIT
|
||||||
|
int rwnx_start_monitor_if_xmit(struct sk_buff *skb, struct net_device *dev);
|
||||||
|
#endif
|
||||||
|
int rwnx_txdatacfm(void *pthis, void *host_id);
|
||||||
|
|
||||||
|
struct rwnx_hw;
|
||||||
|
struct rwnx_sta;
|
||||||
|
void rwnx_set_traffic_status(struct rwnx_hw *rwnx_hw,
|
||||||
|
struct rwnx_sta *sta,
|
||||||
|
bool available,
|
||||||
|
u8 ps_id);
|
||||||
|
void rwnx_ps_bh_enable(struct rwnx_hw *rwnx_hw, struct rwnx_sta *sta,
|
||||||
|
bool enable);
|
||||||
|
void rwnx_ps_bh_traffic_req(struct rwnx_hw *rwnx_hw, struct rwnx_sta *sta,
|
||||||
|
u16 pkt_req, u8 ps_id);
|
||||||
|
|
||||||
|
void rwnx_switch_vif_sta_txq(struct rwnx_sta *sta, struct rwnx_vif *old_vif,
|
||||||
|
struct rwnx_vif *new_vif);
|
||||||
|
|
||||||
|
int rwnx_dbgfs_print_sta(char *buf, size_t size, struct rwnx_sta *sta,
|
||||||
|
struct rwnx_hw *rwnx_hw);
|
||||||
|
void rwnx_txq_credit_update(struct rwnx_hw *rwnx_hw, int sta_idx, u8 tid,
|
||||||
|
s8 update);
|
||||||
|
void rwnx_tx_push(struct rwnx_hw *rwnx_hw, struct rwnx_txhdr *txhdr, int flags);
|
||||||
|
#ifdef CONFIG_BAND_STEERING
|
||||||
|
void rwnx_probersp_work(struct work_struct *work);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* _RWNX_TX_H_ */
|
||||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue