diff --git a/.github/labeler.yml b/.github/labeler.yml index ede4bb5a02fce7..129357df2bf3bc 100644 --- a/.github/labeler.yml +++ b/.github/labeler.yml @@ -180,6 +180,13 @@ - changed-files: - any-glob-to-any-file: - "target/linux/starfive/**" +"target/stm32": +- changed-files: + - any-glob-to-any-file: + - "target/linux/stm32/**" + - "package/boot/arm-trusted-firmware-stm32/**" + - "package/boot/optee-os-stm32/**" + - "package/boot/uboot-stm32/**" "target/sunxi": - changed-files: - any-glob-to-any-file: diff --git a/config/Config-build.in b/config/Config-build.in index 41c1daccd99564..a9e968f944e787 100644 --- a/config/Config-build.in +++ b/config/Config-build.in @@ -70,7 +70,8 @@ menu "Global build settings" config USE_APK imply PACKAGE_apk-mbedtls - bool "Use APK instead of OPKG to build distribution (EXPERIMENTAL)" + bool "Use APK instead of OPKG to build distribution (BROKEN)" + depends on BROKEN comment "General build options" @@ -295,12 +296,22 @@ menu "Global build settings" Enable GCC Stack Smashing Protection (SSP) for userspace applications config PKG_CC_STACKPROTECTOR_NONE bool "None" + help + No stack smashing protection. config PKG_CC_STACKPROTECTOR_REGULAR bool "Regular" + help + Protects functions with vulnerable objects. + This includes functions with buffers larger than 8 bytes or calls to alloca. config PKG_CC_STACKPROTECTOR_STRONG bool "Strong" + help + Like Regular, but also protects functions with + local arrays or references to local frame addresses. config PKG_CC_STACKPROTECTOR_ALL bool "All" + help + Protects all functions. endchoice choice @@ -310,10 +321,18 @@ menu "Global build settings" Enable GCC Stack-Smashing Protection (SSP) for the kernel config KERNEL_CC_STACKPROTECTOR_NONE bool "None" + help + No stack smashing protection. config KERNEL_CC_STACKPROTECTOR_REGULAR bool "Regular" + help + Protects functions with vulnerable objects. + This includes functions with buffers larger than 8 bytes or calls to alloca. config KERNEL_CC_STACKPROTECTOR_STRONG bool "Strong" + help + Like Regular, but also protects functions with + local arrays or references to local frame addresses. endchoice config KERNEL_STACKPROTECTOR @@ -404,11 +423,11 @@ menu "Global build settings" endchoice - config SECCOMP + config USE_SECCOMP bool "Enable SECCOMP" select KERNEL_SECCOMP select PACKAGE_procd-seccomp - depends on (aarch64 || arm || armeb || mips || mipsel || mips64 || mips64el || i386 || powerpc || x86_64) + depends on (aarch64 || arm || armeb || mips || mipsel || mips64 || mips64el || i386 || loongarch64 || powerpc || x86_64) depends on !TARGET_uml default y help diff --git a/config/Config-kernel.in b/config/Config-kernel.in index 43ed9eaf36b861..64c8c63466a75a 100644 --- a/config/Config-kernel.in +++ b/config/Config-kernel.in @@ -333,6 +333,25 @@ if KERNEL_TASKSTATS endif +config KERNEL_PSI + bool "Compile the kernel with pressure stall information tracking" + help + Collect metrics that indicate how overcommitted the CPU, memory, + and IO capacity are in the system. + + If you say Y here, the kernel will create /proc/pressure/ with the + pressure statistics files cpu, memory, and io. These will indicate + the share of walltime in which some or all tasks in the system are + delayed due to contention of the respective resource. + + In kernels with cgroup support, cgroups (cgroup2 only) will + have cpu.pressure, memory.pressure, and io.pressure files, + which aggregate pressure stalls for the grouped tasks only. + + For more details see Documentation/accounting/psi.rst. + + Say N if unsure. + config KERNEL_KALLSYMS bool "Compile the kernel with symbol table information" default y if !SMALL_FLASH @@ -1187,9 +1206,11 @@ endif config KERNEL_NET_L3_MASTER_DEV bool "L3 Master device support" + default y if !SMALL_FLASH help This module provides glue between core networking code and device drivers to support L3 master devices like VRF. + Increases the compressed kernel size by ~4kB (as of Linux 6.6). config KERNEL_XDP_SOCKETS bool "XDP sockets support" @@ -1218,6 +1239,13 @@ config KERNEL_MPTCP_IPV6 default KERNEL_MPTCP endif +config KERNEL_NF_CONNTRACK_TIMEOUT + bool "Per-connection connection tracking timeout" + default y if !SMALL_FLASH + help + Select this option to enable support for per-connection conntrack timeouts. + Increases the (uncompressed) size of nf_conntrack.ko by ~8kB. + # # NFS related symbols # diff --git a/feeds.conf.default b/feeds.conf.default index fc679335e0e47f..581de056c41e3e 100644 --- a/feeds.conf.default +++ b/feeds.conf.default @@ -1,8 +1,4 @@ -src-git packages https://git.openwrt.org/feed/packages.git -src-git luci https://git.openwrt.org/project/luci.git -src-git routing https://git.openwrt.org/feed/routing.git -src-git telephony https://git.openwrt.org/feed/telephony.git -#src-git video https://github.com/openwrt/video.git -#src-git targets https://github.com/openwrt/targets.git -#src-git oldpackages http://git.openwrt.org/packages.git -#src-link custom /usr/src/openwrt/custom-feed +src-git packages https://git.openwrt.org/feed/packages.git;openwrt-24.10 +src-git luci https://git.openwrt.org/project/luci.git;openwrt-24.10 +src-git routing https://git.openwrt.org/feed/routing.git;openwrt-24.10 +src-git telephony https://git.openwrt.org/feed/telephony.git;openwrt-24.10 diff --git a/include/bpf.mk b/include/bpf.mk index 2b7aa8512c2cb9..b9c8034c683722 100644 --- a/include/bpf.mk +++ b/include/bpf.mk @@ -1,30 +1,40 @@ -BPF_DEPENDS := @HAS_BPF_TOOLCHAIN -LLVM_VER:= +BPF_DEPENDS := @HAS_BPF_TOOLCHAIN +@NEED_BPF_TOOLCHAIN CLANG_MIN_VER:=12 ifneq ($(CONFIG_USE_LLVM_HOST),) + find-llvm-tool=$(firstword $(shell PATH='$(BPF_PATH)' command -v $(1) || echo '$(firstword $(1))-not-found')) + BPF_TOOLCHAIN_HOST_PATH:=$(call qstrip,$(CONFIG_BPF_TOOLCHAIN_HOST_PATH)) ifneq ($(BPF_TOOLCHAIN_HOST_PATH),) BPF_PATH:=$(BPF_TOOLCHAIN_HOST_PATH)/bin:$(PATH) else BPF_PATH:=$(PATH) endif - CLANG:=$(firstword $(shell PATH='$(BPF_PATH)' command -v clang clang-13 clang-12 clang-11)) + CLANG:=$(call find-llvm-tool,clang clang-13 clang-12) LLVM_VER:=$(subst clang,,$(notdir $(CLANG))) -endif -ifneq ($(CONFIG_USE_LLVM_PREBUILT),) - CLANG:=$(TOPDIR)/llvm-bpf/bin/clang -endif -ifneq ($(CONFIG_USE_LLVM_BUILD),) - CLANG:=$(STAGING_DIR_HOST)/llvm-bpf/bin/clang -endif -LLVM_PATH:=$(dir $(CLANG)) -LLVM_LLC:=$(LLVM_PATH)/llc$(LLVM_VER) -LLVM_DIS:=$(LLVM_PATH)/llvm-dis$(LLVM_VER) -LLVM_OPT:=$(LLVM_PATH)/opt$(LLVM_VER) -LLVM_STRIP:=$(LLVM_PATH)/llvm-strip$(LLVM_VER) + BPF_PATH:=$(dir $(CLANG)):$(BPF_PATH) + LLVM_LLC:=$(call find-llvm-tool,llc$(LLVM_VER)) + LLVM_DIS:=$(call find-llvm-tool,llvm-dis$(LLVM_VER)) + LLVM_OPT:=$(call find-llvm-tool,opt$(LLVM_VER)) + LLVM_STRIP:=$(call find-llvm-tool,llvm-strip$(LLVM_VER)) +else + LLVM_PATH:=/invalid + + ifneq ($(CONFIG_USE_LLVM_PREBUILT),) + LLVM_PATH:=$(TOPDIR)/llvm-bpf/bin + endif + ifneq ($(CONFIG_USE_LLVM_BUILD),) + LLVM_PATH:=$(STAGING_DIR_HOST)/llvm-bpf/bin + endif + + CLANG:=$(LLVM_PATH)/clang + LLVM_LLC:=$(LLVM_PATH)/llc + LLVM_DIS:=$(LLVM_PATH)/llvm-dis + LLVM_OPT:=$(LLVM_PATH)/opt + LLVM_STRIP:=$(LLVM_PATH)/llvm-strip +endif BPF_KARCH:=mips BPF_ARCH:=mips$(if $(CONFIG_ARCH_64BIT),64)$(if $(CONFIG_BIG_ENDIAN),,el) diff --git a/include/cmake.mk b/include/cmake.mk index 87309dd0458a82..f59410c2f32dd8 100644 --- a/include/cmake.mk +++ b/include/cmake.mk @@ -97,7 +97,7 @@ define Build/Configure/Default -DCMAKE_SYSTEM_NAME=Linux \ -DCMAKE_SYSTEM_VERSION=1 \ -DCMAKE_SYSTEM_PROCESSOR=$(ARCH) \ - -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_BUILD_TYPE=$(if $(CONFIG_DEBUG),Debug,Release) \ -DCMAKE_C_FLAGS_RELEASE="-DNDEBUG" \ -DCMAKE_CXX_FLAGS_RELEASE="-DNDEBUG" \ -DCMAKE_C_COMPILER_LAUNCHER="$(CMAKE_C_COMPILER_LAUNCHER)" \ diff --git a/include/default-packages.mk b/include/default-packages.mk new file mode 100644 index 00000000000000..c964e92a033aec --- /dev/null +++ b/include/default-packages.mk @@ -0,0 +1,5 @@ +ifneq ($(CONFIG_USE_APK),) + DEFAULT_PACKAGES += apk-mbedtls +else + DEFAULT_PACKAGES += opkg +endif diff --git a/include/feeds.mk b/include/feeds.mk index 87b1562c3edbf7..c3a47cf5f92252 100644 --- a/include/feeds.mk +++ b/include/feeds.mk @@ -37,7 +37,7 @@ define FeedSourcesAppendOPKG echo 'src/gz %d_core %U/targets/%S/packages'; \ $(strip $(if $(CONFIG_PER_FEED_REPO), \ echo 'src/gz %d_base %U/packages/%A/base'; \ - $(if $(filter %SNAPSHOT-y,$(VERSION_NUMBER)-$(CONFIG_BUILDBOT)), \ + $(if $(CONFIG_BUILDBOT), \ echo 'src/gz %d_kmods %U/targets/%S/kmods/$(LINUX_VERSION)-$(LINUX_RELEASE)-$(LINUX_VERMAGIC)';) \ $(foreach feed,$(FEEDS_AVAILABLE), \ $(if $(CONFIG_FEED_$(feed)), \ @@ -51,7 +51,7 @@ define FeedSourcesAppendAPK echo '%U/targets/%S/packages/packages.adb'; \ $(strip $(if $(CONFIG_PER_FEED_REPO), \ echo '%U/packages/%A/base/packages.adb'; \ - $(if $(filter %SNAPSHOT-y,$(VERSION_NUMBER)-$(CONFIG_BUILDBOT)), \ + $(if $(CONFIG_BUILDBOT), \ echo '%U/targets/%S/kmods/$(LINUX_VERSION)-$(LINUX_RELEASE)-$(LINUX_VERMAGIC)/packages.adb';) \ $(foreach feed,$(FEEDS_AVAILABLE), \ $(if $(CONFIG_FEED_$(feed)), \ diff --git a/include/image-commands.mk b/include/image-commands.mk index 2568fb3ade5f3d..a627ffc202cc0a 100644 --- a/include/image-commands.mk +++ b/include/image-commands.mk @@ -732,6 +732,10 @@ define Build/zip rm -rf $@.tmp endef +define Build/zyimage + $(STAGING_DIR_HOST)/bin/zyimage $(1) $@ +endef + define Build/zyxel-ras-image let \ newsize="$(call exp_units,$(RAS_ROOTFS_SIZE))"; \ diff --git a/include/image.mk b/include/image.mk index a4ac1b49cf8aa4..6408719bdc48e3 100644 --- a/include/image.mk +++ b/include/image.mk @@ -21,6 +21,11 @@ include $(INCLUDE_DIR)/rootfs.mk override MAKE:=$(_SINGLE)$(SUBMAKE) override NO_TRACE_MAKE:=$(_SINGLE)$(NO_TRACE_MAKE) +##@ +# @brief Convert size with unit postfix to unitless expression in bytes. +# +# @param 1: Size with unit. Possible unit postfix are `g`, `m`, `k`. +## exp_units = $(subst k, * 1024,$(subst m, * 1024k,$(subst g, * 1024m,$(1)))) target_params = $(subst +,$(space),$*) @@ -111,6 +116,12 @@ endef PROFILE_SANITIZED := $(call tolower,$(subst DEVICE_,,$(subst $(space),-,$(PROFILE)))) +##@ +# @brief Call function for each group of arguments. +# +# @param 1: List of lists of arguments. Lists are separated by `|`. +# @param 2: Function to call for list of arguments. +## define split_args $(foreach data, \ $(subst |,$(space),\ @@ -118,12 +129,24 @@ $(foreach data, \ $(call $(2),$(strip $(subst ^,$(space),$(data))))) endef +##@ +# @brief Call build function with arguments. +# +# @param 1: Function to call. Function name is prepended with `Build/`. +# @param 2...: Function arguments. +## define build_cmd $(if $(Build/$(word 1,$(1))),,$(error Missing Build/$(word 1,$(1)))) $(call Build/$(word 1,$(1)),$(wordlist 2,$(words $(1)),$(1))) endef +##@ +# @brief Call build functions from the list. +# +# @param 1: List of build functions with arguments, separated by `|`. +# First word in each group is a build command without `Build/` prefix. +## define concat_cmd $(call split_args,$(1),build_cmd) endef @@ -163,6 +186,12 @@ DTC_WARN_FLAGS := \ DTC_FLAGS += $(DTC_WARN_FLAGS) DTCO_FLAGS += $(DTC_WARN_FLAGS) +##@ +# @brief Pad file to specified size. +# +# @param 1: File. +# @param 2: Padding. +## define Image/pad-to dd if=$(1) of=$(1).new bs=$(2) conv=sync mv $(1).new $(1) @@ -403,26 +432,53 @@ define Device/InitProfile DEVICE_DESCRIPTION = Build firmware images for $$(DEVICE_TITLE) endef +##@ +# @brief Image configuration variables. +# +# @param 1: Device name. +## define Device/Init + ##@ Device name. DEVICE_NAME := $(1) + ##@ Commands to build kernel. + # Commands with arguments are separated by `|`. + ## KERNEL:= + ##@ Commands to build initramfs. + # Commands with arguments are separated by `|`. + ## KERNEL_INITRAMFS = $$(KERNEL) + ##@ Kernel command line. CMDLINE:= + ##@ Images to build. IMAGES := + ##@ Artifacts to build. ARTIFACTS := + ##@ Device image prefix. DEVICE_IMG_PREFIX := $(IMG_PREFIX)-$(1) + ##@ Device image name. DEVICE_IMG_NAME = $$(DEVICE_IMG_PREFIX)-$$(1)-$$(2) + ##@ Factory image name. FACTORY_IMG_NAME := + ##@ Maximum image size. Optional. IMAGE_SIZE := + ##@ Maximum image size. Optional. NAND_SIZE := + ##@ Kernel image prefix. KERNEL_PREFIX = $$(DEVICE_IMG_PREFIX) + ##@ Kernel image suffix. KERNEL_SUFFIX := -kernel.bin + ##@ Initramfs image suffix. KERNEL_INITRAMFS_SUFFIX = $$(KERNEL_SUFFIX) + ##@ Kernel image name. KERNEL_IMAGE = $$(KERNEL_PREFIX)$$(KERNEL_SUFFIX) + ##@ Initramfs image prefix. KERNEL_INITRAMFS_PREFIX = $$(DEVICE_IMG_PREFIX)-initramfs KERNEL_INITRAMFS_IMAGE = $$(KERNEL_INITRAMFS_PREFIX)$$(KERNEL_INITRAMFS_SUFFIX) + ##@ Initramfs image name. KERNEL_INITRAMFS_NAME = $$(KERNEL_NAME)-initramfs + ##@ Kernel install flag. KERNEL_INSTALL := KERNEL_NAME := vmlinux KERNEL_DEPENDS := @@ -513,6 +569,15 @@ endef define Device/Check/Common _PROFILE_SET = $$(strip $$(foreach profile,$$(PROFILES) DEVICE_$(1),$$(call DEVICE_CHECK_PROFILE,$$(profile)))) + # Check if device is disabled and if so do not mark to be installed when ImageBuilder is used + ifeq ($(IB),1) + ifeq ($$(DEFAULT),n) + _PROFILE_SET := + endif + ifeq ($$(BROKEN),y) + _PROFILE_SET := + endif + endif DEVICE_PACKAGES += $$(call extra_packages,$$(DEVICE_PACKAGES)) ifdef TARGET_PER_DEVICE_ROOTFS $$(eval $$(call merge_packages,_PACKAGES,$$(DEVICE_PACKAGES) $$(call DEVICE_EXTRA_PACKAGES,$(1)))) diff --git a/include/kernel-6.6 b/include/kernel-6.6 index df3464ab4118fa..70decb678662eb 100644 --- a/include/kernel-6.6 +++ b/include/kernel-6.6 @@ -1,2 +1,2 @@ -LINUX_VERSION-6.6 = .58 -LINUX_KERNEL_HASH-6.6.58 = e7df81e588d70fab5ec3ec3bb04ac53d51f0860fc3b1ec45e0a4167a026899db +LINUX_VERSION-6.6 = .104 +LINUX_KERNEL_HASH-6.6.104 = 2a772f9d661afabaaddcdfd1116239acb2d943377aceab9e0baed2b7a915e36a diff --git a/include/kernel-defaults.mk b/include/kernel-defaults.mk index f94ed3323051f2..cbe415abe64ab9 100644 --- a/include/kernel-defaults.mk +++ b/include/kernel-defaults.mk @@ -175,7 +175,6 @@ define Kernel/PrepareConfigPerRootfs [ ! -d "$(1)" ] || rm -rf $(1); \ mkdir $(1) && $(CP) -T $(LINUX_DIR) $(1); \ touch $(1)/.config; \ - rm -rf $(1)/usr/initramfs_data.cpio*; \ } endef @@ -190,6 +189,7 @@ define Kernel/CompileImage/Initramfs $(call Kernel/Configure/Initramfs,$(if $(1),$(1),$(TARGET_DIR)),$(LINUX_DIR)$(2)); \ $(CP) $(GENERIC_PLATFORM_DIR)/other-files/init $(if $(1),$(1),$(TARGET_DIR))/init; \ $(if $(SOURCE_DATE_EPOCH),touch -hcd "@$(SOURCE_DATE_EPOCH)" $(if $(1),$(1),$(TARGET_DIR)) $(if $(1),$(1),$(TARGET_DIR))/init;) \ + rm -rf $(LINUX_DIR)$(2)/usr/initramfs_data.cpio*; \ $(if $(CONFIG_TARGET_ROOTFS_INITRAMFS_SEPARATE), \ $(call locked,{ \ $(if $(call qstrip,$(CONFIG_EXTERNAL_CPIO)), \ diff --git a/include/meson.mk b/include/meson.mk index 2a20c2bd6bd04e..ff452d8b01fa4c 100644 --- a/include/meson.mk +++ b/include/meson.mk @@ -124,7 +124,7 @@ define Build/Configure/Meson $(call Meson/CreateCrossFile,$(PKG_BUILD_DIR)/openwrt-cross.txt) $(call Meson, \ setup \ - --buildtype plain \ + --buildtype $(if $(CONFIG_DEBUG),debug,plain) \ --native-file $(PKG_BUILD_DIR)/openwrt-native.txt \ --cross-file $(PKG_BUILD_DIR)/openwrt-cross.txt \ -Ddefault_library=both \ diff --git a/include/optee-os.mk b/include/optee-os.mk new file mode 100644 index 00000000000000..3694b498fd583a --- /dev/null +++ b/include/optee-os.mk @@ -0,0 +1,113 @@ +include $(INCLUDE_DIR)/prereq.mk + +PKG_NAME ?= optee-os + +ifndef PKG_SOURCE_PROTO +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz +PKG_SOURCE_URL_FILE:=$(PKG_VERSION).tar.gz +PKG_SOURCE_URL = https://github.com/OP-TEE/optee_os/archive/refs/tags/ +TAR_OPTIONS+= --transform 's/optee_os/$(PKG_NAME)/' +endif + +PKG_BUILD_DIR = $(BUILD_DIR)/$(PKG_NAME)-$(BUILD_VARIANT)/$(PKG_NAME)-$(PKG_VERSION) + +PKG_TARGETS := bin +PKG_FLAGS:=nonshared + +PKG_LICENSE:=BSD 2-Clause +PKG_LICENSE_FILES:=LICENSE + +PKG_BUILD_PARALLEL ?= 1 + +$(eval $(call TestHostCommand,python3-cryptography, \ + Please install the Python3 cryptography module, \ + $(STAGING_DIR_HOST)/bin/python3 -c 'import cryptography')) + +$(eval $(call TestHostCommand,python3-pyelftools, \ + Please install the Python3 pyelftools module, \ + $(STAGING_DIR_HOST)/bin/python3 -c 'import elftools')) + +export GCC_HONOUR_COPTS=s + +define Package/optee-os/install/default + $(CP) $(patsubst %,$(PKG_BUILD_DIR)/out/arm-plat-$(PLAT)/core/%,$(OPTEE_IMAGE)) $(1)/ +endef + +Package/optee-os/install = $(Package/optee-os/install/default) + +define Optee-os/Init + BUILD_TARGET:= + BUILD_SUBTARGET:= + BUILD_DEVICES:= + NAME:= + DEPENDS:= + HIDDEN:= + DEFAULT:= + VARIANT:=$(1) + PLAT:=$(1) + PLAT_FLAVOR:= + OPTEE_IMAGE:=tee-header_v2.bin tee-pager_v2.bin tee-pageable_v2.bin +endef + +TARGET_DEP = TARGET_$(BUILD_TARGET)$(if $(BUILD_SUBTARGET),_$(BUILD_SUBTARGET)) + +define Build/Optee-os/Target + $(eval $(call Optee-os/Init,$(1))) + $(eval $(call Optee-os/Default,$(1))) + $(eval $(call Optee-os/$(1),$(1))) + + define Package/optee-os-$(1) + SECTION:=boot + CATEGORY:=Boot Loaders + TITLE:=OPTEE-OS for $(NAME) + VARIANT:=$(VARIANT) + DEPENDS:=@!IN_SDK $(DEPENDS) + HIDDEN:=$(HIDDEN) + ifneq ($(BUILD_TARGET),) + DEPENDS += @$(TARGET_DEP) + ifneq ($(BUILD_DEVICES),) + DEFAULT := y if ($(TARGET_DEP)_Default \ + $(patsubst %,|| $(TARGET_DEP)_DEVICE_%,$(BUILD_DEVICES)) \ + $(patsubst %,|| $(patsubst TARGET_%,TARGET_DEVICE_%,$(TARGET_DEP))_DEVICE_%,$(BUILD_DEVICES))) + endif + endif + $(if $(DEFAULT),DEFAULT:=$(DEFAULT)) + URL:=https://optee.readthedocs.io + endef + + define Package/optee-os-$(1)/install + $$(Package/optee-os/install) + endef +endef + +define Build/Configure/Optee-os +endef + +define Build/Compile/Optee-os + +$(MAKE) $(PKG_JOBS) -C $(PKG_BUILD_DIR) \ + PATH=$(LINUX_DIR)/scripts/dtc/:$(STAGING_DIR_HOST)/bin:$(PATH) \ + CROSS_COMPILE=$(TARGET_CROSS) \ + CROSS_COMPILE_core="$(TARGET_CROSS)" \ + CROSS_COMPILE_ta_arm64="$(TARGET_CROSS)" \ + CROSS_COMPILE_ta_arm32="$(TARGET_CROSS)" \ + $(if $(CONFIG_ARCH_64BIT), CFG_ARM64_core=y CFG_USER_TA_TARGETS=ta_arm64, CFG_ARM32_core=y) \ + PLATFORM="$(PLAT)" \ + PLATFORM_FLAVOR="$(call qstrip,$(PLAT_FLAVOR))" \ + $(OPTEE_MAKE_FLAGS) +endef + +define BuildPackage/Optee-os/Defaults + Build/Configure/Default = $$$$(Build/Configure/Optee-os) + Build/Compile/Default = $$$$(Build/Compile/Optee-os) +endef + +define BuildPackage/Optee-os + $(eval $(call BuildPackage/Optee-os/Defaults)) + $(foreach type,$(if $(DUMP),$(OPTEE_TARGETS),$(BUILD_VARIANT)), \ + $(eval $(call Build/Optee-os/Target,$(type))) + ) + $(eval $(call Build/DefaultTargets)) + $(foreach type,$(if $(DUMP),$(OPTEE_TARGETS),$(BUILD_VARIANT)), \ + $(call BuildPackage,optee-os-$(type)) + ) +endef diff --git a/include/target.mk b/include/target.mk index d13902ad6e78ec..02ea68b15c8121 100644 --- a/include/target.mk +++ b/include/target.mk @@ -7,10 +7,17 @@ ifneq ($(__target_inc),1) __target_inc=1 -# default device type +##@ +# @brief Default device type ( basic | nas | router ). +## DEVICE_TYPE?=router -# Default packages - the really basic set +##@ +# @brief Default packages. +# +# The really basic set. Additional packages are added based on @DEVICE_TYPE and +# @CONFIG_* values. +## DEFAULT_PACKAGES:=\ base-files \ ca-bundle \ @@ -27,15 +34,21 @@ DEFAULT_PACKAGES:=\ urandom-seed \ urngd -# For the basic set +##@ +# @brief Default packages for @DEVICE_TYPE basic. +## DEFAULT_PACKAGES.basic:= -# For nas targets +##@ +# @brief Default packages for @DEVICE_TYPE nas. +## DEFAULT_PACKAGES.nas:=\ block-mount \ fdisk \ lsblk \ mdadm -# For router targets +##@ +# @brief Default packages for @DEVICE_TYPE router. +## DEFAULT_PACKAGES.router:=\ dnsmasq \ firewall4 \ @@ -77,51 +90,26 @@ else endif endif -ifneq ($(DUMP),) - # Parse generic config that might be set before a .config is generated to modify the - # default package configuration - # Keep DYNAMIC_DEF_PKG_CONF in sync with toplevel.mk to reflect the same configs - DYNAMIC_DEF_PKG_CONF := CONFIG_USE_APK CONFIG_SELINUX CONFIG_SMALL_FLASH CONFIG_SECCOMP - $(foreach config, $(DYNAMIC_DEF_PKG_CONF), \ - $(eval $(config) := $(shell grep "$(config)=y" $(TOPDIR)/.config 2>/dev/null)) \ - ) - # The config options that are enabled by default and where other default - # packages depends on needs to be set if they are missing in the .config. - ifeq ($(shell grep "CONFIG_SECCOMP" $(TOPDIR)/.config 2>/dev/null),) - ifeq ($(filter $(BOARD), uml),) - ifneq ($(filter $(ARCH), aarch64 arm armeb mips mipsel mips64 mips64el i386 powerpc x86_64),) - CONFIG_SECCOMP := y - endif - endif - endif -endif - -ifneq ($(CONFIG_USE_APK),) -DEFAULT_PACKAGES+=apk-mbedtls -else -DEFAULT_PACKAGES+=opkg -endif - -ifneq ($(CONFIG_SELINUX),) -DEFAULT_PACKAGES+=busybox-selinux procd-selinux -else -DEFAULT_PACKAGES+=busybox procd -endif - # include ujail on systems with enough storage -ifeq ($(CONFIG_SMALL_FLASH),) -DEFAULT_PACKAGES+=procd-ujail -endif - -# include seccomp ld-preload hooks if kernel supports it -ifneq ($(CONFIG_SECCOMP),) -DEFAULT_PACKAGES+=procd-seccomp +ifeq ($(filter small_flash,$(FEATURES)),) + DEFAULT_PACKAGES+=procd-ujail endif # Add device specific packages (here below to allow device type set from subtarget) DEFAULT_PACKAGES += $(DEFAULT_PACKAGES.$(DEVICE_TYPE)) +##@ +# @brief Filter out packages, prepended with `-`. +# +# @param 1: Package list. +## filter_packages = $(filter-out -% $(patsubst -%,%,$(filter -%,$(1))),$(1)) + +##@ +# @brief Append extra package dependencies. +# +# @param 1: Package list. +## extra_packages = $(if $(filter wpad wpad-% nas,$(1)),iwinfo) define ProfileDefault diff --git a/include/toplevel.mk b/include/toplevel.mk index e5f5e0fecd8de4..092dff786c9922 100644 --- a/include/toplevel.mk +++ b/include/toplevel.mk @@ -75,22 +75,7 @@ endif _ignore = $(foreach p,$(IGNORE_PACKAGES),--ignore $(p)) -# Config that will invalidate the .targetinfo as they will affect -# DEFAULT_PACKAGES. -# Keep DYNAMIC_DEF_PKG_CONF in sync with target.mk to reflect the same configs -DYNAMIC_DEF_PKG_CONF := CONFIG_USE_APK CONFIG_SELINUX CONFIG_SMALL_FLASH CONFIG_SECCOMP -check-dynamic-def-pkg: FORCE - @+DEF_PKG_CONFS=""; \ - if [ -f $(TOPDIR)/.config ]; then \ - for config in $(DYNAMIC_DEF_PKG_CONF); do \ - DEF_PKG_CONFS="$$DEF_PKG_CONFS "$$(grep "$$config"=y $(TOPDIR)/.config); \ - done; \ - fi; \ - [ ! -f tmp/.packagedynamicdefault ] || OLD_DEF_PKG_CONFS=$$(cat tmp/.packagedynamicdefault); \ - [ "$$DEF_PKG_CONFS" = "$$OLD_DEF_PKG_CONFS" ] || rm -rf tmp/info/.targetinfo*; \ - mkdir -p tmp && echo "$$DEF_PKG_CONFS" > tmp/.packagedynamicdefault; - -prepare-tmpinfo: check-dynamic-def-pkg FORCE +prepare-tmpinfo: FORCE @+$(MAKE) -r -s $(STAGING_DIR_HOST)/.prereq-build $(PREP_MK) mkdir -p tmp/info feeds [ -e $(TOPDIR)/feeds/base ] || ln -sf $(TOPDIR)/package $(TOPDIR)/feeds/base diff --git a/include/trusted-firmware-a.mk b/include/trusted-firmware-a.mk index e469dae9840087..521225fa2898bb 100644 --- a/include/trusted-firmware-a.mk +++ b/include/trusted-firmware-a.mk @@ -1,12 +1,20 @@ PKG_NAME ?= trusted-firmware-a PKG_CPE_ID ?= cpe:/a:arm:trusted_firmware-a -ifndef PKG_SOURCE_PROTO -PKG_SOURCE = trusted-firmware-a-$(PKG_VERSION).tar.gz -PKG_SOURCE_URL:=https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git/snapshot -endif +PKG_LTS ?= +ifneq ($(PKG_LTS),) +PKG_VERSION_PREFIX:=lts-v +PKG_BUILD_DIR = $(BUILD_DIR)/$(PKG_NAME)-$(BUILD_VARIANT)/$(PKG_NAME)-$(PKG_VERSION_PREFIX)$(PKG_VERSION) +else +PKG_VERSION_PREFIX:=v PKG_BUILD_DIR = $(BUILD_DIR)/$(PKG_NAME)-$(BUILD_VARIANT)/$(PKG_NAME)-$(PKG_VERSION) +endif + +ifndef PKG_SOURCE_PROTO +PKG_SOURCE = trusted-firmware-a-$(PKG_VERSION_PREFIX)$(PKG_VERSION).tar.gz +PKG_SOURCE_URL:=https://codeload.github.com/TrustedFirmware-A/trusted-firmware-a/tar.gz/$(PKG_VERSION_PREFIX)$(PKG_VERSION)? +endif PKG_TARGETS := bin PKG_FLAGS:=nonshared @@ -82,7 +90,7 @@ define Build/Compile/Trusted-Firmware-A OPENSSL_DIR=$(STAGING_DIR_HOST) \ $(if $(DTC),DTC="$(DTC)") \ PLAT=$(PLAT) \ - BUILD_STRING="OpenWrt v$(PKG_VERSION)-$(PKG_RELEASE) ($(VARIANT))" \ + BUILD_STRING="OpenWrt $(PKG_VERSION_PREFIX)$(PKG_VERSION)-$(PKG_RELEASE) ($(VARIANT))" \ $(if $(CONFIG_BINUTILS_VERSION_2_37)$(CONFIG_BINUTILS_VERSION_2_38),,LDFLAGS="-no-warn-rwx-segments") \ $(TFA_MAKE_FLAGS) endef diff --git a/include/version.mk b/include/version.mk index 1ac29b629adb6b..a6ebe587797707 100644 --- a/include/version.mk +++ b/include/version.mk @@ -23,13 +23,13 @@ PKG_CONFIG_DEPENDS += \ sanitize = $(call tolower,$(subst _,-,$(subst $(space),-,$(1)))) VERSION_NUMBER:=$(call qstrip,$(CONFIG_VERSION_NUMBER)) -VERSION_NUMBER:=$(if $(VERSION_NUMBER),$(VERSION_NUMBER),SNAPSHOT) +VERSION_NUMBER:=$(if $(VERSION_NUMBER),$(VERSION_NUMBER),24.10-SNAPSHOT) VERSION_CODE:=$(call qstrip,$(CONFIG_VERSION_CODE)) VERSION_CODE:=$(if $(VERSION_CODE),$(VERSION_CODE),$(REVISION)) VERSION_REPO:=$(call qstrip,$(CONFIG_VERSION_REPO)) -VERSION_REPO:=$(if $(VERSION_REPO),$(VERSION_REPO),https://downloads.openwrt.org/snapshots) +VERSION_REPO:=$(if $(VERSION_REPO),$(VERSION_REPO),https://downloads.openwrt.org/releases/24.10-SNAPSHOT) VERSION_DIST:=$(call qstrip,$(CONFIG_VERSION_DIST)) VERSION_DIST:=$(if $(VERSION_DIST),$(VERSION_DIST),OpenWrt) diff --git a/package/Makefile b/package/Makefile index abe76a619fac4a..2343777195d969 100644 --- a/package/Makefile +++ b/package/Makefile @@ -142,10 +142,7 @@ else $(call ERROR_MESSAGE,WARNING: Applying padding in $$d/Packages to workaround usign SHA-512 bug!); \ { echo ""; echo ""; } >> Packages;; \ esac; \ - echo -n '{"architecture": "$(ARCH_PACKAGES)", "packages":{' > index.json; \ - sed -n -e 's/^Package: \(.*\)$$/"\1":/p' -e 's/^Version: \(.*\)$$/"\1",/p' Packages | tr '\n' ' ' >> index.json; \ - echo '}}' >> index.json; \ - sed -i 's/, }}/}}/' index.json; \ + $(SCRIPT_DIR)/make-index-json.py -f opkg -a "$(ARCH_PACKAGES)" Packages > index.json; \ gzip -9nc Packages > Packages.gz; \ ); done ifdef CONFIG_SIGNED_PACKAGES diff --git a/package/base-files/Makefile b/package/base-files/Makefile index 4da50a27362dce..c78c073699f2dc 100644 --- a/package/base-files/Makefile +++ b/package/base-files/Makefile @@ -39,7 +39,11 @@ endif define Package/base-files SECTION:=base CATEGORY:=Base system - DEPENDS:=+netifd +libc +jsonfilter +SIGNED_PACKAGES:usign +SIGNED_PACKAGES:openwrt-keyring +NAND_SUPPORT:ubi-utils +fstools +fwtool + DEPENDS:= \ + +netifd +libc +jsonfilter +SIGNED_PACKAGES:usign +SIGNED_PACKAGES:openwrt-keyring \ + +NAND_SUPPORT:ubi-utils +fstools +fwtool \ + +SELINUX:procd-selinux +!SELINUX:procd +USE_SECCOMP:procd-seccomp \ + +SELINUX:busybox-selinux +!SELINUX:busybox TITLE:=Base filesystem for OpenWrt URL:=http://openwrt.org/ VERSION:=$(PKG_RELEASE)~$(lastword $(subst -, ,$(REVISION))) @@ -251,6 +255,7 @@ ifneq ($(CONFIG_USE_APK),) $(VERSION_SED_SCRIPT) $(1)/etc/apk/repositories rm -f $(1)/etc/uci-defaults/13_fix-group-user + rm -f $(1)/sbin/pkg_check else $(if $(CONFIG_CLEAN_IPKG),, \ mkdir -p $(1)/etc/opkg; \ diff --git a/package/base-files/files/etc/init.d/boot b/package/base-files/files/etc/init.d/boot index c7d1d4af3ad375..a26d4886b2873b 100755 --- a/package/base-files/files/etc/init.d/boot +++ b/package/base-files/files/etc/init.d/boot @@ -24,6 +24,8 @@ boot() { chmod 1777 /var/lock mkdir -p /var/log mkdir -p /var/run + ln -s /var/run /run + ln -s /var/lock /run/lock mkdir -p /var/state mkdir -p /var/tmp mkdir -p /tmp/.uci @@ -33,9 +35,9 @@ boot() { mkdir -p /tmp/resolv.conf.d touch /tmp/resolv.conf.d/resolv.conf.auto ln -sf /tmp/resolv.conf.d/resolv.conf.auto /tmp/resolv.conf - grep -q debugfs /proc/filesystems && /bin/mount -o noatime -t debugfs debugfs /sys/kernel/debug + grep -q debugfs /proc/filesystems && /bin/mount -o nosuid,nodev,noexec,noatime -t debugfs debugfs /sys/kernel/debug grep -q bpf /proc/filesystems && /bin/mount -o nosuid,nodev,noexec,noatime,mode=0700 -t bpf bpffs /sys/fs/bpf - grep -q pstore /proc/filesystems && /bin/mount -o noatime -t pstore pstore /sys/fs/pstore + grep -q pstore /proc/filesystems && /bin/mount -o nosuid,nodev,noexec,noatime -t pstore pstore /sys/fs/pstore [ "$FAILSAFE" = "true" ] && touch /tmp/.failsafe touch /tmp/.config_pending diff --git a/package/base-files/files/etc/rc.common b/package/base-files/files/etc/rc.common index d7473038444cb1..abf72ea3372fe8 100755 --- a/package/base-files/files/etc/rc.common +++ b/package/base-files/files/etc/rc.common @@ -100,10 +100,6 @@ service_triggers() { return 0 } -service_data() { - return 0 -} - service_running() { local instance="${1:-*}" diff --git a/package/base-files/files/etc/uci-defaults/50-root-passwd b/package/base-files/files/etc/uci-defaults/50-root-passwd index 9eddf1559baf33..f0bb519aece4f4 100644 --- a/package/base-files/files/etc/uci-defaults/50-root-passwd +++ b/package/base-files/files/etc/uci-defaults/50-root-passwd @@ -3,10 +3,16 @@ json_init json_load "$(cat /etc/board.json)" -json_select credentials - json_get_vars root_password_hash root_password_hash - [ -z "$root_password_hash" ] || sed -i "s|^root:[^:]*|root:$root_password_hash|g" /etc/shadow +if json_is_a credentials object; then + json_select credentials + json_get_vars root_password_hash root_password_hash + if [ -n "$root_password_hash" ]; then + sed -i "s|^root:[^:]*|root:$root_password_hash|g" /etc/shadow + fi - json_get_vars root_password_plain root_password_plain - [ -z "$root_password_plain" ] || { (echo "$root_password_plain"; sleep 1; echo "$root_password_plain") | passwd root } -json_select .. + json_get_vars root_password_plain root_password_plain + if [ -n "$root_password_plain" ]; then + (echo "$root_password_plain"; sleep 1; echo "$root_password_plain") | passwd root + fi + json_select .. +fi diff --git a/package/base-files/files/lib/functions/caldata.sh b/package/base-files/files/lib/functions/caldata.sh index 09289728c0f5e3..f0fc907aeff1a2 100644 --- a/package/base-files/files/lib/functions/caldata.sh +++ b/package/base-files/files/lib/functions/caldata.sh @@ -125,8 +125,8 @@ caldata_valid() { caldata_patch_data() { local data=$1 local data_count=$((${#1} / 2)) - local data_offset=$(($2)) - local chksum_offset=$(($3)) + [ -n "$2" ] && local data_offset=$(($2)) + [ -n "$3" ] && local chksum_offset=$(($3)) local target=$4 local fw_data local fw_chksum diff --git a/package/base-files/files/lib/functions/system.sh b/package/base-files/files/lib/functions/system.sh index 048e32f0e16414..f43281b5dceb07 100644 --- a/package/base-files/files/lib/functions/system.sh +++ b/package/base-files/files/lib/functions/system.sh @@ -66,7 +66,7 @@ get_mac_ascii() { local key="$2" local mac_dirty - mac_dirty=$(strings "$part" | sed -n 's/^'"$key"'=//p') + mac_dirty=$(strings "$part" | tr -d ' \t' | sed -n 's/^'"$key"'=//p' | head -n 1) # "canonicalize" mac [ -n "$mac_dirty" ] && macaddr_canonicalize "$mac_dirty" diff --git a/package/base-files/image-config.in b/package/base-files/image-config.in index dee06e9b864b78..80db993d46b837 100644 --- a/package/base-files/image-config.in +++ b/package/base-files/image-config.in @@ -190,7 +190,7 @@ if VERSIONOPT config VERSION_REPO string prompt "Release repository" - default "https://downloads.openwrt.org/snapshots" + default "https://downloads.openwrt.org/releases/24.10-SNAPSHOT" help This is the repository address embedded in the image, it defaults to the trunk snapshot repo; the url may contain the following placeholders: diff --git a/package/boot/arm-trusted-firmware-mediatek/Makefile b/package/boot/arm-trusted-firmware-mediatek/Makefile index 3f70f337845150..a543196feb5d73 100644 --- a/package/boot/arm-trusted-firmware-mediatek/Makefile +++ b/package/boot/arm-trusted-firmware-mediatek/Makefile @@ -35,6 +35,8 @@ define Trusted-Firmware-A/Default DRAM_USE_COMB:= RAM_BOOT_UART_DL:= USE_UBI:= + FIP_OFFSET:= + FIP_SIZE:= endef define Trusted-Firmware-A/mt7622-nor-1ddr @@ -221,6 +223,16 @@ define Trusted-Firmware-A/mt7981-spim-nand-ddr3 DDR_TYPE:=ddr3 endef +define Trusted-Firmware-A/mt7981-cudy-tr3000-v1 + NAME:=Cudy TR3000 v1 (SPI-NAND via SPIM, DDR3) + BOOT_DEVICE:=spim-nand + BUILD_SUBTARGET:=filogic + PLAT:=mt7981 + DDR_TYPE:=ddr3 + FIP_OFFSET:=0x3c0000 + FIP_SIZE:=0x200000 +endef + define Trusted-Firmware-A/mt7986-ram-ddr4 NAME:=MediaTek MT7986 (RAM, DDR4) BOOT_DEVICE:=ram @@ -352,6 +364,15 @@ define Trusted-Firmware-A/mt7986-spim-nand-ddr3 DDR_TYPE:=ddr3 endef +define Trusted-Firmware-A/mt7986-spim-nand-ubi-ddr3 + NAME:=MediaTek MT7986 (SPI-NAND via SPIM using UBI, DDR3) + BOOT_DEVICE:=spim-nand + BUILD_SUBTARGET:=filogic + PLAT:=mt7986 + DDR_TYPE:=ddr3 + USE_UBI:=1 +endef + define Trusted-Firmware-A/mt7988-nor-ddr3 NAME:=MediaTek MT7988 (SPI-NOR, DDR3) BOOT_DEVICE:=nor @@ -525,12 +546,14 @@ TFA_TARGETS:= \ mt7981-ram-ddr4 \ mt7981-emmc-ddr4 \ mt7981-spim-nand-ddr4 \ + mt7981-cudy-tr3000-v1 \ mt7986-ram-ddr3 \ mt7986-emmc-ddr3 \ mt7986-nor-ddr3 \ mt7986-sdmmc-ddr3 \ mt7986-snand-ddr3 \ mt7986-spim-nand-ddr3 \ + mt7986-spim-nand-ubi-ddr3 \ mt7986-ram-ddr4 \ mt7986-emmc-ddr4 \ mt7986-nor-ddr4 \ @@ -570,6 +593,9 @@ TFA_MAKE_FLAGS += \ $(if $(RAM_BOOT_UART_DL),RAM_BOOT_UART_DL=1) \ $(if $(USE_UBI),UBI=1 $(if $(findstring mt7622,$(PLAT)),OVERRIDE_UBI_START_ADDR=0x80000)) \ $(if $(USE_UBI),UBI=1 $(if $(findstring mt7981,$(PLAT)),OVERRIDE_UBI_START_ADDR=0x100000)) \ + $(if $(USE_UBI),UBI=1 $(if $(findstring mt7986,$(PLAT)),OVERRIDE_UBI_START_ADDR=0x200000)) \ + $(if $(FIP_OFFSET),OVERRIDE_FIP_BASE=$(FIP_OFFSET)) \ + $(if $(FIP_SIZE),OVERRIDE_FIP_SIZE=$(FIP_SIZE)) \ $(if $(RAM_BOOT_UART_DL),bl2,all) define Package/trusted-firmware-a-ram/install diff --git a/package/boot/arm-trusted-firmware-stm32/Makefile b/package/boot/arm-trusted-firmware-stm32/Makefile new file mode 100644 index 00000000000000..46c00a51d13e06 --- /dev/null +++ b/package/boot/arm-trusted-firmware-stm32/Makefile @@ -0,0 +1,64 @@ +# +# Copyright (C) 2024 Bootlin +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +PKG_VERSION:=2.10.17 +PKG_RELEASE:=1 +PKG_LTS:=1 + +PKG_HASH:=2558b2579dd1c45db6de89c49e647c109022d45da03eb74e0f6123c294295099 +PKG_MAINTAINER:=Thomas Richard + +include $(INCLUDE_DIR)/kernel.mk +include $(INCLUDE_DIR)/trusted-firmware-a.mk +include $(INCLUDE_DIR)/package.mk + +define Trusted-Firmware-A/Default + BUILD_TARGET:=stm32 + BUILD_DEVICES:=$(1) + DEPENDS:=+u-boot-$(1) +optee-os-$(1) +endef + +define Trusted-Firmware-A/stm32mp1 + BUILD_SUBTARGET:=stm32mp1 + PLAT:=stm32mp1 + MAKE_ARGS += BL32_EXTRA2=$(STAGING_DIR_IMAGE)/$(BUILD_VARIANT)-tee-pageable_v2.bin \ + STM32MP_USB_PROGRAMMER=1 \ + STM32MP1_OPTEE_IN_SYSRAM=1 \ + ARM_ARCH_MAJOR=7 +endef + +define Trusted-Firmware-A/stm32mp135f-dk + $(call Trusted-Firmware-A/stm32mp1) + NAME:=STM32MP135F-DK + DTB_FILE_NAME=stm32mp135f-dk.dtb +endef + +TFA_TARGETS := stm32mp135f-dk + +TFA_MAKE_FLAGS += \ + ARCH=aarch32 AARCH32_SP=optee \ + BL32=$(STAGING_DIR_IMAGE)/$(BUILD_VARIANT)-tee-header_v2.bin \ + BL32_EXTRA1=$(STAGING_DIR_IMAGE)/$(BUILD_VARIANT)-tee-pager_v2.bin \ + BL33=$(STAGING_DIR_IMAGE)/$(BUILD_VARIANT)-u-boot.bin \ + BL33_CFG=$(STAGING_DIR_IMAGE)/$(BUILD_VARIANT)-u-boot.dtb \ + DTB_FILE_NAME=$(DTB_FILE_NAME) \ + STM32MP_SDMMC=1 \ + TARGET_BOARD="" \ + $(MAKE_ARGS) \ + all fip + +define Package/trusted-firmware-a/install + $(INSTALL_DIR) $(STAGING_DIR_IMAGE) + $(CP) $(PKG_BUILD_DIR)/build/$(PLAT)/release/tf-a-$(BUILD_VARIANT).stm32 \ + $(STAGING_DIR_IMAGE)/tf-a-$(BUILD_VARIANT).stm32 + $(CP) $(PKG_BUILD_DIR)/build/$(PLAT)/release/fip.bin \ + $(STAGING_DIR_IMAGE)/fip-$(BUILD_VARIANT).bin +endef + +$(eval $(call BuildPackage/Trusted-Firmware-A)) diff --git a/package/boot/optee-os-stm32/Makefile b/package/boot/optee-os-stm32/Makefile new file mode 100644 index 00000000000000..9e681127e6a1b2 --- /dev/null +++ b/package/boot/optee-os-stm32/Makefile @@ -0,0 +1,49 @@ +# +# Copyright (C) 2024 Bootlin +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +PKG_VERSION:=4.3.0 +PKG_RELEASE:=1 + +PKG_HASH:=390b271905c828d6def9fa6a77bbaa425f3b434d733c8eb18f582ccbc6896096 +PKG_MAINTAINER:=Thomas Richard + +OPTEE_USE_INTREE_DTC:=1 + +include $(INCLUDE_DIR)/kernel.mk +include $(INCLUDE_DIR)/optee-os.mk +include $(INCLUDE_DIR)/package.mk + +define Optee-os/Default + BUILD_TARGET:=stm32 +endef + +define Optee-os/stm32mp1 + BUILD_SUBTARGET:=stm32mp1 + PLAT:=stm32mp1 +endef + +define Optee-os/stm32mp135f-dk + $(call Optee-os/stm32mp1) + NAME:=STM32MP135F-DK + PLAT_FLAVOR:=135F_DK +endef + +OPTEE_TARGETS := stm32mp135f-dk + +define Package/optee-os/install/default +endef + +define Build/InstallDev + $(INSTALL_DIR) $(STAGING_DIR_IMAGE) + $(foreach img,$(OPTEE_IMAGE), \ + $(CP) $(PKG_BUILD_DIR)/out/arm-plat-$(PLAT)/core/$(img) $(STAGING_DIR_IMAGE)/$(BUILD_VARIANT)-$(img); \ + ) +endef + +$(eval $(call BuildPackage/Optee-os)) diff --git a/package/boot/uboot-d1/Makefile b/package/boot/uboot-d1/Makefile index 083a219baf6fab..611922443b0800 100644 --- a/package/boot/uboot-d1/Makefile +++ b/package/boot/uboot-d1/Makefile @@ -30,7 +30,7 @@ define U-Boot/dongshan_nezha_stu OPENSBI:=generic DEPENDS:=+opensbi_generic UBOOT_DTS:=sun20i-d1-dongshan-nezha-stu.dtb - BUILD_DEVICES:=dongshan_nezha_stu + BUILD_DEVICES:=100ask_dongshan-nezha-stu endef define U-Boot/lichee_rv_dock @@ -38,7 +38,7 @@ define U-Boot/lichee_rv_dock OPENSBI:=generic DEPENDS:=+opensbi_generic UBOOT_DTS:=sun20i-d1-lichee-rv-dock.dtb - BUILD_DEVICES:=lichee_rv_dock + BUILD_DEVICES:=sipeed_lichee-rv-dock endef define U-Boot/mangopi_mq_pro @@ -46,7 +46,7 @@ define U-Boot/mangopi_mq_pro OPENSBI:=generic DEPENDS:=+opensbi_generic UBOOT_DTS:=sun20i-d1-mangopi-mq-pro.dtb - BUILD_DEVICES:=mangopi_mq_pro + BUILD_DEVICES:=widora_mangopi-mq-pro endef define U-Boot/nezha @@ -54,7 +54,7 @@ define U-Boot/nezha OPENSBI:=generic DEPENDS:=+opensbi_generic UBOOT_DTS:=sun20i-d1-nezha.dtb - BUILD_DEVICES:=nezha + BUILD_DEVICES:=allwinner_d1-nezha endef UBOOT_TARGETS := \ @@ -74,7 +74,7 @@ endef define Build/InstallDev $(INSTALL_DIR) $(STAGING_DIR_IMAGE) $(INSTALL_BIN) $(PKG_BUILD_DIR)/$(DTS_DIR)/$(UBOOT_DTS) $(STAGING_DIR_IMAGE)/$(UBOOT_DTS) - $(INSTALL_BIN) $(PKG_BUILD_DIR)/$(UBOOT_IMAGE) $(STAGING_DIR_IMAGE)/$(BUILD_VARIANT)-$(UBOOT_IMAGE) + $(INSTALL_BIN) $(PKG_BUILD_DIR)/$(UBOOT_IMAGE) $(STAGING_DIR_IMAGE)/$(BUILD_DEVICES)-$(UBOOT_IMAGE) mkimage -C none -A riscv -T script -d uEnv-$(UENV).txt \ $(STAGING_DIR_IMAGE)/$(BUILD_DEVICES)-boot.scr endef diff --git a/package/boot/uboot-envtools/files/ath79 b/package/boot/uboot-envtools/files/ath79 index 1d9d3bcfaa1fc5..c989e61bd550f4 100644 --- a/package/boot/uboot-envtools/files/ath79 +++ b/package/boot/uboot-envtools/files/ath79 @@ -28,6 +28,7 @@ asus,rt-ac59u-v2|\ asus,zenwifi-cd6n|\ asus,zenwifi-cd6r|\ buffalo,bhr-4grv2|\ +buffalo,wzr-450hp2|\ devolo,magic-2-wifi|\ engenius,eap300-v2|\ engenius,eap350-v1|\ @@ -163,6 +164,7 @@ ruckus,zf7372) ubootenv_add_uci_config "/dev/mtd2" "0x0" "0x40000" "0x10000" ;; sophos,ap15|\ +sophos,ap15c|\ sophos,ap55|\ sophos,ap55c|\ sophos,ap100|\ diff --git a/package/boot/uboot-envtools/files/imx_cortexa53 b/package/boot/uboot-envtools/files/imx_cortexa53 new file mode 100644 index 00000000000000..6aad4ce86710de --- /dev/null +++ b/package/boot/uboot-envtools/files/imx_cortexa53 @@ -0,0 +1,21 @@ +[ -e /etc/config/ubootenv ] && exit 0 + +touch /etc/config/ubootenv + +. /lib/uboot-envtools.sh +. /lib/functions.sh + +board=$(board_name) + +case "$board" in +gw,imx8m*|\ +gateworks,imx8m*) + # board boots from emmc boot0 hardware partition + ubootenv_add_uci_config /dev/mmcblk2boot0 0x3f0000 0x8000 + ubootenv_add_uci_config /dev/mmcblk2boot0 0x3f8000 0x8000 +esac + +config_load ubootenv +config_foreach ubootenv_add_app_config ubootenv + +exit 0 diff --git a/package/boot/uboot-envtools/files/mediatek_filogic b/package/boot/uboot-envtools/files/mediatek_filogic index a38024de65976b..3f8fa0d54388c0 100644 --- a/package/boot/uboot-envtools/files/mediatek_filogic +++ b/package/boot/uboot-envtools/files/mediatek_filogic @@ -34,11 +34,16 @@ ubootenv_add_ubi_default() { case "$board" in abt,asr3000|\ +cmcc,a10-ubootmod|\ +cudy,tr3000-v1-ubootmod|\ h3c,magic-nx30-pro|\ jcg,q30-pro|\ +mercusys,mr90x-v1-ubi|\ netcore,n60|\ +netis,nx31|\ nokia,ea0326gmp|\ qihoo,360t7|\ +routerich,ax3000-ubootmod|\ tplink,tl-xdr4288|\ tplink,tl-xdr6086|\ tplink,tl-xdr6088|\ @@ -49,6 +54,17 @@ xiaomi,redmi-router-ax6000-ubootmod|\ zyxel,ex5601-t0-ubootmod) ubootenv_add_ubi_default ;; +acer,predator-w6|\ +acer,predator-w6d|\ +acer,vero-w6m|\ +glinet,gl-mt2500|\ +glinet,gl-mt6000|\ +glinet,gl-x3000|\ +glinet,gl-xe3000|\ +huasifei,wh3000) + local envdev=$(find_mmc_part "u-boot-env") + ubootenv_add_uci_config "$envdev" "0x0" "0x80000" + ;; asus,rt-ax59u) ubootenv_add_uci_config "/dev/mtd0" "0x100000" "0x20000" "0x20000" ;; @@ -83,21 +99,20 @@ zbtlink,zbt-z8102ax|\ zbtlink,zbt-z8103ax) ubootenv_add_uci_config "/dev/mtd1" "0x0" "0x20000" "0x20000" ;; -dlink,aquila-pro-ai-m30-a1) +dlink,aquila-pro-ai-m30-a1|\ +dlink,aquila-pro-ai-m60-a1) ubootenv_add_uci_config "/dev/mtd1" "0x0" "0x40000" "0x40000" ;; -glinet,gl-x3000|\ -glinet,gl-xe3000|\ -glinet,gl-mt2500|\ -glinet,gl-mt6000) - local envdev=$(find_mmc_part "u-boot-env") - ubootenv_add_uci_config "$envdev" "0x0" "0x80000" +gatonetworks,gdsp) + ubootenv_add_uci_config "/dev/mtd1" "0x0" "0x10000" "0x10000" ;; glinet,gl-mt3000) ubootenv_add_uci_config "/dev/mtd1" "0x0" "0x80000" "0x20000" ;; +mercusys,mr80x-v3|\ mercusys,mr90x-v1|\ routerich,ax3000|\ +routerich,ax3000-v1|\ tplink,re6000xd) local envdev=/dev/mtd$(find_mtd_index "u-boot-env") ubootenv_add_uci_config "$envdev" "0x0" "0x20000" "0x20000" "1" @@ -115,6 +130,9 @@ smartrg,sdg-8734) local envdev=$(find_mmc_part "u-boot-env" "mmcblk0") ubootenv_add_uci_config "$envdev" "0x0" "0x8000" "0x8000" ;; +tplink,archer-ax80-v1) + ubootenv_add_uci_config "/dev/mtd1" "0x0" "0x20000" "0x20000" "8" + ;; ubnt,unifi-6-plus) ubootenv_add_uci_config "/dev/mtd1" "0x0" "0x80000" "0x10000" ;; diff --git a/package/boot/uboot-envtools/files/qualcommax_ipq807x b/package/boot/uboot-envtools/files/qualcommax_ipq807x index f5fb07a4db0bf0..2d76045c66e568 100644 --- a/package/boot/uboot-envtools/files/qualcommax_ipq807x +++ b/package/boot/uboot-envtools/files/qualcommax_ipq807x @@ -37,6 +37,11 @@ linksys,mx8500) [ -n "$idx" ] && \ ubootenv_add_uci_config "/dev/mtd$idx" "0x0" "0x40000" "0x20000" "2" ;; +linksys,mx4300) + idx="$(find_mtd_index u_env)" + [ -n "$idx" ] && \ + ubootenv_add_uci_config "/dev/mtd$idx" "0x0" "0x40000" "0x40000" "1" + ;; netgear,sxr80|\ netgear,sxs80|\ tplink,eap660hd-v1) diff --git a/package/boot/uboot-envtools/files/ramips b/package/boot/uboot-envtools/files/ramips index 341687625c8603..b0f8c1c1689944 100644 --- a/package/boot/uboot-envtools/files/ramips +++ b/package/boot/uboot-envtools/files/ramips @@ -19,6 +19,7 @@ alfa-network,r36m-e4g|\ alfa-network,tube-e4g|\ engenius,epg600|\ engenius,esr600h|\ +hongdian,h8922-v30|\ linksys,re7000|\ meig,slt866|\ sitecom,wlr-4100-v1-002|\ @@ -62,6 +63,7 @@ kroks,kndrt31r19|\ mediatek,linkit-smart-7688|\ samknows,whitebox-v8|\ xiaomi,mi-router-4c|\ +xiaomi,miwifi-3a|\ xiaomi,miwifi-nano|\ zbtlink,zbt-wg2626|\ zte,mf283plus) @@ -147,7 +149,8 @@ xiaomi,mi-router-cr6608|\ xiaomi,mi-router-cr6609) ubootenv_add_uci_config "/dev/mtd1" "0x0" "0x10000" "0x20000" ;; -dna,valokuitu-plus-ex400) +dna,valokuitu-plus-ex400|\ +genexis,pulse-ex400) ubootenv_add_uci_config "/dev/ubi0_0" "0x0" "0x1f000" "0x1f000" "1" ubootenv_add_uci_config "/dev/ubi0_1" "0x0" "0x1f000" "0x1f000" "1" ;; diff --git a/package/boot/uboot-envtools/files/realtek b/package/boot/uboot-envtools/files/realtek index cd2446432d7dac..055730eb27b3d2 100644 --- a/package/boot/uboot-envtools/files/realtek +++ b/package/boot/uboot-envtools/files/realtek @@ -28,6 +28,7 @@ zyxel,gs1900-10hp|\ zyxel,gs1900-16|\ zyxel,gs1900-24-v1|\ zyxel,gs1900-24e|\ +zyxel,gs1900-24ep|\ zyxel,gs1900-24hp-v1|\ zyxel,gs1900-24hp-v2) idx="$(find_mtd_index u-boot-env)" diff --git a/package/boot/uboot-mediatek/Makefile b/package/boot/uboot-mediatek/Makefile index e5a0a393fe5cb8..f68a5d6ff583ba 100644 --- a/package/boot/uboot-mediatek/Makefile +++ b/package/boot/uboot-mediatek/Makefile @@ -231,6 +231,18 @@ define U-Boot/mt7981_abt_asr3000 DEPENDS:=+trusted-firmware-a-mt7981-spim-nand-ddr3 endef +define U-Boot/mt7981_cmcc_a10 + NAME:=CMCC A10 + BUILD_SUBTARGET:=filogic + BUILD_DEVICES:=cmcc_a10-ubootmod + UBOOT_CONFIG:=mt7981_cmcc_a10 + UBOOT_IMAGE:=u-boot.fip + BL2_BOOTDEV:=spim-nand + BL2_SOC:=mt7981 + BL2_DDRTYPE:=ddr3 + DEPENDS:=+trusted-firmware-a-mt7981-spim-nand-ddr3 +endef + define U-Boot/mt7981_cmcc_rax3000m-emmc NAME:=CMCC RAX3000M BUILD_SUBTARGET:=filogic @@ -255,6 +267,17 @@ define U-Boot/mt7981_cmcc_rax3000m-nand DEPENDS:=+trusted-firmware-a-mt7981-spim-nand-ddr4 endef +define U-Boot/mt7981_cudy_tr3000-v1 + NAME:=Cudy TR3000 v1 + BUILD_SUBTARGET:=filogic + BUILD_DEVICES:=cudy_tr3000-v1-ubootmod + UBOOT_CONFIG:=mt7981_cudy_tr3000-v1 + UBOOT_IMAGE:=u-boot.fip + BL2_BOOTDEV:=cudy-tr3000-v1 + BL2_SOC:=mt7981 + DEPENDS:=+trusted-firmware-a-mt7981-cudy-tr3000-v1 +endef + define U-Boot/mt7981_glinet_gl-x3000 NAME:=GL.iNet GL-X3000 BUILD_SUBTARGET:=filogic @@ -303,6 +326,18 @@ define U-Boot/mt7981_jcg_q30-pro DEPENDS:=+trusted-firmware-a-mt7981-spim-nand-ddr3 endef +define U-Boot/mt7981_netis_nx31 + NAME:=netis NX31 + BUILD_SUBTARGET:=filogic + BUILD_DEVICES:=netis_nx31 + UBOOT_CONFIG:=mt7981_netis_nx31 + UBOOT_IMAGE:=u-boot.fip + BL2_BOOTDEV:=spim-nand + BL2_SOC:=mt7981 + BL2_DDRTYPE:=ddr3 + DEPENDS:=+trusted-firmware-a-mt7981-spim-nand-ddr3 +endef + define U-Boot/mt7981_nokia_ea0326gmp NAME:=Nokia EA0326GMP BUILD_SUBTARGET:=filogic @@ -364,13 +399,26 @@ define U-Boot/mt7981_rfb-emmc DEPENDS:=+trusted-firmware-a-mt7981-emmc-ddr3 endef +define U-Boot/mt7981_gatonetworks_gdsp + NAME:=GatoNetworks GDSP + BUILD_SUBTARGET:=filogic + BUILD_DEVICES:=gatonetworks_gdsp + UBOOT_CONFIG:=mt7981_gatonetworks_gdsp + UBOOT_IMAGE:=u-boot.fip + BL2_BOOTDEV:=nor + BL2_SOC:=mt7981 + BL2_DDRTYPE:=ddr3 + DEPENDS:=+trusted-firmware-a-mt7981-nor-ddr3 + FIP_COMPRESS:=1 +endef + define U-Boot/mt7981_rfb-nor NAME:=MT7981 Reference Board BUILD_SUBTARGET:=filogic BUILD_DEVICES:=mediatek_mt7981-rfb UBOOT_CONFIG:=mt7981_nor_rfb UBOOT_IMAGE:=u-boot.fip - BL2_BOOTDEV:=spim-nand + BL2_BOOTDEV:=nor BL2_SOC:=mt7981 BL2_DDRTYPE:=ddr3 DEPENDS:=+trusted-firmware-a-mt7981-nor-ddr3 @@ -400,6 +448,18 @@ define U-Boot/mt7981_rfb-snfi DEPENDS:=+trusted-firmware-a-mt7981-snand-ddr3 endef +define U-Boot/mt7981_routerich_ax3000 + NAME:=Routerich AX3000 + BUILD_SUBTARGET:=filogic + BUILD_DEVICES:=routerich_ax3000-ubootmod + UBOOT_CONFIG:=mt7981_routerich_ax3000 + UBOOT_IMAGE:=u-boot.fip + BL2_BOOTDEV:=spim-nand + BL2_SOC:=mt7981 + BL2_DDRTYPE:=ddr3 + DEPENDS:=+trusted-firmware-a-mt7981-spim-nand-ddr3 +endef + define U-Boot/mt7981_qihoo_360t7 NAME:=Qihoo 360T7 BUILD_SUBTARGET:=filogic @@ -545,6 +605,18 @@ define U-Boot/mt7986_jdcloud_re-cp-03 DEPENDS:=+trusted-firmware-a-mt7986-emmc-ddr4 endef +define U-Boot/mt7986_mercusys_mr90x-v1 + NAME:=MERCUSYS MR90X v1 + BUILD_SUBTARGET:=filogic + BUILD_DEVICES:=mercusys_mr90x-v1-ubi + UBOOT_CONFIG:=mt7986_mercusys_mr90x-v1 + UBOOT_IMAGE:=u-boot.fip + BL2_BOOTDEV:=spim-nand-ubi + BL2_SOC:=mt7986 + BL2_DDRTYPE:=ddr3 + DEPENDS:=+trusted-firmware-a-mt7986-spim-nand-ubi-ddr3 +endef + define U-Boot/mt7986_netcore_n60 NAME:=Netcore N60 BUILD_SUBTARGET:=filogic @@ -629,6 +701,18 @@ define U-Boot/mt7986_zyxel_ex5601-t0 DEPENDS:=+trusted-firmware-a-mt7986-spim-nand-4k-ddr4 endef +define U-Boot/mt7988_arcadyan_mozart + NAME:=Arcadyan Mozart + BUILD_SUBTARGET:=filogic + BUILD_DEVICES:=arcadyan_mozart + UBOOT_CONFIG:=mt7988a_arcadyan_mozart + UBOOT_IMAGE:=u-boot.fip + BL2_BOOTDEV:=emmc + BL2_SOC:=mt7988 + BL2_DDRTYPE:=comb + DEPENDS:=+trusted-firmware-a-mt7988-emmc-comb +endef + define U-Boot/mt7988_bananapi_bpi-r4-emmc NAME:=BananaPi BPi-R4 BUILD_SUBTARGET:=filogic @@ -783,12 +867,16 @@ UBOOT_TARGETS := \ mt7628_ravpower_rp-wd009 \ mt7629_rfb \ mt7981_abt_asr3000 \ + mt7981_cmcc_a10 \ mt7981_cmcc_rax3000m-emmc \ mt7981_cmcc_rax3000m-nand \ + mt7981_cudy_tr3000-v1 \ + mt7981_gatonetworks_gdsp \ mt7981_glinet_gl-x3000 \ mt7981_glinet_gl-xe3000 \ mt7981_h3c_magic-nx30-pro \ mt7981_jcg_q30-pro \ + mt7981_netis_nx31 \ mt7981_nokia_ea0326gmp \ mt7981_openwrt_one-snand \ mt7981_openwrt_one-nor \ @@ -797,6 +885,7 @@ UBOOT_TARGETS := \ mt7981_rfb-nor \ mt7981_rfb-sd \ mt7981_rfb-snfi \ + mt7981_routerich_ax3000 \ mt7981_qihoo_360t7 \ mt7981_xiaomi_mi-router-ax3000t \ mt7981_xiaomi_mi-router-wr30u \ @@ -808,6 +897,7 @@ UBOOT_TARGETS := \ mt7986_bananapi_bpi-r3-mini-snand \ mt7986_glinet_gl-mt6000 \ mt7986_jdcloud_re-cp-03 \ + mt7986_mercusys_mr90x-v1 \ mt7986_netcore_n60 \ mt7986_tplink_tl-xdr4288 \ mt7986_tplink_tl-xdr6086 \ @@ -816,6 +906,7 @@ UBOOT_TARGETS := \ mt7986_xiaomi_redmi-router-ax6000 \ mt7986_zyxel_ex5601-t0 \ mt7986_rfb \ + mt7988_arcadyan_mozart \ mt7988_bananapi_bpi-r4-emmc \ mt7988_bananapi_bpi-r4-sdmmc \ mt7988_bananapi_bpi-r4-snand \ @@ -831,7 +922,8 @@ UBOOT_TARGETS := \ UBOOT_CUSTOMIZE_CONFIG := \ --disable TOOLS_KWBIMAGE \ --disable TOOLS_LIBCRYPTO \ - --disable TOOLS_MKEFICAPSULE + --disable TOOLS_MKEFICAPSULE \ + --enable SERIAL_RX_BUFFER ifdef CONFIG_TARGET_mediatek UBOOT_MAKE_FLAGS += $(UBOOT_IMAGE:.fip=.bin) diff --git a/package/boot/uboot-mediatek/patches/010-menu-fix-the-logic-checking-whether-ESC-key-is-press.patch b/package/boot/uboot-mediatek/patches/010-menu-fix-the-logic-checking-whether-ESC-key-is-press.patch new file mode 100644 index 00000000000000..f3589c46220c4c --- /dev/null +++ b/package/boot/uboot-mediatek/patches/010-menu-fix-the-logic-checking-whether-ESC-key-is-press.patch @@ -0,0 +1,63 @@ +From 72b4ba8417d33516b8489bac3c90dbbbf781a3d2 Mon Sep 17 00:00:00 2001 +From: Weijie Gao +Date: Tue, 29 Oct 2024 17:47:10 +0800 +Subject: [PATCH 1/3] menu: fix the logic checking whether ESC key is pressed + +It's observed that the bootmenu on a serial console sometimes +incorrectly quitted with superfluous characters filled to command +line input: + +> *** U-Boot Boot Menu *** +> +> 1. Startup system (Default) +> 2. Upgrade firmware +> 3. Upgrade ATF BL2 +> 4. Upgrade ATF FIP +> 5. Load image +> 0. U-Boot console +> +> +> Press UP/DOWN to move, ENTER to select, ESC to quit +>MT7988> [B + +Analysis shows it was caused by the wrong logic of bootmenu_loop: + +At first the bootmenu_loop received the first ESC char correctly. + +However, during the second call to bootmenu_loop, there's no data +in the UART Rx FIFO. Due to the low baudrate, the second char of +the down array key sequence hasn't be fully received. + +But bootmenu_loop just did a mdelay(10), and then treated it as a +single ESC key press event. It didn't even try tstc() again after +the 10ms timeout. + +This patch fixes this issue by letting bootmenu_loop check tstc() +twice. + +Tested-By: E Shattow +Signed-off-by: Weijie Gao +--- + common/menu.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +--- a/common/menu.c ++++ b/common/menu.c +@@ -525,14 +525,15 @@ enum bootmenu_key bootmenu_loop(struct b + struct cli_ch_state *cch) + { + enum bootmenu_key key; +- int c; ++ int c, errchar = 0; + + c = cli_ch_process(cch, 0); + if (!c) { + while (!c && !tstc()) { + schedule(); + mdelay(10); +- c = cli_ch_process(cch, -ETIMEDOUT); ++ c = cli_ch_process(cch, errchar); ++ errchar = -ETIMEDOUT; + } + if (!c) { + c = getchar(); diff --git a/package/boot/uboot-mediatek/patches/011-menu-add-support-to-check-if-menu-needs-to-be-reprin.patch b/package/boot/uboot-mediatek/patches/011-menu-add-support-to-check-if-menu-needs-to-be-reprin.patch new file mode 100644 index 00000000000000..9d356ff0b4c257 --- /dev/null +++ b/package/boot/uboot-mediatek/patches/011-menu-add-support-to-check-if-menu-needs-to-be-reprin.patch @@ -0,0 +1,112 @@ +From f1cbdd3330f0055dfbff0ef7d86276c4cc3cff2a Mon Sep 17 00:00:00 2001 +From: Weijie Gao +Date: Tue, 29 Oct 2024 17:47:16 +0800 +Subject: [PATCH 2/3] menu: add support to check if menu needs to be reprinted + +This patch adds a new callback named need_reprint for menu. +The need_reprint will be called before printing the menu. If the +callback exists and returns FALSE, menu printing will be canceled. + +This is very useful if the menu was not changed. It can save time +for serial-based menu to handle more input data. + +Signed-off-by: Weijie Gao +--- + boot/pxe_utils.c | 2 +- + cmd/bootmenu.c | 2 +- + cmd/eficonfig.c | 2 +- + common/menu.c | 11 +++++++++++ + include/menu.h | 1 + + 5 files changed, 15 insertions(+), 3 deletions(-) + +--- a/boot/pxe_utils.c ++++ b/boot/pxe_utils.c +@@ -1449,7 +1449,7 @@ static struct menu *pxe_menu_to_menu(str + * Create a menu and add items for all the labels. + */ + m = menu_create(cfg->title, DIV_ROUND_UP(cfg->timeout, 10), +- cfg->prompt, NULL, label_print, NULL, NULL); ++ cfg->prompt, NULL, label_print, NULL, NULL, NULL); + if (!m) + return NULL; + +--- a/cmd/bootmenu.c ++++ b/cmd/bootmenu.c +@@ -506,7 +506,7 @@ static enum bootmenu_ret bootmenu_show(i + + menu = menu_create(NULL, bootmenu->delay, 1, menu_display_statusline, + bootmenu_print_entry, bootmenu_choice_entry, +- bootmenu); ++ NULL, bootmenu); + if (!menu) { + bootmenu_destroy(bootmenu); + return BOOTMENU_RET_FAIL; +--- a/cmd/eficonfig.c ++++ b/cmd/eficonfig.c +@@ -443,7 +443,7 @@ efi_status_t eficonfig_process_common(st + efi_menu->menu_desc = menu_desc; + + menu = menu_create(NULL, 0, 1, display_statusline, item_data_print, +- item_choice, efi_menu); ++ item_choice, NULL, efi_menu); + if (!menu) + return EFI_INVALID_PARAMETER; + +--- a/common/menu.c ++++ b/common/menu.c +@@ -43,6 +43,7 @@ struct menu { + void (*display_statusline)(struct menu *); + void (*item_data_print)(void *); + char *(*item_choice)(void *); ++ bool (*need_reprint)(void *); + void *item_choice_data; + struct list_head items; + int item_cnt; +@@ -117,6 +118,11 @@ static inline void *menu_item_destroy(st + */ + static inline void menu_display(struct menu *m) + { ++ if (m->need_reprint) { ++ if (!m->need_reprint(m->item_choice_data)) ++ return; ++ } ++ + if (m->title) { + puts(m->title); + putc('\n'); +@@ -362,6 +368,9 @@ int menu_item_add(struct menu *m, char * + * item. Returns a key string corresponding to the chosen item or NULL if + * no item has been selected. + * ++ * need_reprint - If not NULL, will be called before printing the menu. ++ * Returning FALSE means the menu does not need reprint. ++ * + * item_choice_data - Will be passed as the argument to the item_choice function + * + * Returns a pointer to the menu if successful, or NULL if there is +@@ -371,6 +380,7 @@ struct menu *menu_create(char *title, in + void (*display_statusline)(struct menu *), + void (*item_data_print)(void *), + char *(*item_choice)(void *), ++ bool (*need_reprint)(void *), + void *item_choice_data) + { + struct menu *m; +@@ -386,6 +396,7 @@ struct menu *menu_create(char *title, in + m->display_statusline = display_statusline; + m->item_data_print = item_data_print; + m->item_choice = item_choice; ++ m->need_reprint = need_reprint; + m->item_choice_data = item_choice_data; + m->item_cnt = 0; + +--- a/include/menu.h ++++ b/include/menu.h +@@ -13,6 +13,7 @@ struct menu *menu_create(char *title, in + void (*display_statusline)(struct menu *), + void (*item_data_print)(void *), + char *(*item_choice)(void *), ++ bool (*need_reprint)(void *), + void *item_choice_data); + int menu_default_set(struct menu *m, char *item_key); + int menu_get_choice(struct menu *m, void **choice); diff --git a/package/boot/uboot-mediatek/patches/012-bootmenu-add-reprint-check.patch b/package/boot/uboot-mediatek/patches/012-bootmenu-add-reprint-check.patch new file mode 100644 index 00000000000000..8f4db3a82eb8a5 --- /dev/null +++ b/package/boot/uboot-mediatek/patches/012-bootmenu-add-reprint-check.patch @@ -0,0 +1,75 @@ +From 702752cfae954648d6133bdff19283343b3339ef Mon Sep 17 00:00:00 2001 +From: Weijie Gao +Date: Tue, 29 Oct 2024 17:47:22 +0800 +Subject: [PATCH 3/3] bootmenu: add reprint check + +Record the last active menu item and check if it equals to the +current selected item before reprint. + +Signed-off-by: Weijie Gao +--- + cmd/bootmenu.c | 16 +++++++++++++++- + include/menu.h | 1 + + 2 files changed, 16 insertions(+), 1 deletion(-) + +--- a/cmd/bootmenu.c ++++ b/cmd/bootmenu.c +@@ -103,11 +103,13 @@ static char *bootmenu_choice_entry(void + + switch (key) { + case BKEY_UP: ++ menu->last_active = menu->active; + if (menu->active > 0) + --menu->active; + /* no menu key selected, regenerate menu */ + return NULL; + case BKEY_DOWN: ++ menu->last_active = menu->active; + if (menu->active < menu->count - 1) + ++menu->active; + /* no menu key selected, regenerate menu */ +@@ -133,6 +135,17 @@ static char *bootmenu_choice_entry(void + return NULL; + } + ++static bool bootmenu_need_reprint(void *data) ++{ ++ struct bootmenu_data *menu = data; ++ bool need_reprint; ++ ++ need_reprint = menu->last_active != menu->active; ++ menu->last_active = menu->active; ++ ++ return need_reprint; ++} ++ + static void bootmenu_destroy(struct bootmenu_data *menu) + { + struct bootmenu_entry *iter = menu->first; +@@ -332,6 +345,7 @@ static struct bootmenu_data *bootmenu_cr + + menu->delay = delay; + menu->active = 0; ++ menu->last_active = -1; + menu->first = NULL; + + default_str = env_get("bootmenu_default"); +@@ -506,7 +520,7 @@ static enum bootmenu_ret bootmenu_show(i + + menu = menu_create(NULL, bootmenu->delay, 1, menu_display_statusline, + bootmenu_print_entry, bootmenu_choice_entry, +- NULL, bootmenu); ++ bootmenu_need_reprint, bootmenu); + if (!menu) { + bootmenu_destroy(bootmenu); + return BOOTMENU_RET_FAIL; +--- a/include/menu.h ++++ b/include/menu.h +@@ -40,6 +40,7 @@ int menu_show(int bootdelay); + struct bootmenu_data { + int delay; /* delay for autoboot */ + int active; /* active menu entry */ ++ int last_active; /* last active menu entry */ + int count; /* total count of menu entries */ + struct bootmenu_entry *first; /* first menu entry */ + }; diff --git a/package/boot/uboot-mediatek/patches/100-16-cmd-bootmenu-add-ability-to-select-item-by-shortkey.patch b/package/boot/uboot-mediatek/patches/100-16-cmd-bootmenu-add-ability-to-select-item-by-shortkey.patch index 4aa4318493ef5f..47e158b521ceca 100644 --- a/package/boot/uboot-mediatek/patches/100-16-cmd-bootmenu-add-ability-to-select-item-by-shortkey.patch +++ b/package/boot/uboot-mediatek/patches/100-16-cmd-bootmenu-add-ability-to-select-item-by-shortkey.patch @@ -35,7 +35,7 @@ Signed-off-by: Weijie Gao } switch (key) { -@@ -112,6 +113,12 @@ static char *bootmenu_choice_entry(void +@@ -114,6 +115,12 @@ static char *bootmenu_choice_entry(void ++menu->active; /* no menu key selected, regenerate menu */ return NULL; @@ -48,7 +48,7 @@ Signed-off-by: Weijie Gao case BKEY_SELECT: iter = menu->first; for (i = 0; i < menu->active; ++i) -@@ -169,6 +176,9 @@ static int prepare_bootmenu_entry(struct +@@ -182,6 +189,9 @@ static int prepare_bootmenu_entry(struct unsigned short int i = *index; struct bootmenu_entry *entry = NULL; struct bootmenu_entry *iter = *current; @@ -58,7 +58,7 @@ Signed-off-by: Weijie Gao while ((option = bootmenu_getoption(i))) { -@@ -183,11 +193,24 @@ static int prepare_bootmenu_entry(struct +@@ -196,11 +206,24 @@ static int prepare_bootmenu_entry(struct if (!entry) return -ENOMEM; @@ -84,15 +84,15 @@ Signed-off-by: Weijie Gao entry->command = strdup(sep + 1); if (!entry->command) { -@@ -333,6 +356,7 @@ static struct bootmenu_data *bootmenu_cr - menu->delay = delay; +@@ -347,6 +370,7 @@ static struct bootmenu_data *bootmenu_cr menu->active = 0; + menu->last_active = -1; menu->first = NULL; + menu->last_choiced = false; default_str = env_get("bootmenu_default"); if (default_str) -@@ -368,9 +392,9 @@ static struct bootmenu_data *bootmenu_cr +@@ -382,9 +406,9 @@ static struct bootmenu_data *bootmenu_cr /* Add Quit entry if exiting bootmenu is disabled */ if (!IS_ENABLED(CONFIG_BOOTMENU_DISABLE_UBOOT_CONSOLE)) @@ -106,7 +106,7 @@ Signed-off-by: Weijie Gao free(entry); --- a/common/menu.c +++ b/common/menu.c -@@ -48,6 +48,33 @@ struct menu { +@@ -49,6 +49,33 @@ struct menu { int item_cnt; }; @@ -140,7 +140,7 @@ Signed-off-by: Weijie Gao /* * An iterator function for menu items. callback will be called for each item * in m, with m, a pointer to the item, and extra being passed to callback. If -@@ -426,7 +453,7 @@ int menu_destroy(struct menu *m) +@@ -437,7 +464,7 @@ int menu_destroy(struct menu *m) } enum bootmenu_key bootmenu_autoboot_loop(struct bootmenu_data *menu, @@ -149,7 +149,7 @@ Signed-off-by: Weijie Gao { enum bootmenu_key key = BKEY_NONE; int i, c; -@@ -461,6 +488,19 @@ enum bootmenu_key bootmenu_autoboot_loop +@@ -472,6 +499,19 @@ enum bootmenu_key bootmenu_autoboot_loop break; default: key = BKEY_NONE; @@ -169,7 +169,7 @@ Signed-off-by: Weijie Gao break; } break; -@@ -481,7 +521,8 @@ enum bootmenu_key bootmenu_autoboot_loop +@@ -492,7 +532,8 @@ enum bootmenu_key bootmenu_autoboot_loop return key; } @@ -179,7 +179,7 @@ Signed-off-by: Weijie Gao { enum bootmenu_key key; -@@ -513,6 +554,20 @@ enum bootmenu_key bootmenu_conv_key(int +@@ -524,6 +565,20 @@ enum bootmenu_key bootmenu_conv_key(int case ' ': key = BKEY_SPACE; break; @@ -200,15 +200,16 @@ Signed-off-by: Weijie Gao default: key = BKEY_NONE; break; -@@ -522,11 +577,16 @@ enum bootmenu_key bootmenu_conv_key(int +@@ -533,11 +588,17 @@ enum bootmenu_key bootmenu_conv_key(int } enum bootmenu_key bootmenu_loop(struct bootmenu_data *menu, - struct cli_ch_state *cch) -+ struct cli_ch_state *cch, int *choice) ++ struct cli_ch_state *cch, ++ int *choice) { enum bootmenu_key key; - int c; + int c, errchar = 0; + if (menu->last_choiced) { + menu->last_choiced = false; @@ -218,7 +219,7 @@ Signed-off-by: Weijie Gao c = cli_ch_process(cch, 0); if (!c) { while (!c && !tstc()) { -@@ -540,7 +600,7 @@ enum bootmenu_key bootmenu_loop(struct b +@@ -552,7 +613,7 @@ enum bootmenu_key bootmenu_loop(struct b } } @@ -238,7 +239,7 @@ Signed-off-by: Weijie Gao struct cli_ch_state; struct menu; -@@ -19,6 +21,8 @@ int menu_get_choice(struct menu *m, void +@@ -20,6 +22,8 @@ int menu_get_choice(struct menu *m, void int menu_item_add(struct menu *m, char *item_key, void *item_data); int menu_destroy(struct menu *m); int menu_default_choice(struct menu *m, void **choice); @@ -247,15 +248,15 @@ Signed-off-by: Weijie Gao /** * menu_show() Show a boot menu -@@ -41,6 +45,7 @@ struct bootmenu_data { - int active; /* active menu entry */ +@@ -43,6 +47,7 @@ struct bootmenu_data { + int last_active; /* last active menu entry */ int count; /* total count of menu entries */ struct bootmenu_entry *first; /* first menu entry */ + bool last_choiced; }; /** enum bootmenu_key - keys that can be returned by the bootmenu */ -@@ -51,6 +56,7 @@ enum bootmenu_key { +@@ -53,6 +58,7 @@ enum bootmenu_key { BKEY_SELECT, BKEY_QUIT, BKEY_SAVE, @@ -263,7 +264,7 @@ Signed-off-by: Weijie Gao /* 'extra' keys, which are used by menus but not cedit */ BKEY_PLUS, -@@ -81,7 +87,7 @@ enum bootmenu_key { +@@ -83,7 +89,7 @@ enum bootmenu_key { * anything else: KEY_NONE */ enum bootmenu_key bootmenu_autoboot_loop(struct bootmenu_data *menu, @@ -272,7 +273,7 @@ Signed-off-by: Weijie Gao /** * bootmenu_loop() - handle waiting for a keypress when autoboot is disabled -@@ -107,7 +113,7 @@ enum bootmenu_key bootmenu_autoboot_loop +@@ -109,7 +115,7 @@ enum bootmenu_key bootmenu_autoboot_loop * Space: BKEY_SPACE */ enum bootmenu_key bootmenu_loop(struct bootmenu_data *menu, @@ -281,7 +282,7 @@ Signed-off-by: Weijie Gao /** * bootmenu_conv_key() - Convert a U-Boot keypress into a menu key -@@ -115,6 +121,7 @@ enum bootmenu_key bootmenu_loop(struct b +@@ -117,6 +123,7 @@ enum bootmenu_key bootmenu_loop(struct b * @ichar: Keypress to convert (ASCII, including control characters) * Returns: Menu key that corresponds to @ichar, or BKEY_NONE if none */ diff --git a/package/boot/uboot-mediatek/patches/211-cmd-bootmenu-custom-title.patch b/package/boot/uboot-mediatek/patches/211-cmd-bootmenu-custom-title.patch index 76ff745e93f8b4..be06832ea1ea32 100644 --- a/package/boot/uboot-mediatek/patches/211-cmd-bootmenu-custom-title.patch +++ b/package/boot/uboot-mediatek/patches/211-cmd-bootmenu-custom-title.patch @@ -1,6 +1,6 @@ --- a/cmd/bootmenu.c +++ b/cmd/bootmenu.c -@@ -451,7 +451,11 @@ static void menu_display_statusline(stru +@@ -465,7 +465,11 @@ static void menu_display_statusline(stru printf(ANSI_CURSOR_POSITION, 1, 1); puts(ANSI_CLEAR_LINE); printf(ANSI_CURSOR_POSITION, 2, 3); @@ -13,7 +13,7 @@ puts(ANSI_CLEAR_LINE_TO_END); printf(ANSI_CURSOR_POSITION, 3, 1); puts(ANSI_CLEAR_LINE); -@@ -536,6 +540,7 @@ static enum bootmenu_ret bootmenu_show(i +@@ -550,6 +554,7 @@ static enum bootmenu_ret bootmenu_show(i return BOOTMENU_RET_FAIL; } @@ -23,8 +23,8 @@ goto cleanup; --- a/include/menu.h +++ b/include/menu.h -@@ -45,6 +45,7 @@ struct bootmenu_data { - int active; /* active menu entry */ +@@ -47,6 +47,7 @@ struct bootmenu_data { + int last_active; /* last active menu entry */ int count; /* total count of menu entries */ struct bootmenu_entry *first; /* first menu entry */ + char *mtitle; /* custom menu title */ diff --git a/package/boot/uboot-mediatek/patches/401-update-u7623-defconfig.patch b/package/boot/uboot-mediatek/patches/401-update-u7623-defconfig.patch index 1fb0ae9c9eb0b7..7d193696720214 100644 --- a/package/boot/uboot-mediatek/patches/401-update-u7623-defconfig.patch +++ b/package/boot/uboot-mediatek/patches/401-update-u7623-defconfig.patch @@ -187,13 +187,12 @@ leds { compatible = "gpio-leds"; -@@ -109,6 +122,19 @@ +@@ -109,6 +122,18 @@ }; }; + key_pins_a: keys-alt { + mux { -+ function = "gpio"; + groups = "msdc3"; + }; + diff --git a/package/boot/uboot-mediatek/patches/445-add-cudy_tr3000-v1.patch b/package/boot/uboot-mediatek/patches/445-add-cudy_tr3000-v1.patch new file mode 100644 index 00000000000000..e7d83b90cacdf5 --- /dev/null +++ b/package/boot/uboot-mediatek/patches/445-add-cudy_tr3000-v1.patch @@ -0,0 +1,330 @@ +--- /dev/null ++++ b/configs/mt7981_cudy_tr3000-v1_defconfig +@@ -0,0 +1,107 @@ ++CONFIG_ARM=y ++CONFIG_SYS_HAS_NONCACHED_MEMORY=y ++CONFIG_POSITION_INDEPENDENT=y ++CONFIG_ARCH_MEDIATEK=y ++CONFIG_TEXT_BASE=0x41e00000 ++CONFIG_SYS_MALLOC_F_LEN=0x4000 ++CONFIG_NR_DRAM_BANKS=1 ++CONFIG_DEFAULT_DEVICE_TREE="mt7981-cudy-tr3000-v1" ++CONFIG_OF_LIBFDT_OVERLAY=y ++CONFIG_TARGET_MT7981=y ++CONFIG_PRE_CON_BUF_ADDR=0x4007EF00 ++CONFIG_DEBUG_UART_BASE=0x11002000 ++CONFIG_DEBUG_UART_CLOCK=40000000 ++CONFIG_SYS_LOAD_ADDR=0x46000000 ++CONFIG_DEBUG_UART=y ++CONFIG_FIT=y ++CONFIG_BOOTDELAY=30 ++CONFIG_AUTOBOOT_KEYED=y ++CONFIG_AUTOBOOT_MENU_SHOW=y ++CONFIG_DEFAULT_FDT_FILE="mediatek/mt7981-cudy-tr3000-v1.dtb" ++CONFIG_LOGLEVEL=7 ++CONFIG_PRE_CONSOLE_BUFFER=y ++CONFIG_LOG=y ++CONFIG_BOARD_LATE_INIT=y ++CONFIG_HUSH_PARSER=y ++CONFIG_SYS_PROMPT="MT7981> " ++CONFIG_CMD_CPU=y ++CONFIG_CMD_LICENSE=y ++CONFIG_CMD_BOOTMENU=y ++CONFIG_CMD_ASKENV=y ++CONFIG_CMD_ERASEENV=y ++CONFIG_CMD_ENV_FLAGS=y ++CONFIG_CMD_STRINGS=y ++CONFIG_CMD_DM=y ++CONFIG_CMD_GPIO=y ++CONFIG_CMD_GPT=y ++CONFIG_CMD_MTD=y ++CONFIG_CMD_PART=y ++CONFIG_CMD_DHCP=y ++CONFIG_CMD_TFTPSRV=y ++CONFIG_CMD_RARP=y ++CONFIG_CMD_PING=y ++CONFIG_CMD_CDP=y ++CONFIG_CMD_SNTP=y ++CONFIG_CMD_DNS=y ++CONFIG_CMD_LINK_LOCAL=y ++CONFIG_CMD_PXE=y ++CONFIG_CMD_CACHE=y ++CONFIG_CMD_PSTORE=y ++CONFIG_CMD_PSTORE_MEM_ADDR=0x42ff0000 ++CONFIG_CMD_UUID=y ++CONFIG_CMD_HASH=y ++CONFIG_CMD_SMC=y ++CONFIG_CMD_UBI=y ++CONFIG_CMD_UBI_RENAME=y ++CONFIG_OF_EMBED=y ++CONFIG_ENV_OVERWRITE=y ++CONFIG_ENV_IS_IN_UBI=y ++CONFIG_SYS_REDUNDAND_ENVIRONMENT=y ++CONFIG_ENV_UBI_PART="ubi" ++CONFIG_ENV_UBI_VOLUME="ubootenv" ++CONFIG_ENV_UBI_VOLUME_REDUND="ubootenv2" ++CONFIG_SYS_RELOC_GD_ENV_ADDR=y ++CONFIG_USE_DEFAULT_ENV_FILE=y ++CONFIG_DEFAULT_ENV_FILE="cudy_tr3000-v1_env" ++CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y ++CONFIG_VERSION_VARIABLE=y ++CONFIG_NET_RANDOM_ETHADDR=y ++CONFIG_NETCONSOLE=y ++CONFIG_USE_IPADDR=y ++CONFIG_IPADDR="192.168.1.1" ++CONFIG_USE_SERVERIP=y ++CONFIG_SERVERIP="192.168.1.254" ++CONFIG_REGMAP=y ++CONFIG_SYSCON=y ++CONFIG_BUTTON=y ++CONFIG_BUTTON_GPIO=y ++CONFIG_CLK=y ++CONFIG_GPIO_HOG=y ++CONFIG_LED=y ++CONFIG_LED_BLINK=y ++CONFIG_LED_GPIO=y ++# CONFIG_MMC is not set ++CONFIG_MTD=y ++CONFIG_DM_MTD=y ++CONFIG_MTD_SPI_NAND=y ++CONFIG_MTD_UBI_FASTMAP=y ++CONFIG_PHY_FIXED=y ++CONFIG_MEDIATEK_ETH=y ++CONFIG_PHY=y ++CONFIG_PINCTRL=y ++CONFIG_PINCONF=y ++CONFIG_PINCTRL_MT7981=y ++CONFIG_POWER_DOMAIN=y ++CONFIG_MTK_POWER_DOMAIN=y ++CONFIG_DM_REGULATOR=y ++CONFIG_DM_REGULATOR_FIXED=y ++CONFIG_DM_REGULATOR_GPIO=y ++CONFIG_RAM=y ++CONFIG_DM_SERIAL=y ++CONFIG_MTK_SERIAL=y ++CONFIG_SPI=y ++CONFIG_DM_SPI=y ++CONFIG_MTK_SPIM=y ++CONFIG_ZSTD=y ++CONFIG_HEXDUMP=y ++CONFIG_LMB_MAX_REGIONS=64 +--- /dev/null ++++ b/arch/arm/dts/mt7981-cudy-tr3000-v1.dts +@@ -0,0 +1,160 @@ ++// SPDX-License-Identifier: GPL-2.0-or-later ++ ++/dts-v1/; ++#include "mt7981.dtsi" ++#include ++#include ++ ++/ { ++ #address-cells = <1>; ++ #size-cells = <1>; ++ model = "Cudy TR3000 v1"; ++ compatible = "mediatek,mt7981", "mediatek,mt7981-rfb"; ++ ++ chosen { ++ stdout-path = &uart0; ++ tick-timer = &timer0; ++ }; ++ ++ memory@40000000 { ++ device_type = "memory"; ++ reg = <0x40000000 0x20000000>; ++ }; ++ ++ gpio-keys { ++ compatible = "gpio-keys"; ++ ++ button-reset { ++ label = "reset"; ++ linux,code = ; ++ gpios = <&gpio 1 GPIO_ACTIVE_LOW>; ++ }; ++ ++ button-mode { ++ label = "mode"; ++ linux,code = ; ++ linux,input-type = ; ++ gpios = <&gpio 0 GPIO_ACTIVE_HIGH>; ++ debounce-interval = <60>; ++ }; ++ }; ++ ++ gpio-leds { ++ compatible = "gpio-leds"; ++ ++ led_status: led-0 { ++ label = "red:power"; ++ gpios = <&gpio 11 GPIO_ACTIVE_LOW>; ++ default-state = "on"; ++ }; ++ ++ led-1 { ++ label = "white:status"; ++ gpios = <&gpio 10 GPIO_ACTIVE_LOW>; ++ default-state = "off"; ++ }; ++ }; ++}; ++ ++ð { ++ status = "okay"; ++ mediatek,gmac-id = <1>; ++ phy-mode = "gmii"; ++ phy-handle = <&phy0>; ++ ++ mdio { ++ phy0: ethernet-phy@0 { ++ compatible = "ethernet-phy-id03a2.9461"; ++ reg = <0x0>; ++ phy-mode = "gmii"; ++ }; ++ }; ++}; ++ ++&pinctrl { ++ spi_flash_pins: spi0-pins-func-1 { ++ mux { ++ function = "flash"; ++ groups = "spi0", "spi0_wp_hold"; ++ }; ++ ++ conf-pu { ++ pins = "SPI0_CS", "SPI0_HOLD", "SPI0_WP"; ++ drive-strength = ; ++ bias-pull-up = ; ++ }; ++ ++ conf-pd { ++ pins = "SPI0_CLK", "SPI0_MOSI", "SPI0_MISO"; ++ drive-strength = ; ++ bias-pull-down = ; ++ }; ++ }; ++}; ++ ++&spi0 { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&spi_flash_pins>; ++ status = "okay"; ++ must_tx; ++ enhance_timing; ++ dma_ext; ++ ipm_design; ++ support_quad; ++ tick_dly = <2>; ++ sample_sel = <0>; ++ ++ spi_nand@0 { ++ compatible = "spi-nand"; ++ reg = <0>; ++ spi-max-frequency = <52000000>; ++ ++ partitions { ++ compatible = "fixed-partitions"; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ partition@0 { ++ label = "bl2"; ++ reg = <0x0 0x100000>; ++ }; ++ ++ partition@100000 { ++ label = "u-boot-env"; ++ reg = <0x100000 0x80000>; ++ }; ++ ++ partition@180000 { ++ label = "factory"; ++ reg = <0x180000 0x200000>; ++ }; ++ ++ partition@380000 { ++ label = "bdinfo"; ++ reg = <0x380000 0x40000>; ++ }; ++ ++ partition@3c0000 { ++ label = "fip"; ++ reg = <0x3c0000 0x200000>; ++ }; ++ ++ partition@5c0000 { ++ label = "ubi"; ++ reg = <0x5c0000 0x7a40000>; ++ compatible = "linux,ubi"; ++ }; ++ }; ++ }; ++}; ++ ++&uart0 { ++ mediatek,force-highspeed; ++ status = "okay"; ++}; ++ ++&watchdog { ++ status = "disabled"; ++}; +--- /dev/null ++++ b/cudy_tr3000-v1_env +@@ -0,0 +1,54 @@ ++ipaddr=192.168.1.1 ++serverip=192.168.1.254 ++loadaddr=0x46000000 ++console=earlycon=uart8250,mmio32,0x11002000 console=ttyS0 ++bootcmd=if pstore check ; then run boot_recovery ; else run boot_ubi ; fi ++bootconf=config-1 ++bootdelay=0 ++bootfile=openwrt-mediatek-filogic-cudy_tr3000-v1-ubootmod-initramfs-recovery.itb ++bootfile_bl2=openwrt-mediatek-filogic-cudy_tr3000-v1-ubootmod-preloader.bin ++bootfile_fip=openwrt-mediatek-filogic-cudy_tr3000-v1-ubootmod-bl31-uboot.fip ++bootfile_upg=openwrt-mediatek-filogic-cudy_tr3000-v1-ubootmod-squashfs-sysupgrade.itb ++bootled_pwr=red:power ++bootled_rec=white:status ++bootmenu_confirm_return=askenv - Press ENTER to return to menu ; bootmenu 60 ++bootmenu_default=0 ++bootmenu_delay=0 ++bootmenu_title= ( ( ( OpenWrt ) ) ) ++bootmenu_0=Initialize environment.=run _firstboot ++bootmenu_0d=Run default boot command.=run boot_default ++bootmenu_1=Boot system via TFTP.=run boot_tftp ; run bootmenu_confirm_return ++bootmenu_2=Boot production system from NAND.=run boot_production ; run bootmenu_confirm_return ++bootmenu_3=Boot recovery system from NAND.=run boot_recovery ; run bootmenu_confirm_return ++bootmenu_4=Load production system via TFTP then write to NAND.=setenv noboot 1 ; setenv replacevol 1 ; run boot_tftp_production ; setenv noboot ; setenv replacevol ; run bootmenu_confirm_return ++bootmenu_5=Load recovery system via TFTP then write to NAND.=setenv noboot 1 ; setenv replacevol 1 ; run boot_tftp_recovery ; setenv noboot ; setenv replacevol ; run bootmenu_confirm_return ++bootmenu_6=Load BL31+U-Boot FIP via TFTP then write to NAND.=run boot_tftp_write_fip ; run bootmenu_confirm_return ++bootmenu_7=Load BL2 preloader via TFTP then write to NAND.=run boot_tftp_write_bl2 ; run bootmenu_confirm_return ++bootmenu_8=Reboot.=reset ++bootmenu_9=Reset all settings to factory defaults.=run reset_factory ; reset ++boot_first=if button reset ; then led $bootled_rec on ; run boot_tftp_recovery ; setenv flag_recover 1 ; run boot_default ; fi ; bootmenu ++boot_default=if env exists flag_recover ; then else run bootcmd ; fi ; run boot_recovery ; setenv replacevol 1 ; run boot_tftp_forever ++boot_production=led $bootled_pwr on ; run ubi_read_production && bootm $loadaddr#$bootconf ; led $bootled_pwr off ++boot_recovery=led $bootled_rec on ; run ubi_read_recovery && bootm $loadaddr#$bootconf ; led $bootled_rec off ++boot_ubi=run boot_production ; run boot_recovery ; run boot_tftp_forever ++boot_tftp_forever=led $bootled_rec on ; while true ; do run boot_tftp_recovery ; sleep 1 ; done ++boot_tftp_production=tftpboot $loadaddr $bootfile_upg && env exists replacevol && iminfo $loadaddr && run ubi_write_production ; if env exists noboot ; then else bootm $loadaddr#$bootconf ; fi ++boot_tftp_recovery=tftpboot $loadaddr $bootfile && env exists replacevol && iminfo $loadaddr && run ubi_write_recovery ; if env exists noboot ; then else bootm $loadaddr#$bootconf ; fi ++boot_tftp=tftpboot $loadaddr $bootfile && bootm $loadaddr#$bootconf ++boot_tftp_write_fip=tftpboot $loadaddr $bootfile_fip && run mtd_write_fip && run reset_factory ++boot_tftp_write_bl2=tftpboot $loadaddr $bootfile_bl2 && run mtd_write_bl2 ++reset_factory=ubi part ubi ; mw $loadaddr 0x0 0x800 ; ubi write $loadaddr ubootenv 0x800 ; ubi write $loadaddr ubootenv2 0x800 ++mtd_write_fip=mtd erase fip && mtd write fip $loadaddr ++mtd_write_bl2=mtd erase bl2 && mtd write bl2 $loadaddr ++ubi_create_env=ubi check ubootenv || ubi create ubootenv 0x100000 dynamic || run ubi_format ; ubi check ubootenv2 || ubi create ubootenv2 0x100000 dynamic || run ubi_format ++ubi_format=ubi detach ; mtd erase ubi && ubi part ubi ; reset ++ubi_prepare_rootfs=if ubi check rootfs_data ; then else if env exists rootfs_data_max ; then ubi create rootfs_data $rootfs_data_max dynamic || ubi create rootfs_data - dynamic ; else ubi create rootfs_data - dynamic ; fi ; fi ++ubi_read_production=ubi read $loadaddr fit && iminfo $loadaddr && run ubi_prepare_rootfs ++ubi_read_recovery=ubi check recovery && ubi read $loadaddr recovery ++ubi_remove_rootfs=ubi check rootfs_data && ubi remove rootfs_data ++ubi_write_production=ubi check fit && ubi remove fit ; run ubi_remove_rootfs ; ubi create fit $filesize dynamic && ubi write $loadaddr fit $filesize ++ubi_write_recovery=ubi check recovery && ubi remove recovery ; run ubi_remove_rootfs ; ubi create recovery $filesize dynamic && ubi write $loadaddr recovery $filesize ++_init_env=setenv _init_env ; run ubi_create_env ; saveenv ; saveenv ++_firstboot=setenv _firstboot ; run _switch_to_menu ; run _init_env ; run boot_first ++_switch_to_menu=setenv _switch_to_menu ; setenv bootdelay 3 ; setenv bootmenu_delay 3 ; setenv bootmenu_0 $bootmenu_0d ; setenv bootmenu_0d ; run _bootmenu_update_title ++_bootmenu_update_title=setenv _bootmenu_update_title ; setenv bootmenu_title "$bootmenu_title $ver" diff --git a/package/boot/uboot-mediatek/patches/445-add-netis-nx31.patch b/package/boot/uboot-mediatek/patches/445-add-netis-nx31.patch new file mode 100644 index 00000000000000..55a94189d30687 --- /dev/null +++ b/package/boot/uboot-mediatek/patches/445-add-netis-nx31.patch @@ -0,0 +1,334 @@ +--- /dev/null ++++ b/configs/mt7981_netis_nx31_defconfig +@@ -0,0 +1,106 @@ ++CONFIG_ARM=y ++CONFIG_SYS_HAS_NONCACHED_MEMORY=y ++CONFIG_POSITION_INDEPENDENT=y ++CONFIG_ARCH_MEDIATEK=y ++CONFIG_TEXT_BASE=0x41e00000 ++CONFIG_SYS_MALLOC_F_LEN=0x4000 ++CONFIG_NR_DRAM_BANKS=1 ++CONFIG_DEFAULT_DEVICE_TREE="mt7981-netis_nx31" ++CONFIG_OF_LIBFDT_OVERLAY=y ++CONFIG_TARGET_MT7981=y ++CONFIG_SYS_LOAD_ADDR=0x46000000 ++CONFIG_PRE_CON_BUF_ADDR=0x4007ef00 ++CONFIG_DEBUG_UART_BASE=0x11002000 ++CONFIG_DEBUG_UART_CLOCK=40000000 ++CONFIG_DEBUG_UART=y ++CONFIG_FIT=y ++CONFIG_BOOTDELAY=30 ++CONFIG_AUTOBOOT_KEYED=y ++CONFIG_AUTOBOOT_MENU_SHOW=y ++CONFIG_DEFAULT_FDT_FILE="mediatek/mt7981-netis_nx31.dtb" ++CONFIG_LOGLEVEL=7 ++CONFIG_PRE_CONSOLE_BUFFER=y ++CONFIG_LOG=y ++CONFIG_BOARD_LATE_INIT=y ++CONFIG_HUSH_PARSER=y ++CONFIG_SYS_PROMPT="MT7981> " ++CONFIG_CMD_CPU=y ++CONFIG_CMD_LICENSE=y ++CONFIG_CMD_BOOTMENU=y ++CONFIG_CMD_ASKENV=y ++CONFIG_CMD_ERASEENV=y ++CONFIG_CMD_ENV_FLAGS=y ++CONFIG_CMD_STRINGS=y ++CONFIG_CMD_DM=y ++CONFIG_CMD_GPIO=y ++CONFIG_CMD_GPT=y ++CONFIG_CMD_MTD=y ++CONFIG_CMD_PART=y ++CONFIG_CMD_TFTPSRV=y ++CONFIG_CMD_RARP=y ++CONFIG_CMD_CDP=y ++CONFIG_CMD_SNTP=y ++CONFIG_CMD_LINK_LOCAL=y ++CONFIG_CMD_DHCP=y ++CONFIG_CMD_DNS=y ++CONFIG_CMD_PING=y ++CONFIG_CMD_PXE=y ++CONFIG_CMD_CACHE=y ++CONFIG_CMD_PSTORE=y ++CONFIG_CMD_PSTORE_MEM_ADDR=0x42ff0000 ++CONFIG_CMD_UUID=y ++CONFIG_CMD_HASH=y ++CONFIG_CMD_SMC=y ++CONFIG_CMD_UBI=y ++CONFIG_CMD_UBI_RENAME=y ++CONFIG_OF_EMBED=y ++CONFIG_ENV_OVERWRITE=y ++CONFIG_ENV_IS_IN_UBI=y ++CONFIG_SYS_REDUNDAND_ENVIRONMENT=y ++CONFIG_ENV_UBI_PART="ubi" ++CONFIG_ENV_UBI_VOLUME="ubootenv" ++CONFIG_ENV_UBI_VOLUME_REDUND="ubootenv2" ++CONFIG_SYS_RELOC_GD_ENV_ADDR=y ++CONFIG_USE_DEFAULT_ENV_FILE=y ++CONFIG_DEFAULT_ENV_FILE="defenvs/netis_nx31_env" ++CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y ++CONFIG_VERSION_VARIABLE=y ++CONFIG_NETCONSOLE=y ++CONFIG_USE_IPADDR=y ++CONFIG_IPADDR="192.168.1.1" ++CONFIG_USE_SERVERIP=y ++CONFIG_SERVERIP="192.168.1.254" ++CONFIG_NET_RANDOM_ETHADDR=y ++CONFIG_BUTTON=y ++CONFIG_BUTTON_GPIO=y ++CONFIG_CLK=y ++CONFIG_GPIO_HOG=y ++CONFIG_LED=y ++CONFIG_LED_BLINK=y ++CONFIG_LED_GPIO=y ++# CONFIG_MMC is not set ++CONFIG_MTD=y ++CONFIG_DM_MTD=y ++CONFIG_MTD_SPI_NAND=y ++CONFIG_MTD_UBI_FASTMAP=y ++CONFIG_PHY_FIXED=y ++CONFIG_MEDIATEK_ETH=y ++CONFIG_PHY=y ++CONFIG_PHY_MTK_TPHY=y ++CONFIG_PINCTRL=y ++CONFIG_PINCONF=y ++CONFIG_PINCTRL_MT7981=y ++CONFIG_POWER_DOMAIN=y ++CONFIG_MTK_POWER_DOMAIN=y ++CONFIG_DM_REGULATOR=y ++CONFIG_DM_REGULATOR_FIXED=y ++CONFIG_DM_REGULATOR_GPIO=y ++CONFIG_RAM=y ++CONFIG_DM_SERIAL=y ++CONFIG_SERIAL_RX_BUFFER=y ++CONFIG_MTK_SERIAL=y ++CONFIG_SPI=y ++CONFIG_DM_SPI=y ++CONFIG_MTK_SPIM=y ++CONFIG_ZSTD=y ++CONFIG_HEXDUMP=y +--- /dev/null ++++ b/arch/arm/dts/mt7981-netis_nx31.dts +@@ -0,0 +1,162 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* ++ * Copyright (c) 2025 ++ * Author: Mikhail Zhilkin ++ */ ++ ++/dts-v1/; ++#include "mt7981.dtsi" ++#include ++#include ++ ++/ { ++ #address-cells = <1>; ++ #size-cells = <1>; ++ model = "netis NX31"; ++ compatible = "netis,nx31", "mediatek,mt7981"; ++ ++ chosen { ++ stdout-path = &uart0; ++ tick-timer = &timer0; ++ }; ++ ++ memory@40000000 { ++ device_type = "memory"; ++ reg = <0x40000000 0x10000000>; ++ }; ++ ++ keys { ++ compatible = "gpio-keys"; ++ ++ button-0 { ++ label = "mesh"; ++ linux,code = ; ++ gpios = <&gpio 1 GPIO_ACTIVE_LOW>; ++ }; ++ ++ button-1 { ++ label = "reset"; ++ linux,code = ; ++ gpios = <&gpio 1 GPIO_ACTIVE_LOW>; ++ }; ++ }; ++ ++ leds { ++ compatible = "gpio-leds"; ++ ++ led-0 { ++ label = "blue:wlan2g"; ++ gpios = <&gpio 5 GPIO_ACTIVE_LOW>; ++ }; ++ ++ led-1 { ++ label = "blue:status"; ++ gpios = <&gpio 7 GPIO_ACTIVE_LOW>; ++ }; ++ ++ led-2 { ++ label = "blue:wan"; ++ gpios = <&gpio 8 GPIO_ACTIVE_LOW>; ++ }; ++ ++ led-3 { ++ label = "blue:wlan5g"; ++ gpios = <&gpio 34 GPIO_ACTIVE_LOW>; ++ }; ++ }; ++}; ++ ++&uart0 { ++ mediatek,force-highspeed; ++ status = "okay"; ++}; ++ ++ð { ++ status = "okay"; ++ mediatek,gmac-id = <0>; ++ phy-mode = "2500base-x"; ++ mediatek,switch = "mt7531"; ++ reset-gpios = <&gpio 39 GPIO_ACTIVE_HIGH>; ++ ++ fixed-link { ++ speed = <2500>; ++ full-duplex; ++ }; ++}; ++ ++&pinctrl { ++ spi_flash_pins: spi0-pins-func-1 { ++ mux { ++ function = "flash"; ++ groups = "spi0", "spi0_wp_hold"; ++ }; ++ ++ conf-pu { ++ pins = "SPI0_CS", "SPI0_HOLD", "SPI0_WP"; ++ drive-strength = ; ++ bias-pull-up = ; ++ }; ++ ++ conf-pd { ++ pins = "SPI0_CLK", "SPI0_MOSI", "SPI0_MISO"; ++ drive-strength = ; ++ bias-pull-down = ; ++ }; ++ }; ++}; ++ ++&spi0 { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&spi_flash_pins>; ++ status = "okay"; ++ must_tx; ++ enhance_timing; ++ dma_ext; ++ ipm_design; ++ support_quad; ++ tick_dly = <2>; ++ sample_sel = <0>; ++ ++ spi_nand@0 { ++ compatible = "spi-nand"; ++ reg = <0>; ++ spi-max-frequency = <52000000>; ++ ++ partitions { ++ compatible = "fixed-partitions"; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ partition@0 { ++ label = "BL2"; ++ reg = <0x0 0x100000>; ++ }; ++ ++ partition@100000 { ++ label = "u-boot-env (unused)"; ++ reg = <0x100000 0x80000>; ++ }; ++ ++ partition@160000 { ++ label = "Factory"; ++ reg = <0x180000 0x200000>; ++ }; ++ ++ partition@380000 { ++ label = "FIP"; ++ reg = <0x380000 0x200000>; ++ }; ++ ++ partition@580000 { ++ label = "ubi"; ++ reg = <0x580000 0x7a80000>; ++ }; ++ }; ++ }; ++}; ++ ++&watchdog { ++ status = "disabled"; ++}; +--- /dev/null ++++ b/defenvs/netis_nx31_env +@@ -0,0 +1,57 @@ ++ipaddr=192.168.1.1 ++serverip=192.168.1.254 ++loadaddr=0x46000000 ++console=earlycon=uart8250,mmio32,0x11002000 console=ttyS0 ++bootcmd=run check_buttons ; if pstore check ; then run boot_recovery ; else run boot_ubi ; fi ++bootconf=config-1 ++bootdelay=0 ++bootfile=openwrt-mediatek-filogic-netis_nx31-initramfs-recovery.itb ++bootfile_bl2=openwrt-mediatek-filogic-netis_nx31-preloader.bin ++bootfile_fip=openwrt-mediatek-filogic-netis_nx31-bl31-uboot.fip ++bootfile_upg=openwrt-mediatek-filogic-netis_nx31-squashfs-sysupgrade.itb ++bootled_status=blue:status ++bootmenu_confirm_return=askenv - Press ENTER to return to menu ; bootmenu 60 ++bootmenu_default=0 ++bootmenu_delay=0 ++bootmenu_title= ( ( ( OpenWrt ) ) ) ++bootmenu_0=Initialize environment.=run _firstboot ++bootmenu_0d=Run default boot command.=run boot_default ++bootmenu_1=Boot system via TFTP.=run boot_tftp ; run bootmenu_confirm_return ++bootmenu_2=Boot production system from NAND.=run boot_production ; run bootmenu_confirm_return ++bootmenu_3=Boot recovery system from NAND.=run boot_recovery ; run bootmenu_confirm_return ++bootmenu_4=Load production system via TFTP then write to NAND.=setenv noboot 1 ; setenv replacevol 1 ; run boot_tftp_production ; setenv noboot ; setenv replacevol ; run bootmenu_confirm_return ++bootmenu_5=Load recovery system via TFTP then write to NAND.=setenv noboot 1 ; setenv replacevol 1 ; run boot_tftp_recovery ; setenv noboot ; setenv replacevol ; run bootmenu_confirm_return ++bootmenu_6=Load BL31+U-Boot FIP via TFTP then write to NAND.=run boot_tftp_write_fip ; run bootmenu_confirm_return ++bootmenu_7=Load BL2 preloader via TFTP then write to NAND.=run boot_tftp_write_bl2 ; run bootmenu_confirm_return ++bootmenu_8=Reboot.=reset ++bootmenu_9=Reset all settings to factory defaults.=run reset_factory ; reset ++boot_first=if button reset ; then led $bootled_status on ; run boot_default ; fi ; bootmenu ++boot_default=if env exists flag_recover ; then else run bootcmd ; fi ; run boot_recovery ; setenv replacevol 1 ; run boot_tftp_forever ++boot_production=led $bootled_status on ; run ubi_read_production && bootm $loadaddr#$bootconf ; led bootled_status off ++boot_recovery=led $bootled_status on ; run ubi_read_recovery && bootm $loadaddr#$bootconf ; led bootled_status off ++boot_ubi=run boot_production ; run boot_recovery ; run boot_tftp_forever ++boot_tftp_forever=led $bootled_status on ; while true ; do run boot_tftp ; sleep 1 ; done ++boot_tftp_production=tftpboot $loadaddr $bootfile_upg && env exists replacevol && iminfo $loadaddr && run ubi_write_production ; if env exists noboot ; then else bootm $loadaddr#$bootconf ; fi ++boot_tftp_recovery=tftpboot $loadaddr $bootfile && env exists replacevol && iminfo $loadaddr && run ubi_write_recovery ; if env exists noboot ; then else bootm $loadaddr#$bootconf ; fi ++boot_tftp=tftpboot $loadaddr $bootfile && bootm $loadaddr#$bootconf ++boot_tftp_write_fip=tftpboot $loadaddr $bootfile_fip && run mtd_write_fip && run reset_factory ++boot_tftp_write_bl2=tftpboot $loadaddr $bootfile_bl2 && run mtd_write_bl2 ++check_buttons=if button reset ; then run boot_tftp ; fi ++ethaddr_factory=mtd read Factory 0x40080000 0x1e0000 0x20000 && env readmem -b ethaddr 0x4009ef20 0x6 ; setenv ethaddr_factory ++part_default=production ++part_recovery=recovery ++reset_factory=ubi part ubi ; mw $loadaddr 0x0 0x800 ; ubi write $loadaddr ubootenv 0x800 ; ubi write $loadaddr ubootenv2 0x800 ++mtd_write_fip=mtd erase FIP && mtd write FIP $loadaddr ++mtd_write_bl2=mtd erase BL2 && mtd write BL2 $loadaddr ++ubi_create_env=ubi check ubootenv || ubi create ubootenv 0x100000 dynamic || run ubi_format ; ubi check ubootenv2 || ubi create ubootenv2 0x100000 dynamic || run ubi_format ++ubi_format=ubi detach ; mtd erase ubi && ubi part ubi ; reset ++ubi_prepare_rootfs=if ubi check rootfs_data ; then else if env exists rootfs_data_max ; then ubi create rootfs_data $rootfs_data_max dynamic || ubi create rootfs_data - dynamic ; else ubi create rootfs_data - dynamic ; fi ; fi ++ubi_read_production=ubi read $loadaddr fit && iminfo $loadaddr && run ubi_prepare_rootfs ++ubi_read_recovery=ubi check recovery && ubi read $loadaddr recovery ++ubi_remove_rootfs=ubi check rootfs_data && ubi remove rootfs_data ++ubi_write_production=ubi check fit && ubi remove fit ; run ubi_remove_rootfs ; ubi create fit $filesize dynamic && ubi write $loadaddr fit $filesize ++ubi_write_recovery=ubi check recovery && ubi remove recovery ; run ubi_remove_rootfs ; ubi create recovery $filesize dynamic && ubi write $loadaddr recovery $filesize ++_init_env=setenv _init_env ; run ubi_create_env ; saveenv ; saveenv ++_firstboot=setenv _firstboot ; run ethaddr_factory ; run _switch_to_menu ; run _init_env ; run boot_first ++_switch_to_menu=setenv _switch_to_menu ; setenv bootdelay 3 ; setenv bootmenu_delay 3 ; setenv bootmenu_0 $bootmenu_0d ; setenv bootmenu_0d ; run _bootmenu_update_title ++_bootmenu_update_title=setenv _bootmenu_update_title ; setenv bootmenu_title "$bootmenu_title $ver" diff --git a/package/boot/uboot-mediatek/patches/446-add-cmcc_a10.patch b/package/boot/uboot-mediatek/patches/446-add-cmcc_a10.patch new file mode 100644 index 00000000000000..b6165a797b055d --- /dev/null +++ b/package/boot/uboot-mediatek/patches/446-add-cmcc_a10.patch @@ -0,0 +1,327 @@ +--- /dev/null ++++ b/configs/mt7981_cmcc_a10_defconfig +@@ -0,0 +1,107 @@ ++CONFIG_ARM=y ++CONFIG_SYS_HAS_NONCACHED_MEMORY=y ++CONFIG_POSITION_INDEPENDENT=y ++CONFIG_ARCH_MEDIATEK=y ++CONFIG_TEXT_BASE=0x41e00000 ++CONFIG_SYS_MALLOC_F_LEN=0x4000 ++CONFIG_NR_DRAM_BANKS=1 ++CONFIG_DEFAULT_DEVICE_TREE="mt7981-cmcc-a10" ++CONFIG_OF_LIBFDT_OVERLAY=y ++CONFIG_TARGET_MT7981=y ++CONFIG_PRE_CON_BUF_ADDR=0x4007EF00 ++CONFIG_DEBUG_UART_BASE=0x11002000 ++CONFIG_DEBUG_UART_CLOCK=40000000 ++CONFIG_SYS_LOAD_ADDR=0x46000000 ++CONFIG_DEBUG_UART=y ++CONFIG_FIT=y ++CONFIG_BOOTDELAY=30 ++CONFIG_AUTOBOOT_KEYED=y ++CONFIG_AUTOBOOT_MENU_SHOW=y ++CONFIG_DEFAULT_FDT_FILE="mediatek/mt7981-cmcc-a10.dtb" ++CONFIG_LOGLEVEL=7 ++CONFIG_PRE_CONSOLE_BUFFER=y ++CONFIG_LOG=y ++CONFIG_BOARD_LATE_INIT=y ++CONFIG_HUSH_PARSER=y ++CONFIG_SYS_PROMPT="MT7981> " ++CONFIG_CMD_CPU=y ++CONFIG_CMD_LICENSE=y ++CONFIG_CMD_BOOTMENU=y ++CONFIG_CMD_ASKENV=y ++CONFIG_CMD_ERASEENV=y ++CONFIG_CMD_ENV_FLAGS=y ++CONFIG_CMD_STRINGS=y ++CONFIG_CMD_DM=y ++CONFIG_CMD_GPIO=y ++CONFIG_CMD_GPT=y ++CONFIG_CMD_MTD=y ++CONFIG_CMD_PART=y ++CONFIG_CMD_DHCP=y ++CONFIG_CMD_TFTPSRV=y ++CONFIG_CMD_RARP=y ++CONFIG_CMD_PING=y ++CONFIG_CMD_CDP=y ++CONFIG_CMD_SNTP=y ++CONFIG_CMD_DNS=y ++CONFIG_CMD_LINK_LOCAL=y ++CONFIG_CMD_PXE=y ++CONFIG_CMD_CACHE=y ++CONFIG_CMD_PSTORE=y ++CONFIG_CMD_PSTORE_MEM_ADDR=0x42ff0000 ++CONFIG_CMD_UUID=y ++CONFIG_CMD_HASH=y ++CONFIG_CMD_SMC=y ++CONFIG_CMD_UBI=y ++CONFIG_CMD_UBI_RENAME=y ++CONFIG_OF_EMBED=y ++CONFIG_ENV_OVERWRITE=y ++CONFIG_ENV_IS_IN_UBI=y ++CONFIG_SYS_REDUNDAND_ENVIRONMENT=y ++CONFIG_ENV_UBI_PART="ubi" ++CONFIG_ENV_UBI_VOLUME="ubootenv" ++CONFIG_ENV_UBI_VOLUME_REDUND="ubootenv2" ++CONFIG_SYS_RELOC_GD_ENV_ADDR=y ++CONFIG_USE_DEFAULT_ENV_FILE=y ++CONFIG_DEFAULT_ENV_FILE="cmcc_a10_env" ++CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y ++CONFIG_VERSION_VARIABLE=y ++CONFIG_NET_RANDOM_ETHADDR=y ++CONFIG_NETCONSOLE=y ++CONFIG_USE_IPADDR=y ++CONFIG_IPADDR="192.168.1.1" ++CONFIG_USE_SERVERIP=y ++CONFIG_SERVERIP="192.168.1.254" ++CONFIG_REGMAP=y ++CONFIG_SYSCON=y ++CONFIG_BUTTON=y ++CONFIG_BUTTON_GPIO=y ++CONFIG_CLK=y ++CONFIG_GPIO_HOG=y ++CONFIG_LED=y ++CONFIG_LED_BLINK=y ++CONFIG_LED_GPIO=y ++# CONFIG_MMC is not set ++CONFIG_MTD=y ++CONFIG_DM_MTD=y ++CONFIG_MTD_SPI_NAND=y ++CONFIG_MTD_UBI_FASTMAP=y ++CONFIG_PHY_FIXED=y ++CONFIG_MEDIATEK_ETH=y ++CONFIG_PHY=y ++CONFIG_PINCTRL=y ++CONFIG_PINCONF=y ++CONFIG_PINCTRL_MT7981=y ++CONFIG_POWER_DOMAIN=y ++CONFIG_MTK_POWER_DOMAIN=y ++CONFIG_DM_REGULATOR=y ++CONFIG_DM_REGULATOR_FIXED=y ++CONFIG_DM_REGULATOR_GPIO=y ++CONFIG_RAM=y ++CONFIG_DM_SERIAL=y ++CONFIG_MTK_SERIAL=y ++CONFIG_SPI=y ++CONFIG_DM_SPI=y ++CONFIG_MTK_SPIM=y ++CONFIG_ZSTD=y ++CONFIG_HEXDUMP=y ++CONFIG_LMB_MAX_REGIONS=64 +--- /dev/null ++++ b/arch/arm/dts/mt7981-cmcc-a10.dts +@@ -0,0 +1,157 @@ ++// SPDX-License-Identifier: GPL-2.0-or-later ++ ++/dts-v1/; ++#include "mt7981.dtsi" ++#include ++#include ++ ++/ { ++ #address-cells = <1>; ++ #size-cells = <1>; ++ model = "CMCC A10"; ++ compatible = "mediatek,mt7981", "mediatek,mt7981-rfb"; ++ ++ chosen { ++ stdout-path = &uart0; ++ tick-timer = &timer0; ++ }; ++ ++ memory@40000000 { ++ device_type = "memory"; ++ reg = <0x40000000 0x10000000>; ++ }; ++ ++ gpio-keys { ++ compatible = "gpio-keys"; ++ ++ button-reset { ++ label = "reset"; ++ linux,code = ; ++ gpios = <&gpio 1 GPIO_ACTIVE_LOW>; ++ }; ++ ++ button-wps { ++ label = "wps"; ++ linux,code = ; ++ gpios = <&gpio 0 GPIO_ACTIVE_LOW>; ++ }; ++ }; ++ ++ gpio-leds { ++ compatible = "gpio-leds"; ++ ++ led-0 { ++ label = "blue:status"; ++ gpios = <&gpio 9 GPIO_ACTIVE_LOW>; ++ default-state = "off"; ++ }; ++ ++ running_led: led-1 { ++ label = "green:status"; ++ gpios = <&gpio 10 GPIO_ACTIVE_LOW>; ++ default-state = "off"; ++ }; ++ ++ boot_led: led-2 { ++ label = "red:status"; ++ gpios = <&gpio 11 GPIO_ACTIVE_LOW>; ++ default-state = "on"; ++ }; ++ }; ++}; ++ ++ð { ++ status = "okay"; ++ mediatek,gmac-id = <0>; ++ phy-mode = "2500base-x"; ++ mediatek,switch = "mt7531"; ++ reset-gpios = <&gpio 39 GPIO_ACTIVE_HIGH>; ++ ++ fixed-link { ++ speed = <2500>; ++ full-duplex; ++ }; ++}; ++ ++&pinctrl { ++ spi_flash_pins: spi0-pins-func-1 { ++ mux { ++ function = "flash"; ++ groups = "spi0", "spi0_wp_hold"; ++ }; ++ ++ conf-pu { ++ pins = "SPI0_CS", "SPI0_HOLD", "SPI0_WP"; ++ drive-strength = ; ++ bias-pull-up = ; ++ }; ++ ++ conf-pd { ++ pins = "SPI0_CLK", "SPI0_MOSI", "SPI0_MISO"; ++ drive-strength = ; ++ bias-pull-down = ; ++ }; ++ }; ++}; ++ ++&spi0 { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&spi_flash_pins>; ++ status = "okay"; ++ must_tx; ++ enhance_timing; ++ dma_ext; ++ ipm_design; ++ support_quad; ++ tick_dly = <2>; ++ sample_sel = <0>; ++ ++ spi_nand@0 { ++ compatible = "spi-nand"; ++ reg = <0>; ++ spi-max-frequency = <52000000>; ++ ++ partitions { ++ compatible = "fixed-partitions"; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ partition@0 { ++ label = "bl2"; ++ reg = <0x0 0x100000>; ++ }; ++ ++ partition@100000 { ++ label = "u-boot-env"; ++ reg = <0x100000 0x80000>; ++ }; ++ ++ partition@180000 { ++ label = "factory"; ++ reg = <0x180000 0x200000>; ++ }; ++ ++ partition@380000 { ++ label = "fip"; ++ reg = <0x380000 0x200000>; ++ }; ++ ++ partition@580000 { ++ label = "ubi"; ++ reg = <0x580000 0x7a80000>; ++ compatible = "linux,ubi"; ++ }; ++ }; ++ }; ++}; ++ ++&uart0 { ++ mediatek,force-highspeed; ++ status = "okay"; ++}; ++ ++&watchdog { ++ status = "disabled"; ++}; +--- /dev/null ++++ b/cmcc_a10_env +@@ -0,0 +1,54 @@ ++ipaddr=192.168.1.1 ++serverip=192.168.1.254 ++loadaddr=0x46000000 ++console=earlycon=uart8250,mmio32,0x11002000 console=ttyS0 ++bootcmd=if pstore check ; then run boot_recovery ; else run boot_ubi ; fi ++bootconf=config-1 ++bootdelay=0 ++bootfile=openwrt-mediatek-filogic-cmcc_a10-ubootmod-initramfs-recovery.itb ++bootfile_bl2=openwrt-mediatek-filogic-cmcc_a10-ubootmod-preloader.bin ++bootfile_fip=openwrt-mediatek-filogic-cmcc_a10-ubootmod-bl31-uboot.fip ++bootfile_upg=openwrt-mediatek-filogic-cmcc_a10-ubootmod-squashfs-sysupgrade.itb ++bootled_pwr=red:status ++bootled_rec=blue:status ++bootmenu_confirm_return=askenv - Press ENTER to return to menu ; bootmenu 60 ++bootmenu_default=0 ++bootmenu_delay=0 ++bootmenu_title= ( ( ( OpenWrt ) ) ) ++bootmenu_0=Initialize environment.=run _firstboot ++bootmenu_0d=Run default boot command.=run boot_default ++bootmenu_1=Boot system via TFTP.=run boot_tftp ; run bootmenu_confirm_return ++bootmenu_2=Boot production system from NAND.=run boot_production ; run bootmenu_confirm_return ++bootmenu_3=Boot recovery system from NAND.=run boot_recovery ; run bootmenu_confirm_return ++bootmenu_4=Load production system via TFTP then write to NAND.=setenv noboot 1 ; setenv replacevol 1 ; run boot_tftp_production ; setenv noboot ; setenv replacevol ; run bootmenu_confirm_return ++bootmenu_5=Load recovery system via TFTP then write to NAND.=setenv noboot 1 ; setenv replacevol 1 ; run boot_tftp_recovery ; setenv noboot ; setenv replacevol ; run bootmenu_confirm_return ++bootmenu_6=Load BL31+U-Boot FIP via TFTP then write to NAND.=run boot_tftp_write_fip ; run bootmenu_confirm_return ++bootmenu_7=Load BL2 preloader via TFTP then write to NAND.=run boot_tftp_write_bl2 ; run bootmenu_confirm_return ++bootmenu_8=Reboot.=reset ++bootmenu_9=Reset all settings to factory defaults.=run reset_factory ; reset ++boot_first=if button reset ; then led $bootled_rec on ; run boot_tftp_recovery ; setenv flag_recover 1 ; run boot_default ; fi ; bootmenu ++boot_default=if env exists flag_recover ; then else run bootcmd ; fi ; run boot_recovery ; setenv replacevol 1 ; run boot_tftp_forever ++boot_production=led $bootled_pwr on ; run ubi_read_production && bootm $loadaddr#$bootconf ; led $bootled_pwr off ++boot_recovery=led $bootled_rec on ; run ubi_read_recovery && bootm $loadaddr#$bootconf ; led $bootled_rec off ++boot_ubi=run boot_production ; run boot_recovery ; run boot_tftp_forever ++boot_tftp_forever=led $bootled_rec on ; while true ; do run boot_tftp_recovery ; sleep 1 ; done ++boot_tftp_production=tftpboot $loadaddr $bootfile_upg && env exists replacevol && iminfo $loadaddr && run ubi_write_production ; if env exists noboot ; then else bootm $loadaddr#$bootconf ; fi ++boot_tftp_recovery=tftpboot $loadaddr $bootfile && env exists replacevol && iminfo $loadaddr && run ubi_write_recovery ; if env exists noboot ; then else bootm $loadaddr#$bootconf ; fi ++boot_tftp=tftpboot $loadaddr $bootfile && bootm $loadaddr#$bootconf ++boot_tftp_write_fip=tftpboot $loadaddr $bootfile_fip && run mtd_write_fip && run reset_factory ++boot_tftp_write_bl2=tftpboot $loadaddr $bootfile_bl2 && run mtd_write_bl2 ++reset_factory=ubi part ubi ; mw $loadaddr 0x0 0x800 ; ubi write $loadaddr ubootenv 0x800 ; ubi write $loadaddr ubootenv2 0x800 ++mtd_write_fip=mtd erase fip && mtd write fip $loadaddr ++mtd_write_bl2=mtd erase bl2 && mtd write bl2 $loadaddr ++ubi_create_env=ubi check ubootenv || ubi create ubootenv 0x100000 dynamic || run ubi_format ; ubi check ubootenv2 || ubi create ubootenv2 0x100000 dynamic || run ubi_format ++ubi_format=ubi detach ; mtd erase ubi && ubi part ubi ; reset ++ubi_prepare_rootfs=if ubi check rootfs_data ; then else if env exists rootfs_data_max ; then ubi create rootfs_data $rootfs_data_max dynamic || ubi create rootfs_data - dynamic ; else ubi create rootfs_data - dynamic ; fi ; fi ++ubi_read_production=ubi read $loadaddr fit && iminfo $loadaddr && run ubi_prepare_rootfs ++ubi_read_recovery=ubi check recovery && ubi read $loadaddr recovery ++ubi_remove_rootfs=ubi check rootfs_data && ubi remove rootfs_data ++ubi_write_production=ubi check fit && ubi remove fit ; run ubi_remove_rootfs ; ubi create fit $filesize dynamic && ubi write $loadaddr fit $filesize ++ubi_write_recovery=ubi check recovery && ubi remove recovery ; run ubi_remove_rootfs ; ubi create recovery $filesize dynamic && ubi write $loadaddr recovery $filesize ++_init_env=setenv _init_env ; run ubi_create_env ; saveenv ; saveenv ++_firstboot=setenv _firstboot ; run _switch_to_menu ; run _init_env ; run boot_first ++_switch_to_menu=setenv _switch_to_menu ; setenv bootdelay 3 ; setenv bootmenu_delay 3 ; setenv bootmenu_0 $bootmenu_0d ; setenv bootmenu_0d ; run _bootmenu_update_title ++_bootmenu_update_title=setenv _bootmenu_update_title ; setenv bootmenu_title "$bootmenu_title $ver" diff --git a/package/boot/uboot-mediatek/patches/453-add-openwrt-one.patch b/package/boot/uboot-mediatek/patches/453-add-openwrt-one.patch index cf5f79f5841996..1968f66953d8fe 100644 --- a/package/boot/uboot-mediatek/patches/453-add-openwrt-one.patch +++ b/package/boot/uboot-mediatek/patches/453-add-openwrt-one.patch @@ -519,7 +519,7 @@ +_bootmenu_update_title=setenv _bootmenu_update_title ; setenv bootmenu_title "$bootmenu_title $ver" --- /dev/null +++ b/openwrt-one-spi-nand_env -@@ -0,0 +1,60 @@ +@@ -0,0 +1,61 @@ +ethaddr_factory=mtd read factory 0x46000000 0x0 0x20000 && env readmem -b ethaddr 0x4600002a 0x6 ; setenv ethaddr_factory +ipaddr=192.168.11.11 +serverip=192.168.11.23 @@ -561,6 +561,7 @@ +check_buttons=if button front ; then run boot_recovery ; run boot_tftp ; run led_loop_error ; else if button back ; then ; run usb_recover ; run led_loop_error ; fi ; fi +led_boot=led green on ; led white on ; led red on +led_done=led green on ; led white off ; led red off ++led_loop_done=led white off ; led green on ; echo done ; while true ; do sleep 1 ; done +led_loop_error=led white off ; led green off ; while true ; do led red on ; sleep 1 ; led red off ; sleep 1 ; done +led_start=led white on ; led green off ; led red off +preboot=run led_boot diff --git a/package/boot/uboot-mediatek/patches/456-add-arcadyan-mozart.patch b/package/boot/uboot-mediatek/patches/456-add-arcadyan-mozart.patch new file mode 100644 index 00000000000000..5c9c6e697719c4 --- /dev/null +++ b/package/boot/uboot-mediatek/patches/456-add-arcadyan-mozart.patch @@ -0,0 +1,308 @@ +--- /dev/null ++++ b/configs/mt7988a_arcadyan_mozart_defconfig +@@ -0,0 +1,119 @@ ++CONFIG_ARM=y ++CONFIG_SYS_HAS_NONCACHED_MEMORY=y ++CONFIG_POSITION_INDEPENDENT=y ++CONFIG_ARCH_MEDIATEK=y ++CONFIG_TEXT_BASE=0x41e00000 ++CONFIG_SYS_MALLOC_F_LEN=0x4000 ++CONFIG_NR_DRAM_BANKS=1 ++CONFIG_ENV_SIZE=0x40000 ++CONFIG_ENV_OFFSET=0x400000 ++CONFIG_DEFAULT_DEVICE_TREE="mt7988a-arcadyan-mozart" ++CONFIG_OF_LIBFDT_OVERLAY=y ++CONFIG_TARGET_MT7988=y ++CONFIG_PRE_CON_BUF_ADDR=0x4007EF00 ++CONFIG_DEBUG_UART_BASE=0x11000000 ++CONFIG_DEBUG_UART_CLOCK=40000000 ++CONFIG_ENV_OFFSET_REDUND=0x440000 ++CONFIG_SYS_LOAD_ADDR=0x50000000 ++CONFIG_PCI=y ++CONFIG_DEBUG_UART=y ++CONFIG_AHCI=y ++CONFIG_FIT=y ++CONFIG_BOOTDELAY=30 ++CONFIG_AUTOBOOT_KEYED=y ++CONFIG_AUTOBOOT_MENU_SHOW=y ++CONFIG_OF_SYSTEM_SETUP=y ++CONFIG_DEFAULT_FDT_FILE="mediatek/mt7988a-arcadyan-mozart.dtb" ++CONFIG_SYS_CBSIZE=512 ++CONFIG_SYS_PBSIZE=1049 ++CONFIG_LOGLEVEL=7 ++CONFIG_PRE_CONSOLE_BUFFER=y ++CONFIG_LOG=y ++CONFIG_BOARD_LATE_INIT=y ++CONFIG_HUSH_PARSER=y ++CONFIG_SYS_PROMPT="MT7988> " ++CONFIG_CMD_CPU=y ++CONFIG_CMD_LICENSE=y ++# CONFIG_CMD_BOOTEFI_BOOTMGR is not set ++CONFIG_CMD_BOOTMENU=y ++CONFIG_CMD_ASKENV=y ++CONFIG_CMD_ERASEENV=y ++CONFIG_CMD_ENV_FLAGS=y ++CONFIG_CMD_STRINGS=y ++CONFIG_CMD_DM=y ++CONFIG_CMD_GPIO=y ++CONFIG_CMD_PWM=y ++CONFIG_CMD_GPT=y ++CONFIG_CMD_MMC=y ++CONFIG_CMD_MTD=y ++CONFIG_CMD_PART=y ++CONFIG_CMD_PCI=y ++CONFIG_CMD_SF_TEST=y ++CONFIG_CMD_USB=y ++CONFIG_CMD_DHCP=y ++CONFIG_CMD_TFTPSRV=y ++CONFIG_CMD_RARP=y ++CONFIG_CMD_PING=y ++CONFIG_CMD_CDP=y ++CONFIG_CMD_SNTP=y ++CONFIG_CMD_DNS=y ++CONFIG_CMD_LINK_LOCAL=y ++CONFIG_CMD_PXE=y ++CONFIG_CMD_CACHE=y ++CONFIG_CMD_PSTORE=y ++CONFIG_CMD_PSTORE_MEM_ADDR=0x42ff0000 ++CONFIG_CMD_UUID=y ++CONFIG_CMD_HASH=y ++CONFIG_CMD_SMC=y ++CONFIG_CMD_EXT4=y ++CONFIG_CMD_FAT=y ++CONFIG_CMD_FS_GENERIC=y ++CONFIG_CMD_FS_UUID=y ++CONFIG_OF_EMBED=y ++CONFIG_ENV_OVERWRITE=y ++CONFIG_ENV_IS_IN_MMC=y ++CONFIG_SYS_REDUNDAND_ENVIRONMENT=y ++CONFIG_SYS_RELOC_GD_ENV_ADDR=y ++CONFIG_USE_DEFAULT_ENV_FILE=y ++CONFIG_DEFAULT_ENV_FILE="arcadyan_mozart_env" ++CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y ++CONFIG_VERSION_VARIABLE=y ++CONFIG_NET_RANDOM_ETHADDR=y ++CONFIG_NETCONSOLE=y ++CONFIG_USE_IPADDR=y ++CONFIG_IPADDR="192.168.1.1" ++CONFIG_USE_SERVERIP=y ++CONFIG_SERVERIP="192.168.1.254" ++CONFIG_REGMAP=y ++CONFIG_SYSCON=y ++CONFIG_BUTTON=y ++CONFIG_BUTTON_GPIO=y ++CONFIG_CLK=y ++CONFIG_GPIO_HOG=y ++CONFIG_LED=y ++CONFIG_LED_BLINK=y ++CONFIG_LED_GPIO=y ++CONFIG_SUPPORT_EMMC_BOOT=y ++CONFIG_MMC_HS200_SUPPORT=y ++CONFIG_MMC_MTK=y ++CONFIG_PHY_FIXED=y ++CONFIG_MEDIATEK_ETH=y ++CONFIG_PHY=y ++CONFIG_PHY_MTK_TPHY=y ++CONFIG_PINCTRL=y ++CONFIG_PINCONF=y ++CONFIG_PINCTRL_MT7988=y ++CONFIG_POWER_DOMAIN=y ++CONFIG_MTK_POWER_DOMAIN=y ++CONFIG_DM_REGULATOR=y ++CONFIG_DM_REGULATOR_FIXED=y ++CONFIG_DM_REGULATOR_GPIO=y ++CONFIG_DM_PWM=y ++CONFIG_PWM_MTK=y ++CONFIG_RAM=y ++CONFIG_SCSI=y ++CONFIG_DM_SERIAL=y ++CONFIG_MTK_SERIAL=y ++CONFIG_ZSTD=y ++CONFIG_HEXDUMP=y ++CONFIG_LMB_MAX_REGIONS=64 +--- /dev/null ++++ b/arcadyan_mozart_env +@@ -0,0 +1,55 @@ ++ipaddr=192.168.1.1 ++serverip=192.168.1.254 ++loadaddr=0x50000000 ++bootargs=console=ttyS0,115200n1 pci=pcie_bus_perf root=/dev/fit0 rootwait ++bootcmd=if pstore check ; then run boot_recovery ; else run boot_emmc ; fi ++bootconf=config-1 ++bootconf_extra= ++bootdelay=0 ++bootfile=openwrt-mediatek-filogic-arcadyan_mozart-initramfs.itb ++bootfile_bl2=openwrt-mediatek-filogic-arcadyan_mozart-emmc-preloader.bin ++bootfile_fip=openwrt-mediatek-filogic-arcadyan_mozart-emmc-bl31-uboot.fip ++bootfile_upg=openwrt-mediatek-filogic-arcadyan_mozart-squashfs-sysupgrade.itb ++bootled_pwr=blue:status ++bootled_rec=red:status ++bootmenu_confirm_return=askenv - Press ENTER to return to menu ; bootmenu 60 ++bootmenu_default=0 ++bootmenu_delay=0 ++bootmenu_title= ( ( ( OpenWrt ) ) ) [eMMC] ++bootmenu_0=Initialize environment.=run _firstboot ++bootmenu_0d=Run default boot command.=run boot_default ++bootmenu_1=Boot system via TFTP.=run boot_tftp ; run bootmenu_confirm_return ++bootmenu_2=Boot production system from eMMC.=run boot_production ; run bootmenu_confirm_return ++bootmenu_3=Boot recovery system from eMMC.=run boot_recovery ; run bootmenu_confirm_return ++bootmenu_4=Load production system via TFTP then write to eMMC.=setenv noboot 1 ; setenv replacevol 1 ; run boot_tftp_production ; setenv noboot ; setenv replacevol ; run bootmenu_confirm_return ++bootmenu_5=Load recovery system via TFTP then write to eMMC.=setenv noboot 1 ; setenv replacevol 1 ; run boot_tftp_recovery ; setenv noboot ; setenv replacevol ; run bootmenu_confirm_return ++bootmenu_6=Load BL31+U-Boot FIP via TFTP then write to eMMC.=run boot_tftp_write_fip ; run bootmenu_confirm_return ++bootmenu_7=Load BL2 preloader via TFTP then write to eMMC.=run boot_tftp_write_bl2 ; run bootmenu_confirm_return ++bootmenu_8=Reboot.=reset ++bootmenu_9=Reset all settings to factory defaults.=run reset_factory ; reset ++boot_first=if button reset ; then led $bootled_rec on ; run boot_tftp_recovery ; setenv flag_recover 1 ; run boot_default ; fi ; bootmenu ++boot_default=if env exists flag_recover ; then else run bootcmd ; fi ; run boot_recovery ; setenv replacevol 1 ; run boot_tftp_forever ++boot_production=led $bootled_pwr on ; run emmc_read_production && bootm $loadaddr#$bootconf#$bootconf_extra ; led $bootled_pwr off ++boot_recovery=led $bootled_rec on ; run emmc_read_recovery && bootm $loadaddr#$bootconf#$bootconf_extra ; led $bootled_rec off ++boot_emmc=run boot_production ; run boot_recovery ++boot_tftp_forever=led $bootled_rec on ; while true ; do run boot_tftp_recovery ; sleep 1 ; done ++boot_tftp_production=tftpboot $loadaddr $bootfile_upg && env exists replacevol && iminfo $loadaddr && run emmc_write_production ; if env exists noboot ; then else bootm $loadaddr#$bootconf#$bootconf_extra ; fi ++boot_tftp_recovery=tftpboot $loadaddr $bootfile && env exists replacevol && iminfo $loadaddr && run emmc_write_recovery ; if env exists noboot ; then else bootm $loadaddr#$bootconf ; fi ++boot_tftp_write_fip=tftpboot $loadaddr $bootfile_fip && run emmc_write_fip ++boot_tftp_write_bl2=tftpboot $loadaddr $bootfile_bl2 && run emmc_write_bl2 ++boot_tftp=tftpboot $loadaddr $bootfile && bootm $loadaddr#$bootconf ++mmc_write_vol=imszb $loadaddr image_size && test 0x$image_size -le 0x$part_size && mmc erase 0x$part_addr 0x$image_size && mmc write $loadaddr 0x$part_addr 0x$image_size ++mmc_read_vol=mmc read $loadaddr $part_addr 0x100 && imszb $loadaddr image_size && test 0x$image_size -le 0x$part_size && mmc read $loadaddr 0x$part_addr 0x$image_size && setexpr filesize $image_size * 0x200 ++part_default=production ++part_recovery=recovery ++reset_factory=eraseenv && reset ++emmc_read_production=part start mmc 0 $part_default part_addr && part size mmc 0 $part_default part_size && run mmc_read_vol ++emmc_read_recovery=part start mmc 0 $part_recovery part_addr && part size mmc 0 $part_recovery part_size && run mmc_read_vol ++emmc_write_bl2=mmc partconf 0 1 1 1 && mmc erase 0x0 0x400 && mmc write $fileaddr 0x0 0x400 ; mmc partconf 0 1 1 0 ++emmc_write_fip=mmc erase 0x3400 0x2000 && mmc write $fileaddr 0x3400 0x2000 && mmc erase 0x2000 0x800 ++emmc_write_production=part start mmc 0 $part_default part_addr && part size mmc 0 $part_default part_size && run mmc_write_vol ++emmc_write_recovery=part start mmc 0 $part_recovery part_addr && part size mmc 0 $part_recovery part_size && run mmc_write_vol ++_init_env=setenv _init_env ; setenv _create_env ; saveenv ; saveenv ++_firstboot=setenv _firstboot ; run _switch_to_menu ; run _init_env ; run boot_first ++_switch_to_menu=setenv _switch_to_menu ; setenv bootdelay 3 ; setenv bootmenu_delay 3 ; setenv bootmenu_0 $bootmenu_0d ; setenv bootmenu_0d ; run _bootmenu_update_title ++_bootmenu_update_title=setenv _bootmenu_update_title ; setenv bootmenu_title "$bootmenu_title $ver" +--- /dev/null ++++ b/arch/arm/dts/mt7988a-arcadyan-mozart.dts +@@ -0,0 +1,125 @@ ++// SPDX-License-Identifier: GPL-2.0 ++ ++/dts-v1/; ++#include "mt7988.dtsi" ++#include ++#include ++ ++/ { ++ model = "MediaTek / Arcadyan - Mozart"; ++ compatible = "arcadyan,mozart", "mediatek,mt7988"; ++ ++ chosen { ++ stdout-path = &uart0; ++ }; ++ ++ memory@40000000 { ++ device_type = "memory"; ++ reg = <0 0x40000000 0 0x40000000>; ++ }; ++ ++ reg_3p3v: regulator-3p3v { ++ compatible = "regulator-fixed"; ++ regulator-name = "fixed-3.3V"; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-boot-on; ++ regulator-always-on; ++ }; ++ ++ reg_1p8v: regulator-1p8v { ++ compatible = "regulator-fixed"; ++ regulator-name = "fixed-1.8V"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-boot-on; ++ regulator-always-on; ++ }; ++ ++ keys { ++ compatible = "gpio-keys"; ++ ++ wps { ++ label = "reset"; ++ linux,code = ; ++ gpios = <&gpio 143 GPIO_ACTIVE_LOW>; ++ }; ++ }; ++ ++ leds { ++ compatible = "gpio-leds"; ++ ++ led-red { ++ label = "red:status"; ++ gpios = <&gpio 29 GPIO_ACTIVE_HIGH>; ++ }; ++ ++ led-green { ++ label = "blue:status"; ++ gpios = <&gpio 30 GPIO_ACTIVE_HIGH>; ++ }; ++ ++ led-blue { ++ label = "blue:status"; ++ gpios = <&gpio 31 GPIO_ACTIVE_HIGH>; ++ }; ++ }; ++}; ++ ++&uart0 { ++ status = "okay"; ++}; ++ ++ð { ++ status = "okay"; ++ mediatek,gmac-id = <0>; ++ phy-mode = "usxgmii"; ++ mediatek,switch = "mt7988"; ++ ++ fixed-link { ++ speed = <1000>; ++ full-duplex; ++ pause; ++ }; ++}; ++ ++&pinctrl { ++ mmc0_pins_default: mmc0default { ++ mux { ++ function = "flash"; ++ groups = "emmc_51"; ++ }; ++ ++ conf-cmd-dat { ++ pins = "EMMC_DATA_0", "EMMC_DATA_1", "EMMC_DATA_2", ++ "EMMC_DATA_3", "EMMC_DATA_4", "EMMC_DATA_5", ++ "EMMC_DATA_6", "EMMC_DATA_7", "EMMC_CMD"; ++ input-enable; ++ }; ++ ++ conf-clk { ++ pins = "EMMC_CK"; ++ }; ++ ++ conf-dsl { ++ pins = "EMMC_DSL"; ++ }; ++ ++ conf-rst { ++ pins = "EMMC_RSTB"; ++ }; ++ }; ++}; ++ ++&mmc0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&mmc0_pins_default>; ++ max-frequency = <52000000>; ++ bus-width = <8>; ++ cap-mmc-highspeed; ++ cap-mmc-hw-reset; ++ vmmc-supply = <®_3p3v>; ++ vqmmc-supply = <®_1p8v>; ++ non-removable; ++ status = "okay"; ++}; diff --git a/package/boot/uboot-mediatek/patches/457-initialized-the-watchdog-subsystem-later.patch b/package/boot/uboot-mediatek/patches/457-initialized-the-watchdog-subsystem-later.patch new file mode 100644 index 00000000000000..7919b365601a7a --- /dev/null +++ b/package/boot/uboot-mediatek/patches/457-initialized-the-watchdog-subsystem-later.patch @@ -0,0 +1,54 @@ +From 9c1ad8a18ac1a20aee7a617964bcae3e90dac700 Mon Sep 17 00:00:00 2001 +From: Enrico Mioso +Date: Wed, 23 Oct 2024 17:46:35 +0200 +Subject: [PATCH] uboot-mediatek: initialized the watchdog subsystem later + +Initialize the watchdog subsystem later during initialization, to allow for +the gpio-wdt driver to work. + +Signed-off-by: Enrico Mioso +--- + common/board_r.c | 11 ++++------- + 1 file changed, 4 insertions(+), 7 deletions(-) + +--- a/common/board_r.c ++++ b/common/board_r.c +@@ -663,19 +663,13 @@ static init_fnc_t init_sequence_r[] = { + serial_initialize, + initr_announce, + dm_announce, +-#if CONFIG_IS_ENABLED(WDT) +- initr_watchdog, +-#endif +- INIT_FUNC_WATCHDOG_RESET + arch_initr_trap, + #if defined(CONFIG_BOARD_EARLY_INIT_R) + board_early_init_r, + #endif +- INIT_FUNC_WATCHDOG_RESET + #ifdef CONFIG_POST + post_output_backlog, + #endif +- INIT_FUNC_WATCHDOG_RESET + #if defined(CONFIG_PCI_INIT_R) && defined(CONFIG_SYS_EARLY_PCI_INIT) + /* + * Do early PCI configuration _before_ the flash gets initialised, +@@ -690,7 +684,6 @@ static init_fnc_t init_sequence_r[] = { + #ifdef CONFIG_MTD_NOR_FLASH + initr_flash, + #endif +- INIT_FUNC_WATCHDOG_RESET + #if defined(CONFIG_PPC) || defined(CONFIG_M68K) || defined(CONFIG_X86) + /* initialize higher level parts of CPU like time base and timers */ + cpu_init_r, +@@ -719,6 +712,10 @@ static init_fnc_t init_sequence_r[] = { + #ifdef CONFIG_PVBLOCK + initr_pvblock, + #endif ++#if CONFIG_IS_ENABLED(WDT) ++ initr_watchdog, ++#endif ++ INIT_FUNC_WATCHDOG_RESET + initr_env, + #ifdef CONFIG_SYS_MALLOC_BOOTPARAMS + initr_malloc_bootparams, diff --git a/package/boot/uboot-mediatek/patches/458-add-GatoNetworks-GDSP.patch b/package/boot/uboot-mediatek/patches/458-add-GatoNetworks-GDSP.patch new file mode 100644 index 00000000000000..28bdd95e15355d --- /dev/null +++ b/package/boot/uboot-mediatek/patches/458-add-GatoNetworks-GDSP.patch @@ -0,0 +1,406 @@ +From 57d0f608d925cb688b5c9b71512fca7d228f07f6 Mon Sep 17 00:00:00 2001 +From: Enrico Mioso +Date: Wed, 23 Oct 2024 20:39:28 +0200 +Subject: [PATCH] add GatoNetworks GDSP + +Signed-off-by: Enrico Mioso +--- + arch/arm/dts/mt7981-gatonetworks_gdsp.dts | 200 +++++++++++++++++++++ + configs/mt7981_gatonetworks_gdsp_defconfig | 144 +++++++++++++++ + gatonetworks_gdsp_env | 38 ++++ + 3 files changed, 382 insertions(+) + create mode 100644 arch/arm/dts/mt7981-gatonetworks_gdsp.dts + create mode 100644 configs/mt7981_gatonetworks_gdsp_defconfig + create mode 100644 gatonetworks_gdsp_env + +--- /dev/null ++++ b/arch/arm/dts/mt7981-gatonetworks_gdsp.dts +@@ -0,0 +1,200 @@ ++// SPDX-License-Identifier: GPL-2.0-or-later OR MIT ++ ++/dts-v1/; ++#include "mt7981.dtsi" ++#include ++#include ++ ++/ { ++ #address-cells = <1>; ++ #size-cells = <1>; ++ model = "GatoNetworks GDSP"; ++ compatible = "gatonetworks,gdsp", "mediatek,mt7981"; ++ chosen { ++ stdout-path = &uart0; ++ tick-timer = &timer0; ++ }; ++ ++ memory { ++ device_type = "memory"; ++ reg = <0x40000000 0x10000000>; ++ }; ++ ++ keys { ++ compatible = "gpio-keys"; ++ ++ reset { ++ label = "reset"; ++ linux,code = ; ++ gpios = <&gpio 1 GPIO_ACTIVE_LOW>; ++ }; ++ }; ++ ++ leds { ++ compatible = "gpio-leds"; ++ ++ sim1 { ++ label = "sim1"; ++ gpios = <&gpio 13 GPIO_ACTIVE_LOW>; ++ }; ++ ++ sim2 { ++ label = "sim2"; ++ gpios = <&gpio 0 GPIO_ACTIVE_LOW>; ++ }; ++ ++ sg1 { ++ label = "sg1"; ++ gpios = <&gpio 10 GPIO_ACTIVE_LOW>; ++ }; ++ ++ sg2 { ++ label = "sg2"; ++ gpios = <&gpio 11 GPIO_ACTIVE_LOW>; ++ }; ++ ++ sg3 { ++ label = "sg3"; ++ gpios = <&gpio 12 GPIO_ACTIVE_LOW>; ++ }; ++ ++ sg4 { ++ label = "sg4"; ++ gpios = <&gpio 7 GPIO_ACTIVE_LOW>; ++ }; ++ ++ sg5 { ++ label = "sg5"; ++ gpios = <&gpio 8 GPIO_ACTIVE_LOW>; ++ }; ++ ++ sg6 { ++ label = "sg6"; ++ gpios = <&gpio 9 GPIO_ACTIVE_LOW>; ++ }; ++ }; ++ gpio-watchdog { ++ compatible = "linux,wdt-gpio"; ++ gpios = <&gpio 6 GPIO_ACTIVE_LOW>; ++ hw_algo = "toggle"; ++ hw_margin_ms = <25000>; ++ always-running; ++ u-boot,autostart; ++ }; ++}; ++ ++ð { ++ status = "okay"; ++ mediatek,gmac-id = <0>; ++ phy-mode = "2500base-x"; ++ mediatek,switch = "mt7531"; ++ reset-gpios = <&gpio 39 GPIO_ACTIVE_HIGH>; ++ ++ fixed-link { ++ speed = <2500>; ++ full-duplex; ++ }; ++}; ++ ++&spi2 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&spi2_flash_pins>; ++ status = "okay"; ++ must_tx; ++ enhance_timing; ++ dma_ext; ++ ipm_design; ++ support_quad; ++ tick_dly = <2>; ++ sample_sel = <0>; ++ ++ flash@0 { ++ compatible = "jedec,spi-nor"; ++ reg = <0>; ++ spi-max-frequency = <52000000>; ++ ++ partitions { ++ compatible = "fixed-partitions"; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ partition@00000 { ++ label = "BL2"; ++ reg = <0x00000 0x0040000>; ++ read-only; ++ }; ++ ++ partition@40000 { ++ label = "u-boot-env"; ++ reg = <0x40000 0x0010000>; ++ }; ++ ++ partition@50000 { ++ label = "Factory"; ++ reg = <0x50000 0x00B0000>; ++ read-only; ++ }; ++ ++ partition@100000 { ++ label = "FIP"; ++ reg = <0x100000 0x0080000>; ++ }; ++ ++ partition@180000 { ++ label = "firmware"; ++ reg = <0x180000 0x1E80000>; ++ }; ++ }; ++ }; ++}; ++ ++&pinctrl { ++ uart1_pins: uart1-pins { ++ mux { ++ function = "uart"; ++ groups = "uart1_0"; ++ }; ++ }; ++ ++ uart2_pins: uart2-pins { ++ mux { ++ function = "uart"; ++ groups = "uart2_0_tx_rx"; ++ }; ++ }; ++ ++ spi2_flash_pins: spi2-pins { ++ mux { ++ function = "spi"; ++ groups = "spi2", "spi2_wp_hold"; ++ }; ++ ++ conf-pu { ++ pins = "SPI2_CS", "SPI2_HOLD", "SPI2_WP"; ++ drive-strength = ; ++ bias-pull-up = ; ++ }; ++ ++ conf-pd { ++ pins = "SPI2_CLK", "SPI2_MOSI", "SPI2_MISO"; ++ drive-strength = ; ++ bias-pull-down = ; ++ }; ++ }; ++}; ++ ++&uart0 { ++ status = "okay"; ++}; ++ ++&uart1 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart1_pins>; ++ status = "okay"; ++}; ++ ++&uart2 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart2_pins>; ++ status = "okay"; ++}; +--- /dev/null ++++ b/configs/mt7981_gatonetworks_gdsp_defconfig +@@ -0,0 +1,144 @@ ++CONFIG_ARM=y ++CONFIG_SYS_HAS_NONCACHED_MEMORY=y ++CONFIG_POSITION_INDEPENDENT=y ++CONFIG_ARCH_MEDIATEK=y ++CONFIG_TEXT_BASE=0x41e00000 ++CONFIG_SYS_MALLOC_F_LEN=0x4000 ++CONFIG_NR_DRAM_BANKS=1 ++CONFIG_ENV_SIZE=0x10000 ++CONFIG_ENV_OFFSET=0x0 ++CONFIG_DEFAULT_DEVICE_TREE="mt7981-gatonetworks_gdsp" ++CONFIG_OF_LIBFDT_OVERLAY=y ++CONFIG_TARGET_MT7981=y ++CONFIG_WATCHDOG_TIMEOUT_MSECS=25000 ++CONFIG_DEBUG_UART_BASE=0x11002000 ++CONFIG_DEBUG_UART_CLOCK=40000000 ++CONFIG_SYS_LOAD_ADDR=0x46000000 ++CONFIG_DEBUG_UART=y ++CONFIG_FIT=y ++CONFIG_SPI_BOOT=y ++CONFIG_AUTOBOOT_MENU_SHOW=y ++CONFIG_USE_PREBOOT=y ++CONFIG_DEFAULT_FDT_FILE="mt7981-gatonetworks_gdsp" ++CONFIG_SYS_CBSIZE=512 ++CONFIG_SYS_PBSIZE=1049 ++CONFIG_LOGLEVEL=7 ++CONFIG_CONSOLE_MUX=y ++CONFIG_LOG=y ++CONFIG_BOARD_LATE_INIT=y ++CONFIG_HUSH_PARSER=y ++CONFIG_SYS_PROMPT="GDSP> " ++CONFIG_SYS_MAXARGS=16 ++CONFIG_CMD_BDINFO_EXTRA=y ++CONFIG_CMD_CPU=y ++CONFIG_CMD_HISTORY=y ++CONFIG_CMD_LICENSE=y ++# CONFIG_BOOTM_NETBSD is not set ++# CONFIG_BOOTM_PLAN9 is not set ++# CONFIG_BOOTM_RTEMS is not set ++# CONFIG_BOOTM_VXWORKS is not set ++# CONFIG_CMD_BOOTEFI_BOOTMGR is not set ++CONFIG_CMD_BOOTMENU=y ++CONFIG_CMD_ASKENV=y ++CONFIG_CMD_ERASEENV=y ++CONFIG_CMD_ENV_CALLBACK=y ++CONFIG_CMD_ENV_FLAGS=y ++CONFIG_CRC32_VERIFY=y ++CONFIG_LOOPW=y ++CONFIG_CMD_MEMINFO=y ++CONFIG_CMD_MEMTEST=y ++CONFIG_CMD_STRINGS=y ++# CONFIG_CMD_UNLZ4 is not set ++# CONFIG_CMD_UNZIP is not set ++CONFIG_CMD_DM=y ++CONFIG_CMD_GPIO=y ++CONFIG_CMD_GPIO_READ=y ++CONFIG_CMD_PWM=y ++CONFIG_CMD_MTD=y ++# CONFIG_CMD_NAND_EXT is not set ++CONFIG_CMD_SF_TEST=y ++CONFIG_CMD_CAT=y ++CONFIG_CMD_SETEXPR_FMT=y ++CONFIG_CMD_XXD=y ++CONFIG_CMD_DHCP=y ++CONFIG_CMD_TFTPPUT=y ++CONFIG_CMD_TFTPSRV=y ++CONFIG_CMD_RARP=y ++CONFIG_CMD_PING=y ++CONFIG_CMD_CDP=y ++CONFIG_CMD_SNTP=y ++CONFIG_CMD_DNS=y ++CONFIG_CMD_LINK_LOCAL=y ++CONFIG_CMD_PXE=y ++CONFIG_CMD_CACHE=y ++# CONFIG_CMD_EFICONFIG is not set ++CONFIG_CMD_PSTORE=y ++CONFIG_CMD_PSTORE_MEM_ADDR=0x42ff0000 ++CONFIG_CMD_UUID=y ++CONFIG_CMD_HASH=y ++CONFIG_CMD_SMC=y ++CONFIG_CMD_FAT=y ++CONFIG_CMD_FS_GENERIC=y ++CONFIG_CMD_FS_UUID=y ++CONFIG_ENV_OVERWRITE=y ++CONFIG_ENV_IS_IN_MTD=y ++CONFIG_ENV_MTD_NAME="u-boot-env" ++CONFIG_ENV_SIZE_REDUND=0x0 ++CONFIG_SYS_RELOC_GD_ENV_ADDR=y ++CONFIG_USE_DEFAULT_ENV_FILE=y ++CONFIG_DEFAULT_ENV_FILE="gatonetworks_gdsp_env" ++CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y ++CONFIG_VERSION_VARIABLE=y ++CONFIG_NET_RANDOM_ETHADDR=y ++CONFIG_NETCONSOLE=y ++CONFIG_REGMAP=y ++CONFIG_SYSCON=y ++CONFIG_BUTTON=y ++CONFIG_BUTTON_GPIO=y ++CONFIG_CLK=y ++CONFIG_GPIO_HOG=y ++CONFIG_LED=y ++CONFIG_LED_BLINK=y ++CONFIG_LED_GPIO=y ++# CONFIG_MMC is not set ++CONFIG_MTD=y ++CONFIG_DM_MTD=y ++CONFIG_MTD_SPI_NAND=y ++CONFIG_DM_SPI_FLASH=y ++CONFIG_SPI_FLASH_SFDP_SUPPORT=y ++CONFIG_SPI_FLASH_EON=y ++CONFIG_SPI_FLASH_GIGADEVICE=y ++CONFIG_SPI_FLASH_ISSI=y ++CONFIG_SPI_FLASH_MACRONIX=y ++CONFIG_SPI_FLASH_SPANSION=y ++CONFIG_SPI_FLASH_STMICRO=y ++CONFIG_SPI_FLASH_WINBOND=y ++CONFIG_SPI_FLASH_XMC=y ++CONFIG_SPI_FLASH_XTX=y ++CONFIG_SPI_FLASH_MTD=y ++CONFIG_UBI_SILENCE_MSG=y ++CONFIG_PHY_FIXED=y ++CONFIG_MEDIATEK_ETH=y ++CONFIG_PHY=y ++CONFIG_PHY_MTK_TPHY=y ++CONFIG_PINCTRL=y ++CONFIG_PINCONF=y ++CONFIG_PINCTRL_MT7981=y ++CONFIG_POWER_DOMAIN=y ++CONFIG_MTK_POWER_DOMAIN=y ++CONFIG_DM_PWM=y ++CONFIG_PWM_MTK=y ++CONFIG_DM_SERIAL=y ++CONFIG_MTK_SERIAL=y ++CONFIG_SPI=y ++CONFIG_DM_SPI=y ++CONFIG_MTK_SPIM=y ++CONFIG_USB=y ++CONFIG_USB_XHCI_HCD=y ++CONFIG_USB_XHCI_MTK=y ++CONFIG_USB_STORAGE=y ++CONFIG_WDT=y ++CONFIG_WDT_GPIO=y ++CONFIG_UBIFS_SILENCE_MSG=y ++CONFIG_HEXDUMP=y ++CONFIG_LMB_MAX_REGIONS=64 +--- /dev/null ++++ b/gatonetworks_gdsp_env +@@ -0,0 +1,38 @@ ++load_factory_data=if env exists factory_data_present ; then else mtd read Factory $loadaddr 0x0 0x1000 ; setenv factory_data_present 1 ; fi ++lan_mac_factory=run load_factory_data ; setexpr macoffs $loadaddr + 0x2a ; env readmem -b lan_mac $macoffs 0x6 ; setenv lan_mac_factory ; setenv macoffs ++wan_mac_factory=run load_factory_data ; setexpr macoffs $loadaddr + 0x24 ; env readmem -b wan_mac $macoffs 0x6 ; setenv wan_mac_factory ; setenv macoffs ++label_mac_factory=run load_factory_data ; setexpr macoffs $loadaddr + 0x4 ; env readmem -b label_mac $macoffs 0x6 ; setenv label_mac_factory ; setenv macoffs ++ethaddr_factory=setenv ethaddr $lan_mac ; setenv ethaddr_factory ++wifi_mac_factory=setenv wifi_mac $label_mac ; setenv wifi_mac_factory ++env_cleanup=setenv load_factory_data ; setenv factory_data_present ; setenv env_cleanup ++ipaddr=192.168.1.1 ++serverip=192.168.1.10 ++loadaddr=0x46000000 ++bootcmd=run boot_nor ++bootdelay=0 ++bootfile=openwrt-mediatek-filogic-gatonetworks_gdsp-initramfs-kernel.bin ++bootfile_upg=openwrt-mediatek-filogic-gatonetworks_gdsp-squashfs-sysupgrade.bin ++bootmenu_confirm_return=askenv - Press ENTER to return to menu ; bootmenu 60 ++bootmenu_default=0 ++bootmenu_delay=0 ++bootmenu_title= ( ( ( OpenWrt ) ) ) ++bootmenu_0=Initialize environment.=run _firstboot ++bootmenu_0d=Run default boot command.=run boot_default ++bootmenu_1=Boot system via TFTP.=run boot_tftp ; run bootmenu_confirm_return ++bootmenu_2=Boot system from flash.=run boot_nor ; run bootmenu_confirm_return ++bootmenu_3=Load system via TFTP then write to flash.=run boot_tftp_sysupgrade ; run bootmenu_confirm_return ++bootmenu_4=Reset all settings to factory defaults.=run reset_factory ; reset ++bootmenu_5=Reboot.=reset ++boot_first=if button reset ; then run boot_tftp ; setenv flag_recover 1 ; run boot_default ; fi ; bootmenu ++boot_default=if env exists flag_recover ; then else run bootcmd ; fi ; run boot_tftp_forever ++boot_nor=mtd read firmware ${loadaddr} ; bootm $loadaddr ++boot_tftp=tftpboot $loadaddr $bootfile && bootm $loadaddr ++boot_tftp_forever=while true ; do run boot_tftp ; sleep 1 ; done ++boot_tftp_sysupgrade=tftpboot $loadaddr $bootfile_upg && iminfo $loadaddr && run nor_write_production ++reset_factory=env default -a && saveenv && reset ++nor_pad_size=setexpr image_eb $filesize / 0x1000 ; setexpr tmp1 image_size % 0x1000 ; test 0x$tmp1 -gt 0 && setexpr image_eb $image_eb + 1 ; setexpr image_eb $image_eb * 0x1000 ++nor_write_production=run nor_pad_size ; test 0x$image_eb -le 0x1e80000 && mtd erase firmware 0x0 0x$image_eb && mtd write firmware $loadaddr 0x0 $filesize ++_init_env=setenv _init_env ; saveenv ++_firstboot=setenv _firstboot ; run _switch_to_menu ; run lan_mac_factory ; run wan_mac_factory ; run label_mac_factory ; run env_cleanup ; run ethaddr_factory ; run wifi_mac_factory ; run _init_env ; run boot_first ++_switch_to_menu=setenv _switch_to_menu ; setenv bootdelay 3 ; setenv bootmenu_delay 3 ; setenv bootmenu_0 $bootmenu_0d ; setenv bootmenu_0d ; run _bootmenu_update_title ++_bootmenu_update_title=setenv _bootmenu_update_title ; setenv bootmenu_title "$bootmenu_title $ver" diff --git a/package/boot/uboot-mediatek/patches/459-add-mercusys-mr90x-v1.patch b/package/boot/uboot-mediatek/patches/459-add-mercusys-mr90x-v1.patch new file mode 100644 index 00000000000000..4fae619aa1a2a9 --- /dev/null +++ b/package/boot/uboot-mediatek/patches/459-add-mercusys-mr90x-v1.patch @@ -0,0 +1,343 @@ +--- /dev/null ++++ b/configs/mt7986_mercusys_mr90x-v1_defconfig +@@ -0,0 +1,107 @@ ++CONFIG_ARM=y ++CONFIG_SYS_HAS_NONCACHED_MEMORY=y ++CONFIG_POSITION_INDEPENDENT=y ++CONFIG_ARCH_MEDIATEK=y ++CONFIG_TEXT_BASE=0x41e00000 ++CONFIG_SYS_MALLOC_F_LEN=0x4000 ++CONFIG_NR_DRAM_BANKS=1 ++CONFIG_DEFAULT_DEVICE_TREE="mt7986b-mercusys_mr90x-v1" ++CONFIG_OF_LIBFDT_OVERLAY=y ++CONFIG_TARGET_MT7986=y ++CONFIG_PRE_CON_BUF_ADDR=0x4007ef00 ++CONFIG_DEBUG_UART_BASE=0x11002000 ++CONFIG_DEBUG_UART_CLOCK=40000000 ++CONFIG_SYS_LOAD_ADDR=0x46000000 ++CONFIG_DEBUG_UART=y ++CONFIG_FIT=y ++CONFIG_BOOTDELAY=30 ++CONFIG_AUTOBOOT_KEYED=y ++CONFIG_AUTOBOOT_MENU_SHOW=y ++CONFIG_DEFAULT_FDT_FILE="mediatek/mt7986b-mercusys_mr90x-v1.dtb" ++CONFIG_LOGLEVEL=7 ++CONFIG_PRE_CONSOLE_BUFFER=y ++CONFIG_LOG=y ++CONFIG_BOARD_LATE_INIT=y ++CONFIG_HUSH_PARSER=y ++CONFIG_SYS_PROMPT="MT7986> " ++CONFIG_CMD_CPU=y ++CONFIG_CMD_LICENSE=y ++CONFIG_CMD_BOOTMENU=y ++CONFIG_CMD_ASKENV=y ++CONFIG_CMD_ERASEENV=y ++CONFIG_CMD_ENV_FLAGS=y ++CONFIG_CMD_STRINGS=y ++CONFIG_CMD_DM=y ++CONFIG_CMD_GPIO=y ++CONFIG_CMD_MTD=y ++CONFIG_CMD_DHCP=y ++CONFIG_CMD_TFTPSRV=y ++CONFIG_CMD_RARP=y ++CONFIG_CMD_PING=y ++CONFIG_CMD_CDP=y ++CONFIG_CMD_SNTP=y ++CONFIG_CMD_DNS=y ++CONFIG_CMD_LINK_LOCAL=y ++CONFIG_CMD_PXE=y ++CONFIG_CMD_CACHE=y ++CONFIG_CMD_PSTORE=y ++CONFIG_CMD_PSTORE_MEM_ADDR=0x42ff0000 ++CONFIG_CMD_UUID=y ++CONFIG_CMD_HASH=y ++CONFIG_CMD_SMC=y ++CONFIG_CMD_UBI=y ++CONFIG_CMD_UBI_RENAME=y ++CONFIG_OF_EMBED=y ++CONFIG_ENV_OVERWRITE=y ++CONFIG_ENV_IS_IN_UBI=y ++CONFIG_SYS_REDUNDAND_ENVIRONMENT=y ++CONFIG_ENV_UBI_PART="ubi" ++CONFIG_ENV_UBI_VOLUME="ubootenv" ++CONFIG_ENV_UBI_VOLUME_REDUND="ubootenv2" ++CONFIG_SYS_RELOC_GD_ENV_ADDR=y ++CONFIG_USE_DEFAULT_ENV_FILE=y ++CONFIG_DEFAULT_ENV_FILE="mercusys_mr90x-v1_env" ++CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y ++CONFIG_VERSION_VARIABLE=y ++CONFIG_NET_RANDOM_ETHADDR=y ++CONFIG_NETCONSOLE=y ++CONFIG_USE_IPADDR=y ++CONFIG_IPADDR="192.168.1.1" ++CONFIG_USE_SERVERIP=y ++CONFIG_SERVERIP="192.168.1.254" ++CONFIG_REGMAP=y ++CONFIG_SYSCON=y ++CONFIG_BUTTON=y ++CONFIG_BUTTON_GPIO=y ++CONFIG_CLK=y ++CONFIG_GPIO_HOG=y ++# CONFIG_I2C is not set ++# CONFIG_MMC is not set ++CONFIG_LED=y ++CONFIG_LED_BLINK=y ++CONFIG_LED_GPIO=y ++CONFIG_MTD=y ++CONFIG_DM_MTD=y ++CONFIG_MTD_SPI_NAND=y ++CONFIG_MTD_UBI_FASTMAP=y ++CONFIG_PHY_FIXED=y ++CONFIG_MEDIATEK_ETH=y ++CONFIG_PHY=y ++CONFIG_PINCTRL=y ++CONFIG_PINCONF=y ++CONFIG_PINCTRL_MT7986=y ++CONFIG_POWER_DOMAIN=y ++CONFIG_MTK_POWER_DOMAIN=y ++CONFIG_DM_REGULATOR=y ++CONFIG_DM_REGULATOR_FIXED=y ++CONFIG_DM_REGULATOR_GPIO=y ++CONFIG_RAM=y ++CONFIG_DM_SERIAL=y ++CONFIG_MTK_SERIAL=y ++CONFIG_SPI=y ++CONFIG_DM_SPI=y ++CONFIG_MTK_SPIM=y ++CONFIG_RANDOM_UUID=y ++CONFIG_ZSTD=y ++CONFIG_HEXDUMP=y ++CONFIG_LMB_MAX_REGIONS=64 +--- /dev/null ++++ b/arch/arm/dts/mt7986b-mercusys_mr90x-v1.dts +@@ -0,0 +1,174 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* ++ * Copyright (c) 2024 ++ * Author: Mikhail Zhilkin ++ */ ++ ++/dts-v1/; ++#include "mt7986.dtsi" ++#include ++#include ++ ++/ { ++ #address-cells = <1>; ++ #size-cells = <1>; ++ model = "MERCUSYS MR90X v1"; ++ compatible = "mediatek,mt7986", "mediatek,mt7986-rfb"; ++ ++ chosen { ++ stdout-path = &uart0; ++ tick-timer = &timer0; ++ }; ++ ++ memory@40000000 { ++ device_type = "memory"; ++ reg = <0x40000000 0x20000000>; ++ }; ++ ++ keys { ++ compatible = "gpio-keys"; ++ ++ reset { ++ label = "reset"; ++ linux,code = ; ++ gpios = <&gpio 10 GPIO_ACTIVE_LOW>; ++ }; ++ }; ++ ++ leds { ++ compatible = "gpio-leds"; ++ ++ led-0 { ++ label = "green:lan2"; ++ gpios = <&gpio 7 GPIO_ACTIVE_LOW>; ++ }; ++ ++ led-1 { ++ label = "green:lan1"; ++ gpios = <&gpio 9 GPIO_ACTIVE_LOW>; ++ }; ++ ++ led-2 { ++ label = "green:lan0"; ++ gpios = <&gpio 12 GPIO_ACTIVE_LOW>; ++ }; ++ ++ led-3 { ++ label = "green:wan"; ++ gpios = <&gpio 13 GPIO_ACTIVE_LOW>; ++ }; ++ ++ led-4 { ++ label = "amber:status"; ++ gpios = <&gpio 16 GPIO_ACTIVE_HIGH>; ++ }; ++ ++ led_status_green: led-5 { ++ label = "green:status"; ++ gpios = <&gpio 17 GPIO_ACTIVE_HIGH>; ++ }; ++ }; ++}; ++ ++&uart0 { ++ status = "okay"; ++}; ++ ++&uart1 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart1_pins>; ++ status = "disabled"; ++}; ++ ++ð { ++ status = "okay"; ++ mediatek,gmac-id = <0>; ++ phy-mode = "2500base-x"; ++ mediatek,switch = "mt7531"; ++ reset-gpios = <&gpio 5 GPIO_ACTIVE_HIGH>; ++ ++ fixed-link { ++ speed = <2500>; ++ full-duplex; ++ }; ++}; ++ ++&pinctrl { ++ spi_flash_pins: spi0-pins-func-1 { ++ mux { ++ function = "flash"; ++ groups = "spi0", "spi0_wp_hold"; ++ }; ++ ++ conf-pu { ++ pins = "SPI2_CS", "SPI2_HOLD", "SPI2_WP"; ++ drive-strength = ; ++ bias-pull-up = ; ++ }; ++ ++ conf-pd { ++ pins = "SPI2_CLK", "SPI2_MOSI", "SPI2_MISO"; ++ drive-strength = ; ++ bias-pull-down = ; ++ }; ++ }; ++ ++ spic_pins: spi1-pins-func-1 { ++ mux { ++ function = "spi"; ++ groups = "spi1_2"; ++ }; ++ }; ++ ++ uart1_pins: spi1-pins-func-3 { ++ mux { ++ function = "uart"; ++ groups = "uart1_2"; ++ }; ++ }; ++}; ++ ++&spi0 { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&spi_flash_pins>; ++ status = "okay"; ++ must_tx; ++ enhance_timing; ++ dma_ext; ++ ipm_design; ++ tick_dly = <2>; ++ sample_sel = <0>; ++ ++ spi_nand@1 { ++ compatible = "spi-nand"; ++ reg = <1>; ++ spi-max-frequency = <20000000>; ++ ++ partitions { ++ compatible = "fixed-partitions"; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ partition@0 { ++ reg = <0x0 0x100000>; ++ label = "bl2"; ++ }; ++ ++ partition@100000 { ++ reg = <0x100000 0x100000>; ++ label = "factory"; ++ }; ++ ++ partition@200000 { ++ reg = <0x200000 0x7e00000>; ++ label = "ubi"; ++ }; ++ }; ++ }; ++}; ++ ++&watchdog { ++ status = "disabled"; ++}; +--- /dev/null ++++ b/mercusys_mr90x-v1_env +@@ -0,0 +1,53 @@ ++ipaddr=192.168.1.1 ++serverip=192.168.1.254 ++loadaddr=0x46000000 ++console=earlycon=uart8250,mmio32,0x11002000 console=ttyS0 ++bootargs=console=ttyS0,115200n8 console_msg_format=syslog ++bootcmd=run check_buttons ; run boot_production ; run boot_recovery ++bootconf=config-1 ++bootdelay=0 ++bootfile=openwrt-mediatek-filogic-mercusys_mr90x-v1-ubi-initramfs-recovery.itb ++bootfile_bl2=openwrt-mediatek-filogic-mercusys_mr90x-v1-ubi-preloader.bin ++bootfile_fip=openwrt-mediatek-filogic-mercusys_mr90x-v1-ubi-bl31-uboot.fip ++bootfile_upg=openwrt-mediatek-filogic-mercusys_mr90x-v1-ubi-squashfs-sysupgrade.itb ++bootmenu_confirm_return=askenv - Press ENTER to return to menu ; bootmenu 60 ++bootmenu_default=0 ++bootmenu_delay=0 ++bootmenu_title= ( ( ( OpenWrt ) ) ) [SPI-NAND] ++bootmenu_0=Initialize environment.=run _firstboot ++bootmenu_0d=Run default boot command.=run boot_default ++bootmenu_1=Boot system via TFTP.=run boot_tftp ; run bootmenu_confirm_return ++bootmenu_2=Boot production system from NAND.=run boot_production ; run bootmenu_confirm_return ++bootmenu_3=Boot recovery system from NAND.=run boot_recovery ; run bootmenu_confirm_return ++bootmenu_4=Load production system via TFTP then write to NAND.=noboot=1 ; replacevol=1 ; run boot_tftp_production ; noboot= ; replacevol= ; run bootmenu_confirm_return ++bootmenu_5=Load recovery system via TFTP then write to NAND.=noboot=1 ; replacevol=1 ; run boot_tftp_recovery ; noboot= ; replacevol= ; run bootmenu_confirm_return ++bootmenu_6=Load BL31+U-Boot FIP via TFTP then write to NAND.=run boot_tftp_write_fip ; run bootmenu_confirm_return ++bootmenu_7=Load BL2 preloader via TFTP then write to NAND.=run boot_tftp_write_bl2 ; run bootmenu_confirm_return ++bootmenu_8=Reboot.=reset ++bootmenu_9=Reset all settings to factory defaults.=run reset_factory ; reset ++boot_default=run led_boot ; run bootcmd ; run boot_recovery ; replacevol=1 ; run boot_tftp_forever ++boot_production=run led_boot ; run ubi_read_production && bootm $loadaddr#$bootconf ++boot_recovery=run led_boot ; run ubi_read_recovery && bootm $loadaddr#$bootconf ++boot_tftp=run led_boot ; tftpboot $loadaddr $bootfile && bootm $loadaddr#$bootconf ++boot_tftp_forever=run led_boot ; while true ; do run boot_tftp ; sleep 1 ; done ++boot_tftp_production=run led_boot ; tftpboot $loadaddr $bootfile_upg && test $replacevol = 1 && iminfo $loadaddr && run ubi_write_production ; if test $noboot = 1 ; then else bootm $loadaddr#$bootconf ; fi ++boot_tftp_recovery=run led_boot ; tftpboot $loadaddr $bootfile && test $replacevol = 1 && iminfo $loadaddr && run ubi_write_recovery ; if test $noboot = 1 ; then else bootm $loadaddr#$bootconf ; fi ++boot_tftp_write_fip=run led_boot ; tftpboot $loadaddr $bootfile_fip && run ubi_write_fip && run reset_factory ++boot_tftp_write_bl2=run led_boot ; tftpboot $loadaddr $bootfile_bl2 && run snand_write_bl2 ++check_buttons=if button reset ; then run boot_tftp ; fi ++ethaddr_factory=mtd read factory 0x40080000 0x0 0x20000 && env readmem -b ethaddr 0x40088000 0x6 ; setenv ethaddr_factory ++led_boot=led green:status off ; led amber:status on ++reset_factory=mw $loadaddr 0xff 0x1f000 ; ubi write $loadaddr ubootenv 0x1f000 ; ubi write $loadaddr ubootenv2 0x1f000 ; ubi remove rootfs_data ++snand_write_bl2=mtd erase bl2 && mtd write bl2 $loadaddr 0x0 0x40000 ++ubi_create_env=ubi check ubootenv || ubi create ubootenv 0x1f000 dynamic ; ubi check ubootenv2 || ubi create ubootenv2 0x1f000 dynamic ++ubi_prepare_rootfs=if ubi check rootfs_data ; then else if env exists rootfs_data_max ; then ubi create rootfs_data $rootfs_data_max dynamic || ubi create rootfs_data - dynamic ; else ubi create rootfs_data - dynamic ; fi ; fi ++ubi_read_production=ubi read $loadaddr fit && iminfo $loadaddr && run ubi_prepare_rootfs ++ubi_read_recovery=ubi check recovery && ubi read $loadaddr recovery ++ubi_remove_rootfs=ubi check rootfs_data && ubi remove rootfs_data ++ubi_write_fip=run ubi_remove_rootfs ; ubi check fip && ubi remove fip ; ubi create fip $filesize static && ubi write $loadaddr fip $filesize ++ubi_write_production=ubi check fit && ubi remove fit ; run ubi_remove_rootfs ; ubi create fit $filesize dynamic && ubi write $loadaddr fit $filesize ++ubi_write_recovery=ubi check recovery && ubi remove recovery ; run ubi_remove_rootfs ; ubi create recovery $filesize dynamic && ubi write $loadaddr recovery $filesize ++_init_env=setenv _init_env ; run ubi_create_env ; saveenv ; saveenv ++_firstboot=setenv _firstboot ; run ethaddr_factory ; run _switch_to_menu ; run _init_env ; bootmenu ++_switch_to_menu=setenv _switch_to_menu ; setenv bootdelay 3 ; setenv bootmenu_delay 3 ; setenv bootmenu_0 $bootmenu_0d ; setenv bootmenu_0d ; run _bootmenu_update_title ++_bootmenu_update_title=setenv _bootmenu_update_title ; setenv bootmenu_title "$bootmenu_title $ver" diff --git a/package/boot/uboot-mediatek/patches/460-add-routerich-ax3000.patch b/package/boot/uboot-mediatek/patches/460-add-routerich-ax3000.patch new file mode 100644 index 00000000000000..f33ca076330d1c --- /dev/null +++ b/package/boot/uboot-mediatek/patches/460-add-routerich-ax3000.patch @@ -0,0 +1,362 @@ +--- /dev/null ++++ b/configs/mt7981_routerich_ax3000_defconfig +@@ -0,0 +1,108 @@ ++CONFIG_ARM=y ++CONFIG_SYS_HAS_NONCACHED_MEMORY=y ++CONFIG_POSITION_INDEPENDENT=y ++CONFIG_ARCH_MEDIATEK=y ++CONFIG_TEXT_BASE=0x41e00000 ++CONFIG_SYS_MALLOC_F_LEN=0x4000 ++CONFIG_NR_DRAM_BANKS=1 ++CONFIG_DEFAULT_DEVICE_TREE="mt7981-routerich_ax3000" ++CONFIG_OF_LIBFDT_OVERLAY=y ++CONFIG_TARGET_MT7981=y ++CONFIG_PRE_CON_BUF_ADDR=0x4007ef00 ++CONFIG_DEBUG_UART_BASE=0x11002000 ++CONFIG_DEBUG_UART_CLOCK=40000000 ++CONFIG_SYS_LOAD_ADDR=0x46000000 ++CONFIG_DEBUG_UART=y ++CONFIG_FIT=y ++CONFIG_BOOTDELAY=30 ++CONFIG_AUTOBOOT_KEYED=y ++CONFIG_AUTOBOOT_MENU_SHOW=y ++CONFIG_DEFAULT_FDT_FILE="mediatek/mt7981-routerich_ax3000.dtb" ++CONFIG_LOGLEVEL=7 ++CONFIG_PRE_CONSOLE_BUFFER=y ++CONFIG_LOG=y ++CONFIG_BOARD_LATE_INIT=y ++CONFIG_HUSH_PARSER=y ++CONFIG_SYS_PROMPT="MT7981> " ++CONFIG_CMD_CPU=y ++CONFIG_CMD_LICENSE=y ++CONFIG_CMD_BOOTMENU=y ++CONFIG_CMD_ASKENV=y ++CONFIG_CMD_ERASEENV=y ++CONFIG_CMD_ENV_FLAGS=y ++CONFIG_CMD_STRINGS=y ++CONFIG_CMD_DM=y ++CONFIG_CMD_GPIO=y ++CONFIG_CMD_GPT=y ++CONFIG_CMD_MTD=y ++CONFIG_CMD_PART=y ++CONFIG_CMD_DHCP=y ++CONFIG_CMD_TFTPSRV=y ++CONFIG_CMD_RARP=y ++CONFIG_CMD_PING=y ++CONFIG_CMD_CDP=y ++CONFIG_CMD_SNTP=y ++CONFIG_CMD_DNS=y ++CONFIG_CMD_LINK_LOCAL=y ++CONFIG_CMD_PXE=y ++CONFIG_CMD_CACHE=y ++CONFIG_CMD_PSTORE=y ++CONFIG_CMD_PSTORE_MEM_ADDR=0x42ff0000 ++CONFIG_CMD_UUID=y ++CONFIG_CMD_HASH=y ++CONFIG_CMD_SMC=y ++CONFIG_CMD_UBI=y ++CONFIG_CMD_UBI_RENAME=y ++CONFIG_OF_EMBED=y ++CONFIG_ENV_OVERWRITE=y ++CONFIG_ENV_IS_IN_UBI=y ++CONFIG_SYS_REDUNDAND_ENVIRONMENT=y ++CONFIG_ENV_UBI_PART="ubi" ++CONFIG_ENV_UBI_VOLUME="ubootenv" ++CONFIG_ENV_UBI_VOLUME_REDUND="ubootenv2" ++CONFIG_SYS_RELOC_GD_ENV_ADDR=y ++CONFIG_USE_DEFAULT_ENV_FILE=y ++CONFIG_DEFAULT_ENV_FILE="routerich_ax3000_env" ++CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y ++CONFIG_VERSION_VARIABLE=y ++CONFIG_NET_RANDOM_ETHADDR=y ++CONFIG_NETCONSOLE=y ++CONFIG_USE_IPADDR=y ++CONFIG_IPADDR="192.168.1.1" ++CONFIG_USE_SERVERIP=y ++CONFIG_SERVERIP="192.168.1.254" ++CONFIG_REGMAP=y ++CONFIG_SYSCON=y ++CONFIG_BUTTON=y ++CONFIG_BUTTON_GPIO=y ++CONFIG_CLK=y ++CONFIG_GPIO_HOG=y ++CONFIG_LED=y ++CONFIG_LED_BLINK=y ++CONFIG_LED_GPIO=y ++# CONFIG_MMC is not set ++CONFIG_MTD=y ++CONFIG_DM_MTD=y ++CONFIG_MTD_SPI_NAND=y ++CONFIG_MTD_UBI_FASTMAP=y ++CONFIG_PHY_FIXED=y ++CONFIG_MEDIATEK_ETH=y ++CONFIG_PHY=y ++CONFIG_PHY_MTK_TPHY=y ++CONFIG_PINCTRL=y ++CONFIG_PINCONF=y ++CONFIG_PINCTRL_MT7981=y ++CONFIG_POWER_DOMAIN=y ++CONFIG_MTK_POWER_DOMAIN=y ++CONFIG_DM_REGULATOR=y ++CONFIG_DM_REGULATOR_FIXED=y ++CONFIG_DM_REGULATOR_GPIO=y ++CONFIG_RAM=y ++CONFIG_DM_SERIAL=y ++CONFIG_MTK_SERIAL=y ++CONFIG_SPI=y ++CONFIG_DM_SPI=y ++CONFIG_MTK_SPIM=y ++CONFIG_ZSTD=y ++CONFIG_HEXDUMP=y ++CONFIG_LMB_MAX_REGIONS=64 +--- /dev/null ++++ b/arch/arm/dts/mt7981-routerich_ax3000.dts +@@ -0,0 +1,187 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* ++ * Copyright (c) 2022 MediaTek Inc. ++ * Author: Sam Shih ++ */ ++ ++/dts-v1/; ++#include "mt7981.dtsi" ++#include ++#include ++ ++/ { ++ #address-cells = <1>; ++ #size-cells = <1>; ++ model = "Routerich AX3000"; ++ compatible = "routerich,ax3000", "mediatek,mt7981"; ++ ++ chosen { ++ stdout-path = &uart0; ++ tick-timer = &timer0; ++ }; ++ ++ memory@40000000 { ++ device_type = "memory"; ++ reg = <0x40000000 0x10000000>; ++ }; ++ ++ keys { ++ compatible = "gpio-keys"; ++ ++ button-0 { ++ label = "mesh"; ++ linux,code = ; ++ gpios = <&gpio 1 GPIO_ACTIVE_LOW>; ++ }; ++ ++ button-1 { ++ label = "reset"; ++ linux,code = ; ++ gpios = <&gpio 1 GPIO_ACTIVE_LOW>; ++ }; ++ }; ++ ++ leds { ++ compatible = "gpio-leds"; ++ ++ led-0 { ++ label = "red:wlan5g"; ++ gpios = <&gpio 5 GPIO_ACTIVE_LOW>; ++ }; ++ ++ led-1 { ++ label = "red:wan"; ++ gpios = <&gpio 6 GPIO_ACTIVE_HIGH>; ++ }; ++ ++ led-2 { ++ label = "blue:power"; ++ gpios = <&gpio 7 GPIO_ACTIVE_LOW>; ++ }; ++ ++ led-3 { ++ label = "blue:lan1"; ++ gpios = <&gpio 9 GPIO_ACTIVE_LOW>; ++ }; ++ ++ led-4 { ++ label = "blue:lan2"; ++ gpios = <&gpio 10 GPIO_ACTIVE_LOW>; ++ }; ++ ++ led-5 { ++ label = "blue:lan3"; ++ gpios = <&gpio 11 GPIO_ACTIVE_LOW>; ++ }; ++ ++ led-6 { ++ label = "blue:wan"; ++ gpios = <&gpio 12 GPIO_ACTIVE_LOW>; ++ }; ++ ++ led-7 { ++ label = "blue:wlan2g"; ++ gpios = <&gpio 34 GPIO_ACTIVE_LOW>; ++ }; ++ ++ led-8 { ++ label = "blue:mesh"; ++ gpios = <&gpio 35 GPIO_ACTIVE_LOW>; ++ }; ++ }; ++}; ++ ++&uart0 { ++ mediatek,force-highspeed; ++ status = "okay"; ++}; ++ ++ð { ++ status = "okay"; ++ mediatek,gmac-id = <0>; ++ phy-mode = "2500base-x"; ++ mediatek,switch = "mt7531"; ++ reset-gpios = <&gpio 39 GPIO_ACTIVE_HIGH>; ++ ++ fixed-link { ++ speed = <2500>; ++ full-duplex; ++ }; ++}; ++ ++&pinctrl { ++ spi_flash_pins: spi0-pins-func-1 { ++ mux { ++ function = "flash"; ++ groups = "spi0", "spi0_wp_hold"; ++ }; ++ ++ conf-pu { ++ pins = "SPI0_CS", "SPI0_HOLD", "SPI0_WP"; ++ drive-strength = ; ++ bias-pull-up = ; ++ }; ++ ++ conf-pd { ++ pins = "SPI0_CLK", "SPI0_MOSI", "SPI0_MISO"; ++ drive-strength = ; ++ bias-pull-down = ; ++ }; ++ }; ++}; ++ ++&spi0 { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&spi_flash_pins>; ++ status = "okay"; ++ must_tx; ++ enhance_timing; ++ dma_ext; ++ ipm_design; ++ support_quad; ++ tick_dly = <2>; ++ sample_sel = <0>; ++ ++ spi_nand@0 { ++ compatible = "spi-nand"; ++ reg = <0>; ++ spi-max-frequency = <52000000>; ++ ++ partitions { ++ compatible = "fixed-partitions"; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ partition@0 { ++ label = "bl2"; ++ reg = <0x0 0x100000>; ++ }; ++ ++ partition@100000 { ++ label = "uboot-env-orig"; ++ reg = <0x100000 0x80000>; ++ }; ++ ++ partition@160000 { ++ label = "Factory"; ++ reg = <0x180000 0x200000>; ++ }; ++ ++ partition@380000 { ++ label = "fip"; ++ reg = <0x380000 0x200000>; ++ }; ++ ++ partition@580000 { ++ label = "ubi"; ++ reg = <0x580000 0x7a80000>; ++ }; ++ }; ++ }; ++}; ++ ++&watchdog { ++ status = "disabled"; ++}; +--- /dev/null ++++ b/routerich_ax3000_env +@@ -0,0 +1,58 @@ ++ipaddr=192.168.1.1 ++serverip=192.168.1.254 ++loadaddr=0x46000000 ++console=earlycon=uart8250,mmio32,0x11002000 console=ttyS0 ++bootcmd=run check_buttons ; if pstore check ; then run boot_recovery ; else run boot_ubi ; fi ++bootconf=config-1 ++bootdelay=0 ++bootfile=openwrt-mediatek-filogic-routerich_ax3000-ubootmod-initramfs-recovery.itb ++bootfile_bl2=openwrt-mediatek-filogic-routerich_ax3000-ubootmod-preloader.bin ++bootfile_fip=openwrt-mediatek-filogic-routerich_ax3000-ubootmod-bl31-uboot.fip ++bootfile_upg=openwrt-mediatek-filogic-routerich_ax3000-ubootmod-squashfs-sysupgrade.itb ++bootled_pwr=blue:power ++bootled_rec=blue:power ++bootmenu_confirm_return=askenv - Press ENTER to return to menu ; bootmenu 60 ++bootmenu_default=0 ++bootmenu_delay=0 ++bootmenu_title= ( ( ( OpenWrt ) ) ) ++bootmenu_0=Initialize environment.=run _firstboot ++bootmenu_0d=Run default boot command.=run boot_default ++bootmenu_1=Boot system via TFTP.=run boot_tftp ; run bootmenu_confirm_return ++bootmenu_2=Boot production system from NAND.=run boot_production ; run bootmenu_confirm_return ++bootmenu_3=Boot recovery system from NAND.=run boot_recovery ; run bootmenu_confirm_return ++bootmenu_4=Load production system via TFTP then write to NAND.=setenv noboot 1 ; setenv replacevol 1 ; run boot_tftp_production ; setenv noboot ; setenv replacevol ; run bootmenu_confirm_return ++bootmenu_5=Load recovery system via TFTP then write to NAND.=setenv noboot 1 ; setenv replacevol 1 ; run boot_tftp_recovery ; setenv noboot ; setenv replacevol ; run bootmenu_confirm_return ++bootmenu_6=Load BL31+U-Boot FIP via TFTP then write to NAND.=run boot_tftp_write_fip ; run bootmenu_confirm_return ++bootmenu_7=Load BL2 preloader via TFTP then write to NAND.=run boot_tftp_write_bl2 ; run bootmenu_confirm_return ++bootmenu_8=Reboot.=reset ++bootmenu_9=Reset all settings to factory defaults.=run reset_factory ; reset ++boot_first=if button reset ; then led $bootled_rec on ; run boot_default ; fi ; bootmenu ++boot_default=if env exists flag_recover ; then else run bootcmd ; fi ; run boot_recovery ; setenv replacevol 1 ; run boot_tftp_forever ++boot_production=led $bootled_pwr on ; run ubi_read_production && bootm $loadaddr#$bootconf ; led $bootled_pwr off ++boot_recovery=led $bootled_rec on ; run ubi_read_recovery && bootm $loadaddr#$bootconf ; led $bootled_rec off ++boot_ubi=run boot_production ; run boot_recovery ; run boot_tftp_forever ++boot_tftp_forever=led $bootled_rec on ; while true ; do run boot_tftp ; sleep 1 ; done ++boot_tftp_production=tftpboot $loadaddr $bootfile_upg && env exists replacevol && iminfo $loadaddr && run ubi_write_production ; if env exists noboot ; then else bootm $loadaddr#$bootconf ; fi ++boot_tftp_recovery=tftpboot $loadaddr $bootfile && env exists replacevol && iminfo $loadaddr && run ubi_write_recovery ; if env exists noboot ; then else bootm $loadaddr#$bootconf ; fi ++boot_tftp=tftpboot $loadaddr $bootfile && bootm $loadaddr#$bootconf ++boot_tftp_write_fip=tftpboot $loadaddr $bootfile_fip && run mtd_write_fip && run reset_factory ++boot_tftp_write_bl2=tftpboot $loadaddr $bootfile_bl2 && run mtd_write_bl2 ++check_buttons=if button reset ; then run boot_tftp ; fi ++ethaddr_factory=mtd read Factory 0x40080000 0x0 0x20000 && env readmem -b ethaddr 0x40080004 0x6 ; setenv ethaddr_factory ++part_default=production ++part_recovery=recovery ++reset_factory=ubi part ubi ; mw $loadaddr 0x0 0x800 ; ubi write $loadaddr ubootenv 0x800 ; ubi write $loadaddr ubootenv2 0x800 ++mtd_write_fip=mtd erase fip && mtd write fip $loadaddr ++mtd_write_bl2=mtd erase bl2 && mtd write bl2 $loadaddr ++ubi_create_env=ubi check ubootenv || ubi create ubootenv 0x100000 dynamic || run ubi_format ; ubi check ubootenv2 || ubi create ubootenv2 0x100000 dynamic || run ubi_format ++ubi_format=ubi detach ; mtd erase ubi && ubi part ubi ; reset ++ubi_prepare_rootfs=if ubi check rootfs_data ; then else if env exists rootfs_data_max ; then ubi create rootfs_data $rootfs_data_max dynamic || ubi create rootfs_data - dynamic ; else ubi create rootfs_data - dynamic ; fi ; fi ++ubi_read_production=ubi read $loadaddr fit && iminfo $loadaddr && run ubi_prepare_rootfs ++ubi_read_recovery=ubi check recovery && ubi read $loadaddr recovery ++ubi_remove_rootfs=ubi check rootfs_data && ubi remove rootfs_data ++ubi_write_production=ubi check fit && ubi remove fit ; run ubi_remove_rootfs ; ubi create fit $filesize dynamic && ubi write $loadaddr fit $filesize ++ubi_write_recovery=ubi check recovery && ubi remove recovery ; run ubi_remove_rootfs ; ubi create recovery $filesize dynamic && ubi write $loadaddr recovery $filesize ++_init_env=setenv _init_env ; run ubi_create_env ; saveenv ; saveenv ++_firstboot=setenv _firstboot ; run ethaddr_factory ; run _switch_to_menu ; run _init_env ; run boot_first ++_switch_to_menu=setenv _switch_to_menu ; setenv bootdelay 3 ; setenv bootmenu_delay 3 ; setenv bootmenu_0 $bootmenu_0d ; setenv bootmenu_0d ; run _bootmenu_update_title ++_bootmenu_update_title=setenv _bootmenu_update_title ; setenv bootmenu_title "$bootmenu_title $ver" diff --git a/package/boot/uboot-rockchip/Makefile b/package/boot/uboot-rockchip/Makefile index 7070ca973d3200..7bb95d3b612b0c 100644 --- a/package/boot/uboot-rockchip/Makefile +++ b/package/boot/uboot-rockchip/Makefile @@ -136,6 +136,20 @@ define U-Boot/nanopi-r4s-rk3399 friendlyarm_nanopi-r4s-enterprise endef +define U-Boot/rock-4c-plus-rk3399 + $(U-Boot/rk3399/Default) + NAME:=ROCK 4C+ + BUILD_DEVICES:= \ + radxa_rock-4c-plus +endef + +define U-Boot/rock-4se-rk3399 + $(U-Boot/rk3399/Default) + NAME:=ROCK 4SE + BUILD_DEVICES:= \ + radxa_rock-4se +endef + define U-Boot/rock-pi-4-rk3399 $(U-Boot/rk3399/Default) NAME:=Rock Pi 4 @@ -300,6 +314,8 @@ endef UBOOT_TARGETS := \ nanopc-t4-rk3399 \ nanopi-r4s-rk3399 \ + rock-4c-plus-rk3399 \ + rock-4se-rk3399 \ rock-pi-4-rk3399 \ rockpro64-rk3399 \ rock-pi-s-rk3308 \ diff --git a/package/boot/uboot-rockchip/patches/002-scripts-dtc-pylibfdt-libfdt-i_shipped-Use-SWIG_AppendOutp.patch b/package/boot/uboot-rockchip/patches/002-scripts-dtc-pylibfdt-libfdt-i_shipped-Use-SWIG_AppendOutp.patch new file mode 100644 index 00000000000000..f5beca8d77a1ae --- /dev/null +++ b/package/boot/uboot-rockchip/patches/002-scripts-dtc-pylibfdt-libfdt-i_shipped-Use-SWIG_AppendOutp.patch @@ -0,0 +1,55 @@ +From a63456b9191fae2fe49f4b121e025792022e3950 Mon Sep 17 00:00:00 2001 +From: Markus Volk +Date: Wed, 30 Oct 2024 06:07:16 +0100 +Subject: [PATCH] scripts/dtc/pylibfdt/libfdt.i_shipped: Use SWIG_AppendOutput +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Swig has changed language specific AppendOutput functions. The helper +macro SWIG_AppendOutput remains unchanged. Use that instead +of SWIG_Python_AppendOutput, which would require an extra parameter +since swig 4.3.0. + +/home/flk/poky/build-test/tmp/work/qemux86_64-poky-linux/u-boot/2024.10/git/arch/x86/cpu/u-boot-64.lds +| scripts/dtc/pylibfdt/libfdt_wrap.c: In function ‘_wrap_fdt_next_node’: +| scripts/dtc/pylibfdt/libfdt_wrap.c:5581:17: error: too few arguments to function ‘SWIG_Python_AppendOutput’ +| 5581 | resultobj = SWIG_Python_AppendOutput(resultobj, val); +| | ^~~~~~~~~~~~~~~~~~~~~~~~ + +Signed-off-by: Markus Volk +Reported-by: Rudi Heitbaum +Link: https://github.com/dgibson/dtc/pull/154 +--- + scripts/dtc/pylibfdt/libfdt.i_shipped | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +--- a/scripts/dtc/pylibfdt/libfdt.i_shipped ++++ b/scripts/dtc/pylibfdt/libfdt.i_shipped +@@ -1037,7 +1037,7 @@ typedef uint32_t fdt32_t; + fdt_string(fdt1, fdt32_to_cpu($1->nameoff))); + buff = PyByteArray_FromStringAndSize( + (const char *)($1 + 1), fdt32_to_cpu($1->len)); +- resultobj = SWIG_Python_AppendOutput(resultobj, buff); ++ resultobj = SWIG_AppendOutput(resultobj, buff); + } + } + +@@ -1076,7 +1076,7 @@ typedef uint32_t fdt32_t; + + %typemap(argout) int *depth { + PyObject *val = Py_BuildValue("i", *arg$argnum); +- resultobj = SWIG_Python_AppendOutput(resultobj, val); ++ resultobj = SWIG_AppendOutput(resultobj, val); + } + + %apply int *depth { int *depth }; +@@ -1092,7 +1092,7 @@ typedef uint32_t fdt32_t; + if (PyTuple_GET_SIZE(resultobj) == 0) + resultobj = val; + else +- resultobj = SWIG_Python_AppendOutput(resultobj, val); ++ resultobj = SWIG_AppendOutput(resultobj, val); + } + } + diff --git a/package/boot/uboot-stm32/Makefile b/package/boot/uboot-stm32/Makefile new file mode 100644 index 00000000000000..58754aedd5a7c5 --- /dev/null +++ b/package/boot/uboot-stm32/Makefile @@ -0,0 +1,51 @@ +# +# Copyright (C) 2024 Bootlin +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +PKG_VERSION:=2024.07 +PKG_RELEASE:=1 + +PKG_HASH:=f591da9ab90ef3d6b3d173766d0ddff90c4ed7330680897486117df390d83c8f +PKG_MAINTAINER:=Thomas Richard + +UBOOT_USE_INTREE_DTC:=1 + +include $(INCLUDE_DIR)/u-boot.mk +include $(INCLUDE_DIR)/package.mk + +define U-Boot/Default + BUILD_TARGET:=stm32 + UBOOT_IMAGE:=u-boot.bin u-boot.dtb +endef + +define U-Boot/stm32mp13 + BUILD_SUBTARGET:=stm32mp1 + UBOOT_CONFIG:=stm32mp13 +endef + +define U-Boot/stm32mp135f-dk + $(call U-Boot/stm32mp13) + NAME:=STM32MP135F-DK + DEVICE_TREE:=stm32mp135f-dk +endef + +UBOOT_TARGETS := stm32mp135f-dk + +UBOOT_MAKE_FLAGS += DEVICE_TREE=$(DEVICE_TREE) + +define Build/InstallDev + $(INSTALL_DIR) $(STAGING_DIR_IMAGE) + $(foreach img,$(UBOOT_IMAGE), \ + $(CP) $(PKG_BUILD_DIR)/$(img) $(STAGING_DIR_IMAGE)/$(BUILD_VARIANT)-$(img); \ + ) +endef + +define Package/u-boot/install/default +endef + +$(eval $(call BuildPackage/U-Boot)) diff --git a/package/devel/gdb/Makefile b/package/devel/gdb/Makefile index 366746be87fbaf..7bdc6c83cbe899 100644 --- a/package/devel/gdb/Makefile +++ b/package/devel/gdb/Makefile @@ -9,7 +9,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=gdb PKG_VERSION:=15.2 -PKG_RELEASE:=1 +PKG_RELEASE:=2 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz PKG_SOURCE_URL:=@GNU/gdb @@ -37,7 +37,7 @@ $(call Package/gdb/Default) endef define Package/gdb/description -GDB, the GNU Project debugger, allows you to see what is going on `inside' +GDB, the GNU Project debugger, allows you to see what is going on 'inside' another program while it executes -- or what another program was doing at the moment it crashed. endef diff --git a/package/devel/perf/Makefile b/package/devel/perf/Makefile index 20be59516dad12..0129dc61186da0 100644 --- a/package/devel/perf/Makefile +++ b/package/devel/perf/Makefile @@ -10,7 +10,7 @@ include $(INCLUDE_DIR)/kernel.mk PKG_NAME:=perf PKG_VERSION:=$(LINUX_VERSION) -PKG_RELEASE:=5 +PKG_RELEASE:=6 PKG_BUILD_FLAGS:=no-mips16 no-lto PKG_BUILD_PARALLEL:=1 @@ -50,6 +50,7 @@ MAKE_FLAGS = \ NO_LZMA=1 \ NO_BACKTRACE=1 \ NO_LIBNUMA=1 \ + NO_SLANG=1 \ NO_GTK2=1 \ NO_LIBAUDIT=1 \ NO_LIBCRYPTO=1 \ diff --git a/package/devel/strace/Makefile b/package/devel/strace/Makefile index f418bea5a724c7..892c05467e4ebf 100644 --- a/package/devel/strace/Makefile +++ b/package/devel/strace/Makefile @@ -9,12 +9,12 @@ include $(TOPDIR)/rules.mk include $(INCLUDE_DIR)/kernel.mk PKG_NAME:=strace -PKG_VERSION:=6.11 +PKG_VERSION:=6.12 PKG_RELEASE:=1 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz PKG_SOURCE_URL:=https://strace.io/files/$(PKG_VERSION) -PKG_HASH:=83262583a3529f02c3501aa8b8ac772b4cbc03dc934e98bab6e4883626e283a5 +PKG_HASH:=c47da93be45b6055f4dc741d7f20efaf50ca10160a5b100c109b294fd9c0bdfe PKG_MAINTAINER:=Felix Fietkau PKG_LICENSE:=LGPL-2.1-or-later diff --git a/package/firmware/intel-microcode/Makefile b/package/firmware/intel-microcode/Makefile index bdd8ae73d88f3c..2ec1f22c35d872 100644 --- a/package/firmware/intel-microcode/Makefile +++ b/package/firmware/intel-microcode/Makefile @@ -8,12 +8,12 @@ include $(TOPDIR)/rules.mk PKG_NAME:=intel-microcode -PKG_VERSION:=20240531 +PKG_VERSION:=20250211 PKG_RELEASE:=1 PKG_SOURCE:=intel-microcode_3.$(PKG_VERSION).1.tar.xz PKG_SOURCE_URL:=@DEBIAN/pool/non-free-firmware/i/intel-microcode/ -PKG_HASH:=808cbb57a790dab7060b59b31e70e54ac47d3798d75e9784ed57a65b9f951fc4 +PKG_HASH:=06b7aca49790d673623cb42f7a62a517d82555ce96371d2967b568d6e30fd787 PKG_BUILD_DIR:=$(BUILD_DIR)/intel-microcode-3.$(PKG_VERSION).1 PKG_CPE_ID:=cpe:/a:intel:microcode diff --git a/package/firmware/ipq-wifi/Makefile b/package/firmware/ipq-wifi/Makefile index 4732a14b1b4e1b..41a2a009cb3ce9 100644 --- a/package/firmware/ipq-wifi/Makefile +++ b/package/firmware/ipq-wifi/Makefile @@ -6,9 +6,9 @@ PKG_RELEASE:=1 PKG_SOURCE_PROTO:=git PKG_SOURCE_URL=$(PROJECT_GIT)/project/firmware/qca-wireless.git -PKG_SOURCE_DATE:=2024-10-08 -PKG_SOURCE_VERSION:=dcbab62272bf5cab2ed857bc655d240970e14f2a -PKG_MIRROR_HASH:=e53a3872abf5e35db6baaceb56e6ffa289f8dd9b6226cf8a4d5b87b541179175 +PKG_SOURCE_DATE:=2025-08-25 +PKG_SOURCE_VERSION:=a510502e7922b0a61e455e43479a62e7d27cf3ba +PKG_MIRROR_HASH:=0b8120ce09fdd9176e77b65f2c0866e14aa580ba7e6dd9440f37011418346be7 PKG_FLAGS:=nonshared include $(INCLUDE_DIR)/package.mk @@ -54,7 +54,9 @@ ALLWIFIBOARDS:= \ skspruce_wia3300-20 \ spectrum_sax1v1k \ tplink_eap660hd-v1 \ + tplink_archer-c6-v2 \ wallys_dr40x9 \ + xiaomi_aiot-ac2350 \ xiaomi_ax3600 \ xiaomi_ax9000 \ yyets_le1 \ @@ -72,7 +74,7 @@ define Package/ipq-wifi-default SUBMENU:=ath10k Board-Specific Overrides SECTION:=firmware CATEGORY:=Firmware - DEPENDS:=@(TARGET_ipq40xx||TARGET_ipq806x||TARGET_qualcommax) + DEPENDS:=@(TARGET_ath79||TARGET_ipq40xx||TARGET_ipq806x||TARGET_qualcommax) TITLE:=Custom Board endef @@ -95,6 +97,8 @@ define ipq-wifi-install-one $(call ipq-wifi-install-one-to,$(1),$(2),QCA9887/hw1.0),\ $(if $(filter $(suffix $(1)),.QCA9984 .qca9984),\ $(call ipq-wifi-install-one-to,$(1),$(2),QCA9984/hw1.0),\ + $(if $(filter $(suffix $(1)),.QCA9988 .qca9988),\ + $(call ipq-wifi-install-one-to,$(1),$(2),QCA9984/hw1.0),\ $(if $(filter $(suffix $(1)),.QCA99X0 .qca99x0),\ $(call ipq-wifi-install-one-to,$(1),$(2),QCA99X0/hw2.0),\ $(if $(filter $(suffix $(1)),.IPQ6018 .ipq6018),\ @@ -104,7 +108,7 @@ define ipq-wifi-install-one $(if $(filter $(suffix $(1)),.QCN9074 .qcn9074),\ $(call ipq-wifi-install-ath11-one-to,$(1),$(2),QCN9074/hw1.0),\ $(error Unrecognized board-file suffix '$(suffix $(1))' for '$(1)')\ - )))))))) + ))))))))) endef # Blank line required at end of above define due to foreach context @@ -181,7 +185,9 @@ $(eval $(call generate-ipq-wifi-package,redmi_ax6,Redmi AX6)) $(eval $(call generate-ipq-wifi-package,skspruce_wia3300-20,SKSpruce WIA3300-20)) $(eval $(call generate-ipq-wifi-package,spectrum_sax1v1k,Spectrum SAX1V1K)) $(eval $(call generate-ipq-wifi-package,tplink_eap660hd-v1,TP-Link EAP660 HD v1)) +$(eval $(call generate-ipq-wifi-package,tplink_archer-c6-v2,TP-Link Archer C6 V2)) $(eval $(call generate-ipq-wifi-package,wallys_dr40x9,Wallys DR40X9)) +$(eval $(call generate-ipq-wifi-package,xiaomi_aiot-ac2350,Xiaomi AIoT AC2350)) $(eval $(call generate-ipq-wifi-package,xiaomi_ax3600,Xiaomi AX3600)) $(eval $(call generate-ipq-wifi-package,xiaomi_ax9000,Xiaomi AX9000)) $(eval $(call generate-ipq-wifi-package,yyets_le1,YYeTs LE1)) diff --git a/package/firmware/lantiq/dsl-vrx200-firmware-xdsl/Makefile b/package/firmware/lantiq/dsl-vrx200-firmware-xdsl/Makefile index 37db950beae54f..b6e1d11efc60a6 100644 --- a/package/firmware/lantiq/dsl-vrx200-firmware-xdsl/Makefile +++ b/package/firmware/lantiq/dsl-vrx200-firmware-xdsl/Makefile @@ -40,7 +40,7 @@ define Package/dsl-vrx200-firmware-xdsl-a CATEGORY:=Firmware TITLE:=VRX200 / VR9 CPE xDSL Annex A firmware URL:=http://www.lantiq.com/ - DEPENDS:=@TARGET_lantiq_xrx200 + DEPENDS:=@(TARGET_lantiq_xrx200||TARGET_lantiq_xrx200_legacy) endef define Package/dsl-vrx200-firmware-xdsl-a/description @@ -52,7 +52,7 @@ define Package/dsl-vrx200-firmware-xdsl-b CATEGORY:=Firmware TITLE:=VRX200 / VR9 CPE xDSL Annex B firmware URL:=http://www.lantiq.com/ - DEPENDS:=@TARGET_lantiq_xrx200 + DEPENDS:=@(TARGET_lantiq_xrx200||TARGET_lantiq_xrx200_legacy) endef define Package/dsl-vrx200-firmware-xdsl-b/description @@ -64,7 +64,7 @@ define Package/dsl-vrx200-firmware-xdsl-a-patch CATEGORY:=Firmware TITLE:=VRX200 / VR9 CPE xDSL Annex B to Annex A firmware patch URL:=http://www.lantiq.com/ - DEPENDS:=@TARGET_lantiq_xrx200 +dsl-vrx200-firmware-xdsl-b +bspatch + DEPENDS:=@(TARGET_lantiq_xrx200||TARGET_lantiq_xrx200_legacy) +dsl-vrx200-firmware-xdsl-b +bspatch endef define Package/dsl-vrx200-firmware-xdsl-a-patch/description @@ -76,7 +76,7 @@ define Package/dsl-vrx200-firmware-xdsl-b-patch CATEGORY:=Firmware TITLE:=VRX200 / VR9 CPE xDSL Annex A to Annex B firmware patch URL:=http://www.lantiq.com/ - DEPENDS:=@TARGET_lantiq_xrx200 +dsl-vrx200-firmware-xdsl-a +bspatch + DEPENDS:=@(TARGET_lantiq_xrx200||TARGET_lantiq_xrx200_legacy) +dsl-vrx200-firmware-xdsl-a +bspatch endef define Package/dsl-vrx200-firmware-xdsl-b-patch/description diff --git a/package/firmware/linux-firmware/Makefile b/package/firmware/linux-firmware/Makefile index de69360aff5232..a2b78967f7a676 100644 --- a/package/firmware/linux-firmware/Makefile +++ b/package/firmware/linux-firmware/Makefile @@ -8,12 +8,12 @@ include $(TOPDIR)/rules.mk PKG_NAME:=linux-firmware -PKG_VERSION:=20241017 -PKG_RELEASE:=1 +PKG_VERSION:=20241110 +PKG_RELEASE:=2 PKG_SOURCE_URL:=@KERNEL/linux/kernel/firmware PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz -PKG_HASH:=a26c38ef5a83272f2b98ce8bf8ca1865a852a3deea49ce5a8dd804b914351273 +PKG_HASH:=32e6d3eb5c7fcb69fe5d58976c6deafa0d6552719c6e74835064aff049d25bd7 PKG_MAINTAINER:=Felix Fietkau diff --git a/package/firmware/linux-firmware/broadcom.mk b/package/firmware/linux-firmware/broadcom.mk index c4e5885f77c232..c37edf211c0b7a 100644 --- a/package/firmware/linux-firmware/broadcom.mk +++ b/package/firmware/linux-firmware/broadcom.mk @@ -128,12 +128,18 @@ define Package/brcmfmac-nvram-43455-sdio/install $(LN) \ brcmfmac43455-sdio.raspberrypi,4-model-b.txt \ $(1)/lib/firmware/brcm/brcmfmac43455-sdio.raspberrypi,5-model-b.txt + $(LN) \ + brcmfmac43455-sdio.raspberrypi,4-model-b.txt \ + $(1)/lib/firmware/brcm/brcmfmac43455-sdio.raspberrypi,5-compute-module.txt $(LN) \ brcmfmac43455-sdio.raspberrypi,4-model-b.txt \ $(1)/lib/firmware/brcm/brcmfmac43455-sdio.Raspberry\ Pi\ Foundation-Raspberry\ Pi\ Compute\ Module\ 4.txt $(LN) \ brcmfmac43455-sdio.raspberrypi,4-model-b.txt \ $(1)/lib/firmware/brcm/brcmfmac43455-sdio.Raspberry\ Pi\ Foundation-Raspberry\ Pi\ 5\ Model\ B.txt + $(LN) \ + brcmfmac43455-sdio.raspberrypi,4-model-b.txt \ + $(1)/lib/firmware/brcm/brcmfmac43455-sdio.Raspberry\ Pi\ Foundation-Raspberry\ Pi\ Compute\ Module\ 5.txt $(INSTALL_DATA) \ $(PKG_BUILD_DIR)/brcm/brcmfmac43455-sdio.MINIX-NEO\ Z83-4.txt \ $(1)/lib/firmware/brcm/ diff --git a/package/firmware/linux-firmware/intel.mk b/package/firmware/linux-firmware/intel.mk index 225b2aa86295e3..eb5ac29159aecf 100644 --- a/package/firmware/linux-firmware/intel.mk +++ b/package/firmware/linux-firmware/intel.mk @@ -199,6 +199,14 @@ define Package/iwlwifi-firmware-ax210/install endef $(eval $(call BuildPackage,iwlwifi-firmware-ax210)) +Package/iwlwifi-firmware-ax411 = $(call Package/firmware-default,Intel AX411 firmware) +define Package/iwlwifi-firmware-ax411/install + $(INSTALL_DIR) $(1)/lib/firmware + $(INSTALL_DATA) $(PKG_BUILD_DIR)/iwlwifi-so-a0-gf4-a0-89.ucode $(1)/lib/firmware + $(INSTALL_DATA) $(PKG_BUILD_DIR)/iwlwifi-so-a0-gf4-a0.pnvm $(1)/lib/firmware +endef +$(eval $(call BuildPackage,iwlwifi-firmware-ax411)) + Package/iwlwifi-firmware-be200 = $(call Package/firmware-default,Intel BE200 firmware) define Package/iwlwifi-firmware-be200/install $(INSTALL_DIR) $(1)/lib/firmware @@ -216,29 +224,49 @@ define Package/e100-firmware/install endef $(eval $(call BuildPackage,e100-firmware)) -Package/intel-igpu-firmware-dmc = $(call Package/firmware-default,Intel iGPU DMC Display MC firmware) -define Package/intel-igpu-firmware-dmc/install +i915_deps:=+i915-firmware-dmc +i915-firmware-guc +i915-firmware-huc +i915-firmware-gsc +Package/i915-firmware = $(call Package/firmware-default,Intel I915 firmware \(meta package\),$(i915_deps),LICENSE.i915) +define Package/i915-firmware/install + true +endef +$(eval $(call BuildPackage,i915-firmware)) + +Package/i915-firmware-dmc = $(call Package/firmware-default,Intel I915 DMC firmware,,LICENSE.i915) +define Package/i915-firmware-dmc/install $(INSTALL_DIR) $(1)/lib/firmware/i915 - $(CP) \ - $(PKG_BUILD_DIR)/i915/*_dmc_*.bin* \ - $(1)/lib/firmware/i915/ + for f in $(PKG_BUILD_DIR)/i915/*_dmc*.bin; do \ + t=`echo $$$${f##*/} | cut -d_ -f2 | cut -d. -f1`; \ + if [ "$$$$t" = dmc ]; then $(CP) $$$$f $(1)/lib/firmware/i915/; fi \ + done endef -$(eval $(call BuildPackage,intel-igpu-firmware-dmc)) +$(eval $(call BuildPackage,i915-firmware-dmc)) -Package/intel-igpu-firmware-guc = $(call Package/firmware-default,Intel iGPU GUC Graphics MC firmware) -define Package/intel-igpu-firmware-guc/install +Package/i915-firmware-guc = $(call Package/firmware-default,Intel I915 GUC firmware,,LICENSE.i915) +define Package/i915-firmware-guc/install $(INSTALL_DIR) $(1)/lib/firmware/i915 - $(CP) \ - $(PKG_BUILD_DIR)/i915/*_guc_*.bin* \ - $(1)/lib/firmware/i915/ + for f in $(PKG_BUILD_DIR)/i915/*_guc*.bin; do \ + t=`echo $$$${f##*/} | cut -d_ -f2 | cut -d. -f1`; \ + if [ "$$$$t" = guc ]; then $(CP) $$$$f $(1)/lib/firmware/i915/; fi \ + done endef -$(eval $(call BuildPackage,intel-igpu-firmware-guc)) +$(eval $(call BuildPackage,i915-firmware-guc)) -Package/intel-igpu-firmware-huc = $(call Package/firmware-default,Intel iGPU HUC H.265 MC firmware) -define Package/intel-igpu-firmware-huc/install +Package/i915-firmware-huc = $(call Package/firmware-default,Intel I915 HUC firmware,,LICENSE.i915) +define Package/i915-firmware-huc/install $(INSTALL_DIR) $(1)/lib/firmware/i915 - $(CP) \ - $(PKG_BUILD_DIR)/i915/*_huc_*.bin* \ - $(1)/lib/firmware/i915/ + for f in $(PKG_BUILD_DIR)/i915/*_huc*.bin; do \ + t=`echo $$$${f##*/} | cut -d_ -f2 | cut -d. -f1`; \ + if [ "$$$$t" = huc ]; then $(CP) $$$$f $(1)/lib/firmware/i915/; fi \ + done +endef +$(eval $(call BuildPackage,i915-firmware-huc)) + +Package/i915-firmware-gsc = $(call Package/firmware-default,Intel I915 GSC firmware,,LICENSE.i915) +define Package/i915-firmware-gsc/install + $(INSTALL_DIR) $(1)/lib/firmware/i915 + for f in $(PKG_BUILD_DIR)/i915/*_gsc*.bin; do \ + t=`echo $$$${f##*/} | cut -d_ -f2 | cut -d. -f1`; \ + if [ "$$$$t" = gsc ]; then $(CP) $$$$f $(1)/lib/firmware/i915/; fi \ + done endef -$(eval $(call BuildPackage,intel-igpu-firmware-huc)) +$(eval $(call BuildPackage,i915-firmware-gsc)) diff --git a/package/firmware/linux-firmware/qca_ath11k.mk b/package/firmware/linux-firmware/qca_ath11k.mk index 3571198d1b666b..9fdd6119488dd9 100644 --- a/package/firmware/linux-firmware/qca_ath11k.mk +++ b/package/firmware/linux-firmware/qca_ath11k.mk @@ -10,7 +10,11 @@ Package/ath11k-firmware-wcn6750 = $(call Package/firmware-default,WCN6750 ath11k define Package/ath11k-firmware-wcn6750/install $(INSTALL_DIR) $(1)/lib/firmware/ath11k/WCN6750/hw1.0 $(INSTALL_DATA) \ - $(PKG_BUILD_DIR)/ath11k/WCN6750/hw1.0/* $(1)/lib/firmware/ath11k/WCN6750/hw1.0/ + $(PKG_BUILD_DIR)/ath11k/WCN6750/hw1.0/board-2.bin $(1)/lib/firmware/ath11k/WCN6750/hw1.0/ + $(INSTALL_DATA) \ + $(PKG_BUILD_DIR)/ath11k/WCN6750/hw1.0/Notice.txt $(1)/lib/firmware/ath11k/WCN6750/hw1.0/ + $(INSTALL_DATA) \ + $(PKG_BUILD_DIR)/ath11k/WCN6750/hw1.0/sc7280/wpss.mbn $(1)/lib/firmware/ath11k/WCN6750/hw1.0/ endef $(eval $(call BuildPackage,ath11k-firmware-wcn6750)) diff --git a/package/firmware/linux-firmware/realtek.mk b/package/firmware/linux-firmware/realtek.mk index c2ab1c9d0dee0a..749d93be3e2909 100644 --- a/package/firmware/linux-firmware/realtek.mk +++ b/package/firmware/linux-firmware/realtek.mk @@ -140,6 +140,20 @@ define Package/rtl8761bu-firmware/install endef $(eval $(call BuildPackage,rtl8761bu-firmware)) +Package/rtl8812a-firmware = $(call Package/firmware-default,RealTek RTL8812AU firmware) +define Package/rtl8812a-firmware/install + $(INSTALL_DIR) $(1)/lib/firmware/rtw88 + $(INSTALL_DATA) $(PKG_BUILD_DIR)/rtw88/rtw8812a_fw.bin $(1)/lib/firmware/rtw88 +endef +$(eval $(call BuildPackage,rtl8812a-firmware)) + +Package/rtl8821a-firmware = $(call Package/firmware-default,RealTek RTL8821AU firmware) +define Package/rtl8821a-firmware/install + $(INSTALL_DIR) $(1)/lib/firmware/rtw88 + $(INSTALL_DATA) $(PKG_BUILD_DIR)/rtw88/rtw8821a_fw.bin $(1)/lib/firmware/rtw88 +endef +$(eval $(call BuildPackage,rtl8821a-firmware)) + Package/rtl8821ae-firmware = $(call Package/firmware-default,RealTek RTL8821AE firmware,,LICENCE.rtlwifi_firmware.txt) define Package/rtl8821ae-firmware/install $(INSTALL_DIR) $(1)/lib/firmware/rtlwifi diff --git a/package/firmware/murata-firmware/Makefile b/package/firmware/murata-firmware/Makefile new file mode 100644 index 00000000000000..1d9efda576201c --- /dev/null +++ b/package/firmware/murata-firmware/Makefile @@ -0,0 +1,57 @@ +# +# Copyright (C) 2024 Bootlin +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=murata-firmware +PKG_RELEASE:=1 + +PKG_SOURCE_PROTO:=git +PKG_SOURCE_DATE:=2024-09-12 +PKG_SOURCE_URL:=https://github.com/murata-wireless/cyw-fmac-fw.git +PKG_MIRROR_HASH:=26f8a2df800666daab183b2842e5b3d591b1e5b31769d5429f9d70527f43d152 +PKG_SOURCE_VERSION:=50ac17bb65b2342cd954d49d9bc492709d431c3c + +PKG_MAINTAINER:=Thomas Richard +PKG_LICENSE_FILES:=LICENCE + +include $(INCLUDE_DIR)/package.mk + +define Package/murata-firmware-default + SECTION:=firmware + CATEGORY:=Firmware + URL:=https://community.murata.com/ +endef + +define Build/Compile +endef + +define Package/murata-firmware-43430-sdio + $(Package/murata-firmware-default) + TITLE:=BCM43430 FullMac SDIO firmware + CONFLICTS:=cypress-firmware-43430-sdio +endef + +define Package/murata-firmware-43430-sdio/install + $(INSTALL_DIR) $(1)/lib/firmware/murata + $(INSTALL_DATA) \ + $(PKG_BUILD_DIR)/cyfmac43430-sdio.bin \ + $(1)/lib/firmware/murata/ + $(INSTALL_DATA) \ + $(PKG_BUILD_DIR)/cyfmac43430-sdio.1DX.clm_blob \ + $(1)/lib/firmware/murata/ + $(INSTALL_DIR) $(1)/lib/firmware/brcm + $(LN) \ + ../murata/cyfmac43430-sdio.bin \ + $(1)/lib/firmware/brcm/brcmfmac43430-sdio.bin + $(LN) \ + ../murata/cyfmac43430-sdio.1DX.clm_blob \ + $(1)/lib/firmware/brcm/brcmfmac43430-sdio.clm_blob +endef + +$(eval $(call BuildPackage,murata-firmware-43430-sdio)) + diff --git a/package/firmware/murata-nvram/Makefile b/package/firmware/murata-nvram/Makefile new file mode 100644 index 00000000000000..daf382e3bc003d --- /dev/null +++ b/package/firmware/murata-nvram/Makefile @@ -0,0 +1,48 @@ +# +# Copyright (C) 2024 Bootlin +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=murata-nvram +PKG_RELEASE:=1 + +PKG_SOURCE_PROTO:=git +PKG_SOURCE_DATE:=2024-09-28 +PKG_SOURCE_URL:=https://github.com/murata-wireless/cyw-fmac-nvram.git +PKG_MIRROR_HASH:=e2fc6f1f9898edfd67f5495e615882700f03b42a75efa2e3f4e2d524aed0efb8 +PKG_SOURCE_VERSION:=255819aab07572d87576a13329ef9d4c654167aa + +PKG_MAINTAINER:=Thomas Richard +PKG_LICENSE_FILES:=LICENCE.cypress + +include $(INCLUDE_DIR)/package.mk + +define Package/murata-nvram-default + SECTION:=firmware + CATEGORY:=Firmware + URL:=https://community.murata.com/ +endef + +define Build/Compile +endef + +define Package/murata-nvram-43430-sdio + $(Package/murata-nvram-default) + TITLE:=BCM43430 SDIO NVRAM + CONFLICTS:=brcmfmac-nvram-43430-sdio +endef + +define Package/murata-nvram-43430-sdio/install + $(INSTALL_DIR) $(1)/lib/firmware/brcm + $(INSTALL_DATA) ./files/cyfmac43430-sdio.1DX.stm32.txt \ + $(1)/lib/firmware/brcm/ + $(LN) \ + cyfmac43430-sdio.1DX.stm32.txt \ + $(1)/lib/firmware/brcm/brcmfmac43430-sdio.st,stm32mp135f-dk.txt +endef + +$(eval $(call BuildPackage,murata-nvram-43430-sdio)) diff --git a/package/firmware/murata-nvram/files/cyfmac43430-sdio.1DX.stm32.txt b/package/firmware/murata-nvram/files/cyfmac43430-sdio.1DX.stm32.txt new file mode 100755 index 00000000000000..f06abf03808e94 --- /dev/null +++ b/package/firmware/murata-nvram/files/cyfmac43430-sdio.1DX.stm32.txt @@ -0,0 +1,47 @@ +# This NVRAM file is based on cyfmac43430-sdio.1DX.txt, except that the muxenab +# parameter was unset to enable IB IRQ (OOB IRQ is not stable on STM32 +# platforms). +# 2.4 GHz, 20 MHz BW mode +manfid=0x2d0 +prodid=0x0726 +vendid=0x14e4 +devid=0x43e2 +boardtype=0x0726 +boardrev=0x1202 +boardnum=22 +macaddr=00:90:4c:c5:12:38 +sromrev=11 +boardflags=0x00404201 +boardflags3=0x08000000 +xtalfreq=37400 +nocrc=1 +ag0=0 +aa2g=1 +ccode=ALL +#pa0itssit=0x20 +extpagain2g=0 +pa2ga0=-145,6667,-751 +AvVmid_c0=0x0,0xc8 +cckpwroffset0=2 +maxp2ga0=74 +#txpwrbckof=6 +cckbw202gpo=0 +legofdmbw202gpo=0x88888888 +mcsbw202gpo=0xaaaaaaaa +propbw202gpo=0xdd +ofdmdigfilttype=18 +ofdmdigfilttypebe=18 +papdmode=1 +papdvalidtest=1 +pacalidx2g=48 +papdepsoffset=-22 +papdendidx=58 +il0macaddr=00:90:4c:c5:12:38 +wl0id=0x431b +# muxenab defined to enable OOB IRQ. Level sensitive interrupt via WL_HOST_WAKE line. +# muxenab=0x10 +#BT COEX deferral limit setting +#btc_params 8 45000 +#btc_params 10 20000 +#spurconfig=0x3 +# End of NVRAM - do not remove this line # diff --git a/package/firmware/omnia-mcu-firmware/Makefile b/package/firmware/omnia-mcu-firmware/Makefile index 6f7bd6ca70737e..9c1c8fbe6c6b55 100644 --- a/package/firmware/omnia-mcu-firmware/Makefile +++ b/package/firmware/omnia-mcu-firmware/Makefile @@ -29,7 +29,6 @@ define Package/omnia-mcu-firmware CATEGORY:=Firmware URL:=https://gitlab.nic.cz/turris/hw/$(PKG_DISTNAME)/-/releases TITLE:=CZ.NIC Turris Omnia MCU firmware - DEPENDS:=@TARGET_mvebu_cortexa9_DEVICE_cznic_turris-omnia endef define Package/omnia-mcu-firmware/description diff --git a/package/firmware/wireless-regdb/Makefile b/package/firmware/wireless-regdb/Makefile index 7d4cf63c479f4b..d45c95e5e3d4f0 100644 --- a/package/firmware/wireless-regdb/Makefile +++ b/package/firmware/wireless-regdb/Makefile @@ -1,14 +1,14 @@ include $(TOPDIR)/rules.mk PKG_NAME:=wireless-regdb -PKG_VERSION:=2024.10.07 +PKG_VERSION:=2025.07.10 PKG_RELEASE:=1 PKG_LICENSE:=ISC PKG_LICENSE_FILES:=LICENSE PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz PKG_SOURCE_URL:=@KERNEL/software/network/wireless-regdb/ -PKG_HASH:=f76f2bd79a653e9f9dd50548d99d03a4a4eb157da056dfd5892f403ec28fb3d5 +PKG_HASH:=a8340bcdcd1b5db6c79149879d122b170f3bb075381718d4f429ad831a6fa28d PKG_MAINTAINER:=Felix Fietkau diff --git a/package/kernel/ath10k-ct/patches/130-ath10k-read-qcom-coexist-support-as-a-u32.patch b/package/kernel/ath10k-ct/patches/130-ath10k-read-qcom-coexist-support-as-a-u32.patch deleted file mode 100644 index 61090a49d0e44f..00000000000000 --- a/package/kernel/ath10k-ct/patches/130-ath10k-read-qcom-coexist-support-as-a-u32.patch +++ /dev/null @@ -1,60 +0,0 @@ -From 630df9786fdaeb78c21f1e28c9b70ac83a1b482c Mon Sep 17 00:00:00 2001 -From: Vincent Tremblay -Date: Sat, 31 Dec 2022 09:24:00 -0500 -Subject: [PATCH] ath10k: read qcom,coexist-support as a u32 - -Read qcom,coexist-support as a u32 instead of a u8 - -When we set the property to <1> in the DT (as specified in the doc), -"of_property_read_u8" read 0 instead of 1. This is because of the data format. - -By default <1> is written with 32 bits. -The problem is that the driver is trying to read a u8. - -The difference can be visualized using hexdump in a running device: -Default 32 bits output: -======================= -0000000 0000 0100 -0000004 - -8 bits output: -============== -0000000 0001 -0000001 - -By changing "of_property_read_u8" by "of_property_read_u32", the driver -is aligned with the documentation and is able to read the value without -modifying the DT. - -The other solution would be to force the value in the DT to be saved as -an 8 bits value (qcom,coexist-support = /bits/ 8 <1>), -which is against the doc and less intuitive. - -Validation: -=========== -The patch was tested on a real device and we can see in the debug logs -that the feature is properly initialized: - -[ 109.102097] ath10k_ahb a000000.wifi: boot coex_support 1 coex_gpio_pin 52 - -Signed-off-by: Vincent Tremblay - ---- a/ath10k-6.10/core.c -+++ b/ath10k-6.10/core.c -@@ -2871,14 +2871,14 @@ done: - static void ath10k_core_fetch_btcoex_dt(struct ath10k *ar) - { - struct device_node *node; -- u8 coex_support = 0; -+ u32 coex_support = 0; - int ret; - - node = ar->dev->of_node; - if (!node) - goto out; - -- ret = of_property_read_u8(node, "qcom,coexist-support", &coex_support); -+ ret = of_property_read_u32(node, "qcom,coexist-support", &coex_support); - if (ret) { - ar->coex_support = true; - goto out; diff --git a/package/kernel/ath10k-ct/patches/205-ath10k-ct-silence-warning-caused-by-unsupported-retr.patch b/package/kernel/ath10k-ct/patches/205-ath10k-ct-silence-warning-caused-by-unsupported-retr.patch new file mode 100644 index 00000000000000..9d6b0954ff027f --- /dev/null +++ b/package/kernel/ath10k-ct/patches/205-ath10k-ct-silence-warning-caused-by-unsupported-retr.patch @@ -0,0 +1,34 @@ +From: Shiji Yang +Date: Fri, 28 Mar 2025 20:26:04 +0800 +Subject: [PATCH] ath10k-ct: silence warning caused by unsupported retry_limit + value + +Some retry_limit values are not supported by ath10k wave2 chips. +We can just skip config it for these chips. And it's safe to +return 0 in this case because the hardware is still working. + +Suggested-by: Ben Greear +Signed-off-by: Shiji Yang +--- + ath10k-6.14/mac.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/ath10k-6.10/mac.c ++++ b/ath10k-6.10/mac.c +@@ -5395,7 +5395,7 @@ static int ath10k_config_retry_limit(str + */ + ath10k_warn(ar, "Firmware lacks feature flag indicating a retry limit of > 2 is OK, requested limit: %d\n", + limit); +- return -EINVAL; ++ goto skip_retry_limit; + } + + list_for_each_entry(arvif, &ar->arvifs, list) { +@@ -5406,6 +5406,7 @@ static int ath10k_config_retry_limit(str + } + } + ++skip_retry_limit: + return ret; + } + diff --git a/package/kernel/ath10k-ct/patches/206-ath10k-ct-silence-noisy-log-caused-by-flushing-queue.patch b/package/kernel/ath10k-ct/patches/206-ath10k-ct-silence-noisy-log-caused-by-flushing-queue.patch new file mode 100644 index 00000000000000..8b8042e5d701d8 --- /dev/null +++ b/package/kernel/ath10k-ct/patches/206-ath10k-ct-silence-noisy-log-caused-by-flushing-queue.patch @@ -0,0 +1,31 @@ +From: Shiji Yang +Date: Fri, 28 Mar 2025 21:02:27 +0800 +Subject: [PATCH] ath10k-ct: silence noisy log caused by flushing queue + +.flush() is a regular mac80211 operation aims to clear all pending +frames from the hardware queue. Only developers need to care about it. + +Signed-off-by: Shiji Yang +--- + ath10k-6.14/mac.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +--- a/ath10k-6.10/mac.c ++++ b/ath10k-6.10/mac.c +@@ -9061,12 +9061,12 @@ static void ath10k_flush(struct ieee8021 + if (vif) { + arvif = (void *)vif->drv_priv; + vid = arvif->vdev_id; +- ath10k_info(ar, "mac flush vdev %d drop %d queues 0x%x ar->paused: 0x%lx arvif->paused: 0x%lx\n", +- arvif->vdev_id, drop, queues, ar->tx_paused, arvif->tx_paused); ++ ath10k_dbg(ar, ATH10K_DBG_MAC, "mac flush vdev %d drop %d queues 0x%x ar->paused: 0x%lx arvif->paused: 0x%lx\n", ++ arvif->vdev_id, drop, queues, ar->tx_paused, arvif->tx_paused); + } + else { +- ath10k_info(ar, "mac flush null vif, drop %d queues 0x%x\n", +- drop, queues); ++ ath10k_dbg(ar, ATH10K_DBG_MAC, "mac flush null vif, drop %d queues 0x%x\n", ++ drop, queues); + } + + diff --git a/package/kernel/ath10k-ct/patches/988-ath10k-always-use-mac80211-loss-detection.patch b/package/kernel/ath10k-ct/patches/988-ath10k-always-use-mac80211-loss-detection.patch index 35026cc0f943d5..1f9f38c2b04dae 100644 --- a/package/kernel/ath10k-ct/patches/988-ath10k-always-use-mac80211-loss-detection.patch +++ b/package/kernel/ath10k-ct/patches/988-ath10k-always-use-mac80211-loss-detection.patch @@ -18,7 +18,7 @@ Signed-off-by: David Bauer --- a/ath10k-6.10/mac.c +++ b/ath10k-6.10/mac.c -@@ -11316,7 +11316,6 @@ int ath10k_mac_register(struct ath10k *a +@@ -11317,7 +11317,6 @@ int ath10k_mac_register(struct ath10k *a ieee80211_hw_set(ar->hw, CHANCTX_STA_CSA); ieee80211_hw_set(ar->hw, QUEUE_CONTROL); ieee80211_hw_set(ar->hw, SUPPORTS_TX_FRAG); diff --git a/package/kernel/bcm27xx-gpu-fw/Makefile b/package/kernel/bcm27xx-gpu-fw/Makefile index 6de2fd7501c45b..2d90406b58926d 100644 --- a/package/kernel/bcm27xx-gpu-fw/Makefile +++ b/package/kernel/bcm27xx-gpu-fw/Makefile @@ -2,13 +2,13 @@ include $(TOPDIR)/rules.mk include $(INCLUDE_DIR)/kernel.mk PKG_NAME:=bcm27xx-gpu-fw -PKG_VERSION:=2024.10.08 +PKG_VERSION:=2025.04.30 PKG_VERSION_REAL:=1.$(subst .,,$(PKG_VERSION)) PKG_RELEASE:=1 PKG_SOURCE:=raspi-firmware_$(PKG_VERSION_REAL).orig.tar.xz PKG_SOURCE_URL:=https://github.com/raspberrypi/firmware/releases/download/$(PKG_VERSION_REAL) -PKG_HASH:=11e7bedcd0f52729bbc82ae8de3cb3f52eb4ae3d6bdb3e11fbfdbea9c4a2b1c3 +PKG_HASH:=25bcff5992c6d7057de4a5c6834b7f90b7136fe12aa63fa32793329bf74a95bf PKG_FLAGS:=nonshared @@ -33,6 +33,10 @@ define Build/Compile true endef +define Package/bcm27xx-gpu-fw/install + true +endef + define Build/InstallDev $(CP) $(PKG_BUILD_DIR)/boot/bootcode.bin $(KERNEL_BUILD_DIR) $(CP) $(PKG_BUILD_DIR)/boot/LICENCE.broadcom $(KERNEL_BUILD_DIR) diff --git a/package/kernel/bcm63xx-cfe/Makefile b/package/kernel/bcm63xx-cfe/Makefile index 9bd61afdead5c3..8b6fa8010c650b 100644 --- a/package/kernel/bcm63xx-cfe/Makefile +++ b/package/kernel/bcm63xx-cfe/Makefile @@ -6,9 +6,9 @@ PKG_RELEASE:=1 PKG_SOURCE_URL:=https://github.com/openwrt/bcm63xx-cfe.git PKG_SOURCE_PROTO:=git -PKG_SOURCE_DATE:=2024-06-25 -PKG_SOURCE_VERSION:=6519bd2dde3535cafeea43157755f4dbef2f90c5 -PKG_MIRROR_HASH:=db4da580b7a611a2b4ddd4ff812e5f8ddfd9694b6f5fd8246a341e61967c00ef +PKG_SOURCE_DATE:=2025-04-02 +PKG_SOURCE_VERSION:=b8128fa4bdcdaf97549138965b00d5d7ceb7bb0f +PKG_MIRROR_HASH:=d33fad4fb5f4419bb287f3c3df6cceabab01fc7852c24cf29a15befa38cc0d45 PKG_FLAGS:=nonshared diff --git a/package/kernel/cryptodev-linux/Makefile b/package/kernel/cryptodev-linux/Makefile index ea1bd241617b7d..165cc60487b5b0 100644 --- a/package/kernel/cryptodev-linux/Makefile +++ b/package/kernel/cryptodev-linux/Makefile @@ -28,7 +28,7 @@ include $(INCLUDE_DIR)/package.mk define KernelPackage/cryptodev SUBMENU:=Cryptographic API modules TITLE:=Driver for cryptographic acceleration - URL:=http://cryptodev-linux.org/ + URL:=https://github.com/cryptodev-linux/cryptodev-linux DEPENDS:=+kmod-crypto-authenc +kmod-crypto-hash FILES:=$(PKG_BUILD_DIR)/cryptodev.$(LINUX_KMOD_SUFFIX) AUTOLOAD:=$(call AutoLoad,50,cryptodev) @@ -36,8 +36,9 @@ define KernelPackage/cryptodev endef define KernelPackage/cryptodev/description - This is a driver for that allows to use the Linux kernel supported - hardware ciphers by user-space applications. + This driver allows use of the Linux kernel supported hardware-based + cryptographic and hash accelerators by user-space applications, + via a "/dev/crypto" device. endef define Build/Configure diff --git a/package/kernel/gpio-button-hotplug/src/gpio-button-hotplug.c b/package/kernel/gpio-button-hotplug/src/gpio-button-hotplug.c index 1dd0ff2a1a1abf..9876dee90fc821 100644 --- a/package/kernel/gpio-button-hotplug/src/gpio-button-hotplug.c +++ b/package/kernel/gpio-button-hotplug/src/gpio-button-hotplug.c @@ -302,7 +302,7 @@ struct gpio_keys_button_dev { struct device *dev; struct gpio_keys_platform_data *pdata; - struct gpio_keys_button_data data[0]; + struct gpio_keys_button_data data[]; }; static void gpio_keys_polled_queue_work(struct gpio_keys_button_dev *bdev) @@ -693,7 +693,6 @@ static struct platform_driver gpio_keys_driver = { .remove = gpio_keys_remove, .driver = { .name = "gpio-keys", - .owner = THIS_MODULE, .of_match_table = of_match_ptr(gpio_keys_of_match), }, }; @@ -703,7 +702,6 @@ static struct platform_driver gpio_keys_polled_driver = { .remove = gpio_keys_remove, .driver = { .name = "gpio-keys-polled", - .owner = THIS_MODULE, .of_match_table = of_match_ptr(gpio_keys_polled_of_match), }, }; diff --git a/package/kernel/gpio-nct5104d/src/gpio-nct5104d.c b/package/kernel/gpio-nct5104d/src/gpio-nct5104d.c index e31a94b5cfb20d..ffeab29eda2efa 100644 --- a/package/kernel/gpio-nct5104d/src/gpio-nct5104d.c +++ b/package/kernel/gpio-nct5104d/src/gpio-nct5104d.c @@ -366,7 +366,6 @@ nct5104d_gpio_device_add(const struct nct5104d_sio *sio) static struct platform_driver nct5104d_gpio_driver = { .driver = { - .owner = THIS_MODULE, .name = DRVNAME, }, .probe = nct5104d_gpio_probe, diff --git a/package/kernel/lantiq/ltq-adsl-mei/src/drv_mei_cpe.c b/package/kernel/lantiq/ltq-adsl-mei/src/drv_mei_cpe.c index ba23232ee9429c..5ee5b70b4774e4 100644 --- a/package/kernel/lantiq/ltq-adsl-mei/src/drv_mei_cpe.c +++ b/package/kernel/lantiq/ltq-adsl-mei/src/drv_mei_cpe.c @@ -1787,6 +1787,7 @@ extern void ifx_usb_enable_afe_oc(void); */ static irqreturn_t IFX_MEI_IrqHandle (int int1, void *void0) { + u32 stat; u32 scratch; DSL_DEV_Device_t *pDev = (DSL_DEV_Device_t *) void0; #if defined(CONFIG_LTQ_MEI_FW_LOOPBACK) && defined(DFE_PING_TEST) @@ -1820,6 +1821,12 @@ static irqreturn_t IFX_MEI_IrqHandle (int int1, void *void0) if (dsl_bsp_event_callback[event].function) (*dsl_bsp_event_callback[event].function)(pDev, event, dsl_bsp_event_callback[event].pData); } else { // normal message + IFX_MEI_LongWordReadOffset (pDev, (u32) ME_ARC2ME_STAT, &stat); + if (!(stat & ARC_TO_MEI_MSGAV)) { + // status register indicates there is no message + return IRQ_NONE; + } + IFX_MEI_MailboxRead (pDev, DSL_DEV_PRIVATE(pDev)->CMV_RxMsg, MSG_LENGTH); if (DSL_DEV_PRIVATE(pDev)-> cmv_waiting == 1) { DSL_DEV_PRIVATE(pDev)-> arcmsgav = 1; @@ -2807,7 +2814,6 @@ static struct platform_driver ltq_mei_driver = { .remove = ltq_mei_remove, .driver = { .name = "lantiq,mei-xway", - .owner = THIS_MODULE, .of_match_table = ltq_mei_match, }, }; diff --git a/package/kernel/lantiq/ltq-adsl/patches/120-platform.patch b/package/kernel/lantiq/ltq-adsl/patches/120-platform.patch index 7bbcf35cd2834c..69f2b45e321cd3 100644 --- a/package/kernel/lantiq/ltq-adsl/patches/120-platform.patch +++ b/package/kernel/lantiq/ltq-adsl/patches/120-platform.patch @@ -36,7 +36,7 @@ } #ifndef _lint -@@ -1159,8 +1159,30 @@ module_param(debug_level, byte, 0); +@@ -1159,8 +1159,29 @@ module_param(debug_level, byte, 0); MODULE_PARM_DESC(debug_level, "set to get more (1) or fewer (4) debug outputs"); #endif /* #ifndef DSL_DEBUG_DISABLE*/ @@ -59,7 +59,6 @@ + .remove = __devexit_p(ltq_adsl_remove), + .driver = { + .name = "adsl", -+ .owner = THIS_MODULE, + .of_match_table = ltq_adsl_match, + }, +}; diff --git a/package/kernel/lantiq/ltq-atm/Makefile b/package/kernel/lantiq/ltq-atm/Makefile index b81f3bb2938224..ca19c5052e9b24 100644 --- a/package/kernel/lantiq/ltq-atm/Makefile +++ b/package/kernel/lantiq/ltq-atm/Makefile @@ -33,7 +33,7 @@ endef KernelPackage/ltq-atm-danube=$(call KernelPackage/ltq-atm-template,danube,(TARGET_lantiq_xway||TARGET_lantiq_xway_legacy)) KernelPackage/ltq-atm-ar9=$(call KernelPackage/ltq-atm-template,ar9,TARGET_lantiq_xway) KernelPackage/ltq-atm-ase=$(call KernelPackage/ltq-atm-template,ase,TARGET_lantiq_ase) -KernelPackage/ltq-atm-vr9=$(call KernelPackage/ltq-atm-template,vr9,TARGET_lantiq_xrx200) +KernelPackage/ltq-atm-vr9=$(call KernelPackage/ltq-atm-template,vr9,(TARGET_lantiq_xrx200||TARGET_lantiq_xrx200_legacy)) define Build/Configure endef diff --git a/package/kernel/lantiq/ltq-atm/src/ltq_atm.c b/package/kernel/lantiq/ltq-atm/src/ltq_atm.c index 0cb49a59bd0e4d..6b1e0321b3ee17 100644 --- a/package/kernel/lantiq/ltq-atm/src/ltq_atm.c +++ b/package/kernel/lantiq/ltq-atm/src/ltq_atm.c @@ -1894,7 +1894,6 @@ static struct platform_driver ltq_atm_driver = { .remove = ltq_atm_remove, .driver = { .name = "atm", - .owner = THIS_MODULE, .of_match_table = ltq_atm_match, }, }; diff --git a/package/kernel/lantiq/ltq-deu/Makefile b/package/kernel/lantiq/ltq-deu/Makefile index 4e8127afabb986..96414bf186f696 100644 --- a/package/kernel/lantiq/ltq-deu/Makefile +++ b/package/kernel/lantiq/ltq-deu/Makefile @@ -21,14 +21,14 @@ define KernelPackage/ltq-deu-template TITLE:=deu driver for $(1) URL:=http://www.lantiq.com/ VARIANT:=$(1) - DEPENDS:=@TARGET_lantiq_$(2) +kmod-crypto-manager +kmod-crypto-des + DEPENDS:=@$(2) +kmod-crypto-manager +kmod-crypto-des FILES:=$(PKG_BUILD_DIR)/ltq_deu_$(1).ko AUTOLOAD:=$(call AutoProbe,ltq_deu_$(1)) endef -KernelPackage/ltq-deu-danube=$(call KernelPackage/ltq-deu-template,danube,xway) -KernelPackage/ltq-deu-ar9=$(call KernelPackage/ltq-deu-template,ar9,xway) -KernelPackage/ltq-deu-vr9=$(call KernelPackage/ltq-deu-template,vr9,xrx200) +KernelPackage/ltq-deu-danube=$(call KernelPackage/ltq-deu-template,danube,TARGET_lantiq_xway) +KernelPackage/ltq-deu-ar9=$(call KernelPackage/ltq-deu-template,ar9,TARGET_lantiq_xway) +KernelPackage/ltq-deu-vr9=$(call KernelPackage/ltq-deu-template,vr9,(TARGET_lantiq_xrx200||TARGET_lantiq_xrx200_legacy)) define Build/Configure endef diff --git a/package/kernel/lantiq/ltq-deu/src/ifxmips_deu.c b/package/kernel/lantiq/ltq-deu/src/ifxmips_deu.c index 096b8b5bba83fb..e44e84c03cd7a3 100644 --- a/package/kernel/lantiq/ltq-deu/src/ifxmips_deu.c +++ b/package/kernel/lantiq/ltq-deu/src/ifxmips_deu.c @@ -196,7 +196,6 @@ static struct platform_driver ltq_deu_driver = { .remove = ltq_deu_remove, .driver = { .name = "deu", - .owner = THIS_MODULE, .of_match_table = ltq_deu_match, }, }; diff --git a/package/kernel/lantiq/ltq-ptm/Makefile b/package/kernel/lantiq/ltq-ptm/Makefile index 03b121887470d0..c3ab47c1b3e5fb 100644 --- a/package/kernel/lantiq/ltq-ptm/Makefile +++ b/package/kernel/lantiq/ltq-ptm/Makefile @@ -22,7 +22,7 @@ define KernelPackage/ltq-ptm-template TITLE:=ptm driver for $(1) URL:=http://www.lantiq.com/ VARIANT:=$(1) - DEPENDS:=@TARGET_lantiq_$(2) + DEPENDS:=@$(2) ifeq ($(1),vr9) DEPENDS+= +PACKAGE_kmod-ltq-ptm-$(1):kmod-ltq-vdsl-vr9-mei else @@ -34,10 +34,10 @@ endif FILES:=$(PKG_BUILD_DIR)/ltq_ptm_$(1).ko endef -KernelPackage/ltq-ptm-danube=$(call KernelPackage/ltq-ptm-template,danube,xway) -KernelPackage/ltq-ptm-ar9=$(call KernelPackage/ltq-ptm-template,ar9,xway) -KernelPackage/ltq-ptm-ase=$(call KernelPackage/ltq-ptm-template,ase,ase) -KernelPackage/ltq-ptm-vr9=$(call KernelPackage/ltq-ptm-template,vr9,xrx200) +KernelPackage/ltq-ptm-danube=$(call KernelPackage/ltq-ptm-template,danube,TARGET_lantiq_xway) +KernelPackage/ltq-ptm-ar9=$(call KernelPackage/ltq-ptm-template,ar9,TARGET_lantiq_xway) +KernelPackage/ltq-ptm-ase=$(call KernelPackage/ltq-ptm-template,ase,TARGET_lantiq_ase) +KernelPackage/ltq-ptm-vr9=$(call KernelPackage/ltq-ptm-template,vr9,(TARGET_lantiq_xrx200||TARGET_lantiq_xrx200_legacy)) define Build/Configure endef diff --git a/package/kernel/lantiq/ltq-ptm/src/ifxmips_ptm_adsl.c b/package/kernel/lantiq/ltq-ptm/src/ifxmips_ptm_adsl.c index 3ff01d588ad24a..5e5535348d832f 100644 --- a/package/kernel/lantiq/ltq-ptm/src/ifxmips_ptm_adsl.c +++ b/package/kernel/lantiq/ltq-ptm/src/ifxmips_ptm_adsl.c @@ -1600,7 +1600,6 @@ static struct platform_driver ltq_ptm_driver = { .remove = ltq_ptm_remove, .driver = { .name = "ptm", - .owner = THIS_MODULE, .of_match_table = ltq_ptm_match, }, }; diff --git a/package/kernel/lantiq/ltq-ptm/src/ifxmips_ptm_vdsl.c b/package/kernel/lantiq/ltq-ptm/src/ifxmips_ptm_vdsl.c index 6731904bba9a85..c5bbd9fd874594 100644 --- a/package/kernel/lantiq/ltq-ptm/src/ifxmips_ptm_vdsl.c +++ b/package/kernel/lantiq/ltq-ptm/src/ifxmips_ptm_vdsl.c @@ -1138,7 +1138,6 @@ static struct platform_driver ltq_ptm_driver = { .remove = ltq_ptm_remove, .driver = { .name = "ptm", - .owner = THIS_MODULE, .of_match_table = ltq_ptm_match, }, }; diff --git a/package/kernel/lantiq/ltq-vdsl-fw/Makefile b/package/kernel/lantiq/ltq-vdsl-fw/Makefile index 88883ffdee0f4a..61833e018c28db 100644 --- a/package/kernel/lantiq/ltq-vdsl-fw/Makefile +++ b/package/kernel/lantiq/ltq-vdsl-fw/Makefile @@ -19,7 +19,7 @@ define Package/ltq-vdsl-vr9-vectoring-fw-installer TITLE:=VDSL2 Vectoring Firmware installer SECTION:=net CATEGORY:=Network - DEPENDS:=@TARGET_lantiq_xrx200 +kmod-ltq-vdsl-vr9 + DEPENDS:=@(TARGET_lantiq_xrx200||TARGET_lantiq_xrx200_legacy) +kmod-ltq-vdsl-vr9 endef define Build/Prepare diff --git a/package/kernel/lantiq/ltq-vdsl-vr9-mei/Makefile b/package/kernel/lantiq/ltq-vdsl-vr9-mei/Makefile index e9c5a681fd0098..9b3dac299feac1 100644 --- a/package/kernel/lantiq/ltq-vdsl-vr9-mei/Makefile +++ b/package/kernel/lantiq/ltq-vdsl-vr9-mei/Makefile @@ -29,7 +29,7 @@ define KernelPackage/ltq-vdsl-vr9-mei TITLE:=mei driver for vdsl SECTION:=sys SUBMENU:=Network Devices - DEPENDS:=@TARGET_lantiq_xrx200 +kmod-ltq-ifxos +kmod-ltq-vectoring + DEPENDS:=@(TARGET_lantiq_xrx200||TARGET_lantiq_xrx200_legacy) +kmod-ltq-ifxos +kmod-ltq-vectoring FILES:=$(PKG_BUILD_DIR)/src/drv_mei_cpe.ko AUTOLOAD:=$(call AutoLoad,50,drv_mei_cpe) endef @@ -44,7 +44,7 @@ define Package/ltq-vdsl-vr9-mei-test CATEGORY:=Network TITLE:=Lantiq mei driver test tool URL:=http://www.lantiq.com/ - DEPENDS:=@TARGET_lantiq_xrx200 + DEPENDS:=@(TARGET_lantiq_xrx200||TARGET_lantiq_xrx200_legacy) endef define Package/ltq-vdsl-vr9-mei-test/description diff --git a/package/kernel/lantiq/ltq-vdsl-vr9/Makefile b/package/kernel/lantiq/ltq-vdsl-vr9/Makefile index ebcb935a739dc4..5a53c050d4bfc0 100644 --- a/package/kernel/lantiq/ltq-vdsl-vr9/Makefile +++ b/package/kernel/lantiq/ltq-vdsl-vr9/Makefile @@ -29,7 +29,7 @@ define KernelPackage/ltq-vdsl-vr9 TITLE:=vdsl driver SECTION:=sys SUBMENU:=Network Devices - DEPENDS:=@TARGET_lantiq_xrx200 +kmod-ltq-vdsl-vr9-mei + DEPENDS:=@(TARGET_lantiq_xrx200||TARGET_lantiq_xrx200_legacy) +kmod-ltq-vdsl-vr9-mei FILES:=$(PKG_BUILD_DIR)/src/drv_dsl_cpe_api.ko AUTOLOAD:=$(call AutoLoad,51,drv_dsl_cpe_api) endef diff --git a/package/kernel/lantiq/ltq-vectoring/Makefile b/package/kernel/lantiq/ltq-vectoring/Makefile index 6076df77428091..ea177942b48c59 100644 --- a/package/kernel/lantiq/ltq-vectoring/Makefile +++ b/package/kernel/lantiq/ltq-vectoring/Makefile @@ -20,7 +20,7 @@ define KernelPackage/ltq-vectoring CATEGORY:=Kernel modules SUBMENU:=Network Devices TITLE:=driver for sending vectoring error samples - DEPENDS:=@TARGET_lantiq_xrx200 + DEPENDS:=@(TARGET_lantiq_xrx200||TARGET_lantiq_xrx200_legacy) FILES:=$(PKG_BUILD_DIR)/$(MAKE_PATH)/ltq_vectoring.ko AUTOLOAD:=$(call AutoLoad,49,ltq_vectoring) endef @@ -38,7 +38,7 @@ define KernelPackage/ltq-vectoring-test CATEGORY:=Kernel modules SUBMENU:=Network Devices TITLE:=driver for testing the vectoring driver - DEPENDS:=@TARGET_lantiq_xrx200 +kmod-ltq-vectoring + DEPENDS:=@(TARGET_lantiq_xrx200||TARGET_lantiq_xrx200_legacy) +kmod-ltq-vectoring FILES:=$(PKG_BUILD_DIR)/$(MAKE_PATH)/ltq_vectoring_test.ko endef diff --git a/package/kernel/lantiq/vrx518_tc/Makefile b/package/kernel/lantiq/vrx518_tc/Makefile index a5718d9d5b2a2d..d92c6d1c639133 100644 --- a/package/kernel/lantiq/vrx518_tc/Makefile +++ b/package/kernel/lantiq/vrx518_tc/Makefile @@ -10,7 +10,7 @@ include $(INCLUDE_DIR)/kernel.mk PKG_NAME:=vrx518_tc PKG_VERSION:=1.5.12.4 -PKG_RELEASE:=3 +PKG_RELEASE:=4 PKG_BASE_NAME:=vrx518_tc_drv UGW_VERSION=8.5.2.10 diff --git a/package/kernel/lantiq/vrx518_tc/patches/100-compat.patch b/package/kernel/lantiq/vrx518_tc/patches/100-compat.patch index d04c1ed5df0dc2..81e32369baefcc 100644 --- a/package/kernel/lantiq/vrx518_tc/patches/100-compat.patch +++ b/package/kernel/lantiq/vrx518_tc/patches/100-compat.patch @@ -166,7 +166,7 @@ - return (skb->DW0 >> 3) & 0xF; +// return (skb->DW0 >> 3) & 0xF; -+ return 1; ++ return 0; /* We use only one connection for now, so return the first connection id */ } static int atm_get_qid_by_vcc(struct net_device *dev, struct sk_buff *skb, diff --git a/package/kernel/lantiq/vrx518_tc/patches/101-dcdp-atm_tc-drop-extra-qos-classes.patch b/package/kernel/lantiq/vrx518_tc/patches/101-dcdp-atm_tc-drop-extra-qos-classes.patch new file mode 100644 index 00000000000000..5c7b24654538e5 --- /dev/null +++ b/package/kernel/lantiq/vrx518_tc/patches/101-dcdp-atm_tc-drop-extra-qos-classes.patch @@ -0,0 +1,144 @@ +Extra ATM traffic classes requires atm_qos struct extension and a set of +new defines. What itself requires atm.h updates both in the kernel and +in the toolchain. On another hand we do not have any real users of these +traffic classes. + +In absence of real user there are no benefits to support this +functionality. There is only the burden of maintenance of extra patches +all around the building framework. So just drop these extra QoS traffic +classes in order to facilitate maintenance and avoid side effects like +breaking compatibility with existing userspace tools like linux-atm. + +Signed-off-by: Sergey Ryazanov +-- +--- a/dcdp/atm_tc.c ++++ b/dcdp/atm_tc.c +@@ -463,34 +463,9 @@ static void set_qsb(struct atm_priv *pri + /* Weighted Fair Queueing Factor (WFQF) */ + switch (qos->txtp.traffic_class) { + case ATM_CBR: +- case ATM_VBR_RT: + /* real time queue gets weighted fair queueing bypass */ + q_parm_tbl.bit.wfqf = 0; + break; +- case ATM_VBR_NRT: +- case ATM_UBR_PLUS: +- /* WFQF calculation here is based on virtual cell rates, +- to reduce granularity for high rates +- */ +- /* WFQF is maximum cell rate / garenteed cell rate */ +- /* wfqf = qsb_minimum_cell_rate * QSB_WFQ_NONUBR_MAX / +- requested_minimum_peak_cell_rate +- */ +- if (qos->txtp.min_pcr == 0) +- q_parm_tbl.bit.wfqf = QSB_WFQ_NONUBR_MAX; +- else { +- tmp = QSB_GCR_MIN * QSB_WFQ_NONUBR_MAX / +- qos->txtp.min_pcr; +- if (tmp == 0) +- q_parm_tbl.bit.wfqf = 1; +- else if (tmp > QSB_WFQ_NONUBR_MAX) +- q_parm_tbl.bit.wfqf +- = QSB_WFQ_NONUBR_MAX; +- else +- q_parm_tbl.bit.wfqf = tmp; +- } +- break; +- + case ATM_UBR: + default: + q_parm_tbl.bit.wfqf = QSB_WFQ_UBR_BYPASS; +@@ -498,42 +473,9 @@ static void set_qsb(struct atm_priv *pri + } + + /* Sustained Cell Rate (SCR) Leaky Bucket Shaper VBR.0/VBR.1 */ +- if (qos->txtp.traffic_class == ATM_VBR_RT || +- qos->txtp.traffic_class == ATM_VBR_NRT) { +- if (qos->txtp.scr == 0) { +- /* disable shaper */ +- q_vbr_parm_tbl.bit.taus = 0; +- q_vbr_parm_tbl.bit.ts = 0; +- } else { +- /* Cell Loss Priority (CLP) */ +- if ((vcc->atm_options & ATM_ATMOPT_CLP)) +- /* CLP1 */ +- q_parm_tbl.bit.vbr = 1; +- else +- /* CLP0 */ +- q_parm_tbl.bit.vbr = 0; +- /* Rate Shaper Parameter (TS) and +- Burst Tolerance Parameter for SCR (tauS) +- */ +- tmp = ((qsb_clk * param->qsb_tstep) >> 5) / +- qos->txtp.scr + 1; +- q_vbr_parm_tbl.bit.ts +- = tmp > QSB_TP_TS_MAX ? QSB_TP_TS_MAX : tmp; +- tmp = (qos->txtp.mbs - 1) * +- (q_vbr_parm_tbl.bit.ts - +- q_parm_tbl.bit.tp) / 64; +- if (tmp == 0) +- q_vbr_parm_tbl.bit.taus = 1; +- else if (tmp > QSB_TAUS_MAX) +- q_vbr_parm_tbl.bit.taus +- = QSB_TAUS_MAX; +- else +- q_vbr_parm_tbl.bit.taus = tmp; +- } +- } else { +- q_vbr_parm_tbl.bit.taus = 0; +- q_vbr_parm_tbl.bit.ts = 0; +- } ++ /* NB: shaper disabled since there no user interface to activate it */ ++ q_vbr_parm_tbl.bit.taus = 0; ++ q_vbr_parm_tbl.bit.ts = 0; + + /* Queue Parameter Table (QPT) */ + tc_w32(QSB_QPT_SET_MASK, QSB_RTM); +@@ -1064,15 +1006,6 @@ static int ppe_open(struct atm_vcc *vcc) + /* check bandwidth */ + if ((vcc->qos.txtp.traffic_class == ATM_CBR && + vcc->qos.txtp.max_pcr > +- (port->tx_max_cell_rate - port->tx_used_cell_rate)) +- || (vcc->qos.txtp.traffic_class == ATM_VBR_RT && +- vcc->qos.txtp.max_pcr > +- (port->tx_max_cell_rate - port->tx_used_cell_rate)) +- || (vcc->qos.txtp.traffic_class == ATM_VBR_NRT && +- vcc->qos.txtp.scr > +- (port->tx_max_cell_rate - port->tx_used_cell_rate)) +- || (vcc->qos.txtp.traffic_class == ATM_UBR_PLUS && +- vcc->qos.txtp.min_pcr > + (port->tx_max_cell_rate - port->tx_used_cell_rate))) { + tc_dbg(priv->tc_priv, MSG_INIT, "exceed TX line rate\n"); + return -EINVAL; +@@ -1128,15 +1061,8 @@ static int ppe_open(struct atm_vcc *vcc) + /* reserve bandwidth */ + switch (vcc->qos.txtp.traffic_class) { + case ATM_CBR: +- case ATM_VBR_RT: + port->tx_used_cell_rate += vcc->qos.txtp.max_pcr; + break; +- case ATM_VBR_NRT: +- port->tx_used_cell_rate += vcc->qos.txtp.scr; +- break; +- case ATM_UBR_PLUS: +- port->tx_used_cell_rate += vcc->qos.txtp.min_pcr; +- break; + } + + /* update atm_vcc structure */ +@@ -1222,15 +1148,8 @@ static void ppe_close(struct atm_vcc *vc + /* release bandwidth */ + switch (vcc->qos.txtp.traffic_class) { + case ATM_CBR: +- case ATM_VBR_RT: + port->tx_used_cell_rate -= vcc->qos.txtp.max_pcr; + break; +- case ATM_VBR_NRT: +- port->tx_used_cell_rate -= vcc->qos.txtp.scr; +- break; +- case ATM_UBR_PLUS: +- port->tx_used_cell_rate -= vcc->qos.txtp.min_pcr; +- break; + } + + /* idle for a while to let parallel operation finish */ diff --git a/package/kernel/lantiq/vrx518_tc/patches/200-swplat.patch b/package/kernel/lantiq/vrx518_tc/patches/200-swplat.patch index edc97998b739de..930fa6632c373f 100644 --- a/package/kernel/lantiq/vrx518_tc/patches/200-swplat.patch +++ b/package/kernel/lantiq/vrx518_tc/patches/200-swplat.patch @@ -3,7 +3,7 @@ This replaces it by a basic working implementation. --- a/dcdp/atm_tc.c +++ b/dcdp/atm_tc.c -@@ -603,7 +603,11 @@ static void atm_aca_init(struct atm_priv +@@ -545,7 +545,11 @@ static void atm_aca_init(struct atm_priv cfg = &priv->tc_priv->cfg; txin = ¶m.aca_txin; @@ -15,7 +15,7 @@ This replaces it by a basic working implementation. txin->hd_size_in_dw = cfg->txin.soc_desc_dwsz; txin->pd_desc_base = SB_XBAR_ADDR(__ACA_TX_IN_PD_LIST_BASE); txin->pd_desc_num = __ACA_TX_IN_PD_LIST_NUM; -@@ -625,7 +629,11 @@ static void atm_aca_init(struct atm_priv +@@ -567,7 +571,11 @@ static void atm_aca_init(struct atm_priv txin->soc_cmlt_cnt_addr); txout = ¶m.aca_txout; @@ -27,7 +27,7 @@ This replaces it by a basic working implementation. txout->hd_size_in_dw = cfg->txout.soc_desc_dwsz; txout->pd_desc_base = SB_XBAR_ADDR(__ACA_TX_OUT_PD_LIST_BASE); txout->pd_desc_num = __ACA_TX_OUT_PD_LIST_NUM; -@@ -647,7 +655,11 @@ static void atm_aca_init(struct atm_priv +@@ -589,7 +597,11 @@ static void atm_aca_init(struct atm_priv txout->soc_cmlt_cnt_addr); rxout = ¶m.aca_rxout; @@ -39,7 +39,7 @@ This replaces it by a basic working implementation. rxout->hd_size_in_dw = cfg->rxout.soc_desc_dwsz; rxout->pd_desc_base = SB_XBAR_ADDR(__ACA_RX_OUT_PD_LIST_BASE); rxout->pd_desc_num = __ACA_RX_OUT_PD_LIST_NUM; -@@ -669,7 +681,11 @@ static void atm_aca_init(struct atm_priv +@@ -611,7 +623,11 @@ static void atm_aca_init(struct atm_priv rxout->soc_cmlt_cnt_addr); rxin = ¶m.aca_rxin; @@ -51,7 +51,7 @@ This replaces it by a basic working implementation. rxin->hd_size_in_dw = cfg->rxin.soc_desc_dwsz; rxin->pd_desc_base = SB_XBAR_ADDR(__RX_IN_PD_DES_LIST_BASE); rxin->pd_desc_num = __ACA_RX_IN_PD_LIST_NUM; -@@ -1261,7 +1277,7 @@ static int ppe_ioctl(struct atm_dev *dev +@@ -1180,7 +1196,7 @@ static int ppe_ioctl(struct atm_dev *dev static int ppe_send(struct atm_vcc *vcc, struct sk_buff *skb) { int ret, qid, mpoa_pt, mpoa_type, vid; @@ -60,7 +60,7 @@ This replaces it by a basic working implementation. struct atm_priv *priv; if (!vcc) { -@@ -1327,12 +1343,14 @@ static int ppe_send(struct atm_vcc *vcc, +@@ -1246,12 +1262,14 @@ static int ppe_send(struct atm_vcc *vcc, tc_dbg(priv->tc_priv, MSG_TX, "vid: 0x%x, qid: 0x%x\n", vid, qid); @@ -855,12 +855,12 @@ This replaces it by a basic working implementation. - continue; + + // this seems to be a pointer to a DS PKT buffer -+ phyaddr = desc->data_ptr + desc->byte_off; ++ phyaddr = desc->data_ptr; + ptr = plat_mem_virt(phyaddr); -+ + len = desc->data_len; + -+ dma_sync_single_range_for_cpu(pdev, phyaddr, 0, len, DMA_FROM_DEVICE); ++ dma_sync_single_for_cpu(pdev, phyaddr, desc->byte_off + len, ++ DMA_FROM_DEVICE); + + skb = netdev_alloc_skb(g_plat_priv->netdev, len); + if (unlikely(!skb)) { @@ -871,7 +871,7 @@ This replaces it by a basic working implementation. - ring_idx_inc(rxout, idx); + + dst = skb_put(skb, len); -+ memcpy(dst, ptr, len); ++ memcpy(dst, ptr + desc->byte_off, len); + + priv->tc_ops.recv(g_plat_priv->netdev, skb); + diff --git a/package/kernel/lantiq/vrx518_tc/patches/202-napi.patch b/package/kernel/lantiq/vrx518_tc/patches/202-napi.patch index 266beba1a7e41c..75d18138c0803c 100644 --- a/package/kernel/lantiq/vrx518_tc/patches/202-napi.patch +++ b/package/kernel/lantiq/vrx518_tc/patches/202-napi.patch @@ -296,7 +296,7 @@ priv->tc_ops.umt_start = plat_umt_start; --- a/dcdp/atm_tc.c +++ b/dcdp/atm_tc.c -@@ -3650,7 +3650,7 @@ static void atm_aca_ring_config_init(str +@@ -3569,7 +3569,7 @@ static void atm_aca_ring_config_init(str static int atm_ring_init(struct atm_priv *priv) { atm_aca_ring_config_init(priv); @@ -305,7 +305,7 @@ } static int atm_init(struct tc_priv *tcpriv, u32 ep_id) -@@ -4020,7 +4020,7 @@ void atm_tc_unload(void) +@@ -3939,7 +3939,7 @@ void atm_tc_unload(void) /* unregister device */ if (priv->tc_priv->tc_ops.dev_unreg != NULL) priv->tc_priv->tc_ops.dev_unreg(NULL, diff --git a/package/kernel/lantiq/vrx518_tc/patches/204-dcdp-atm_tc-fix-compilation-warning.patch b/package/kernel/lantiq/vrx518_tc/patches/204-dcdp-atm_tc-fix-compilation-warning.patch index bf2d82e2b552a1..1b70a663cdd54a 100644 --- a/package/kernel/lantiq/vrx518_tc/patches/204-dcdp-atm_tc-fix-compilation-warning.patch +++ b/package/kernel/lantiq/vrx518_tc/patches/204-dcdp-atm_tc-fix-compilation-warning.patch @@ -1,6 +1,6 @@ --- a/dcdp/atm_tc.c +++ b/dcdp/atm_tc.c -@@ -746,7 +746,8 @@ static void atm_aca_init(struct atm_priv +@@ -688,7 +688,8 @@ static void atm_aca_init(struct atm_priv ACA_TXOUT_EN | ACA_RXIN_EN | ACA_RXOUT_EN, 1); } @@ -10,7 +10,7 @@ { struct tm nowtm; char tmbuf[64]; -@@ -765,7 +766,8 @@ static int print_datetime(char *buffer, +@@ -707,7 +708,8 @@ static int print_datetime(char *buffer, nowtm.tm_hour, nowtm.tm_min, nowtm.tm_sec); @@ -20,7 +20,7 @@ return 0; } -@@ -967,7 +969,7 @@ void show_atm_pvc(struct seq_file *seq, +@@ -909,7 +911,7 @@ void show_atm_pvc(struct seq_file *seq, char buf[64]; seq_printf(seq, "\tNet device: %s\n", pvc->dev->name); diff --git a/package/kernel/lantiq/vrx518_tc/patches/206-dcdp-ptm_tc-allow-larger-mtu-to-support-rfc4638.patch b/package/kernel/lantiq/vrx518_tc/patches/206-dcdp-ptm_tc-allow-larger-mtu-to-support-rfc4638.patch new file mode 100644 index 00000000000000..35a709e9fa1ee2 --- /dev/null +++ b/package/kernel/lantiq/vrx518_tc/patches/206-dcdp-ptm_tc-allow-larger-mtu-to-support-rfc4638.patch @@ -0,0 +1,34 @@ +From 3983dc1674fec43beb8ce9d9bfdd6302fef86eae Mon Sep 17 00:00:00 2001 +From: Andrew MacIntyre +Date: Mon, 4 Nov 2024 22:41:25 +1100 +Subject: [PATCH] vrx518_tc: allow larger MTU to support RFC4638 + +vrx518_tc currently sets the interface maximum MTU to the ethernet default +of 1500 bytes by default via ether_setup() called from ptm_setup(). + +To support 1508 byte baby jumbo frames (RFC4638) for PPPoE connections +over VDSL links as already supported by the VR9 ltq_ptm driver ([1], [2]) +set the interface maximum MTU to MAX_MTU. + +MAX_MTU is defined in dcdp/inc/tc_common.h to 2002 bytes and this value is +used in ptm_change_mtu() and elsewhere as the maximum MTU, however this is +short circuited by checks against the interface maximum MTU. + +[1]: https://forum.openwrt.org/t/fritzbox-7530-and-rfc4638-baby-jumbo-frames/181327 +[2]: https://git.openwrt.org/?p=openwrt/openwrt.git;a=commit;h=8a2a20e71e2909f84dab47e51dfda9e292a6c1ae + +Signed-off-by: Andrew MacIntyre +--- + dcdp/ptm_tc.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/dcdp/ptm_tc.c 2023-12-17 16:11:22.503500398 +1100 ++++ b/dcdp/ptm_tc.c 2024-01-26 16:48:49.881623474 +1100 +@@ -657,6 +657,7 @@ static void ptm_setup(struct net_device + ether_setup(dev); + dev->watchdog_timeo = 10 * HZ; + dev->netdev_ops = &g_ptm_netdev_ops; ++ dev->max_mtu = MAX_MTU; + } + + static int ptm_dev_init(struct tc_priv *tc_priv, u32 id, diff --git a/package/kernel/lantiq/vrx518_tc/patches/207-dcdp-atm_tc-fix-crash-on-subif_reg-absence.patch b/package/kernel/lantiq/vrx518_tc/patches/207-dcdp-atm_tc-fix-crash-on-subif_reg-absence.patch new file mode 100644 index 00000000000000..f268c0908cb28a --- /dev/null +++ b/package/kernel/lantiq/vrx518_tc/patches/207-dcdp-atm_tc-fix-crash-on-subif_reg-absence.patch @@ -0,0 +1,75 @@ +From: Sergey Ryazanov +Date: Fri, 10 Jan 2025 00:57:27 +0000 +Subject: [PATCH] vrx518_tc: atm_tc: fix crash on subif_reg absence + +VRX518 (sw_plat) platform does not provid the subif_reg/subif_unreg ops +in the same time ATM TC layer unconditionally calls them, what leads to +the kernel crash on the atm_hook_mpoa_setup hook invocation from the ATM +stack: + + vrx518_tc:mpoa_setup_sync : sync: conn: 0, vpi: 0, vci: 35, mpoa_type: 0, mpoa_mode: 0 + Unable to handle kernel NULL pointer dereference at virtual address 00000000 + +Subif registration is optional and PTM TC do this only when the +corresponding ops are defined. Do the same for ATM TC and call +subif_reg/subif_unreg only if they are not NULL. + +While at it, move subif related data preparation under the 'if' block +in order to group and isolate that aux code. + +Run tested with FRITZ!Box 7530. + +Signed-off-by: Sergey Ryazanov +--- +--- a/dcdp/atm_tc.c ++++ b/dcdp/atm_tc.c +@@ -1158,8 +1158,9 @@ static void ppe_close(struct atm_vcc *vc + validate_oam_htu_entry(priv, 0); + spin_unlock_bh(&priv->atm_lock); + +- priv->tc_priv->tc_ops.subif_unreg(dev, (!dev) ? dev_name : dev->name, +- priv->conn[cid].subif_id, 0); ++ if (priv->tc_priv->tc_ops.subif_unreg) ++ priv->tc_priv->tc_ops.subif_unreg(dev, (!dev) ? dev_name : dev->name, ++ priv->conn[cid].subif_id, 0); + + memset(conn, 0, sizeof(*conn)); + +@@ -2710,24 +2711,26 @@ static void mpoa_setup_sync(struct atm_p + struct wtx_queue_config_t tx_qcfg; + struct uni_cell_header *cell_header; + struct atm_vcc *vcc; +- struct net_device *dev; +- char dev_name[32]; + + tc_dbg(priv->tc_priv, MSG_INIT, + "sync: conn: %d, vpi: %d, vci: %d, mpoa_type: %d, mpoa_mode: %d\n", + conn, priv->conn[conn].vcc->vpi, priv->conn[conn].vcc->vci, + priv->conn[conn].mpoa_type, priv->conn[conn].mpoa_mode); + +- dev = priv->conn[conn].dev; ++ if (priv->tc_priv->tc_ops.subif_reg) { ++ struct net_device *dev; ++ char dev_name[32]; ++ ++ dev = priv->conn[conn].dev; ++ if (!dev) ++ sprintf(dev_name, "atm_%d%d", ++ priv->conn[conn].vcc->vpi, priv->conn[conn].vcc->vci); + +- if (!dev) +- sprintf(dev_name, "atm_%d%d", +- priv->conn[conn].vcc->vpi, priv->conn[conn].vcc->vci); +- +- priv->tc_priv->tc_ops.subif_reg(dev, (!dev) ? dev_name : dev->name, +- &priv->conn[conn].subif_id, 0); +- tc_dbg(priv->tc_priv, MSG_INIT, +- "conn[%d]subif_id[%x]", conn, priv->conn[conn].subif_id); ++ priv->tc_priv->tc_ops.subif_reg(dev, !dev ? dev_name : dev->name, ++ &priv->conn[conn].subif_id, 0); ++ tc_dbg(priv->tc_priv, MSG_INIT, ++ "conn[%d]subif_id[%x]", conn, priv->conn[conn].subif_id); ++ } + vcc = priv->conn[conn].vcc; + + /* set htu entry */ diff --git a/package/kernel/linux/modules/can.mk b/package/kernel/linux/modules/can.mk index c86d02d8deeab0..1a4c81cc31c53c 100644 --- a/package/kernel/linux/modules/can.mk +++ b/package/kernel/linux/modules/can.mk @@ -245,6 +245,25 @@ endef $(eval $(call KernelPackage,can-usb-esd)) +define KernelPackage/can-usb-gs + TITLE:=Geschwister Schneider UG interfaces + KCONFIG:=CONFIG_CAN_GS_USB + FILES:= \ + $(LINUX_DIR)/drivers/net/can/usb/gs_usb.ko + AUTOLOAD:=$(call AutoProbe,gs_usb) + $(call AddDepends/can,+kmod-usb-core) +endef + +define KernelPackage/can-usb-gsr/description + This driver supports the Geschwister Schneider and + bytewerk.org candleLight compatible + (https://github.com/candle-usb/candleLight_fw) USB/CAN + interfaces. +endef + +$(eval $(call KernelPackage,can-usb-gs)) + + define KernelPackage/can-usb-kvaser TITLE:=Kvaser CAN/USB interface KCONFIG:=CONFIG_CAN_KVASER_USB diff --git a/package/kernel/linux/modules/crypto.mk b/package/kernel/linux/modules/crypto.mk index ce221635470302..78c97121764685 100644 --- a/package/kernel/linux/modules/crypto.mk +++ b/package/kernel/linux/modules/crypto.mk @@ -249,6 +249,15 @@ endef $(eval $(call KernelPackage,crypto-echainiv)) +define KernelPackage/crypto-engine + TITLE:=Crypto engine + KCONFIG:=CONFIG_CRYPTO_ENGINE + FILES:=$(LINUX_DIR)/crypto/crypto_engine.ko + AUTOLOAD:=$(call AutoLoad,09,crypto_engine) + $(call AddDepends/crypto, +kmod-crypto-rsa +kmod-crypto-kpp) +endef + +$(eval $(call KernelPackage,crypto-engine)) define KernelPackage/crypto-essiv TITLE:=ESSIV support for block encryption @@ -357,6 +366,26 @@ endef $(eval $(call KernelPackage,crypto-hmac)) +define KernelPackage/crypto-hw-atmel + TITLE:=Microchip / Atmel ECC/SHA/RNG hw accelerator + DEPENDS:=+kmod-i2c-core +kmod-crypto-ecdh +kmod-crypto-sha1 \ + +kmod-crypto-sha256 +kmod-lib-crc16 +kmod-random-core + KCONFIG:= \ + CONFIG_CRYPTO_HW=y \ + CONFIG_CRYPTO_DEV_ATMEL_I2C \ + CONFIG_CRYPTO_DEV_ATMEL_ECC \ + CONFIG_CRYPTO_DEV_ATMEL_SHA204A + FILES:= \ + $(LINUX_DIR)/drivers/crypto/atmel-i2c.ko \ + $(LINUX_DIR)/drivers/crypto/atmel-ecc.ko \ + $(LINUX_DIR)/drivers/crypto/atmel-sha204a.ko + AUTOLOAD:=$(call AutoLoad,09,atmel-i2c atmel-ecc atmel-sha204a) + $(call AddDepends/crypto) +endef + +$(eval $(call KernelPackage,crypto-hw-atmel)) + + define KernelPackage/crypto-hw-ccp TITLE:=AMD Cryptographic Coprocessor DEPENDS:= \ diff --git a/package/kernel/linux/modules/i2c.mk b/package/kernel/linux/modules/i2c.mk index 3aaf560ea908db..70bdaf22ab5f7a 100644 --- a/package/kernel/linux/modules/i2c.mk +++ b/package/kernel/linux/modules/i2c.mk @@ -116,17 +116,35 @@ I2C_DWPCI_MODULES:= \ define KernelPackage/i2c-designware-pci $(call i2c_defaults,$(I2C_DWPCI_MODULES),59) - TITLE:=Synopsys DesignWare PCI + TITLE:=Synopsys DesignWare I2C PCI DEPENDS:=@PCI_SUPPORT +kmod-i2c-designware-core +kmod-i2c-ccgs-ucsi endef define KernelPackage/i2c-designware-pci/description - Support for Synopsys DesignWare I2C controller. Only master mode is supported. + Support for Synopsys DesignWare I2C PCI controller. Only master mode is + supported. endef $(eval $(call KernelPackage,i2c-designware-pci)) +I2C_DWPLAT_MODULES:= \ + CONFIG_I2C_DESIGNWARE_PLATFORM:drivers/i2c/busses/i2c-designware-platform + +define KernelPackage/i2c-designware-platform + $(call i2c_defaults,$(I2C_DWPLAT_MODULES),59) + TITLE:=Synopsys DesignWare I2C Platform + DEPENDS:=+kmod-i2c-designware-core +endef + +define KernelPackage/i2c-designware-platform/description + Support for Synopsys DesignWare I2C Platform controller. Only master mode + is supported. +endef + +$(eval $(call KernelPackage,i2c-designware-platform)) + + I2C_GPIO_MODULES:= \ CONFIG_I2C_GPIO:drivers/i2c/busses/i2c-gpio diff --git a/package/kernel/linux/modules/iio.mk b/package/kernel/linux/modules/iio.mk index e46544b79cc65c..e98a6830da0342 100644 --- a/package/kernel/linux/modules/iio.mk +++ b/package/kernel/linux/modules/iio.mk @@ -46,6 +46,38 @@ endef $(eval $(call KernelPackage,iio-kfifo-buf)) +define KernelPackage/industrialio-hw-consumer + TITLE:=Provides a bonding way to an other device in hardware + KCONFIG:=CONFIG_IIO_BUFFER_HW_CONSUMER + FILES:=$(LINUX_DIR)/drivers/iio/buffer/industrialio-hw-consumer.ko + AUTOLOAD:=$(call AutoLoad,55,industrialio-hw-consumer) + $(call AddDepends/iio,+kmod-iio-kfifo-buf) +endef + +define KernelPackage/industrialio-hw-consumer/description + Provides a way to bonding when an IIO device has a direct connection + to another device in hardware. In this case buffers for data transfers + are handled by hardware. +endef + +$(eval $(call KernelPackage,industrialio-hw-consumer)) + + +define KernelPackage/industrialio-buffer-cb + TITLE:=Provides callback buffer used for push in-kernel interfaces + KCONFIG:=CONFIG_IIO_BUFFER_CB + FILES:=$(LINUX_DIR)/drivers/iio/buffer/industrialio-buffer-cb.ko + AUTOLOAD:=$(call AutoLoad,55,industrialio-triggered-buffer-cb) + $(call AddDepends/iio) +endef + +define KernelPackage/industrialio-buffer-cb/description + Should be selected by any drivers that do in-kernel push usage. +endef + +$(eval $(call KernelPackage,industrialio-buffer-cb)) + + define KernelPackage/industrialio-triggered-buffer TITLE:=Provides helper functions for setting up triggered buffers. DEPENDS:=+kmod-iio-kfifo-buf diff --git a/package/kernel/linux/modules/leds.mk b/package/kernel/linux/modules/leds.mk index 8b24cb0ef88e94..a555e6bd7a23b5 100644 --- a/package/kernel/linux/modules/leds.mk +++ b/package/kernel/linux/modules/leds.mk @@ -147,6 +147,24 @@ endef $(eval $(call KernelPackage,leds-apu)) +define KernelPackage/leds-ktd202x + SUBMENU:=LED modules + TITLE:=LED support for KTD202x Chips + DEPENDS:=+kmod-i2c-core +kmod-regmap-i2c + KCONFIG:=CONFIG_LEDS_KTD202X + FILES:= $(LINUX_DIR)/drivers/leds/rgb/leds-ktd202x.ko + AUTOLOAD:=$(call AutoProbe,leds-ktd202x,1) +endef + +define KernelPackage/leds-ktd202x/description + This option enables support for the Kinetic KTD2026/KTD2027 + RGB/White LED driver found in different BQ mobile phones. + It is a 3 or 4 channel LED driver programmed via an I2C interface. +endef + +$(eval $(call KernelPackage,leds-ktd202x)) + + define KernelPackage/leds-mlxcpld SUBMENU:=$(LEDS_MENU) TITLE:=LED support for the Mellanox boards @@ -281,6 +299,23 @@ endef $(eval $(call KernelPackage,leds-lp55xx-common)) +define KernelPackage/leds-lp5523 + SUBMENU:=$(LEDS_MENU) + TITLE:=LED driver for LP5523/LP55231 controllers + DEPENDS:=+kmod-i2c-core +kmod-leds-lp55xx-common + KCONFIG:=CONFIG_LEDS_LP5523 + FILES:=$(LINUX_DIR)/drivers/leds/leds-lp5523.ko + AUTOLOAD:=$(call AutoLoad,60,leds-lp5523,1) +endef + +define KernelPackage/leds-lp5523/description + This option enables support for Texas Instruments LP5523/LP55231 + LED controllers. +endef + +$(eval $(call KernelPackage,leds-lp5523)) + + define KernelPackage/leds-lp5562 SUBMENU:=$(LEDS_MENU) TITLE:=LED driver for LP5562 controllers diff --git a/package/kernel/linux/modules/netdevices.mk b/package/kernel/linux/modules/netdevices.mk index cd24fb3ecbc996..c60a9479788f4e 100644 --- a/package/kernel/linux/modules/netdevices.mk +++ b/package/kernel/linux/modules/netdevices.mk @@ -447,9 +447,10 @@ $(eval $(call KernelPackage,phy-micrel)) define KernelPackage/phy-realtek SUBMENU:=$(NETWORK_DEVICES_MENU) TITLE:=Realtek Ethernet PHY driver - KCONFIG:=CONFIG_REALTEK_PHY - DEPENDS:=+kmod-libphy - FILES:=$(LINUX_DIR)/drivers/net/phy/realtek.ko + KCONFIG:=CONFIG_REALTEK_PHY \ + CONFIG_REALTEK_PHY_HWMON=y + DEPENDS:=+kmod-libphy +kmod-hwmon-core + FILES:=$(LINUX_DIR)/drivers/net/phy/realtek/realtek.ko AUTOLOAD:=$(call AutoLoad,18,realtek,1) endef @@ -575,6 +576,23 @@ endef $(eval $(call KernelPackage,dsa-b53-mdio)) +define KernelPackage/dsa-mv88e6060 + SUBMENU:=$(NETWORK_DEVICES_MENU) + TITLE:=Marvell MV88E6060 DSA Switch + DEPENDS:=+kmod-dsa +kmod-phy-marvell + KCONFIG:=CONFIG_NET_DSA_TAG_TRAILER \ + CONFIG_NET_DSA_MV88E6060 + FILES:= \ + $(LINUX_DIR)/drivers/net/dsa/mv88e6060.ko \ + $(LINUX_DIR)/net/dsa/tag_trailer.ko + AUTOLOAD:=$(call AutoLoad,41,mv88e6060,1) +endef + +define KernelPackage/dsa-mv88e6060/description + Kernel modules for MV88E6060 DSA switches +endef + +$(eval $(call KernelPackage,dsa-mv88e6060)) define KernelPackage/dsa-tag-dsa SUBMENU:=$(NETWORK_DEVICES_MENU) @@ -958,7 +976,7 @@ define KernelPackage/r8169 CONFIG_R8169 \ CONFIG_R8169_LEDS=y FILES:=$(LINUX_DIR)/drivers/net/ethernet/realtek/r8169.ko - AUTOLOAD:=$(call AutoProbe,r8169) + AUTOLOAD:=$(call AutoProbe,r8169,1) endef define KernelPackage/r8169/description @@ -1080,7 +1098,6 @@ define KernelPackage/ixgbe TITLE:=Intel(R) 82598/82599 PCI-Express 10 Gigabit Ethernet support DEPENDS:=@PCI_SUPPORT +kmod-mdio +kmod-ptp +kmod-hwmon-core +kmod-libphy +kmod-mdio-devres KCONFIG:=CONFIG_IXGBE \ - CONFIG_IXGBE_VXLAN=n \ CONFIG_IXGBE_HWMON=y \ CONFIG_IXGBE_DCA=n FILES:=$(LINUX_DIR)/drivers/net/ethernet/intel/ixgbe/ixgbe.ko @@ -1099,7 +1116,6 @@ define KernelPackage/ixgbevf TITLE:=Intel(R) 82599 Virtual Function Ethernet support DEPENDS:=@PCI_SUPPORT +kmod-ixgbe KCONFIG:=CONFIG_IXGBEVF \ - CONFIG_IXGBE_VXLAN=n \ CONFIG_IXGBE_HWMON=y \ CONFIG_IXGBE_DCA=n FILES:=$(LINUX_DIR)/drivers/net/ethernet/intel/ixgbevf/ixgbevf.ko @@ -1116,10 +1132,8 @@ $(eval $(call KernelPackage,ixgbevf)) define KernelPackage/i40e SUBMENU:=$(NETWORK_DEVICES_MENU) TITLE:=Intel(R) Ethernet Controller XL710 Family support - DEPENDS:=@PCI_SUPPORT +kmod-mdio +kmod-ptp +kmod-hwmon-core +kmod-libphy + DEPENDS:=@PCI_SUPPORT +kmod-ptp KCONFIG:=CONFIG_I40E \ - CONFIG_I40E_VXLAN=n \ - CONFIG_I40E_HWMON=y \ CONFIG_I40E_DCA=n FILES:=$(LINUX_DIR)/drivers/net/ethernet/intel/i40e/i40e.ko AUTOLOAD:=$(call AutoProbe,i40e) @@ -1525,6 +1539,28 @@ endef $(eval $(call KernelPackage,bnx2x)) +define KernelPackage/bnxt-en + SUBMENU:=$(NETWORK_DEVICES_MENU) + TITLE:=Broadcom NetXtreme-C/E network driver + DEPENDS:=@PCI_SUPPORT +kmod-hwmon-core +kmod-lib-crc32c +kmod-mdio +kmod-ptp + FILES:=$(LINUX_DIR)/drivers/net/ethernet/broadcom/bnxt/bnxt_en.ko + KCONFIG:= \ + CONFIG_BNXT \ + CONFIG_BNXT_SRIOV=y \ + CONFIG_BNXT_FLOWER_OFFLOAD=y \ + CONFIG_BNXT_DCB=n \ + CONFIG_BNXT_HWMON=y + AUTOLOAD:=$(call AutoProbe,bnxt_en) +endef + +define KernelPackage/bnxt-en/description + Supports Broadcom NetXtreme-C/E based Ethernet NICs including: + * BCM573xx + * BCM574xx +endef + +$(eval $(call KernelPackage,bnxt-en)) + define KernelPackage/be2net SUBMENU:=$(NETWORK_DEVICES_MENU) TITLE:=Broadcom Emulex OneConnect 10Gbps NIC @@ -1807,6 +1843,23 @@ endef $(eval $(call KernelPackage,igc)) + +define KernelPackage/hinic + SUBMENU:=$(NETWORK_DEVICES_MENU) + TITLE:=Huawei Intelligent PCIE Network Interface Card support + DEPENDS:=@PCI_SUPPORT @TARGET_x86||TARGET_armsr_armv8 + FILES:=$(LINUX_DIR)/drivers/net/ethernet/huawei/hinic/hinic.ko + KCONFIG:=CONFIG_HINIC + AUTOLOAD:=$(call AutoProbe,hinic) +endef + +define KernelPackage/hinic/description + Kernel module for HiNIC PCIE Ethernet cards +endef + +$(eval $(call KernelPackage,hinic)) + + define KernelPackage/sfc SUBMENU:=$(NETWORK_DEVICES_MENU) TITLE:=Solarflare SFC9000/SFC9100/EF100-family support @@ -1973,3 +2026,19 @@ define KernelPackage/amazon-ena/description endef $(eval $(call KernelPackage,amazon-ena)) + +define KernelPackage/enc28j60 + SUBMENU:=$(NETWORK_DEVICES_MENU) + TITLE:=Microchip ENC28J60 SPI Ethernet driver + KCONFIG:=\ + CONFIG_ENC28J60 \ + CONFIG_ENC28J60_WRITEVERIFY=n + FILES:=$(LINUX_DIR)/drivers/net/ethernet/microchip/enc28j60.ko + AUTOLOAD:=$(call AutoProbe,enc28j60) +endef + +define KernelPackage/enc28j60/description + Kernel module for Microchip ENC28J60 SPI Ethernet controller +endef + +$(eval $(call KernelPackage,enc28j60)) diff --git a/package/kernel/linux/modules/netfilter.mk b/package/kernel/linux/modules/netfilter.mk index cf66bd8cd8c7ee..96531b1e0803a7 100644 --- a/package/kernel/linux/modules/netfilter.mk +++ b/package/kernel/linux/modules/netfilter.mk @@ -1048,6 +1048,40 @@ endef $(eval $(call KernelPackage,nfnetlink-queue)) +define KernelPackage/nfnetlink-cthelper + TITLE:=Netfilter User space conntrack helpers + FILES:=$(LINUX_DIR)/net/netfilter/nfnetlink_cthelper.ko + KCONFIG:=CONFIG_NF_CT_NETLINK_HELPER + AUTOLOAD:=$(call AutoProbe,nfnetlink_cthelper) + $(call AddDepends/nfnetlink,+kmod-nfnetlink-queue +kmod-nf-conntrack-netlink) +endef + +define KernelPackage/nfnetlink-cthelper/description + Kernel modules support for a netlink-based connection tracking + userspace helpers interface +endef + +$(eval $(call KernelPackage,nfnetlink-cthelper)) + + +define KernelPackage/nfnetlink-cttimeout + TITLE:=Netfilter conntrack expectation timeout + FILES:=$(LINUX_DIR)/net/netfilter/nfnetlink_cttimeout.ko + KCONFIG:=CONFIG_NF_CT_NETLINK_TIMEOUT + AUTOLOAD:=$(call AutoProbe,nfnetlink_cttimeout) + $(call AddDepends/nfnetlink,+kmod-nf-conntrack @KERNEL_NF_CONNTRACK_TIMEOUT) +endef + +define KernelPackage/nfnetlink-cttimeout/description + Kernel modules support for a netlink-based connection tracking + userspace timeout interface + + Requires CONFIG_NF_CONNTRACK_TIMEOUT (only enabled for non-small flash devices) +endef + +$(eval $(call KernelPackage,nfnetlink-cttimeout)) + + define KernelPackage/nf-conntrack-netlink TITLE:=Connection tracking netlink interface FILES:=$(LINUX_DIR)/net/netfilter/nf_conntrack_netlink.ko diff --git a/package/kernel/linux/modules/netsupport.mk b/package/kernel/linux/modules/netsupport.mk index 9f349d34ee229b..06ef82328091bd 100644 --- a/package/kernel/linux/modules/netsupport.mk +++ b/package/kernel/linux/modules/netsupport.mk @@ -42,6 +42,24 @@ endef $(eval $(call KernelPackage,atmtcp)) +define KernelPackage/appletalk + SUBMENU:=$(NETWORK_SUPPORT_MENU) + TITLE:=Appletalk protocol support + KCONFIG:= \ + CONFIG_ATALK \ + CONFIG_DEV_APPLETALK \ + CONFIG_IPDDP=n + FILES:=$(LINUX_DIR)/net/appletalk/appletalk.ko + AUTOLOAD:=$(call AutoLoad,40,appletalk) +endef + +define KernelPackage/appletalk/description + Kernel module for AppleTalk protocol. +endef + +$(eval $(call KernelPackage,appletalk)) + + define KernelPackage/bonding SUBMENU:=$(NETWORK_SUPPORT_MENU) TITLE:=Ethernet bonding driver @@ -1008,7 +1026,7 @@ endef $(eval $(call KernelPackage,bpf-test)) -SCHED_MODULES_EXTRA = sch_codel sch_gred sch_multiq sch_sfq sch_teql sch_fq act_pedit act_simple act_skbmod act_csum em_cmp em_nbyte em_meta em_text +SCHED_MODULES_EXTRA = sch_codel sch_gred sch_multiq sch_sfq sch_teql sch_fq sch_ets act_pedit act_simple act_skbmod act_csum em_cmp em_nbyte em_meta em_text SCHED_FILES_EXTRA = $(foreach mod,$(SCHED_MODULES_EXTRA),$(LINUX_DIR)/net/sched/$(mod).ko) define KernelPackage/sched @@ -1022,6 +1040,7 @@ define KernelPackage/sched CONFIG_NET_SCH_SFQ \ CONFIG_NET_SCH_TEQL \ CONFIG_NET_SCH_FQ \ + CONFIG_NET_SCH_ETS \ CONFIG_NET_ACT_PEDIT \ CONFIG_NET_ACT_SIMP \ CONFIG_NET_ACT_SKBMOD \ diff --git a/package/kernel/linux/modules/other.mk b/package/kernel/linux/modules/other.mk index bbebcf37ec1adb..7b64985fd69e7d 100644 --- a/package/kernel/linux/modules/other.mk +++ b/package/kernel/linux/modules/other.mk @@ -961,6 +961,7 @@ define KernelPackage/thermal CONFIG_THERMAL=y \ CONFIG_THERMAL_OF=y \ CONFIG_CPU_THERMAL=y \ + CONFIG_DEVFREQ_THERMAL=n \ CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y \ CONFIG_THERMAL_DEFAULT_GOV_FAIR_SHARE=n \ CONFIG_THERMAL_DEFAULT_GOV_USER_SPACE=n \ diff --git a/package/kernel/linux/modules/sound.mk b/package/kernel/linux/modules/sound.mk index 623f65ac59add1..f3e44e01eee82d 100644 --- a/package/kernel/linux/modules/sound.mk +++ b/package/kernel/linux/modules/sound.mk @@ -314,6 +314,17 @@ endef $(eval $(call KernelPackage,sound-soc-spdif)) +define KernelPackage/sound-soc-dmic + TITLE:=Generic Digital Microphone CODEC + KCONFIG:=CONFIG_SND_SOC_DMIC + FILES:=$(LINUX_DIR)/sound/soc/codecs/snd-soc-dmic.ko + AUTOLOAD:=$(call AutoProbe,snd-soc-dmic) + $(call AddDepends/sound,+kmod-sound-soc-core) +endef + +$(eval $(call KernelPackage,sound-soc-dmic)) + + define KernelPackage/pcspkr DEPENDS:=@TARGET_x86 +kmod-input-core TITLE:=PC speaker support diff --git a/package/kernel/linux/modules/spi.mk b/package/kernel/linux/modules/spi.mk index 78a1c8a03283b2..5e8ab03b1800c0 100644 --- a/package/kernel/linux/modules/spi.mk +++ b/package/kernel/linux/modules/spi.mk @@ -73,3 +73,41 @@ define KernelPackage/spi-dev/description endef $(eval $(call KernelPackage,spi-dev)) + + +define KernelPackage/spi-dw + SUBMENU:=$(SPI_MENU) + TITLE:=DesignWare SPI controller driver (core) + KCONFIG:=\ + CONFIG_SPI=y \ + CONFIG_SPI_DESIGNWARE \ + CONFIG_SPI_DYNAMIC=y \ + CONFIG_SPI_MASTER=y + FILES:=\ + $(LINUX_DIR)/drivers/spi/spi-dw.ko + AUTOLOAD:=$(call AutoProbe,spi-dw) +endef + +define KernelPackage/spi-dw/description + This package contains the DesignWare SPI core driver. +endef + +$(eval $(call KernelPackage,spi-dw)) + + +define KernelPackage/spi-dw-mmio + SUBMENU:=$(SPI_MENU) + TITLE:=DesignWare SPI controller driver (MMIO) + DEPENDS:=+kmod-spi-dw + KCONFIG:=\ + CONFIG_SPI_DW_MMIO + FILES:=\ + $(LINUX_DIR)/drivers/spi/spi-dw-mmio.ko + AUTOLOAD:=$(call AutoProbe,spi-dw-mmio) +endef + +define KernelPackage/spi-dw-mmio/description + This package contains the DesignWare SPI MMIO driver. +endef + +$(eval $(call KernelPackage,spi-dw-mmio)) diff --git a/package/kernel/linux/modules/usb.mk b/package/kernel/linux/modules/usb.mk index 458c8c4ba68f86..481d2be59a201e 100644 --- a/package/kernel/linux/modules/usb.mk +++ b/package/kernel/linux/modules/usb.mk @@ -519,6 +519,23 @@ endef $(eval $(call KernelPackage,usb-dwc3)) +define KernelPackage/usb-dwc3-octeon + TITLE:=DWC3 Cavium Octeon USB driver + DEPENDS:=@TARGET_octeon +kmod-usb-dwc3 + KCONFIG:= CONFIG_USB_DWC3_OCTEON + FILES:= $(LINUX_DIR)/drivers/usb/dwc3/dwc3-octeon.ko + AUTOLOAD:=$(call AutoProbe,dwc3-octeon,1) + $(call AddDepends/usb) +endef + +define KernelPackage/usb-dwc3-octeon/description + This driver adds support for Cavium Octeon platforms with DesignWare + Core USB3 IP. +endef + +$(eval $(call KernelPackage,usb-dwc3-octeon)) + + define KernelPackage/usb-dwc3-qcom TITLE:=DWC3 Qualcomm USB driver DEPENDS:=@(TARGET_ipq40xx||TARGET_ipq806x||TARGET_qualcommax) +kmod-usb-dwc3 @@ -576,6 +593,7 @@ define KernelPackage/usb-audio CONFIG_SND_USB_AUDIO $(call AddDepends/usb) $(call AddDepends/sound) + DEPENDS+=+kmod-media-controller FILES:= \ $(LINUX_DIR)/sound/usb/snd-usbmidi-lib.ko \ $(LINUX_DIR)/sound/usb/snd-usb-audio.ko @@ -1719,7 +1737,7 @@ $(eval $(call KernelPackage,usbip-server)) define KernelPackage/usb-chipidea TITLE:=Host and device support for Chipidea controllers - DEPENDS:=+USB_GADGET_SUPPORT:kmod-usb-gadget @TARGET_ath79 +kmod-usb-ehci +kmod-usb-phy-nop +kmod-usb-roles + DEPENDS:=+USB_GADGET_SUPPORT:kmod-usb-gadget @TARGET_ath79 +kmod-usb-ehci +kmod-usb-phy-nop +kmod-usb-roles +kmod-phy-ath79-usb KCONFIG:= \ CONFIG_EXTCON \ CONFIG_USB_CHIPIDEA \ diff --git a/package/kernel/linux/modules/video.mk b/package/kernel/linux/modules/video.mk index 52fc55bbadd07b..9bb030bf57fd0d 100644 --- a/package/kernel/linux/modules/video.mk +++ b/package/kernel/linux/modules/video.mk @@ -12,6 +12,28 @@ V4L2_DIR=v4l2-core V4L2_USB_DIR=usb V4L2_MEM2MEM_DIR=platform +# +# Media +# +define KernelPackage/media-controller + SUBMENU:=$(VIDEO_MENU) + TITLE:=Media Controller API + KCONFIG:= \ + CONFIG_MEDIA_SUPPORT \ + CONFIG_MEDIA_CONTROLLER=y + FILES:= \ + $(LINUX_DIR)/drivers/media/mc/mc.ko + AUTOLOAD:=$(call AutoProbe,mc) +endef + +define KernelPackage/media-controller/description + Kernel modules for media controller API used to query media devices + internal topology and configure it dynamically. +endef + +$(eval $(call KernelPackage,media-controller)) + + # # Video Display # @@ -311,6 +333,38 @@ endef $(eval $(call KernelPackage,drm-exec)) +define KernelPackage/drm-dma-helper + SUBMENU:=$(VIDEO_MENU) + HIDDEN:=1 + TITLE:=GEM DMA helper functions + DEPENDS:=@DISPLAY_SUPPORT +kmod-drm-kms-helper + KCONFIG:=CONFIG_DRM_GEM_DMA_HELPER + FILES:=$(LINUX_DIR)/drivers/gpu/drm/drm_dma_helper.ko + AUTOLOAD:=$(call AutoProbe,drm_dma_helper) +endef + +define KernelPackage/drm-dma-helper/description + GEM DMA helper functions. +endef + +$(eval $(call KernelPackage,drm-dma-helper)) + +define KernelPackage/drm-mipi-dbi + SUBMENU:=$(VIDEO_MENU) + HIDDEN:=1 + TITLE:=MIPI DBI helpers + DEPENDS:=@DISPLAY_SUPPORT +kmod-backlight +kmod-drm-kms-helper + KCONFIG:=CONFIG_DRM_MIPI_DBI + FILES:=$(LINUX_DIR)/drivers/gpu/drm/drm_mipi_dbi.ko + AUTOLOAD:=$(call AutoProbe,drm_mipi_dbi) +endef + +define KernelPackage/drm-mipi-dbi/description + MIPI Display Bus Interface (DBI) LCD controller support. +endef + +$(eval $(call KernelPackage,drm-mipi-dbi)) + define KernelPackage/drm-ttm SUBMENU:=$(VIDEO_MENU) TITLE:=GPU memory management subsystem @@ -406,6 +460,49 @@ endef $(eval $(call KernelPackage,drm-amdgpu)) +define KernelPackage/drm-i915 + SUBMENU:=$(VIDEO_MENU) + TITLE:=Intel i915 DRM support + DEPENDS:=@(TARGET_x86_64||TARGET_x86_generic||TARGET_x86_legacy) \ + @DISPLAY_SUPPORT +kmod-backlight +kmod-drm-ttm \ + +kmod-drm-ttm-helper +kmod-drm-kms-helper +kmod-i2c-algo-bit +i915-firmware-dmc \ + +kmod-drm-display-helper +kmod-drm-buddy +kmod-acpi-video \ + +kmod-drm-exec +kmod-drm-suballoc-helper + KCONFIG:=CONFIG_DRM_I915 \ + CONFIG_DRM_I915_CAPTURE_ERROR=y \ + CONFIG_DRM_I915_COMPRESS_ERROR=y \ + CONFIG_DRM_I915_DEBUG=n \ + CONFIG_DRM_I915_DEBUG_GUC=n \ + CONFIG_DRM_I915_DEBUG_MMIO=n \ + CONFIG_DRM_I915_DEBUG_RUNTIME_PM=n \ + CONFIG_DRM_I915_DEBUG_VBLANK_EVADE=n \ + CONFIG_DRM_I915_FENCE_TIMEOUT=10000 \ + CONFIG_DRM_I915_FORCE_PROBE="" \ + CONFIG_DRM_I915_HEARTBEAT_INTERVAL=2500 \ + CONFIG_DRM_I915_LOW_LEVEL_TRACEPOINTS=n \ + CONFIG_DRM_I915_MAX_REQUEST_BUSYWAIT=8000 \ + CONFIG_DRM_I915_PREEMPT_TIMEOUT=640 \ + CONFIG_DRM_I915_PREEMPT_TIMEOUT_COMPUTE=7500 \ + CONFIG_DRM_I915_REQUEST_TIMEOUT=20000 \ + CONFIG_DRM_I915_SELFTEST=n \ + CONFIG_DRM_I915_STOP_TIMEOUT=100 \ + CONFIG_DRM_I915_SW_FENCE_CHECK_DAG=n \ + CONFIG_DRM_I915_SW_FENCE_DEBUG_OBJECTS=n \ + CONFIG_DRM_I915_TIMESLICE_DURATION=1 \ + CONFIG_DRM_I915_USERFAULT_AUTOSUSPEND=250 \ + CONFIG_DRM_I915_USERPTR=y \ + CONFIG_DRM_I915_WERROR=n \ + CONFIG_FB_INTEL=n + FILES:=$(LINUX_DIR)/drivers/gpu/drm/i915/i915.ko + AUTOLOAD:=$(call AutoProbe,i915) +endef + +define KernelPackage/drm-i915/description + Direct Rendering Manager (DRM) support for Intel GPU +endef + +$(eval $(call KernelPackage,drm-i915)) + define KernelPackage/drm-imx SUBMENU:=$(VIDEO_MENU) @@ -484,6 +581,24 @@ endef $(eval $(call KernelPackage,drm-imx-ldb)) +define KernelPackage/drm-panel-mipi-dbi + SUBMENU:=$(VIDEO_MENU) + TITLE:=Generic MIPI DBI LCD panel + DEPENDS:=+kmod-drm-mipi-dbi +kmod-drm-dma-helper + KCONFIG:=CONFIG_DRM_PANEL_MIPI_DBI \ + CONFIG_DRM_FBDEV_EMULATION=y \ + CONFIG_DRM_FBDEV_OVERALLOC=100 + FILES:= \ + $(LINUX_DIR)/drivers/gpu/drm/tiny/panel-mipi-dbi.ko + AUTOLOAD:=$(call AutoProbe,panel-mipi-dbi) +endef + +define KernelPackage/drm-panel-mipi-dbi/description + Generic driver for MIPI Alliance Display Bus Interface +endef + +$(eval $(call KernelPackage,drm-panel-mipi-dbi)) + define KernelPackage/drm-radeon SUBMENU:=$(VIDEO_MENU) TITLE:=Radeon DRM support @@ -508,9 +623,8 @@ $(eval $(call KernelPackage,drm-radeon)) define KernelPackage/video-core SUBMENU:=$(VIDEO_MENU) TITLE=Video4Linux support - DEPENDS:=+PACKAGE_kmod-i2c-core:kmod-i2c-core + DEPENDS:=+PACKAGE_kmod-i2c-core:kmod-i2c-core +kmod-media-controller KCONFIG:= \ - CONFIG_MEDIA_SUPPORT \ CONFIG_MEDIA_CAMERA_SUPPORT=y \ CONFIG_VIDEO_DEV \ CONFIG_V4L_PLATFORM_DRIVERS=y \ @@ -566,6 +680,25 @@ endef $(eval $(call KernelPackage,video-videobuf2)) +define KernelPackage/video-async + TITLE:=V4L2 ASYNC support + KCONFIG:=CONFIG_V4L2_ASYNC + FILES:=$(LINUX_DIR)/drivers/media/$(V4L2_DIR)/v4l2-async.ko + $(call AddDepends/video) + AUTOLOAD:=$(call AutoProbe,v4l2-async) +endef + +$(eval $(call KernelPackage,video-async)) + +define KernelPackage/video-fwnode + TITLE:=V4L2 FWNODE support + KCONFIG:=CONFIG_V4L2_FWNODE + FILES:=$(LINUX_DIR)/drivers/media/$(V4L2_DIR)/v4l2-fwnode.ko + $(call AddDepends/video,+kmod-video-async) + AUTOLOAD:=$(call AutoProbe,v4l2-fwnode) +endef + +$(eval $(call KernelPackage,video-fwnode)) define KernelPackage/video-cpia2 TITLE:=CPIA2 video driver diff --git a/package/kernel/mac80211/Makefile b/package/kernel/mac80211/Makefile index 22cd0e97b41770..c93f177aecf86d 100644 --- a/package/kernel/mac80211/Makefile +++ b/package/kernel/mac80211/Makefile @@ -10,13 +10,13 @@ include $(INCLUDE_DIR)/kernel.mk PKG_NAME:=mac80211 -PKG_VERSION:=6.11.2 -PKG_RELEASE:=1 +PKG_VERSION:=6.12.44 +PKG_RELEASE:=2 PKG_LICENSE:=GPL-2.0-only PKG_LICENSE_FILES:=COPYING PKG_SOURCE_URL:=http://mirror2.openwrt.org/sources/ -PKG_HASH:=700ea5abef8dde9e3c6df2acd32ff443da735d773d56db9a80269e2237549b34 +PKG_HASH:=85a9f92ddba3bf2970a089e7af576c1135217c387205f4481ea9131c0c45c509 PKG_SOURCE:=backports-$(PKG_VERSION).tar.xz PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/$(if $(BUILD_VARIANT),$(PKG_NAME)-$(BUILD_VARIANT)/)backports-$(PKG_VERSION) diff --git a/package/kernel/mac80211/broadcom.mk b/package/kernel/mac80211/broadcom.mk index a6f42cd19af21b..444d705ab31bfc 100644 --- a/package/kernel/mac80211/broadcom.mk +++ b/package/kernel/mac80211/broadcom.mk @@ -437,6 +437,7 @@ define KernelPackage/brcmfmac/config default y if TARGET_starfive default y if TARGET_rockchip default y if TARGET_sunxi + default y if TARGET_stm32 default n help Enable support for cards attached to an SDIO bus. diff --git a/package/kernel/mac80211/patches/ath/404-regd_no_assoc_hints.patch b/package/kernel/mac80211/patches/ath/404-regd_no_assoc_hints.patch index 895e2ff8d8de6a..8c3d8108aa7447 100644 --- a/package/kernel/mac80211/patches/ath/404-regd_no_assoc_hints.patch +++ b/package/kernel/mac80211/patches/ath/404-regd_no_assoc_hints.patch @@ -1,6 +1,6 @@ --- a/net/wireless/reg.c +++ b/net/wireless/reg.c -@@ -3364,6 +3364,8 @@ void regulatory_hint_country_ie(struct w +@@ -3367,6 +3367,8 @@ void regulatory_hint_country_ie(struct w enum environment_cap env = ENVIRON_ANY; struct regulatory_request *request = NULL, *lr; @@ -9,7 +9,7 @@ /* IE len must be evenly divisible by 2 */ if (country_ie_len & 0x01) return; -@@ -3615,6 +3617,7 @@ static bool is_wiphy_all_set_reg_flag(en +@@ -3618,6 +3620,7 @@ static bool is_wiphy_all_set_reg_flag(en void regulatory_hint_disconnect(void) { diff --git a/package/kernel/mac80211/patches/ath/431-add_platform_eeprom_support_to_ath5k.patch b/package/kernel/mac80211/patches/ath/431-add_platform_eeprom_support_to_ath5k.patch index c762aa6d643fc6..abadadf856c731 100644 --- a/package/kernel/mac80211/patches/ath/431-add_platform_eeprom_support_to_ath5k.patch +++ b/package/kernel/mac80211/patches/ath/431-add_platform_eeprom_support_to_ath5k.patch @@ -8,7 +8,7 @@ #include "../ath.h" #include "ath5k.h" #include "debug.h" -@@ -71,7 +72,7 @@ static void ath5k_pci_read_cachesize(str +@@ -73,7 +74,7 @@ static void ath5k_pci_read_cachesize(str } /* @@ -17,7 +17,7 @@ */ static bool ath5k_pci_eeprom_read(struct ath_common *common, u32 offset, u16 *data) -@@ -79,6 +80,19 @@ ath5k_pci_eeprom_read(struct ath_common +@@ -81,6 +82,19 @@ ath5k_pci_eeprom_read(struct ath_common struct ath5k_hw *ah = common->ah; u32 status, timeout; @@ -37,7 +37,7 @@ /* * Initialize EEPROM access */ -@@ -122,6 +136,16 @@ static int ath5k_pci_eeprom_read_mac(str +@@ -124,6 +138,16 @@ static int ath5k_pci_eeprom_read_mac(str u16 data; int octet; diff --git a/package/kernel/mac80211/patches/ath10k/921-ath10k_init_devices_synchronously.patch b/package/kernel/mac80211/patches/ath10k/921-ath10k_init_devices_synchronously.patch index a7e11679a3196d..df0a0a028e7fe8 100644 --- a/package/kernel/mac80211/patches/ath10k/921-ath10k_init_devices_synchronously.patch +++ b/package/kernel/mac80211/patches/ath10k/921-ath10k_init_devices_synchronously.patch @@ -14,7 +14,7 @@ Signed-off-by: Sven Eckelmann --- a/drivers/net/wireless/ath/ath10k/core.c +++ b/drivers/net/wireless/ath/ath10k/core.c -@@ -3539,6 +3539,16 @@ int ath10k_core_register(struct ath10k * +@@ -3577,6 +3577,16 @@ int ath10k_core_register(struct ath10k * queue_work(ar->workqueue, &ar->register_work); diff --git a/package/kernel/mac80211/patches/ath10k/930-ath10k_add_tpt_led_trigger.patch b/package/kernel/mac80211/patches/ath10k/930-ath10k_add_tpt_led_trigger.patch index b13bc3349820a5..c71123a8fee74b 100644 --- a/package/kernel/mac80211/patches/ath10k/930-ath10k_add_tpt_led_trigger.patch +++ b/package/kernel/mac80211/patches/ath10k/930-ath10k_add_tpt_led_trigger.patch @@ -1,6 +1,6 @@ --- a/drivers/net/wireless/ath/ath10k/mac.c +++ b/drivers/net/wireless/ath/ath10k/mac.c -@@ -9919,6 +9919,21 @@ static int ath10k_mac_init_rd(struct ath +@@ -9924,6 +9924,21 @@ static int ath10k_mac_init_rd(struct ath return 0; } @@ -22,7 +22,7 @@ int ath10k_mac_register(struct ath10k *ar) { static const u32 cipher_suites[] = { -@@ -10281,6 +10296,12 @@ int ath10k_mac_register(struct ath10k *a +@@ -10286,6 +10301,12 @@ int ath10k_mac_register(struct ath10k *a ar->hw->weight_multiplier = ATH10K_AIRTIME_WEIGHT_MULTIPLIER; diff --git a/package/kernel/mac80211/patches/ath10k/975-ath10k-use-tpt-trigger-by-default.patch b/package/kernel/mac80211/patches/ath10k/975-ath10k-use-tpt-trigger-by-default.patch index fc41f5f151163b..be2ccfd0bf799c 100644 --- a/package/kernel/mac80211/patches/ath10k/975-ath10k-use-tpt-trigger-by-default.patch +++ b/package/kernel/mac80211/patches/ath10k/975-ath10k-use-tpt-trigger-by-default.patch @@ -16,7 +16,7 @@ Signed-off-by: Mathias Kresin --- a/drivers/net/wireless/ath/ath10k/core.h +++ b/drivers/net/wireless/ath/ath10k/core.h -@@ -1315,6 +1315,10 @@ struct ath10k { +@@ -1320,6 +1320,10 @@ struct ath10k { s32 tx_power_2g_limit; s32 tx_power_5g_limit; @@ -40,7 +40,7 @@ Signed-off-by: Mathias Kresin if (ret) --- a/drivers/net/wireless/ath/ath10k/mac.c +++ b/drivers/net/wireless/ath/ath10k/mac.c -@@ -10297,7 +10297,7 @@ int ath10k_mac_register(struct ath10k *a +@@ -10302,7 +10302,7 @@ int ath10k_mac_register(struct ath10k *a ar->hw->weight_multiplier = ATH10K_AIRTIME_WEIGHT_MULTIPLIER; #ifdef CPTCFG_MAC80211_LEDS diff --git a/package/kernel/mac80211/patches/ath10k/984-ath10k-Try-to-get-mac-address-from-dts.patch b/package/kernel/mac80211/patches/ath10k/984-ath10k-Try-to-get-mac-address-from-dts.patch index beec6a95eafe74..b62e3c09a0da5f 100644 --- a/package/kernel/mac80211/patches/ath10k/984-ath10k-Try-to-get-mac-address-from-dts.patch +++ b/package/kernel/mac80211/patches/ath10k/984-ath10k-Try-to-get-mac-address-from-dts.patch @@ -26,7 +26,7 @@ Signed-off-by: Ansuel Smith #include #include #include -@@ -3411,6 +3412,8 @@ static int ath10k_core_probe_fw(struct a +@@ -3449,6 +3450,8 @@ static int ath10k_core_probe_fw(struct a device_get_mac_address(ar->dev, ar->mac_addr); diff --git a/package/kernel/mac80211/patches/ath10k/988-ath10k-always-use-mac80211-loss-detection.patch b/package/kernel/mac80211/patches/ath10k/988-ath10k-always-use-mac80211-loss-detection.patch index b9cdae7e1f9303..f7387595a95078 100644 --- a/package/kernel/mac80211/patches/ath10k/988-ath10k-always-use-mac80211-loss-detection.patch +++ b/package/kernel/mac80211/patches/ath10k/988-ath10k-always-use-mac80211-loss-detection.patch @@ -18,7 +18,7 @@ Signed-off-by: David Bauer --- a/drivers/net/wireless/ath/ath10k/mac.c +++ b/drivers/net/wireless/ath/ath10k/mac.c -@@ -10089,7 +10089,6 @@ int ath10k_mac_register(struct ath10k *a +@@ -10094,7 +10094,6 @@ int ath10k_mac_register(struct ath10k *a ieee80211_hw_set(ar->hw, CHANCTX_STA_CSA); ieee80211_hw_set(ar->hw, QUEUE_CONTROL); ieee80211_hw_set(ar->hw, SUPPORTS_TX_FRAG); diff --git a/package/kernel/mac80211/patches/ath11k/903-ath11k-support-setting-FW-memory-mode-via-DT.patch b/package/kernel/mac80211/patches/ath11k/903-ath11k-support-setting-FW-memory-mode-via-DT.patch index 1250147e2bda61..e747738b818fd9 100644 --- a/package/kernel/mac80211/patches/ath11k/903-ath11k-support-setting-FW-memory-mode-via-DT.patch +++ b/package/kernel/mac80211/patches/ath11k/903-ath11k-support-setting-FW-memory-mode-via-DT.patch @@ -31,7 +31,7 @@ Signed-off-by: Robert Marko { .hw_rev = ATH11K_HW_IPQ8074, .name = "ipq8074 hw2.0", -@@ -2147,7 +2147,8 @@ static void ath11k_core_reset(struct wor +@@ -2200,7 +2200,8 @@ static void ath11k_core_reset(struct wor static int ath11k_init_hw_params(struct ath11k_base *ab) { const struct ath11k_hw_params *hw_params = NULL; @@ -41,7 +41,7 @@ Signed-off-by: Robert Marko for (i = 0; i < ARRAY_SIZE(ath11k_hw_params); i++) { hw_params = &ath11k_hw_params[i]; -@@ -2163,7 +2164,31 @@ static int ath11k_init_hw_params(struct +@@ -2216,7 +2217,31 @@ static int ath11k_init_hw_params(struct ab->hw_params = *hw_params; diff --git a/package/kernel/mac80211/patches/ath11k/940-ath11k-Revert-clear-the-keys-properly-when-DISABLE_K.patch b/package/kernel/mac80211/patches/ath11k/940-ath11k-Revert-clear-the-keys-properly-when-DISABLE_K.patch new file mode 100644 index 00000000000000..ec2dc222b66053 --- /dev/null +++ b/package/kernel/mac80211/patches/ath11k/940-ath11k-Revert-clear-the-keys-properly-when-DISABLE_K.patch @@ -0,0 +1,48 @@ +From 52393e2ae12f18fb1a60578c24c46ebab292ddb6 Mon Sep 17 00:00:00 2001 +From: Rameshkumar Sundaram +Date: Mon, 28 Mar 2022 13:21:04 +0530 +Subject: [PATCH] ath11k: Revert: clear the keys properly when DISABLE_KEY +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Reverting the Upstream clear key change added as a part of +436a4e886598 ("ath11k: clear the keys properly +when DISABLE_KEY") +This change exposed a race in WLAN Firmware where target asserts +are seen frequently due FW not synchronizing ath11k host’s clear +key commands(CIPHER changes to NONE) with frames in TX queue. +Hence reverting this change untill FW fixes to synchronize +ath11k host’s clear key command are available. + +Signed-off-by: Rameshkumar Sundaram +--- + drivers/net/wireless/ath/ath11k/mac.c | 4 +++- + drivers/net/wireless/ath/ath11k/wmi.c | 3 +-- + 2 files changed, 4 insertions(+), 3 deletions(-) + +--- a/drivers/net/wireless/ath/ath11k/mac.c ++++ b/drivers/net/wireless/ath/ath11k/mac.c +@@ -4222,7 +4222,9 @@ static int ath11k_install_key(struct ath + return 0; + + if (cmd == DISABLE_KEY) { +- arg.key_cipher = WMI_CIPHER_NONE; ++ /* TODO: Check if FW expects value other than NONE for del */ ++ /* arg.key_cipher = WMI_CIPHER_NONE; */ ++ arg.key_len = 0; + arg.key_data = NULL; + goto install; + } +--- a/drivers/net/wireless/ath/ath11k/wmi.c ++++ b/drivers/net/wireless/ath/ath11k/wmi.c +@@ -1854,8 +1854,7 @@ int ath11k_wmi_vdev_install_key(struct a + tlv = (struct wmi_tlv *)(skb->data + sizeof(*cmd)); + tlv->header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_ARRAY_BYTE) | + FIELD_PREP(WMI_TLV_LEN, key_len_aligned); +- if (arg->key_data) +- memcpy(tlv->value, (u8 *)arg->key_data, key_len_aligned); ++ memcpy(tlv->value, (u8 *)arg->key_data, key_len_aligned); + + ret = ath11k_wmi_cmd_send(wmi, skb, WMI_VDEV_INSTALL_KEY_CMDID); + if (ret) { diff --git a/package/kernel/mac80211/patches/ath12k/001-wifi-ath12k-add-11d-scan-offload-support-and-handle-country-code-for-WCN7850.patch b/package/kernel/mac80211/patches/ath12k/001-wifi-ath12k-add-11d-scan-offload-support-and-handle-country-code-for-WCN7850.patch index d370db104713a0..b265fcdeab1288 100644 --- a/package/kernel/mac80211/patches/ath12k/001-wifi-ath12k-add-11d-scan-offload-support-and-handle-country-code-for-WCN7850.patch +++ b/package/kernel/mac80211/patches/ath12k/001-wifi-ath12k-add-11d-scan-offload-support-and-handle-country-code-for-WCN7850.patch @@ -121,7 +121,7 @@ Acked-by: Jeff Johnson }; static __le32 ath12k_wmi_tlv_hdr(u32 cmd, u32 len) -@@ -2363,7 +2365,10 @@ int ath12k_wmi_send_scan_start_cmd(struc +@@ -2374,7 +2376,10 @@ int ath12k_wmi_send_scan_start_cmd(struc cmd->scan_id = cpu_to_le32(arg->scan_id); cmd->scan_req_id = cpu_to_le32(arg->scan_req_id); cmd->vdev_id = cpu_to_le32(arg->vdev_id); @@ -133,7 +133,7 @@ Acked-by: Jeff Johnson cmd->notify_scan_events = cpu_to_le32(arg->notify_scan_events); ath12k_wmi_copy_scan_event_cntrl_flags(cmd, arg); -@@ -3083,6 +3088,110 @@ out: +@@ -3094,6 +3099,110 @@ out: return ret; } @@ -244,7 +244,7 @@ Acked-by: Jeff Johnson int ath12k_wmi_send_twt_enable_cmd(struct ath12k *ar, u32 pdev_id) { -@@ -5668,6 +5777,50 @@ static void ath12k_wmi_op_ep_tx_credits( +@@ -5714,6 +5823,50 @@ static void ath12k_wmi_op_ep_tx_credits( wake_up(&ab->wmi_ab.tx_credits_wq); } @@ -295,7 +295,7 @@ Acked-by: Jeff Johnson static void ath12k_wmi_htc_tx_complete(struct ath12k_base *ab, struct sk_buff *skb) { -@@ -7269,6 +7422,9 @@ static void ath12k_wmi_op_rx(struct ath1 +@@ -7317,6 +7470,9 @@ static void ath12k_wmi_op_rx(struct ath1 case WMI_GTK_OFFLOAD_STATUS_EVENTID: ath12k_wmi_gtk_offload_status_event(ab, skb); break; @@ -307,7 +307,7 @@ Acked-by: Jeff Johnson ath12k_dbg(ab, ATH12K_DBG_WMI, "Unknown eventid: 0x%x\n", id); --- a/drivers/net/wireless/ath/ath12k/wmi.h +++ b/drivers/net/wireless/ath/ath12k/wmi.h -@@ -3859,6 +3859,28 @@ struct wmi_init_country_cmd { +@@ -3860,6 +3860,28 @@ struct wmi_init_country_cmd { } cc_info; } __packed; @@ -337,8 +337,8 @@ Acked-by: Jeff Johnson __le32 tlv_header; __le32 vdev_id; @@ -3944,6 +3966,16 @@ struct ath12k_wmi_eht_rate_set_params { + #define REG_ALPHA2_LEN 2 #define MAX_6G_REG_RULES 5 - #define REG_US_5G_NUM_REG_RULES 4 +struct wmi_set_current_country_arg { + u8 alpha2[REG_ALPHA2_LEN]; @@ -373,7 +373,7 @@ Acked-by: Jeff Johnson struct ath12k_wmi_rx_reorder_queue_remove_arg *arg); --- a/drivers/net/wireless/ath/ath12k/core.c +++ b/drivers/net/wireless/ath/ath12k/core.c -@@ -1014,6 +1014,7 @@ void ath12k_core_halt(struct ath12k *ar) +@@ -1017,6 +1017,7 @@ void ath12k_core_halt(struct ath12k *ar) cancel_delayed_work_sync(&ar->scan.timeout); cancel_work_sync(&ar->regd_update_work); cancel_work_sync(&ab->rfkill_work); @@ -381,7 +381,7 @@ Acked-by: Jeff Johnson rcu_assign_pointer(ab->pdevs_active[ar->pdev_idx], NULL); synchronize_rcu(); -@@ -1021,6 +1022,34 @@ void ath12k_core_halt(struct ath12k *ar) +@@ -1029,6 +1030,34 @@ void ath12k_core_halt(struct ath12k *ar) idr_init(&ar->txmgmt_idr); } @@ -416,7 +416,7 @@ Acked-by: Jeff Johnson static void ath12k_core_pre_reconfigure_recovery(struct ath12k_base *ab) { struct ath12k *ar; -@@ -1045,8 +1074,10 @@ static void ath12k_core_pre_reconfigure_ +@@ -1053,8 +1082,10 @@ static void ath12k_core_pre_reconfigure_ ar = &ah->radio[j]; ath12k_mac_drain_tx(ar); @@ -428,7 +428,7 @@ Acked-by: Jeff Johnson complete(&ar->scan.on_channel); complete(&ar->peer_assoc_done); complete(&ar->peer_delete_done); -@@ -1312,6 +1343,7 @@ struct ath12k_base *ath12k_core_alloc(st +@@ -1320,6 +1351,7 @@ struct ath12k_base *ath12k_core_alloc(st INIT_WORK(&ab->restart_work, ath12k_core_restart); INIT_WORK(&ab->reset_work, ath12k_core_reset); INIT_WORK(&ab->rfkill_work, ath12k_rfkill_work); @@ -438,7 +438,7 @@ Acked-by: Jeff Johnson init_completion(&ab->htc_suspend); --- a/drivers/net/wireless/ath/ath12k/core.h +++ b/drivers/net/wireless/ath/ath12k/core.h -@@ -199,6 +199,12 @@ enum ath12k_scan_state { +@@ -200,6 +200,12 @@ enum ath12k_scan_state { ATH12K_SCAN_ABORTING, }; @@ -451,7 +451,7 @@ Acked-by: Jeff Johnson enum ath12k_dev_flags { ATH12K_CAC_RUNNING, ATH12K_FLAG_CRASH_FLUSH, -@@ -313,6 +319,8 @@ struct ath12k_vif_iter { +@@ -320,6 +326,8 @@ struct ath12k_vif_iter { #define ATH12K_RX_RATE_TABLE_11AX_NUM 576 #define ATH12K_RX_RATE_TABLE_NUM 320 @@ -460,7 +460,7 @@ Acked-by: Jeff Johnson struct ath12k_rx_peer_rate_stats { u64 ht_mcs_count[HAL_RX_MAX_MCS_HT + 1]; u64 vht_mcs_count[HAL_RX_MAX_MCS_VHT + 1]; -@@ -648,6 +656,13 @@ struct ath12k { +@@ -655,6 +663,13 @@ struct ath12k { u32 freq_low; u32 freq_high; @@ -474,7 +474,7 @@ Acked-by: Jeff Johnson bool nlo_enabled; }; -@@ -880,6 +895,8 @@ struct ath12k_base { +@@ -887,6 +902,8 @@ struct ath12k_base { /* continuous recovery fail count */ atomic_t fail_cont_count; unsigned long reset_fail_timeout; @@ -485,7 +485,7 @@ Acked-by: Jeff Johnson u32 fw_crash_counter; --- a/drivers/net/wireless/ath/ath12k/mac.c +++ b/drivers/net/wireless/ath/ath12k/mac.c -@@ -2947,6 +2947,11 @@ static void ath12k_bss_assoc(struct ath1 +@@ -2949,6 +2949,11 @@ static void ath12k_bss_assoc(struct ath1 if (ret) ath12k_warn(ar->ab, "failed to set vdev %i OBSS PD parameters: %d\n", arvif->vdev_id, ret); @@ -497,7 +497,7 @@ Acked-by: Jeff Johnson } static void ath12k_bss_disassoc(struct ath12k *ar, -@@ -3522,7 +3527,7 @@ void __ath12k_mac_scan_finish(struct ath +@@ -3524,7 +3529,7 @@ void __ath12k_mac_scan_finish(struct ath ar->scan_channel = NULL; ar->scan.roc_freq = 0; cancel_delayed_work(&ar->scan.timeout); @@ -506,9 +506,9 @@ Acked-by: Jeff Johnson break; } } -@@ -3783,7 +3788,12 @@ scan: +@@ -3790,7 +3795,12 @@ scan: - ret = ath12k_start_scan(ar, &arg); + ret = ath12k_start_scan(ar, arg); if (ret) { - ath12k_warn(ar->ab, "failed to start hw scan: %d\n", ret); + if (ret == -EBUSY) @@ -520,7 +520,7 @@ Acked-by: Jeff Johnson spin_lock_bh(&ar->data_lock); ar->scan.state = ATH12K_SCAN_IDLE; spin_unlock_bh(&ar->data_lock); -@@ -3802,6 +3812,11 @@ exit: +@@ -3810,6 +3820,11 @@ exit: mutex_unlock(&ar->conf_mutex); @@ -532,7 +532,7 @@ Acked-by: Jeff Johnson return ret; } -@@ -5986,7 +6001,7 @@ static int ath12k_mac_start(struct ath12 +@@ -5998,7 +6013,7 @@ static int ath12k_mac_start(struct ath12 /* TODO: Do we need to enable ANI? */ @@ -541,7 +541,7 @@ Acked-by: Jeff Johnson ar->num_started_vdevs = 0; ar->num_created_vdevs = 0; -@@ -6166,6 +6181,9 @@ static void ath12k_mac_stop(struct ath12 +@@ -6178,6 +6193,9 @@ static void ath12k_mac_stop(struct ath12 cancel_delayed_work_sync(&ar->scan.timeout); cancel_work_sync(&ar->regd_update_work); cancel_work_sync(&ar->ab->rfkill_work); @@ -551,7 +551,7 @@ Acked-by: Jeff Johnson spin_lock_bh(&ar->data_lock); list_for_each_entry_safe(ppdu_stats, tmp, &ar->ppdu_stats_info, list) { -@@ -6412,6 +6430,117 @@ static void ath12k_mac_op_update_vif_off +@@ -6424,6 +6442,117 @@ static void ath12k_mac_op_update_vif_off ath12k_mac_update_vif_offload(arvif); } @@ -669,7 +669,7 @@ Acked-by: Jeff Johnson static int ath12k_mac_vdev_create(struct ath12k *ar, struct ieee80211_vif *vif) { struct ath12k_hw *ah = ar->ah; -@@ -6526,6 +6655,7 @@ static int ath12k_mac_vdev_create(struct +@@ -6538,6 +6667,7 @@ static int ath12k_mac_vdev_create(struct arvif->vdev_id, ret); goto err_peer_del; } @@ -677,7 +677,7 @@ Acked-by: Jeff Johnson break; case WMI_VDEV_TYPE_STA: param_id = WMI_STA_PS_PARAM_RX_WAKE_POLICY; -@@ -6564,6 +6694,13 @@ static int ath12k_mac_vdev_create(struct +@@ -6576,6 +6706,13 @@ static int ath12k_mac_vdev_create(struct arvif->vdev_id, ret); goto err_peer_del; } @@ -691,7 +691,7 @@ Acked-by: Jeff Johnson break; default: break; -@@ -6904,6 +7041,11 @@ static void ath12k_mac_op_remove_interfa +@@ -6916,6 +7053,11 @@ static void ath12k_mac_op_remove_interfa ath12k_dbg(ab, ATH12K_DBG_MAC, "mac remove interface (vdev %d)\n", arvif->vdev_id); @@ -703,7 +703,7 @@ Acked-by: Jeff Johnson if (arvif->vdev_type == WMI_VDEV_TYPE_AP) { ret = ath12k_peer_delete(ar, arvif->vdev_id, vif->addr); if (ret) -@@ -7744,6 +7886,14 @@ ath12k_mac_op_unassign_vif_chanctx(struc +@@ -7756,6 +7898,14 @@ ath12k_mac_op_unassign_vif_chanctx(struc ar->num_started_vdevs == 1 && ar->monitor_vdev_created) ath12k_mac_monitor_stop(ar); @@ -718,7 +718,7 @@ Acked-by: Jeff Johnson mutex_unlock(&ar->conf_mutex); } -@@ -8282,6 +8432,14 @@ ath12k_mac_op_reconfig_complete(struct i +@@ -8294,6 +8444,14 @@ ath12k_mac_op_reconfig_complete(struct i ath12k_warn(ar->ab, "pdev %d successfully recovered\n", ar->pdev->pdev_id); @@ -733,7 +733,7 @@ Acked-by: Jeff Johnson if (ab->is_reset) { recovery_count = atomic_inc_return(&ab->recovery_count); -@@ -9331,6 +9489,9 @@ static void ath12k_mac_setup(struct ath1 +@@ -9344,6 +9502,9 @@ static void ath12k_mac_setup(struct ath1 INIT_WORK(&ar->wmi_mgmt_tx_work, ath12k_mgmt_over_wmi_tx_work); skb_queue_head_init(&ar->wmi_mgmt_tx_queue); @@ -888,36 +888,36 @@ Acked-by: Jeff Johnson #endif --- a/drivers/net/wireless/ath/ath12k/hw.c +++ b/drivers/net/wireless/ath/ath12k/hw.c -@@ -926,6 +926,7 @@ static const struct ath12k_hw_params ath - .supports_dynamic_smps_6ghz = true, - +@@ -961,6 +961,7 @@ static const struct ath12k_hw_params ath .iova_mask = 0, + + .supports_aspm = false, + .current_cc_support = false, }, { .name = "wcn7850 hw2.0", -@@ -1004,6 +1005,7 @@ static const struct ath12k_hw_params ath - .supports_dynamic_smps_6ghz = false, - +@@ -1041,6 +1042,7 @@ static const struct ath12k_hw_params ath .iova_mask = ATH12K_PCIE_MAX_PAYLOAD_SIZE - 1, + + .supports_aspm = true, + .current_cc_support = true, }, { .name = "qcn9274 hw2.0", -@@ -1078,6 +1080,7 @@ static const struct ath12k_hw_params ath - .supports_dynamic_smps_6ghz = true, - +@@ -1117,6 +1119,7 @@ static const struct ath12k_hw_params ath .iova_mask = 0, + + .supports_aspm = false, + .current_cc_support = false, }, }; --- a/drivers/net/wireless/ath/ath12k/hw.h +++ b/drivers/net/wireless/ath/ath12k/hw.h -@@ -189,6 +189,7 @@ struct ath12k_hw_params { - bool tcl_ring_retry:1; +@@ -190,6 +190,7 @@ struct ath12k_hw_params { bool reoq_lut_support:1; bool supports_shadow_regs:1; + bool supports_aspm:1; + bool current_cc_support:1; u32 num_tcl_banks; diff --git a/package/kernel/mac80211/patches/ath5k/432-ath5k_add_pciids.patch b/package/kernel/mac80211/patches/ath5k/432-ath5k_add_pciids.patch deleted file mode 100644 index bd0e6707a5513b..00000000000000 --- a/package/kernel/mac80211/patches/ath5k/432-ath5k_add_pciids.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- a/drivers/net/wireless/ath/ath5k/pci.c -+++ b/drivers/net/wireless/ath/ath5k/pci.c -@@ -47,6 +47,8 @@ static const struct pci_device_id ath5k_ - { PCI_VDEVICE(ATHEROS, 0x001b) }, /* 5413 Eagle */ - { PCI_VDEVICE(ATHEROS, 0x001c) }, /* PCI-E cards */ - { PCI_VDEVICE(ATHEROS, 0x001d) }, /* 2417 Nala */ -+ { PCI_VDEVICE(ATHEROS, 0xff16) }, /* 2413,2414 sx76x on lantiq_danube */ -+ { PCI_VDEVICE(ATHEROS, 0xff1a) }, /* 2417 arv45xx on lantiq_danube */ - { PCI_VDEVICE(ATHEROS, 0xff1b) }, /* AR5BXB63 */ - { 0 } - }; diff --git a/package/kernel/mac80211/patches/ath9k/356-Revert-ath9k-interpret-requested-txpower-in-EIRP-dom.patch b/package/kernel/mac80211/patches/ath9k/356-Revert-ath9k-interpret-requested-txpower-in-EIRP-dom.patch index 385eea0116df2f..9016da963b35f1 100644 --- a/package/kernel/mac80211/patches/ath9k/356-Revert-ath9k-interpret-requested-txpower-in-EIRP-dom.patch +++ b/package/kernel/mac80211/patches/ath9k/356-Revert-ath9k-interpret-requested-txpower-in-EIRP-dom.patch @@ -8,7 +8,7 @@ This reverts commit 71f5137bf010c6faffab50c0ec15374c59c4a411. --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c -@@ -2977,7 +2977,8 @@ void ath9k_hw_apply_txpower(struct ath_h +@@ -2975,7 +2975,8 @@ void ath9k_hw_apply_txpower(struct ath_h { struct ath_regulatory *reg = ath9k_hw_regulatory(ah); struct ieee80211_channel *channel; @@ -18,7 +18,7 @@ This reverts commit 71f5137bf010c6faffab50c0ec15374c59c4a411. u16 ctl = NO_CTL; if (!chan) -@@ -2989,9 +2990,14 @@ void ath9k_hw_apply_txpower(struct ath_h +@@ -2987,9 +2988,14 @@ void ath9k_hw_apply_txpower(struct ath_h channel = chan->chan; chan_pwr = min_t(int, channel->max_power * 2, MAX_COMBINED_POWER); new_pwr = min_t(int, chan_pwr, reg->power_limit); diff --git a/package/kernel/mac80211/patches/ath9k/365-ath9k-adjust-tx-power-reduction-for-US-regulatory-do.patch b/package/kernel/mac80211/patches/ath9k/365-ath9k-adjust-tx-power-reduction-for-US-regulatory-do.patch index 0c3edc1260ff90..5e5f3e4f10242e 100644 --- a/package/kernel/mac80211/patches/ath9k/365-ath9k-adjust-tx-power-reduction-for-US-regulatory-do.patch +++ b/package/kernel/mac80211/patches/ath9k/365-ath9k-adjust-tx-power-reduction-for-US-regulatory-do.patch @@ -11,7 +11,7 @@ Signed-off-by: Felix Fietkau --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c -@@ -2996,6 +2996,10 @@ void ath9k_hw_apply_txpower(struct ath_h +@@ -2994,6 +2994,10 @@ void ath9k_hw_apply_txpower(struct ath_h if (ant_gain > max_gain) ant_reduction = ant_gain - max_gain; diff --git a/package/kernel/mac80211/patches/ath9k/410-ath9k_allow_adhoc_and_ap.patch b/package/kernel/mac80211/patches/ath9k/410-ath9k_allow_adhoc_and_ap.patch index b2f2763e8e16d9..3144f8291af82c 100644 --- a/package/kernel/mac80211/patches/ath9k/410-ath9k_allow_adhoc_and_ap.patch +++ b/package/kernel/mac80211/patches/ath9k/410-ath9k_allow_adhoc_and_ap.patch @@ -1,6 +1,6 @@ --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c -@@ -882,6 +882,7 @@ static const struct ieee80211_iface_limi +@@ -884,6 +884,7 @@ static const struct ieee80211_iface_limi BIT(NL80211_IFTYPE_AP) }, { .max = 1, .types = BIT(NL80211_IFTYPE_P2P_CLIENT) | BIT(NL80211_IFTYPE_P2P_GO) }, diff --git a/package/kernel/mac80211/patches/ath9k/450-ath9k-enabled-MFP-capability-unconditionally.patch b/package/kernel/mac80211/patches/ath9k/450-ath9k-enabled-MFP-capability-unconditionally.patch index f424ca530be860..50ba45c2a82549 100644 --- a/package/kernel/mac80211/patches/ath9k/450-ath9k-enabled-MFP-capability-unconditionally.patch +++ b/package/kernel/mac80211/patches/ath9k/450-ath9k-enabled-MFP-capability-unconditionally.patch @@ -14,7 +14,7 @@ Signed-off-by: David Bauer --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c -@@ -963,6 +963,7 @@ static void ath9k_set_hw_capab(struct at +@@ -965,6 +965,7 @@ static void ath9k_set_hw_capab(struct at ieee80211_hw_set(hw, HOST_BROADCAST_PS_BUFFERING); ieee80211_hw_set(hw, SUPPORT_FAST_XMIT); ieee80211_hw_set(hw, SUPPORTS_CLONED_SKBS); @@ -22,7 +22,7 @@ Signed-off-by: David Bauer if (ath9k_ps_enable) ieee80211_hw_set(hw, SUPPORTS_PS); -@@ -975,9 +976,6 @@ static void ath9k_set_hw_capab(struct at +@@ -977,9 +978,6 @@ static void ath9k_set_hw_capab(struct at IEEE80211_RADIOTAP_MCS_HAVE_STBC; } diff --git a/package/kernel/mac80211/patches/ath9k/501-ath9k_ahb_init.patch b/package/kernel/mac80211/patches/ath9k/501-ath9k_ahb_init.patch index 740ddc39dc3d03..f4d17f5f57e329 100644 --- a/package/kernel/mac80211/patches/ath9k/501-ath9k_ahb_init.patch +++ b/package/kernel/mac80211/patches/ath9k/501-ath9k_ahb_init.patch @@ -1,6 +1,6 @@ --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c -@@ -1178,25 +1178,25 @@ static int __init ath9k_init(void) +@@ -1180,25 +1180,25 @@ static int __init ath9k_init(void) { int error; diff --git a/package/kernel/mac80211/patches/ath9k/512-ath9k_channelbw_debugfs.patch b/package/kernel/mac80211/patches/ath9k/512-ath9k_channelbw_debugfs.patch index 87d18626da3779..b96f60cde68307 100644 --- a/package/kernel/mac80211/patches/ath9k/512-ath9k_channelbw_debugfs.patch +++ b/package/kernel/mac80211/patches/ath9k/512-ath9k_channelbw_debugfs.patch @@ -181,7 +181,7 @@ hw->max_listen_interval = 1; --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c -@@ -733,6 +733,7 @@ static int ath9k_init_softc(u16 devid, s +@@ -735,6 +735,7 @@ static int ath9k_init_softc(u16 devid, s if (!ath9k_is_chanctx_enabled()) sc->cur_chan->hw_queue_base = 0; diff --git a/package/kernel/mac80211/patches/ath9k/530-ath9k_extra_leds.patch b/package/kernel/mac80211/patches/ath9k/530-ath9k_extra_leds.patch index 4bb27d558cc43c..e0b1bf21bee986 100644 --- a/package/kernel/mac80211/patches/ath9k/530-ath9k_extra_leds.patch +++ b/package/kernel/mac80211/patches/ath9k/530-ath9k_extra_leds.patch @@ -181,7 +181,7 @@ --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c -@@ -1089,7 +1089,7 @@ int ath9k_init_device(u16 devid, struct +@@ -1091,7 +1091,7 @@ int ath9k_init_device(u16 devid, struct #ifdef CPTCFG_MAC80211_LEDS /* must be initialized before ieee80211_register_hw */ diff --git a/package/kernel/mac80211/patches/ath9k/543-ath9k_entropy_from_adc.patch b/package/kernel/mac80211/patches/ath9k/543-ath9k_entropy_from_adc.patch index 0fedc712701afe..8967d59a408a0f 100644 --- a/package/kernel/mac80211/patches/ath9k/543-ath9k_entropy_from_adc.patch +++ b/package/kernel/mac80211/patches/ath9k/543-ath9k_entropy_from_adc.patch @@ -55,7 +55,7 @@ ops->spectral_scan_config = ar9003_hw_spectral_scan_config; --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c -@@ -871,7 +871,8 @@ static void ath9k_init_txpower_limits(st +@@ -873,7 +873,8 @@ static void ath9k_init_txpower_limits(st if (ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ) ath9k_init_band_txpower(sc, NL80211_BAND_5GHZ); @@ -65,7 +65,7 @@ } static const struct ieee80211_iface_limit if_limits[] = { -@@ -1049,6 +1050,18 @@ static void ath9k_set_hw_capab(struct at +@@ -1051,6 +1052,18 @@ static void ath9k_set_hw_capab(struct at wiphy_ext_feature_set(hw->wiphy, NL80211_EXT_FEATURE_CAN_REPLACE_PTK0); } @@ -84,7 +84,7 @@ int ath9k_init_device(u16 devid, struct ath_softc *sc, const struct ath_bus_ops *bus_ops) { -@@ -1096,6 +1109,8 @@ int ath9k_init_device(u16 devid, struct +@@ -1098,6 +1111,8 @@ int ath9k_init_device(u16 devid, struct wiphy_read_of_freq_limits(hw->wiphy); diff --git a/package/kernel/mac80211/patches/ath9k/553-ath9k_of_gpio_mask.patch b/package/kernel/mac80211/patches/ath9k/553-ath9k_of_gpio_mask.patch index 752a4980a40b43..2f9f6d5bd2d865 100644 --- a/package/kernel/mac80211/patches/ath9k/553-ath9k_of_gpio_mask.patch +++ b/package/kernel/mac80211/patches/ath9k/553-ath9k_of_gpio_mask.patch @@ -1,6 +1,6 @@ --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c -@@ -696,6 +696,12 @@ static int ath9k_of_init(struct ath_soft +@@ -698,6 +698,12 @@ static int ath9k_of_init(struct ath_soft return 0; } @@ -13,7 +13,7 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc, const struct ath_bus_ops *bus_ops) { -@@ -804,6 +810,9 @@ static int ath9k_init_softc(u16 devid, s +@@ -806,6 +812,9 @@ static int ath9k_init_softc(u16 devid, s if (ret) goto err_hw; diff --git a/package/kernel/mac80211/patches/brcm/861-brcmfmac-workaround-bug-with-some-inconsistent-BSSes.patch b/package/kernel/mac80211/patches/brcm/860-brcmfmac-workaround-bug-with-some-inconsistent-BSSes.patch similarity index 100% rename from package/kernel/mac80211/patches/brcm/861-brcmfmac-workaround-bug-with-some-inconsistent-BSSes.patch rename to package/kernel/mac80211/patches/brcm/860-brcmfmac-workaround-bug-with-some-inconsistent-BSSes.patch diff --git a/package/kernel/mac80211/patches/brcm/863-brcmfmac-add-in-driver-tables-with-country-codes.patch b/package/kernel/mac80211/patches/brcm/861-brcmfmac-add-in-driver-tables-with-country-codes.patch similarity index 95% rename from package/kernel/mac80211/patches/brcm/863-brcmfmac-add-in-driver-tables-with-country-codes.patch rename to package/kernel/mac80211/patches/brcm/861-brcmfmac-add-in-driver-tables-with-country-codes.patch index 25f0d254c0da64..1f0609e3488887 100644 --- a/package/kernel/mac80211/patches/brcm/863-brcmfmac-add-in-driver-tables-with-country-codes.patch +++ b/package/kernel/mac80211/patches/brcm/861-brcmfmac-add-in-driver-tables-with-country-codes.patch @@ -49,9 +49,9 @@ Signed-off-by: Rafał Miłecki void brcmf_of_probe(struct device *dev, enum brcmf_bus_type bus_type, struct brcmf_mp_device *settings) { -@@ -114,6 +144,8 @@ void brcmf_of_probe(struct device *dev, - of_node_put(root); +@@ -113,6 +143,8 @@ void brcmf_of_probe(struct device *dev, } + of_node_put(root); + brcmf_of_probe_cc(dev, settings); + diff --git a/package/kernel/mac80211/patches/brcm/862-brcmfmac-Disable-power-management.patch b/package/kernel/mac80211/patches/brcm/862-brcmfmac-Disable-power-management.patch deleted file mode 100644 index 3472ff6afc6be1..00000000000000 --- a/package/kernel/mac80211/patches/brcm/862-brcmfmac-Disable-power-management.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 66ae1b1750720a33e29792a177b1e696f4f005fb Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Wed, 9 Mar 2016 17:25:59 +0000 -Subject: [PATCH] brcmfmac: Disable power management - -Disable wireless power saving in the brcmfmac WLAN driver. This is a -temporary measure until the connectivity loss resulting from power -saving is resolved. - -Signed-off-by: Phil Elwell ---- - drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c | 2 ++ - 1 file changed, 2 insertions(+) - ---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c -+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c -@@ -3314,6 +3314,10 @@ brcmf_cfg80211_set_power_mgmt(struct wip - * preference in cfg struct to apply this to - * FW later while initializing the dongle - */ -+#if defined(CONFIG_ARCH_BCM2835) -+ brcmf_dbg(INFO, "power management disabled\n"); -+ enabled = false; -+#endif - cfg->pwr_save = enabled; - if (!check_vif_up(ifp->vif)) { - diff --git a/package/kernel/mac80211/patches/brcm/864-brcmfmac-do-not-use-internal-roaming-engine-by-default.patch b/package/kernel/mac80211/patches/brcm/864-brcmfmac-do-not-use-internal-roaming-engine-by-default.patch deleted file mode 100644 index fe79c40c11cb88..00000000000000 --- a/package/kernel/mac80211/patches/brcm/864-brcmfmac-do-not-use-internal-roaming-engine-by-default.patch +++ /dev/null @@ -1,23 +0,0 @@ -brcmfmac: do not use internal roaming engine by default - -Some evidence of curing disconnects with this disabled, so make it a default. -Can be overridden with module parameter roamoff=0 -See: http://projectable.me/optimize-my-pi-wi-fi/ - -Signed-off-by: Phil Elwell ---- - ---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c -+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c -@@ -59,7 +59,11 @@ static int brcmf_fcmode; - module_param_named(fcmode, brcmf_fcmode, int, 0); - MODULE_PARM_DESC(fcmode, "Mode of firmware signalled flow control"); - -+#if defined(CONFIG_ARCH_BCM2835) -+static int brcmf_roamoff = 1; -+#else - static int brcmf_roamoff; -+#endif - module_param_named(roamoff, brcmf_roamoff, int, 0400); - MODULE_PARM_DESC(roamoff, "Do not use internal roaming engine"); - diff --git a/package/kernel/mac80211/patches/brcm/870-01-rpi-6.12-brcmfmac-adds-support-for-BCM43341-wifi.patch b/package/kernel/mac80211/patches/brcm/870-01-rpi-6.12-brcmfmac-adds-support-for-BCM43341-wifi.patch new file mode 100644 index 00000000000000..23526c936552f3 --- /dev/null +++ b/package/kernel/mac80211/patches/brcm/870-01-rpi-6.12-brcmfmac-adds-support-for-BCM43341-wifi.patch @@ -0,0 +1,29 @@ +From 88759af56f126e6e151f07fa9efc7447079fca9d Mon Sep 17 00:00:00 2001 +From: Cheong2K +Date: Fri, 26 Feb 2016 18:20:10 +0800 +Subject: [PATCH] brcmfmac: adds support for BCM43341 wifi + +Signed-off-by: Phil Elwell +--- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c | 3 ++- + 3 files changed, 4 insertions(+), 3 deletions(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c +@@ -609,6 +609,7 @@ BRCMF_FW_DEF(4329, "brcmfmac4329-sdio"); + BRCMF_FW_DEF(4330, "brcmfmac4330-sdio"); + BRCMF_FW_DEF(4334, "brcmfmac4334-sdio"); + BRCMF_FW_DEF(43340, "brcmfmac43340-sdio"); ++BRCMF_FW_DEF(43341, "brcmfmac43341-sdio"); + BRCMF_FW_DEF(4335, "brcmfmac4335-sdio"); + BRCMF_FW_DEF(43362, "brcmfmac43362-sdio"); + BRCMF_FW_DEF(4339, "brcmfmac4339-sdio"); +@@ -641,7 +642,7 @@ static const struct brcmf_firmware_mappi + BRCMF_FW_ENTRY(BRCM_CC_4330_CHIP_ID, 0xFFFFFFFF, 4330), + BRCMF_FW_ENTRY(BRCM_CC_4334_CHIP_ID, 0xFFFFFFFF, 4334), + BRCMF_FW_ENTRY(BRCM_CC_43340_CHIP_ID, 0xFFFFFFFF, 43340), +- BRCMF_FW_ENTRY(BRCM_CC_43341_CHIP_ID, 0xFFFFFFFF, 43340), ++ BRCMF_FW_ENTRY(BRCM_CC_43341_CHIP_ID, 0xFFFFFFFF, 43341), + BRCMF_FW_ENTRY(BRCM_CC_4335_CHIP_ID, 0xFFFFFFFF, 4335), + BRCMF_FW_ENTRY(BRCM_CC_43362_CHIP_ID, 0xFFFFFFFE, 43362), + BRCMF_FW_ENTRY(BRCM_CC_4339_CHIP_ID, 0xFFFFFFFF, 4339), diff --git a/package/kernel/mac80211/patches/brcm/870-02-rpi-6.12-brcmfmac-Prefer-a-ccode-from-OTP-over-nvram-file.patch b/package/kernel/mac80211/patches/brcm/870-02-rpi-6.12-brcmfmac-Prefer-a-ccode-from-OTP-over-nvram-file.patch new file mode 100644 index 00000000000000..9a7f9eb266409d --- /dev/null +++ b/package/kernel/mac80211/patches/brcm/870-02-rpi-6.12-brcmfmac-Prefer-a-ccode-from-OTP-over-nvram-file.patch @@ -0,0 +1,130 @@ +From 3ac592da09acb47b728ef320e9fecde55c8e0824 Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Fri, 26 Jun 2020 11:51:05 +0100 +Subject: [PATCH] brcmfmac: Prefer a ccode from OTP over nvram file + +Allow the nvram file to set a default ccode (regulatory domain) without +overriding one set in OTP. + +Signed-off-by: Phil Elwell +--- + .../broadcom/brcm80211/brcmfmac/cfg80211.c | 39 +++++++++++++------ + .../broadcom/brcm80211/brcmfmac/firmware.c | 21 +++++++++- + 2 files changed, 47 insertions(+), 13 deletions(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +@@ -9,6 +9,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -8212,31 +8213,45 @@ static void brcmf_cfg80211_reg_notifier( + struct brcmf_if *ifp = brcmf_get_ifp(cfg->pub, 0); + struct brcmf_pub *drvr = cfg->pub; + struct brcmf_fil_country_le ccreq; ++ char *alpha2; + s32 err; + int i; + +- /* The country code gets set to "00" by default at boot, ignore */ +- if (req->alpha2[0] == '0' && req->alpha2[1] == '0') ++ err = brcmf_fil_iovar_data_get(ifp, "country", &ccreq, sizeof(ccreq)); ++ if (err) { ++ bphy_err(drvr, "Country code iovar returned err = %d\n", err); + return; ++ } ++ ++ /* The country code gets set to "00" by default at boot - substitute ++ * any saved ccode from the nvram file unless there is a valid code ++ * already set. ++ */ ++ alpha2 = req->alpha2; ++ if (alpha2[0] == '0' && alpha2[1] == '0') { ++ extern char saved_ccode[2]; ++ ++ if ((isupper(ccreq.country_abbrev[0]) && ++ isupper(ccreq.country_abbrev[1])) || ++ !saved_ccode[0]) ++ return; ++ alpha2 = saved_ccode; ++ pr_debug("brcmfmac: substituting saved ccode %c%c\n", ++ alpha2[0], alpha2[1]); ++ } + + /* ignore non-ISO3166 country codes */ + for (i = 0; i < 2; i++) +- if (req->alpha2[i] < 'A' || req->alpha2[i] > 'Z') { ++ if (alpha2[i] < 'A' || alpha2[i] > 'Z') { + bphy_err(drvr, "not an ISO3166 code (0x%02x 0x%02x)\n", +- req->alpha2[0], req->alpha2[1]); ++ alpha2[0], alpha2[1]); + return; + } + + brcmf_dbg(TRACE, "Enter: initiator=%d, alpha=%c%c\n", req->initiator, +- req->alpha2[0], req->alpha2[1]); +- +- err = brcmf_fil_iovar_data_get(ifp, "country", &ccreq, sizeof(ccreq)); +- if (err) { +- bphy_err(drvr, "Country code iovar returned err = %d\n", err); +- return; +- } ++ alpha2[0], alpha2[1]); + +- err = brcmf_translate_country_code(ifp->drvr, req->alpha2, &ccreq); ++ err = brcmf_translate_country_code(ifp->drvr, alpha2, &ccreq); + if (err) + return; + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c +@@ -10,6 +10,7 @@ + #include + #include + #include ++#include + + #include "debug.h" + #include "firmware.h" +@@ -32,6 +33,8 @@ enum nvram_parser_state { + END + }; + ++char saved_ccode[2] = {}; ++ + /** + * struct nvram_parser - internal info for parser. + * +@@ -562,11 +565,27 @@ static int brcmf_fw_request_nvram_done(c + goto fail; + } + +- if (data) ++ if (data) { ++ char *ccode = strnstr((char *)data, "ccode=", data_len); ++ /* Ensure this is a whole token */ ++ if (ccode && ((void *)ccode == (void *)data || isspace(ccode[-1]))) { ++ /* Comment out the line */ ++ ccode[0] = '#'; ++ ccode += 6; ++ if (isupper(ccode[0]) && isupper(ccode[1]) && ++ isspace(ccode[2])) { ++ pr_debug("brcmfmac: intercepting ccode=%c%c\n", ++ ccode[0], ccode[1]); ++ saved_ccode[0] = ccode[0]; ++ saved_ccode[1] = ccode[1]; ++ } ++ }; ++ + nvram = brcmf_fw_nvram_strip(data, data_len, &nvram_length, + fwctx->req->domain_nr, + fwctx->req->bus_nr, + fwctx->dev); ++ } + + if (free_bcm47xx_nvram) + bcm47xx_nvram_release_contents(data); diff --git a/package/kernel/mac80211/patches/brcm/870-03-rpi-6.12-brcmfmac-Increase-power-saving-delay-to-2s.patch b/package/kernel/mac80211/patches/brcm/870-03-rpi-6.12-brcmfmac-Increase-power-saving-delay-to-2s.patch new file mode 100644 index 00000000000000..f197e890265998 --- /dev/null +++ b/package/kernel/mac80211/patches/brcm/870-03-rpi-6.12-brcmfmac-Increase-power-saving-delay-to-2s.patch @@ -0,0 +1,24 @@ +From 12722e472a963598a88011dd4b6805ed0a0e318f Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Mon, 3 Feb 2020 09:32:22 +0000 +Subject: [PATCH] brcmfmac: Increase power saving delay to 2s + +Increase the delay before entering the lower power state to 2 seconds +(the maximum allowed) in order to reduce the packet latencies, +particularly for inbound packets. + +Signed-off-by: Phil Elwell +--- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +@@ -3338,6 +3338,7 @@ brcmf_cfg80211_set_power_mgmt(struct wip + bphy_err(drvr, "error (%d)\n", err); + } + ++ timeout = 2000; /* 2000ms - the maximum */ + err = brcmf_fil_iovar_int_set(ifp, "pm2_sleep_ret", + min_t(u32, timeout, BRCMF_PS_MAX_TIMEOUT_MS)); + if (err) diff --git a/package/kernel/mac80211/patches/brcm/870-04-rpi-6.12-brcmfmac-non-upstream-support-DS1-exit-firmware-re-download.patch b/package/kernel/mac80211/patches/brcm/870-04-rpi-6.12-brcmfmac-non-upstream-support-DS1-exit-firmware-re-download.patch new file mode 100644 index 00000000000000..e02149a7a056a2 --- /dev/null +++ b/package/kernel/mac80211/patches/brcm/870-04-rpi-6.12-brcmfmac-non-upstream-support-DS1-exit-firmware-re-download.patch @@ -0,0 +1,721 @@ +From e7400640cafcf6bd84049308feb5aeabecf55b46 Mon Sep 17 00:00:00 2001 +From: Praveen Babu C +Date: Tue, 9 Jan 2018 11:33:10 +0530 +Subject: [PATCH] non-upstream: support DS1 exit firmware re-download + +In deep sleep mode (DS1) ARM is off and once exit trigger comes than +mailbox Interrupt comes to host and whole reinitiation should be done +in the ARM to start TX/RX. + +Also fix below issus for DS1 exit: +1. Sent Tx Control frame only after firmware redownload complete (check +F2 Ready before sending Tx Control frame to Firmware) +2. intermittent High DS1 TX Exit latency time (almost 3sec) ==> This is +fixed by skipping host Mailbox interrupt Multiple times (ulp state +mechanism) +3. RX GlOM save/restore in Firmware +4. Add ULP event enable & event_msgs_ext iovar configuration in FMAC +5. Add ULP_EVENT_RECV state machine for sbwad support +6. Support 2 Byte Shared memory read for DS1 Exit HUDI implementation + +Signed-off-by: Praveen Babu C +Signed-off-by: Naveen Gupta +[Merge from 4.14.77 to 5.4.18; set BRCMF_SDIO_MAX_ACCESS_ERRORS to 20] +Signed-off-by: Chi-hsien Lin +JIRA: SWWLAN-135583 +JIRA: SWWLAN-136577 +--- + .../broadcom/brcm80211/brcmfmac/bus.h | 2 +- + .../broadcom/brcm80211/brcmfmac/common.c | 39 +++ + .../broadcom/brcm80211/brcmfmac/core.c | 13 +- + .../broadcom/brcm80211/brcmfmac/debug.h | 1 + + .../broadcom/brcm80211/brcmfmac/fweh.h | 31 ++- + .../broadcom/brcm80211/brcmfmac/pcie.c | 2 +- + .../broadcom/brcm80211/brcmfmac/sdio.c | 260 +++++++++++++++++- + .../broadcom/brcm80211/brcmfmac/sdio.h | 110 ++++++++ + .../broadcom/brcm80211/brcmfmac/usb.c | 4 +- + .../broadcom/brcm80211/include/chipcommon.h | 2 + + 10 files changed, 448 insertions(+), 16 deletions(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h +@@ -298,7 +298,7 @@ void brcmf_rx_event(struct device *dev, + + int brcmf_alloc(struct device *dev, struct brcmf_mp_device *settings); + /* Indication from bus module regarding presence/insertion of dongle. */ +-int brcmf_attach(struct device *dev); ++int brcmf_attach(struct device *dev, bool start_bus); + /* Indication from bus module regarding removal/absence of dongle */ + void brcmf_detach(struct device *dev); + void brcmf_free(struct device *dev); +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c +@@ -20,6 +20,8 @@ + #include "of.h" + #include "firmware.h" + #include "chip.h" ++#include "fweh.h" ++#include + + MODULE_AUTHOR("Broadcom Corporation"); + MODULE_DESCRIPTION("Broadcom 802.11 wireless LAN fullmac driver."); +@@ -274,6 +276,8 @@ int brcmf_c_preinit_dcmds(struct brcmf_i + char *clmver; + char *ptr; + s32 err; ++ struct eventmsgs_ext *eventmask_msg = NULL; ++ u8 msglen; + + if (is_valid_ether_addr(ifp->mac_addr)) { + /* set mac address */ +@@ -433,6 +437,41 @@ int brcmf_c_preinit_dcmds(struct brcmf_i + goto done; + } + ++ /* Enable event_msg_ext specific to 43012 chip */ ++ if (bus->chip == CY_CC_43012_CHIP_ID) { ++ /* Program event_msg_ext to support event larger than 128 */ ++ msglen = (roundup(BRCMF_E_LAST, NBBY) / NBBY) + ++ EVENTMSGS_EXT_STRUCT_SIZE; ++ /* Allocate buffer for eventmask_msg */ ++ eventmask_msg = kzalloc(msglen, GFP_KERNEL); ++ if (!eventmask_msg) { ++ err = -ENOMEM; ++ goto done; ++ } ++ ++ /* Read the current programmed event_msgs_ext */ ++ eventmask_msg->ver = EVENTMSGS_VER; ++ eventmask_msg->len = roundup(BRCMF_E_LAST, NBBY) / NBBY; ++ err = brcmf_fil_iovar_data_get(ifp, "event_msgs_ext", ++ eventmask_msg, ++ msglen); ++ ++ /* Enable ULP event */ ++ brcmf_dbg(EVENT, "enable event ULP\n"); ++ setbit(eventmask_msg->mask, BRCMF_E_ULP); ++ ++ /* Write updated Event mask */ ++ eventmask_msg->ver = EVENTMSGS_VER; ++ eventmask_msg->command = EVENTMSGS_SET_MASK; ++ eventmask_msg->len = (roundup(BRCMF_E_LAST, NBBY) / NBBY); ++ ++ err = brcmf_fil_iovar_data_set(ifp, "event_msgs_ext", ++ eventmask_msg, msglen); ++ if (err) { ++ brcmf_err("Set event_msgs_ext error (%d)\n", err); ++ goto done; ++ } ++ } + /* Setup default scan channel time */ + err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_CHANNEL_TIME, + BRCMF_DEFAULT_SCAN_CHANNEL_TIME); +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c +@@ -1322,7 +1322,7 @@ int brcmf_alloc(struct device *dev, stru + return 0; + } + +-int brcmf_attach(struct device *dev) ++int brcmf_attach(struct device *dev, bool start_bus) + { + struct brcmf_bus *bus_if = dev_get_drvdata(dev); + struct brcmf_pub *drvr = bus_if->drvr; +@@ -1363,10 +1363,13 @@ int brcmf_attach(struct device *dev) + brcmf_fweh_register(drvr, BRCMF_E_PSM_WATCHDOG, + brcmf_psm_watchdog_notify); + +- ret = brcmf_bus_started(drvr, drvr->ops); +- if (ret != 0) { +- bphy_err(drvr, "dongle is not responding: err=%d\n", ret); +- goto fail; ++ if (start_bus) { ++ ret = brcmf_bus_started(drvr, drvr->ops); ++ if (ret != 0) { ++ bphy_err(drvr, "dongle is not responding: err=%d\n", ++ ret); ++ goto fail; ++ } + } + + return 0; +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/debug.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/debug.h +@@ -29,6 +29,7 @@ + #define BRCMF_MSGBUF_VAL 0x00040000 + #define BRCMF_PCIE_VAL 0x00080000 + #define BRCMF_FWCON_VAL 0x00100000 ++#define BRCMF_ULP_VAL 0x00200000 + + /* set default print format */ + #undef pr_fmt +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.h +@@ -94,7 +94,8 @@ struct brcmf_cfg80211_info; + BRCMF_ENUM_DEF(FIFO_CREDIT_MAP, 74) \ + BRCMF_ENUM_DEF(ACTION_FRAME_RX, 75) \ + BRCMF_ENUM_DEF(TDLS_PEER_EVENT, 92) \ +- BRCMF_ENUM_DEF(BCMC_CREDIT_SUPPORT, 127) ++ BRCMF_ENUM_DEF(BCMC_CREDIT_SUPPORT, 127) \ ++ BRCMF_ENUM_DEF(ULP, 146) + + #define BRCMF_ENUM_DEF(id, val) \ + BRCMF_E_##id = (val), +@@ -102,6 +103,12 @@ struct brcmf_cfg80211_info; + /* firmware event codes sent by the dongle */ + enum brcmf_fweh_event_code { + BRCMF_FWEH_EVENT_ENUM_DEFLIST ++ ++ /* this determines event mask length which must match ++ * minimum length check in device firmware so it is ++ * hard-coded here. ++ */ ++ BRCMF_E_LAST + }; + #undef BRCMF_ENUM_DEF + +@@ -280,6 +287,28 @@ struct brcmf_if_event { + u8 role; + }; + ++enum event_msgs_ext_command { ++ EVENTMSGS_NONE = 0, ++ EVENTMSGS_SET_BIT = 1, ++ EVENTMSGS_RESET_BIT = 2, ++ EVENTMSGS_SET_MASK = 3 ++}; ++ ++#define EVENTMSGS_VER 1 ++#define EVENTMSGS_EXT_STRUCT_SIZE offsetof(struct eventmsgs_ext, mask[0]) ++ ++/* len- for SET it would be mask size from the application to the firmware */ ++/* for GET it would be actual firmware mask size */ ++/* maxgetsize - is only used for GET. indicate max mask size that the */ ++/* application can read from the firmware */ ++struct eventmsgs_ext { ++ u8 ver; ++ u8 command; ++ u8 len; ++ u8 maxgetsize; ++ u8 mask[1]; ++}; ++ + typedef int (*brcmf_fweh_handler_t)(struct brcmf_if *ifp, + const struct brcmf_event_msg *evtmsg, + void *data); +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c +@@ -2207,7 +2207,7 @@ static void brcmf_pcie_setup(struct devi + + init_waitqueue_head(&devinfo->mbdata_resp_wait); + +- ret = brcmf_attach(&devinfo->pdev->dev); ++ ret = brcmf_attach(&devinfo->pdev->dev, true); + if (ret) + goto fail; + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c +@@ -35,9 +35,12 @@ + #include "core.h" + #include "common.h" + #include "bcdc.h" ++#include "debug.h" ++#include "fwil.h" + + #define DCMD_RESP_TIMEOUT msecs_to_jiffies(2500) + #define CTL_DONE_TIMEOUT msecs_to_jiffies(2500) ++#define ULP_HUDI_PROC_DONE_TIME msecs_to_jiffies(2500) + + /* watermark expressed in number of words */ + #define DEFAULT_F2_WATERMARK 0x8 +@@ -325,7 +328,16 @@ struct rte_console { + + #define KSO_WAIT_US 50 + #define MAX_KSO_ATTEMPTS (PMU_MAX_TRANSITION_DLY/KSO_WAIT_US) +-#define BRCMF_SDIO_MAX_ACCESS_ERRORS 5 ++#define BRCMF_SDIO_MAX_ACCESS_ERRORS 20 ++ ++static void brcmf_sdio_firmware_callback(struct device *dev, int err, ++ struct brcmf_fw_request *fwreq); ++static struct brcmf_fw_request * ++ brcmf_sdio_prepare_fw_request(struct brcmf_sdio *bus); ++static int brcmf_sdio_f2_ready(struct brcmf_sdio *bus); ++static int brcmf_ulp_event_notify(struct brcmf_if *ifp, ++ const struct brcmf_event_msg *evtmsg, ++ void *data); + + #ifdef DEBUG + /* Device console log buffer state */ +@@ -1105,7 +1117,7 @@ static void brcmf_sdio_get_console_addr( + } + #endif /* DEBUG */ + +-static u32 brcmf_sdio_hostmail(struct brcmf_sdio *bus) ++static u32 brcmf_sdio_hostmail(struct brcmf_sdio *bus, u32 *hmbd) + { + struct brcmf_sdio_dev *sdiod = bus->sdiodev; + struct brcmf_core *core = bus->sdio_core; +@@ -1194,6 +1206,9 @@ static u32 brcmf_sdio_hostmail(struct br + HMB_DATA_FCDATA_MASK | HMB_DATA_VERSION_MASK)) + brcmf_err("Unknown mailbox data content: 0x%02x\n", + hmb_data); ++ /* Populate hmb_data if argument is passed for DS1 check later */ ++ if (hmbd) ++ *hmbd = hmb_data; + + return intstatus; + } +@@ -2580,6 +2595,182 @@ static int brcmf_sdio_intr_rstatus(struc + return ret; + } + ++/* This Function is used to retrieve important ++ * details from dongle related to ULP mode Mostly ++ * values/SHM details that will be vary depending ++ * on the firmware branches ++ */ ++static void ++brcmf_sdio_ulp_preinit(struct device *dev) ++{ ++ struct brcmf_bus *bus_if = dev_get_drvdata(dev); ++ struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio; ++ struct brcmf_if *ifp = bus_if->drvr->iflist[0]; ++ ++ brcmf_dbg(ULP, "Enter\n"); ++ ++ /* Query ulp_sdioctrl iovar to get the ULP related SHM offsets */ ++ brcmf_fil_iovar_data_get(ifp, "ulp_sdioctrl", ++ &sdiodev->fmac_ulp.ulp_shm_offset, ++ sizeof(sdiodev->fmac_ulp.ulp_shm_offset)); ++ ++ sdiodev->ulp = false; ++ ++ brcmf_dbg(ULP, "m_ulp_ctrl_sdio[%x] m_ulp_wakeevt_ind [%x]\n", ++ M_DS1_CTRL_SDIO(sdiodev->fmac_ulp), ++ M_WAKEEVENT_IND(sdiodev->fmac_ulp)); ++ brcmf_dbg(ULP, "m_ulp_wakeind [%x]\n", ++ M_ULP_WAKE_IND(sdiodev->fmac_ulp)); ++} ++ ++/* Reinitialize ARM because In DS1 mode ARM got off */ ++static int ++brcmf_sdio_ulp_reinit_fw(struct brcmf_sdio *bus) ++{ ++ struct brcmf_sdio_dev *sdiodev = bus->sdiodev; ++ struct brcmf_fw_request *fwreq; ++ int err = 0; ++ ++ /* After firmware redownload tx/rx seq are reset accordingly ++ * these values are reset on FMAC side tx_max is initially set to 4, ++ * which later is updated by FW. ++ */ ++ bus->tx_seq = 0; ++ bus->rx_seq = 0; ++ bus->tx_max = 4; ++ ++ fwreq = brcmf_sdio_prepare_fw_request(bus); ++ if (!fwreq) ++ return -ENOMEM; ++ ++ err = brcmf_fw_get_firmwares(sdiodev->dev, fwreq, ++ brcmf_sdio_firmware_callback); ++ if (err != 0) { ++ brcmf_err("async firmware request failed: %d\n", err); ++ kfree(fwreq); ++ } ++ ++ return err; ++} ++ ++/* Check if device is in DS1 mode and handshake with ULP UCODE */ ++static bool ++brcmf_sdio_ulp_pre_redownload_check(struct brcmf_sdio *bus, u32 hmb_data) ++{ ++ struct brcmf_sdio_dev *sdiod = bus->sdiodev; ++ int err = 0; ++ u32 value = 0; ++ u32 val32, ulp_wake_ind, wowl_wake_ind; ++ int reg_addr; ++ unsigned long timeout; ++ struct brcmf_ulp *fmac_ulp = &bus->sdiodev->fmac_ulp; ++ int i = 0; ++ ++ /* If any host mail box data is present, ignore DS1 exit sequence */ ++ if (hmb_data) ++ return false; ++ /* Skip if DS1 Exit is already in progress ++ * This can happen if firmware download is taking more time ++ */ ++ if (fmac_ulp->ulp_state == FMAC_ULP_TRIGGERED) ++ return false; ++ ++ value = brcmf_sdiod_func0_rb(sdiod, SDIO_CCCR_IOEx, &err); ++ ++ if (value == SDIO_FUNC_ENABLE_1) { ++ brcmf_dbg(ULP, "GOT THE INTERRUPT FROM UCODE\n"); ++ sdiod->ulp = true; ++ fmac_ulp->ulp_state = FMAC_ULP_TRIGGERED; ++ ulp_wake_ind = D11SHM_RDW(sdiod, ++ M_ULP_WAKE_IND(sdiod->fmac_ulp), ++ &err); ++ wowl_wake_ind = D11SHM_RDW(sdiod, ++ M_WAKEEVENT_IND(sdiod->fmac_ulp), ++ &err); ++ ++ brcmf_dbg(ULP, "wowl_wake_ind: 0x%08x, ulp_wake_ind: 0x%08x state %s\n", ++ wowl_wake_ind, ulp_wake_ind, (fmac_ulp->ulp_state) ? ++ "DS1 Exit Triggered" : "IDLE State"); ++ ++ if (wowl_wake_ind || ulp_wake_ind) { ++ /* RX wake Don't do anything. ++ * Just bail out and re-download firmware. ++ */ ++ /* Print out PHY TX error block when bit 9 set */ ++ if ((ulp_wake_ind & C_DS1_PHY_TXERR) && ++ M_DS1_PHYTX_ERR_BLK(sdiod->fmac_ulp)) { ++ brcmf_err("Dump PHY TX Error SHM Locations\n"); ++ for (i = 0; i < PHYTX_ERR_BLK_SIZE; i++) { ++ pr_err("0x%x", ++ D11SHM_RDW(sdiod, ++ (M_DS1_PHYTX_ERR_BLK(sdiod->fmac_ulp) + ++ (i * 2)), &err)); ++ } ++ brcmf_err("\n"); ++ } ++ } else { ++ /* TX wake negotiate with MAC */ ++ brcmf_dbg(ULP, "M_DS1_CTRL_SDIO: 0x%08x\n", ++ (u32)D11SHM_RDW(sdiod, ++ M_DS1_CTRL_SDIO(sdiod->fmac_ulp), ++ &err)); ++ val32 = D11SHM_RD(sdiod, ++ M_DS1_CTRL_SDIO(sdiod->fmac_ulp), ++ &err); ++ D11SHM_WR(sdiod, M_DS1_CTRL_SDIO(sdiod->fmac_ulp), ++ val32, (C_DS1_CTRL_SDIO_DS1_EXIT | ++ C_DS1_CTRL_REQ_VALID), &err); ++ val32 = D11REG_RD(sdiod, D11_MACCONTROL_REG, &err); ++ val32 = val32 | D11_MACCONTROL_REG_WAKE; ++ D11REG_WR(sdiod, D11_MACCONTROL_REG, val32, &err); ++ ++ /* Poll for PROC_DONE to be set by ucode */ ++ value = D11SHM_RDW(sdiod, ++ M_DS1_CTRL_SDIO(sdiod->fmac_ulp), ++ &err); ++ /* Wait here (polling) for C_DS1_CTRL_PROC_DONE */ ++ timeout = jiffies + ULP_HUDI_PROC_DONE_TIME; ++ while (!(value & C_DS1_CTRL_PROC_DONE)) { ++ value = D11SHM_RDW(sdiod, ++ M_DS1_CTRL_SDIO(sdiod->fmac_ulp), ++ &err); ++ if (time_after(jiffies, timeout)) ++ break; ++ usleep_range(1000, 2000); ++ } ++ brcmf_dbg(ULP, "M_DS1_CTRL_SDIO: 0x%08x\n", ++ (u32)D11SHM_RDW(sdiod, ++ M_DS1_CTRL_SDIO(sdiod->fmac_ulp), &err)); ++ value = D11SHM_RDW(sdiod, ++ M_DS1_CTRL_SDIO(sdiod->fmac_ulp), ++ &err); ++ if (!(value & C_DS1_CTRL_PROC_DONE)) { ++ brcmf_err("Timeout Failed to enter DS1 Exit state!\n"); ++ return false; ++ } ++ } ++ ++ ulp_wake_ind = D11SHM_RDW(sdiod, ++ M_ULP_WAKE_IND(sdiod->fmac_ulp), ++ &err); ++ wowl_wake_ind = D11SHM_RDW(sdiod, ++ M_WAKEEVENT_IND(sdiod->fmac_ulp), ++ &err); ++ brcmf_dbg(ULP, "wowl_wake_ind: 0x%08x, ulp_wake_ind: 0x%08x\n", ++ wowl_wake_ind, ulp_wake_ind); ++ reg_addr = CORE_CC_REG( ++ brcmf_chip_get_pmu(bus->ci)->base, min_res_mask); ++ brcmf_sdiod_writel(sdiod, reg_addr, ++ DEFAULT_43012_MIN_RES_MASK, &err); ++ if (err) ++ brcmf_err("min_res_mask failed\n"); ++ ++ return true; ++ } ++ ++ return false; ++} ++ + static void brcmf_sdio_dpc(struct brcmf_sdio *bus) + { + struct brcmf_sdio_dev *sdiod = bus->sdiodev; +@@ -2651,8 +2842,11 @@ static void brcmf_sdio_dpc(struct brcmf_ + + /* Handle host mailbox indication */ + if (intstatus & I_HMB_HOST_INT) { ++ u32 hmb_data = 0; + intstatus &= ~I_HMB_HOST_INT; +- intstatus |= brcmf_sdio_hostmail(bus); ++ intstatus |= brcmf_sdio_hostmail(bus, &hmb_data); ++ if (brcmf_sdio_ulp_pre_redownload_check(bus, hmb_data)) ++ brcmf_sdio_ulp_reinit_fw(bus); + } + + sdio_release_host(bus->sdiodev->func1); +@@ -2697,7 +2891,7 @@ static void brcmf_sdio_dpc(struct brcmf_ + brcmf_sdio_clrintr(bus); + + if (bus->ctrl_frame_stat && (bus->clkstate == CLK_AVAIL) && +- txctl_ok(bus)) { ++ txctl_ok(bus) && brcmf_sdio_f2_ready(bus)) { + sdio_claim_host(bus->sdiodev->func1); + if (bus->ctrl_frame_stat) { + err = brcmf_sdio_tx_ctrlframe(bus, bus->ctrl_frame_buf, +@@ -3567,6 +3761,10 @@ static int brcmf_sdio_bus_preinit(struct + if (err < 0) + goto done; + ++ /* initialize SHM address from firmware for DS1 */ ++ if (!bus->sdiodev->ulp) ++ brcmf_sdio_ulp_preinit(dev); ++ + bus->tx_hdrlen = SDPCM_HWHDR_LEN + SDPCM_SWHDR_LEN; + if (sdiodev->sg_support) { + bus->txglom = false; +@@ -4215,7 +4413,7 @@ static void brcmf_sdio_firmware_callback + u8 saveclk, bpreq; + u8 devctl; + +- brcmf_dbg(TRACE, "Enter: dev=%s, err=%d\n", dev_name(dev), err); ++ brcmf_dbg(ULP, "Enter: dev=%s, err=%d\n", dev_name(dev), err); + + if (err) + goto fail; +@@ -4392,12 +4590,25 @@ static void brcmf_sdio_firmware_callback + } + + /* Attach to the common layer, reserve hdr space */ +- err = brcmf_attach(sdiod->dev); ++ err = brcmf_attach(sdiod->dev, !bus->sdiodev->ulp); + if (err != 0) { + brcmf_err("brcmf_attach failed\n"); + goto free; + } + ++ /* Register for ULP events */ ++ if (sdiod->func1->device == SDIO_DEVICE_ID_BROADCOM_CYPRESS_43012) ++ brcmf_fweh_register(bus_if->drvr, BRCMF_E_ULP, ++ brcmf_ulp_event_notify); ++ ++ if (bus->sdiodev->ulp) { ++ /* For ULP, after firmware redownload complete ++ * set ULP state to IDLE ++ */ ++ if (bus->sdiodev->fmac_ulp.ulp_state == FMAC_ULP_TRIGGERED) ++ bus->sdiodev->fmac_ulp.ulp_state = FMAC_ULP_IDLE; ++ } ++ + /* ready */ + return; + +@@ -4640,3 +4851,40 @@ int brcmf_sdio_sleep(struct brcmf_sdio * + + return ret; + } ++ ++/* Check F2 Ready bit before sending data to Firmware */ ++static int ++brcmf_sdio_f2_ready(struct brcmf_sdio *bus) ++{ ++ int ret = -1; ++ int iordy_status = 0; ++ ++ sdio_claim_host(bus->sdiodev->func1); ++ /* Read the status of IOR2 */ ++ iordy_status = brcmf_sdiod_func0_rb(bus->sdiodev, SDIO_CCCR_IORx, NULL); ++ ++ sdio_release_host(bus->sdiodev->func1); ++ ret = iordy_status & SDIO_FUNC_ENABLE_2; ++ return ret; ++} ++ ++static int brcmf_ulp_event_notify(struct brcmf_if *ifp, ++ const struct brcmf_event_msg *evtmsg, ++ void *data) ++{ ++ int err = 0; ++ struct brcmf_bus *bus_if = ifp->drvr->bus_if; ++ struct brcmf_sdio_dev *sdiodev; ++ struct brcmf_sdio *bus; ++ struct brcmf_ulp_event *ulp_event = (struct brcmf_ulp_event *)data; ++ ++ sdiodev = bus_if->bus_priv.sdio; ++ bus = sdiodev->bus; ++ ++ brcmf_dbg(ULP, "Chip went to DS1 state : action %d\n", ++ ulp_event->ulp_dongle_action); ++ if (ulp_event->ulp_dongle_action == FMAC_ULP_ENTRY) ++ bus->sdiodev->fmac_ulp.ulp_state = FMAC_ULP_ENTRY_RECV; ++ ++ return err; ++} +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h +@@ -165,6 +165,35 @@ struct brcmf_sdreg { + struct brcmf_sdio; + struct brcmf_sdiod_freezer; + ++/* ULP SHM Offsets info */ ++struct ulp_shm_info { ++ u32 m_ulp_ctrl_sdio; ++ u32 m_ulp_wakeevt_ind; ++ u32 m_ulp_wakeind; ++ u32 m_ulp_phytxblk; ++}; ++ ++/* FMAC ULP state machine */ ++#define FMAC_ULP_IDLE (0) ++#define FMAC_ULP_ENTRY_RECV (1) ++#define FMAC_ULP_TRIGGERED (2) ++ ++/* BRCMF_E_ULP event data */ ++#define FMAC_ULP_EVENT_VERSION 1 ++#define FMAC_ULP_DISABLE_CONSOLE 1 /* Disable console */ ++#define FMAC_ULP_UCODE_DOWNLOAD 2 /* Download ULP ucode file */ ++#define FMAC_ULP_ENTRY 3 /* Inform ulp entry to Host */ ++ ++struct brcmf_ulp { ++ uint ulp_state; ++ struct ulp_shm_info ulp_shm_offset; ++}; ++ ++struct brcmf_ulp_event { ++ u16 version; ++ u16 ulp_dongle_action; ++}; ++ + struct brcmf_sdio_dev { + struct sdio_func *func1; + struct sdio_func *func2; +@@ -193,6 +222,8 @@ struct brcmf_sdio_dev { + enum brcmf_sdiod_state state; + struct brcmf_sdiod_freezer *freezer; + const struct firmware *clm_fw; ++ struct brcmf_ulp fmac_ulp; ++ bool ulp; + }; + + /* sdio core registers */ +@@ -367,4 +398,83 @@ void brcmf_sdio_wowl_config(struct devic + int brcmf_sdio_sleep(struct brcmf_sdio *bus, bool sleep); + void brcmf_sdio_trigger_dpc(struct brcmf_sdio *bus); + ++/* SHM offsets */ ++#define M_DS1_CTRL_SDIO(ptr) ((ptr).ulp_shm_offset.m_ulp_ctrl_sdio) ++#define M_WAKEEVENT_IND(ptr) ((ptr).ulp_shm_offset.m_ulp_wakeevt_ind) ++#define M_ULP_WAKE_IND(ptr) ((ptr).ulp_shm_offset.m_ulp_wakeind) ++#define M_DS1_PHYTX_ERR_BLK(ptr) ((ptr).ulp_shm_offset.m_ulp_phytxblk) ++ ++#define D11_BASE_ADDR 0x18001000 ++#define D11_AXI_BASE_ADDR 0xE8000000 ++#define D11_SHM_BASE_ADDR (D11_AXI_BASE_ADDR + 0x4000) ++ ++#define D11REG_ADDR(offset) (D11_BASE_ADDR + (offset)) ++#define D11IHR_ADDR(offset) (D11_AXI_BASE_ADDR + 0x400 + (2 * (offset))) ++#define D11SHM_ADDR(offset) (D11_SHM_BASE_ADDR + (offset)) ++ ++/* MacControl register */ ++#define D11_MACCONTROL_REG D11REG_ADDR(0x120) ++#define D11_MACCONTROL_REG_WAKE 0x4000000 ++ ++/* HUDI Sequence SHM bits */ ++#define C_DS1_CTRL_SDIO_DS1_SLEEP 0x1 ++#define C_DS1_CTRL_SDIO_MAC_ON 0x2 ++#define C_DS1_CTRL_SDIO_RADIO_PHY_ON 0x4 ++#define C_DS1_CTRL_SDIO_DS1_EXIT 0x8 ++#define C_DS1_CTRL_PROC_DONE 0x100 ++#define C_DS1_CTRL_REQ_VALID 0x200 ++ ++/* M_ULP_WAKEIND bits */ ++#define C_WATCHDOG_EXPIRY BIT(0) ++#define C_FCBS_ERROR BIT(1) ++#define C_RETX_FAILURE BIT(2) ++#define C_HOST_WAKEUP BIT(3) ++#define C_INVALID_FCBS_BLOCK BIT(4) ++#define C_HUDI_DS1_EXIT BIT(5) ++#define C_LOB_SLEEP BIT(6) ++#define C_DS1_PHY_TXERR BIT(9) ++#define C_DS1_WAKE_TIMER BIT(10) ++ ++#define PHYTX_ERR_BLK_SIZE 18 ++#define D11SHM_FIRST2BYTE_MASK 0xFFFF0000 ++#define D11SHM_SECOND2BYTE_MASK 0x0000FFFF ++#define D11SHM_2BYTE_SHIFT 16 ++ ++#define D11SHM_RD(sdh, offset, ret) \ ++ brcmf_sdiod_readl(sdh, D11SHM_ADDR(offset), ret) ++ ++/* SHM Read is motified based on SHM 4 byte alignment as SHM size is 2 bytes and ++ * 2 byte is currently not working on FMAC ++ * If SHM address is not 4 byte aligned, then right shift by 16 ++ * otherwise, mask the first two MSB bytes ++ * Suppose data in address 7260 is 0x440002 and it is 4 byte aligned ++ * Correct SHM value is 0x2 for this SHM offset and next SHM value is 0x44 ++ */ ++#define D11SHM_RDW(sdh, offset, ret) \ ++ ((offset % 4) ? \ ++ (brcmf_sdiod_readl(sdh, D11SHM_ADDR(offset), ret) \ ++ >> D11SHM_2BYTE_SHIFT) : \ ++ (brcmf_sdiod_readl(sdh, D11SHM_ADDR(offset), ret) \ ++ & D11SHM_SECOND2BYTE_MASK)) ++ ++/* SHM is of size 2 bytes, 4 bytes write will overwrite other SHM's ++ * First read 4 bytes and then clear the required two bytes based on ++ * 4 byte alignment, then update the required value and write the ++ * 4 byte value now ++ */ ++#define D11SHM_WR(sdh, offset, val, mask, ret) \ ++ do { \ ++ if ((offset) % 4) \ ++ val = (val & D11SHM_SECOND2BYTE_MASK) | \ ++ ((mask) << D11SHM_2BYTE_SHIFT); \ ++ else \ ++ val = (mask) | (val & D11SHM_FIRST2BYTE_MASK); \ ++ brcmf_sdiod_writel(sdh, D11SHM_ADDR(offset), val, ret); \ ++ } while (0) ++#define D11REG_WR(sdh, addr, val, ret) \ ++ brcmf_sdiod_writel(sdh, addr, val, ret) ++ ++#define D11REG_RD(sdh, addr, ret) \ ++ brcmf_sdiod_readl(sdh, addr, ret) ++ + #endif /* BRCMFMAC_SDIO_H */ +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c +@@ -1202,7 +1202,7 @@ static void brcmf_usb_probe_phase2(struc + goto error; + + /* Attach to the common driver interface */ +- ret = brcmf_attach(devinfo->dev); ++ ret = brcmf_attach(devinfo->dev, true); + if (ret) + goto error; + +@@ -1279,7 +1279,7 @@ static int brcmf_usb_probe_cb(struct brc + ret = brcmf_alloc(devinfo->dev, devinfo->settings); + if (ret) + goto fail; +- ret = brcmf_attach(devinfo->dev); ++ ret = brcmf_attach(devinfo->dev, true); + if (ret) + goto fail; + /* we are done */ +--- a/drivers/net/wireless/broadcom/brcm80211/include/chipcommon.h ++++ b/drivers/net/wireless/broadcom/brcm80211/include/chipcommon.h +@@ -308,4 +308,6 @@ struct chipcregs { + */ + #define PMU_MAX_TRANSITION_DLY 15000 + ++#define DEFAULT_43012_MIN_RES_MASK 0x0f8bfe77 ++ + #endif /* _SBCHIPC_H */ diff --git a/package/kernel/mac80211/patches/brcm/870-05-rpi-6.12-brcmfmac-Fix-interoperating-DPP-and-other-encryption.patch b/package/kernel/mac80211/patches/brcm/870-05-rpi-6.12-brcmfmac-Fix-interoperating-DPP-and-other-encryption.patch new file mode 100644 index 00000000000000..080ce2bb865709 --- /dev/null +++ b/package/kernel/mac80211/patches/brcm/870-05-rpi-6.12-brcmfmac-Fix-interoperating-DPP-and-other-encryption.patch @@ -0,0 +1,129 @@ +From 4c1d4af0ac83705828dd11fded409163a87ea515 Mon Sep 17 00:00:00 2001 +From: Kurt Lee +Date: Thu, 20 Aug 2020 03:07:02 -0500 +Subject: [PATCH] brcmfmac: Fix interoperating DPP and other encryption network + access + +1. If firmware supports 4-way handshake offload but not supports DPP +4-way offload, when user first connects encryption network, driver will +set "sup_wpa 1" to firmware, but it will further result in DPP +connection failure since firmware won't send EAPOL frame to host. + +2. Fix DPP AP mode handling action frames. + +3. For some firmware without fwsup support, the join procedure will be +skipped due to "sup_wpa" iovar returning not-support. Check the fwsup +feature before do such iovar. + +Signed-off-by: Kurt Lee +Signed-off-by: Double Lo +Signed-off-by: Chi-hsien Lin +--- + .../broadcom/brcm80211/brcmfmac/cfg80211.c | 67 ++++++++++--------- + .../broadcom/brcm80211/brcmfmac/p2p.c | 5 ++ + 2 files changed, 42 insertions(+), 30 deletions(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +@@ -2491,43 +2491,50 @@ brcmf_cfg80211_connect(struct wiphy *wip + goto done; + } + +- if (sme->crypto.psk && +- profile->use_fwsup != BRCMF_PROFILE_FWSUP_SAE) { +- if (WARN_ON(profile->use_fwsup != BRCMF_PROFILE_FWSUP_NONE)) { +- err = -EINVAL; +- goto done; ++ if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_FWSUP)) { ++ if (sme->crypto.psk) { ++ if (profile->use_fwsup != BRCMF_PROFILE_FWSUP_SAE) { ++ if (WARN_ON(profile->use_fwsup != ++ BRCMF_PROFILE_FWSUP_NONE)) { ++ err = -EINVAL; ++ goto done; ++ } ++ brcmf_dbg(INFO, "using PSK offload\n"); ++ profile->use_fwsup = BRCMF_PROFILE_FWSUP_PSK; ++ } ++ } else { ++ profile->use_fwsup = BRCMF_PROFILE_FWSUP_NONE; + } +- brcmf_dbg(INFO, "using PSK offload\n"); +- profile->use_fwsup = BRCMF_PROFILE_FWSUP_PSK; +- } + +- if (profile->use_fwsup != BRCMF_PROFILE_FWSUP_NONE) { +- /* enable firmware supplicant for this interface */ +- err = brcmf_fil_iovar_int_set(ifp, "sup_wpa", 1); +- if (err < 0) { +- bphy_err(drvr, "failed to enable fw supplicant\n"); +- goto done; ++ if (profile->use_fwsup != BRCMF_PROFILE_FWSUP_NONE) { ++ /* enable firmware supplicant for this interface */ ++ err = brcmf_fil_iovar_int_set(ifp, "sup_wpa", 1); ++ if (err < 0) { ++ bphy_err(drvr, "failed to enable fw supplicant\n"); ++ goto done; ++ } ++ } else { ++ err = brcmf_fil_iovar_int_set(ifp, "sup_wpa", 0); + } +- } + +- if (profile->use_fwsup == BRCMF_PROFILE_FWSUP_PSK) +- err = brcmf_set_pmk(ifp, sme->crypto.psk, +- BRCMF_WSEC_MAX_PSK_LEN); +- else if (profile->use_fwsup == BRCMF_PROFILE_FWSUP_SAE) { +- /* clean up user-space RSNE */ +- err = brcmf_fil_iovar_data_set(ifp, "wpaie", NULL, 0); +- if (err) { +- bphy_err(drvr, "failed to clean up user-space RSNE\n"); +- goto done; +- } +- err = brcmf_fwvid_set_sae_password(ifp, &sme->crypto); +- if (!err && sme->crypto.psk) ++ if (profile->use_fwsup == BRCMF_PROFILE_FWSUP_PSK) { + err = brcmf_set_pmk(ifp, sme->crypto.psk, + BRCMF_WSEC_MAX_PSK_LEN); ++ } else if (profile->use_fwsup == BRCMF_PROFILE_FWSUP_SAE) { ++ /* clean up user-space RSNE */ ++ err = brcmf_fil_iovar_data_set(ifp, "wpaie", NULL, 0); ++ if (err) { ++ bphy_err(drvr, "failed to clean up user-space RSNE\n"); ++ goto done; ++ } ++ err = brcmf_fwvid_set_sae_password(ifp, &sme->crypto); ++ if (!err && sme->crypto.psk) ++ err = brcmf_set_pmk(ifp, sme->crypto.psk, ++ BRCMF_WSEC_MAX_PSK_LEN); ++ } ++ if (err) ++ goto done; + } +- if (err) +- goto done; +- + /* Join with specific BSSID and cached SSID + * If SSID is zero join based on BSSID only + */ +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c +@@ -1281,6 +1281,10 @@ static s32 brcmf_p2p_abort_action_frame( + brcmf_dbg(TRACE, "Enter\n"); + + vif = p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif; ++ ++ if (!vif) ++ vif = p2p->bss_idx[P2PAPI_BSSCFG_PRIMARY].vif; ++ + err = brcmf_fil_bsscfg_data_set(vif->ifp, "actframe_abort", &int_val, + sizeof(s32)); + if (err) +@@ -1826,6 +1830,7 @@ bool brcmf_p2p_send_action_frame(struct + /* validate channel and p2p ies */ + if (config_af_params.search_channel && + IS_P2P_SOCIAL_CHANNEL(le32_to_cpu(af_params->channel)) && ++ p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif && + p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif->saved_ie.probe_req_ie_len) { + afx_hdl = &p2p->afx_hdl; + afx_hdl->peer_listen_chan = le32_to_cpu(af_params->channel); diff --git a/package/kernel/mac80211/patches/brcm/870-06-rpi-6.12-brcmfmac-Include-modinfo-for-43456-CLM-blob.patch b/package/kernel/mac80211/patches/brcm/870-06-rpi-6.12-brcmfmac-Include-modinfo-for-43456-CLM-blob.patch new file mode 100644 index 00000000000000..f90406fa9ae488 --- /dev/null +++ b/package/kernel/mac80211/patches/brcm/870-06-rpi-6.12-brcmfmac-Include-modinfo-for-43456-CLM-blob.patch @@ -0,0 +1,26 @@ +From 0ff7f575b657b3fdfbd6902b68a28548208f4d36 Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Thu, 8 May 2025 16:55:27 +0100 +Subject: [PATCH] wifi: brcmfmac: Include modinfo for 43456 CLM blob + +Listing firmware files in the brcmfmac modinfo helps with e.g. initramfs +creation. + +See: https://github.com/raspberrypi/linux/issues/6828 + +Signed-off-by: Phil Elwell +--- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c +@@ -631,7 +631,7 @@ BRCMF_FW_CLM_DEF(43430A1, "brcmfmac43430 + BRCMF_FW_DEF(43430B0, "brcmfmac43430b0-sdio"); + BRCMF_FW_CLM_DEF(43439, "brcmfmac43439-sdio"); + BRCMF_FW_CLM_DEF(43455, "brcmfmac43455-sdio"); +-BRCMF_FW_DEF(43456, "brcmfmac43456-sdio"); ++BRCMF_FW_CLM_DEF(43456, "brcmfmac43456-sdio"); + BRCMF_FW_CLM_DEF(4354, "brcmfmac4354-sdio"); + BRCMF_FW_CLM_DEF(4356, "brcmfmac4356-sdio"); + BRCMF_FW_DEF(4359, "brcmfmac4359-sdio"); diff --git a/package/kernel/mac80211/patches/brcm/865-brcmfmac-disable-dump_survey-on-bcm2835.patch b/package/kernel/mac80211/patches/brcm/871-brcmfmac-disable-dump_survey-on-bcm2835.patch similarity index 87% rename from package/kernel/mac80211/patches/brcm/865-brcmfmac-disable-dump_survey-on-bcm2835.patch rename to package/kernel/mac80211/patches/brcm/871-brcmfmac-disable-dump_survey-on-bcm2835.patch index 275f0aa166e48a..0dd0d11c18a96a 100644 --- a/package/kernel/mac80211/patches/brcm/865-brcmfmac-disable-dump_survey-on-bcm2835.patch +++ b/package/kernel/mac80211/patches/brcm/871-brcmfmac-disable-dump_survey-on-bcm2835.patch @@ -9,7 +9,7 @@ Signed-off-by: Álvaro Fernández Rojas --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c -@@ -7986,6 +7986,7 @@ static s32 brcmf_translate_country_code( +@@ -7991,6 +7991,7 @@ static s32 brcmf_translate_country_code( return 0; } @@ -17,7 +17,7 @@ Signed-off-by: Álvaro Fernández Rojas static int brcmf_parse_dump_obss(char *buf, struct brcmf_dump_survey *survey) { -@@ -8208,6 +8209,7 @@ exit: +@@ -8213,6 +8214,7 @@ exit: brcmf_set_mpc(ifp, 1); return err; } @@ -25,7 +25,7 @@ Signed-off-by: Álvaro Fernández Rojas static void brcmf_cfg80211_reg_notifier(struct wiphy *wiphy, struct regulatory_request *req) -@@ -8360,8 +8362,10 @@ struct brcmf_cfg80211_info *brcmf_cfg802 +@@ -8379,8 +8381,10 @@ struct brcmf_cfg80211_info *brcmf_cfg802 if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_WOWL_GTK)) ops->set_rekey_data = brcmf_cfg80211_set_rekey_data; #endif diff --git a/package/kernel/mac80211/patches/build/070-remove-broken-wext-select.patch b/package/kernel/mac80211/patches/build/070-remove-broken-wext-select.patch deleted file mode 100644 index 121b7faad93795..00000000000000 --- a/package/kernel/mac80211/patches/build/070-remove-broken-wext-select.patch +++ /dev/null @@ -1,10 +0,0 @@ ---- a/drivers/staging/rtl8723bs/Kconfig -+++ b/drivers/staging/rtl8723bs/Kconfig -@@ -5,7 +5,6 @@ config RTL8723BS - depends on m - depends on WLAN && MMC && CFG80211 - depends on m -- select CFG80211_WEXT - depends on CRYPTO - select BPAUTO_CRYPTO_LIB_ARC4 - help diff --git a/package/kernel/mac80211/patches/build/120-headers_version_fix.patch b/package/kernel/mac80211/patches/build/120-headers_version_fix.patch deleted file mode 100644 index 29f500a4d069b4..00000000000000 --- a/package/kernel/mac80211/patches/build/120-headers_version_fix.patch +++ /dev/null @@ -1,14 +0,0 @@ ---- a/backport-include/net/dropreason.h -+++ b/backport-include/net/dropreason.h -@@ -3,10 +3,9 @@ - - #include - -+#include - #if LINUX_VERSION_IS_GEQ(6,0,0) - #include_next --#else --#include - #endif - - #if LINUX_VERSION_IS_LESS(6,4,0) diff --git a/package/kernel/mac80211/patches/build/140-trace_backport.patch b/package/kernel/mac80211/patches/build/140-trace_backport.patch index 00ee47e1a46392..8b77b7e83d9f0b 100644 --- a/package/kernel/mac80211/patches/build/140-trace_backport.patch +++ b/package/kernel/mac80211/patches/build/140-trace_backport.patch @@ -1,6 +1,6 @@ --- a/drivers/bus/mhi/host/trace.h +++ b/drivers/bus/mhi/host/trace.h -@@ -103,7 +103,7 @@ TRACE_EVENT(mhi_gen_tre, +@@ -104,7 +104,7 @@ TRACE_EVENT(mhi_gen_tre, ), TP_fast_assign( @@ -8,8 +8,8 @@ + __assign_str(name, mhi_cntrl->mhi_dev->name); __entry->ch_num = mhi_chan->chan; __entry->wp = mhi_tre; - __entry->tre_ptr = mhi_tre->ptr; -@@ -131,7 +131,7 @@ TRACE_EVENT(mhi_intvec_states, + __entry->tre_ptr = le64_to_cpu(mhi_tre->ptr); +@@ -132,7 +132,7 @@ TRACE_EVENT(mhi_intvec_states, ), TP_fast_assign( @@ -18,7 +18,7 @@ __entry->local_ee = mhi_cntrl->ee; __entry->state = mhi_cntrl->dev_state; __entry->dev_ee = dev_ee; -@@ -158,7 +158,7 @@ TRACE_EVENT(mhi_tryset_pm_state, +@@ -159,7 +159,7 @@ TRACE_EVENT(mhi_tryset_pm_state, ), TP_fast_assign( @@ -27,16 +27,16 @@ if (pm_state) pm_state = __fls(pm_state); __entry->pm_state = pm_state; -@@ -184,7 +184,7 @@ DECLARE_EVENT_CLASS(mhi_process_event_ri +@@ -185,7 +185,7 @@ DECLARE_EVENT_CLASS(mhi_process_event_ri ), TP_fast_assign( - __assign_str(name); + __assign_str(name, mhi_cntrl->mhi_dev->name); __entry->rp = rp; - __entry->ptr = rp->ptr; - __entry->dword0 = rp->dword[0]; -@@ -226,7 +226,7 @@ DECLARE_EVENT_CLASS(mhi_update_channel_s + __entry->ptr = le64_to_cpu(rp->ptr); + __entry->dword0 = le32_to_cpu(rp->dword[0]); +@@ -227,7 +227,7 @@ DECLARE_EVENT_CLASS(mhi_update_channel_s ), TP_fast_assign( @@ -45,7 +45,7 @@ __entry->ch_num = mhi_chan->chan; __entry->state = state; __entry->reason = reason; -@@ -265,7 +265,7 @@ TRACE_EVENT(mhi_pm_st_transition, +@@ -266,7 +266,7 @@ TRACE_EVENT(mhi_pm_st_transition, ), TP_fast_assign( diff --git a/package/kernel/mac80211/patches/build/150-ath_iommu_paging_domain_revert.patch b/package/kernel/mac80211/patches/build/150-ath_iommu_paging_domain_revert.patch index 2c5235e49f1a38..f5ef0c629c286d 100644 --- a/package/kernel/mac80211/patches/build/150-ath_iommu_paging_domain_revert.patch +++ b/package/kernel/mac80211/patches/build/150-ath_iommu_paging_domain_revert.patch @@ -1,6 +1,6 @@ --- a/drivers/net/wireless/ath/ath10k/snoc.c +++ b/drivers/net/wireless/ath/ath10k/snoc.c -@@ -1635,10 +1635,10 @@ static int ath10k_fw_init(struct ath10k +@@ -1637,10 +1637,10 @@ static int ath10k_fw_init(struct ath10k ar_snoc->fw.dev = &pdev->dev; diff --git a/package/kernel/mac80211/patches/build/210-wireless_netns_local_backport.patch b/package/kernel/mac80211/patches/build/210-wireless_netns_local_backport.patch new file mode 100644 index 00000000000000..9a467c43b168b8 --- /dev/null +++ b/package/kernel/mac80211/patches/build/210-wireless_netns_local_backport.patch @@ -0,0 +1,44 @@ +--- a/net/wireless/core.c ++++ b/net/wireless/core.c +@@ -165,11 +165,15 @@ int cfg80211_switch_netns(struct cfg8021 + list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) { + if (!wdev->netdev) + continue; ++#if LINUX_VERSION_IS_GEQ(6,12,0) + wdev->netdev->netns_local = false; ++#endif + err = dev_change_net_namespace(wdev->netdev, net, "wlan%d"); + if (err) + break; ++#if LINUX_VERSION_IS_GEQ(6,12,0) + wdev->netdev->netns_local = true; ++#endif + } + + if (err) { +@@ -181,11 +185,15 @@ int cfg80211_switch_netns(struct cfg8021 + list) { + if (!wdev->netdev) + continue; ++#if LINUX_VERSION_IS_GEQ(6,12,0) + wdev->netdev->netns_local = false; ++#endif + err = dev_change_net_namespace(wdev->netdev, net, + "wlan%d"); + WARN_ON(err); ++#if LINUX_VERSION_IS_GEQ(6,12,0) + wdev->netdev->netns_local = true; ++#endif + } + + return err; +@@ -1525,7 +1533,9 @@ static int cfg80211_netdev_notifier_call + SET_NETDEV_DEVTYPE(dev, &wiphy_type); + wdev->netdev = dev; + /* can only change netns with wiphy */ ++#if LINUX_VERSION_IS_GEQ(6,12,0) + dev->netns_local = true; ++#endif + + cfg80211_init_wdev(wdev); + break; diff --git a/package/kernel/mac80211/patches/build/230-brcmfmac_usb_driver_backport.patch b/package/kernel/mac80211/patches/build/220-brcmfmac_usb_driver_backport.patch similarity index 84% rename from package/kernel/mac80211/patches/build/230-brcmfmac_usb_driver_backport.patch rename to package/kernel/mac80211/patches/build/220-brcmfmac_usb_driver_backport.patch index 25dab46905428b..185b71f1ff05ef 100644 --- a/package/kernel/mac80211/patches/build/230-brcmfmac_usb_driver_backport.patch +++ b/package/kernel/mac80211/patches/build/220-brcmfmac_usb_driver_backport.patch @@ -1,6 +1,6 @@ --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c -@@ -1574,7 +1574,11 @@ static int brcmf_usb_reset_device(struct +@@ -1576,7 +1576,11 @@ static int brcmf_usb_reset_device(struct void brcmf_usb_exit(void) { diff --git a/package/kernel/mac80211/patches/build/235-fix-init_vqs-build-error-on-kernel-6.6.patch b/package/kernel/mac80211/patches/build/230-fix-init_vqs-build-error-on-kernel-6.6.patch similarity index 87% rename from package/kernel/mac80211/patches/build/235-fix-init_vqs-build-error-on-kernel-6.6.patch rename to package/kernel/mac80211/patches/build/230-fix-init_vqs-build-error-on-kernel-6.6.patch index 4b0fe6003f6692..229deee9e8c7c9 100644 --- a/package/kernel/mac80211/patches/build/235-fix-init_vqs-build-error-on-kernel-6.6.patch +++ b/package/kernel/mac80211/patches/build/230-fix-init_vqs-build-error-on-kernel-6.6.patch @@ -1,6 +1,6 @@ --- a/drivers/net/wireless/virtual/mac80211_hwsim.c +++ b/drivers/net/wireless/virtual/mac80211_hwsim.c -@@ -6629,6 +6629,7 @@ static void hwsim_virtio_rx_done(struct +@@ -6636,6 +6636,7 @@ static void hwsim_virtio_rx_done(struct static int init_vqs(struct virtio_device *vdev) { @@ -8,7 +8,7 @@ struct virtqueue_info vqs_info[HWSIM_NUM_VQS] = { [HWSIM_VQ_TX] = { "tx", hwsim_virtio_tx_done }, [HWSIM_VQ_RX] = { "rx", hwsim_virtio_rx_done }, -@@ -6636,6 +6637,19 @@ static int init_vqs(struct virtio_device +@@ -6643,6 +6644,19 @@ static int init_vqs(struct virtio_device return virtio_find_vqs(vdev, HWSIM_NUM_VQS, hwsim_vqs, vqs_info, NULL); diff --git a/package/kernel/mac80211/patches/build/300-backports-handle-genlmsg_multicast_allns-upstream-ba.patch b/package/kernel/mac80211/patches/build/300-backports-handle-genlmsg_multicast_allns-upstream-ba.patch new file mode 100644 index 00000000000000..523b5c67f42de5 --- /dev/null +++ b/package/kernel/mac80211/patches/build/300-backports-handle-genlmsg_multicast_allns-upstream-ba.patch @@ -0,0 +1,121 @@ +From 8dc94a59cfad70ec3a808add56718255eee39ab2 Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Sat, 29 Mar 2025 12:50:55 +0100 +Subject: [PATCH] backports: handle genlmsg_multicast_allns upstream backport + changes + +Better handle genlmsg_multicast_allns upstream backport changes that +dropped a flag to the function middle version. Use a backport function +if backports project is tried to be built on older kernel version. + +Signed-off-by: Christian Marangi +--- + backport-include/net/genetlink.h | 11 +++++ + compat/Makefile | 3 +- + compat/backport-genetlink.c | 60 +++++++++++++++++++++++ + 3 files changed, 73 insertions(+), 1 deletion(-) + +--- a/backport-include/net/genetlink.h ++++ b/backport-include/net/genetlink.h +@@ -172,4 +172,15 @@ static inline int genlmsg_parse(const st + } + #endif /* LINUX_VERSION_IS_LESS(5,2,0) */ + ++#if LINUX_VERSION_IN_RANGE(5,15,0,5,15,169) || \ ++ LINUX_VERSION_IN_RANGE(6,1,0,6,1,115) || \ ++ LINUX_VERSION_IN_RANGE(6,6,0,6,6,58) ++#define genlmsg_multicast_allns LINUX_BACKPORT(genlmsg_multicast_allns) ++int backport_genlmsg_multicast_allns(const struct genl_family *family, ++ struct sk_buff *skb, u32 portid, ++ unsigned int group); ++#endif /* LINUX_VERSION_IN_RANGE(5,15,0,5,15,169) || ++ LINUX_VERSION_IN_RANGE(6,1,0,6,1,115) || ++ LINUX_VERSION_IN_RANGE(6,6,0,6,6,58) */ ++ + #endif /* __BACKPORT_NET_GENETLINK_H */ +--- a/compat/Makefile ++++ b/compat/Makefile +@@ -16,7 +16,8 @@ compat-$(CPTCFG_KERNEL_5_9) += backport- + compat-$(CPTCFG_KERNEL_5_10) += backport-5.10.o + compat-$(CPTCFG_KERNEL_5_11) += backport-5.11.o + compat-$(CPTCFG_KERNEL_5_13) += backport-5.13.o +-compat-$(CPTCFG_KERNEL_5_15) += backport-5.15.o ++compat-$(CPTCFG_KERNEL_5_15) += backport-5.15.o backport-genetlink.o ++compat-$(CPTCFG_KERNEL_6_1) += backport-genetlink.o + compat-$(CPTCFG_KERNEL_6_4) += backport-6.4.o + compat-$(CPTCFG_KERNEL_6_11) += backport-6.11.o + +--- a/compat/backport-genetlink.c ++++ b/compat/backport-genetlink.c +@@ -17,6 +17,7 @@ + #include + #include + ++#if LINUX_VERSION_IS_LESS(5,2,0) + static const struct genl_family *find_family_real_ops(const struct genl_ops **ops) + { + const struct genl_family *family; +@@ -249,3 +250,63 @@ int backport_genlmsg_multicast_allns(con + return genlmsg_mcast(skb, portid, group); + } + EXPORT_SYMBOL_GPL(backport_genlmsg_multicast_allns); ++#endif /* LINUX_VERSION_IS_LESS(5,2,0) */ ++ ++#if LINUX_VERSION_IN_RANGE(5,15,0,5,15,169) || \ ++ LINUX_VERSION_IN_RANGE(6,1,0,6,1,115) || \ ++ LINUX_VERSION_IN_RANGE(6,6,0,6,6,58) ++static int genlmsg_mcast(struct sk_buff *skb, u32 portid, unsigned long group) ++{ ++ struct sk_buff *tmp; ++ struct net *net, *prev = NULL; ++ bool delivered = false; ++ int err; ++ ++ rcu_read_lock(); ++ for_each_net_rcu(net) { ++ if (prev) { ++ tmp = skb_clone(skb, GFP_ATOMIC); ++ if (!tmp) { ++ err = -ENOMEM; ++ goto error; ++ } ++ err = nlmsg_multicast(prev->genl_sock, tmp, ++ portid, group, GFP_ATOMIC); ++ if (!err) ++ delivered = true; ++ else if (err != -ESRCH) ++ goto error; ++ } ++ ++ prev = net; ++ } ++ err = nlmsg_multicast(prev->genl_sock, skb, portid, group, GFP_ATOMIC); ++ ++ rcu_read_unlock(); ++ ++ if (!err) ++ delivered = true; ++ else if (err != -ESRCH) ++ return err; ++ return delivered ? 0 : -ESRCH; ++ error: ++ rcu_read_unlock(); ++ ++ kfree_skb(skb); ++ return err; ++} ++ ++int backport_genlmsg_multicast_allns(const struct genl_family *family, ++ struct sk_buff *skb, u32 portid, ++ unsigned int group) ++{ ++ if (WARN_ON_ONCE(group >= family->n_mcgrps)) ++ return -EINVAL; ++ ++ group = family->mcgrp_offset + group; ++ return genlmsg_mcast(skb, portid, group); ++} ++EXPORT_SYMBOL_GPL(backport_genlmsg_multicast_allns); ++#endif /* LINUX_VERSION_IN_RANGE(5,15,0,5,15,169) || ++ LINUX_VERSION_IN_RANGE(6,1,0,6,1,115) || ++ LINUX_VERSION_IN_RANGE(6,6,0,6,6,58) */ diff --git a/package/kernel/mac80211/patches/mwl/700-mwl8k-missing-pci-id-for-WNR854T.patch b/package/kernel/mac80211/patches/mwl/700-mwl8k-missing-pci-id-for-WNR854T.patch index c3324f4289f8af..7baab80d245254 100644 --- a/package/kernel/mac80211/patches/mwl/700-mwl8k-missing-pci-id-for-WNR854T.patch +++ b/package/kernel/mac80211/patches/mwl/700-mwl8k-missing-pci-id-for-WNR854T.patch @@ -1,6 +1,6 @@ --- a/drivers/net/wireless/marvell/mwl8k.c +++ b/drivers/net/wireless/marvell/mwl8k.c -@@ -5709,6 +5709,7 @@ MODULE_FIRMWARE("mwl8k/fmimage_8366.fw") +@@ -5716,6 +5716,7 @@ MODULE_FIRMWARE("mwl8k/fmimage_8366.fw") MODULE_FIRMWARE(MWL8K_8366_AP_FW(MWL8K_8366_AP_FW_API)); static const struct pci_device_id mwl8k_pci_id_table[] = { diff --git a/package/kernel/mac80211/patches/mwl/900-mwifiex-increase-the-global-limit-up-to-4-SSID.patch b/package/kernel/mac80211/patches/mwl/900-mwifiex-increase-the-global-limit-up-to-4-SSID.patch index caa139a2c6eae9..484b37bfcc53d5 100644 --- a/package/kernel/mac80211/patches/mwl/900-mwifiex-increase-the-global-limit-up-to-4-SSID.patch +++ b/package/kernel/mac80211/patches/mwl/900-mwifiex-increase-the-global-limit-up-to-4-SSID.patch @@ -30,7 +30,7 @@ the card-specific structure. #define MWIFIEX_DMA_ALIGN_SZ 64 #define MWIFIEX_RX_HEADROOM 64 -@@ -100,7 +100,7 @@ +@@ -123,7 +123,7 @@ #define MWIFIEX_RATE_INDEX_OFDM0 4 #define MWIFIEX_MAX_STA_NUM 3 diff --git a/package/kernel/mac80211/patches/mwl/940-mwl8k_init_devices_synchronously.patch b/package/kernel/mac80211/patches/mwl/940-mwl8k_init_devices_synchronously.patch index 062b0600d0c8d4..d021b1e40b9b15 100644 --- a/package/kernel/mac80211/patches/mwl/940-mwl8k_init_devices_synchronously.patch +++ b/package/kernel/mac80211/patches/mwl/940-mwl8k_init_devices_synchronously.patch @@ -1,6 +1,6 @@ --- a/drivers/net/wireless/marvell/mwl8k.c +++ b/drivers/net/wireless/marvell/mwl8k.c -@@ -6295,6 +6295,8 @@ static int mwl8k_probe(struct pci_dev *p +@@ -6302,6 +6302,8 @@ static int mwl8k_probe(struct pci_dev *p priv->running_bsses = 0; @@ -9,7 +9,7 @@ return rc; err_stop_firmware: -@@ -6328,8 +6330,6 @@ static void mwl8k_remove(struct pci_dev +@@ -6335,8 +6337,6 @@ static void mwl8k_remove(struct pci_dev return; priv = hw->priv; diff --git a/package/kernel/mac80211/patches/mwl/950-mwifiex-Print-stringified-name-of-command-in-error-l.patch b/package/kernel/mac80211/patches/mwl/950-mwifiex-Print-stringified-name-of-command-in-error-l.patch index a7ecabde8296a6..93a213265c641c 100644 --- a/package/kernel/mac80211/patches/mwl/950-mwifiex-Print-stringified-name-of-command-in-error-l.patch +++ b/package/kernel/mac80211/patches/mwl/950-mwifiex-Print-stringified-name-of-command-in-error-l.patch @@ -116,7 +116,7 @@ Signed-off-by: Pali Rohár mwifiex_recycle_cmd_node(adapter, cmd_node); queue_work(adapter->workqueue, &adapter->main_work); return -1; -@@ -653,8 +732,8 @@ int mwifiex_send_cmd(struct mwifiex_priv +@@ -655,8 +734,8 @@ int mwifiex_send_cmd(struct mwifiex_priv /* Return error, since the command preparation failed */ if (ret) { mwifiex_dbg(adapter, ERROR, @@ -127,7 +127,7 @@ Signed-off-by: Pali Rohár mwifiex_insert_cmd_to_free_q(adapter, cmd_node); return -1; } -@@ -902,8 +981,9 @@ int mwifiex_process_cmdresp(struct mwifi +@@ -904,8 +983,9 @@ int mwifiex_process_cmdresp(struct mwifi if (adapter->hw_status == MWIFIEX_HW_STATUS_INITIALIZING) { if (ret) { mwifiex_dbg(adapter, ERROR, @@ -139,7 +139,7 @@ Signed-off-by: Pali Rohár mwifiex_init_fw_complete(adapter); return -1; } else if (adapter->last_init_cmd == cmdresp_no) -@@ -1265,8 +1345,8 @@ mwifiex_process_sleep_confirm_resp(struc +@@ -1287,8 +1367,8 @@ mwifiex_process_sleep_confirm_resp(struc if (command != HostCmd_CMD_802_11_PS_MODE_ENH) { mwifiex_dbg(adapter, ERROR, @@ -152,7 +152,7 @@ Signed-off-by: Pali Rohár --- a/drivers/net/wireless/marvell/mwifiex/main.h +++ b/drivers/net/wireless/marvell/mwifiex/main.h -@@ -1084,6 +1084,8 @@ void mwifiex_cancel_all_pending_cmd(stru +@@ -1100,6 +1100,8 @@ void mwifiex_cancel_all_pending_cmd(stru void mwifiex_cancel_pending_scan_cmd(struct mwifiex_adapter *adapter); void mwifiex_cancel_scan(struct mwifiex_adapter *adapter); @@ -177,7 +177,7 @@ Signed-off-by: Pali Rohár adapter->cmd_wait_q.status = -1; --- a/drivers/net/wireless/marvell/mwifiex/uap_cmd.c +++ b/drivers/net/wireless/marvell/mwifiex/uap_cmd.c -@@ -802,7 +802,8 @@ int mwifiex_uap_prepare_cmd(struct mwifi +@@ -964,7 +964,8 @@ int mwifiex_uap_prepare_cmd(struct mwifi break; default: mwifiex_dbg(priv->adapter, ERROR, diff --git a/package/kernel/mac80211/patches/rt2x00/602-01-wifi-rt2x00-Add-support-for-loading-EEPROM-from-user.patch b/package/kernel/mac80211/patches/rt2x00/602-01-wifi-rt2x00-Add-support-for-loading-EEPROM-from-user.patch index b6b1e0da96382d..f3c8ddd4f6533d 100644 --- a/package/kernel/mac80211/patches/rt2x00/602-01-wifi-rt2x00-Add-support-for-loading-EEPROM-from-user.patch +++ b/package/kernel/mac80211/patches/rt2x00/602-01-wifi-rt2x00-Add-support-for-loading-EEPROM-from-user.patch @@ -151,7 +151,7 @@ Signed-off-by: Christian Marangi + } + + if (!ee_name) -+ return 0; ++ return -ENOENT; + + rt2x00_info(rt2x00dev, "Loading EEPROM data from '%s'.\n", ee_name); + diff --git a/package/kernel/mac80211/patches/rt2x00/603-wifi-rt2x00-Add-support-for-loading-EEPROM-from-devicetree-embedded-data.patch b/package/kernel/mac80211/patches/rt2x00/603-wifi-rt2x00-Add-support-for-loading-EEPROM-from-devicetree-embedded-data.patch new file mode 100644 index 00000000000000..0ef946a6cb78b5 --- /dev/null +++ b/package/kernel/mac80211/patches/rt2x00/603-wifi-rt2x00-Add-support-for-loading-EEPROM-from-devicetree-embedded-data.patch @@ -0,0 +1,76 @@ +From adf957124a115bdf3e4728e1ea8c70a632648cf0 Mon Sep 17 00:00:00 2001 +From: Coia Prant +Date: Fri, 14 Feb 2025 15:49:55 +0800 +Subject: [PATCH] wifi: rt2x00: Add support for loading EEPROM from devicetree + embedded data + +This patch allows rt2x00 to load eeprom from devicetree embedded data. + +Example: + +/* load eeprom from embedded data 'eeprom-data' */ +&wmac { + ralink,eeprom-data = <0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff + 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff + 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff + 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff + 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff + 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff + 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff + 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff + 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff + 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff + 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff + 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff + 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff + 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff + 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff + 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff>; +}; + +Signed-off-by: Coia Prant +--- + .../net/wireless/ralink/rt2x00/rt2x00eeprom.c | 25 +++++++++++++++++++ + 1 file changed, 25 insertions(+) + +--- a/drivers/net/wireless/ralink/rt2x00/rt2x00eeprom.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00eeprom.c +@@ -33,6 +33,27 @@ static void rt2800lib_eeprom_swap(struct + rt2x00dev->eeprom[i] = swab16(rt2x00dev->eeprom[i]); + } + ++static int rt2800lib_read_eeprom_data(struct rt2x00_dev *rt2x00dev) ++{ ++ struct device_node *np = rt2x00dev->dev->of_node; ++ unsigned int len = rt2x00dev->ops->eeprom_size; ++ const void *data; ++ int size; ++ ++ data = of_get_property(np, "ralink,eeprom-data", &size); ++ if (!data) ++ return -ENOENT; ++ ++ if (size != len) { ++ dev_err(rt2x00dev->dev, "invalid eeprom size, required: 0x%04x\n", len); ++ return -EINVAL; ++ } ++ ++ memcpy(rt2x00dev->eeprom, data, size); ++ ++ return 0; ++} ++ + #if IS_ENABLED(CONFIG_MTD) + static int rt2800lib_read_eeprom_mtd(struct rt2x00_dev *rt2x00dev) + { +@@ -193,6 +214,10 @@ int rt2x00lib_read_eeprom(struct rt2x00_ + { + int ret; + ++ ret = rt2800lib_read_eeprom_data(rt2x00dev); ++ if (!ret) ++ return 0; ++ + #if IS_ENABLED(CONFIG_MTD) + ret = rt2800lib_read_eeprom_mtd(rt2x00dev); + if (!ret) diff --git a/package/kernel/mac80211/patches/rt2x00/620-01-rt2x00-respect-rt2800-hardware-TX-queue-index.patch b/package/kernel/mac80211/patches/rt2x00/620-01-rt2x00-respect-rt2800-hardware-TX-queue-index.patch new file mode 100644 index 00000000000000..e2c75979dfec2a --- /dev/null +++ b/package/kernel/mac80211/patches/rt2x00/620-01-rt2x00-respect-rt2800-hardware-TX-queue-index.patch @@ -0,0 +1,257 @@ +From 654653e718f6c55c6f29fd94cc8152a92c8166ac Mon Sep 17 00:00:00 2001 +From: Shiji Yang +Date: Tue, 24 Dec 2024 08:36:32 +0800 +Subject: [PATCH 1/2] rt2x00: respect the rt2800 hardware TX queue index + +The Ralink TX queue register index is different from the Linux +IEEE80211 queue id definition. Their conversion table is as follows: + +Queue IEEE80211 Ralink +AC_VO 0 3 +AC_VI 1 2 +AC_BE 2 0 +AC_BK 3 1 + +The TX queues are still functioning properly under the current +configuration. I don't have evidence, but I believe there should +be some differences in the internal hardware implementation of +different TX queues, e.g. interrupt priority. so it's better to +respect the queue index defined by the Ralink when we construct +the TX rings and descriptors. + +And the more important thing is that we are using the wrong queue +index to calculate the register offset and mask in .conf_tx(), +which resulted in writing incorrect AIFSN, CWMAX, CWMIN and TXOP +values for all TX queues. This patch introduces a index conversion +table to fix these parameters. + +Signed-off-by: Shiji Yang +--- + drivers/net/wireless/ralink/rt2x00/rt2800.h | 24 ++++++------ + .../net/wireless/ralink/rt2x00/rt2800lib.c | 20 +++++++--- + .../net/wireless/ralink/rt2x00/rt2800mmio.c | 38 ++++++++++--------- + .../net/wireless/ralink/rt2x00/rt2x00queue.h | 20 ++++++++++ + 4 files changed, 67 insertions(+), 35 deletions(-) + +--- a/drivers/net/wireless/ralink/rt2x00/rt2800.h ++++ b/drivers/net/wireless/ralink/rt2x00/rt2800.h +@@ -379,10 +379,10 @@ + + /* + * WMM_AIFSN_CFG: Aifsn for each EDCA AC +- * AIFSN0: AC_VO +- * AIFSN1: AC_VI +- * AIFSN2: AC_BE +- * AIFSN3: AC_BK ++ * AIFSN0: AC_BE ++ * AIFSN1: AC_BK ++ * AIFSN2: AC_VI ++ * AIFSN3: AC_VO + */ + #define WMM_AIFSN_CFG 0x0214 + #define WMM_AIFSN_CFG_AIFSN0 FIELD32(0x0000000f) +@@ -392,10 +392,10 @@ + + /* + * WMM_CWMIN_CSR: CWmin for each EDCA AC +- * CWMIN0: AC_VO +- * CWMIN1: AC_VI +- * CWMIN2: AC_BE +- * CWMIN3: AC_BK ++ * CWMIN0: AC_BE ++ * CWMIN1: AC_BK ++ * CWMIN2: AC_VI ++ * CWMIN3: AC_VO + */ + #define WMM_CWMIN_CFG 0x0218 + #define WMM_CWMIN_CFG_CWMIN0 FIELD32(0x0000000f) +@@ -405,10 +405,10 @@ + + /* + * WMM_CWMAX_CSR: CWmax for each EDCA AC +- * CWMAX0: AC_VO +- * CWMAX1: AC_VI +- * CWMAX2: AC_BE +- * CWMAX3: AC_BK ++ * CWMAX0: AC_BE ++ * CWMAX1: AC_BK ++ * CWMAX2: AC_VI ++ * CWMAX3: AC_VO + */ + #define WMM_CWMAX_CFG 0x021c + #define WMM_CWMAX_CFG_CWMAX0 FIELD32(0x0000000f) +--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +@@ -835,7 +835,8 @@ void rt2800_write_tx_data(struct queue_e + txdesc->key_idx : txdesc->u.ht.wcid); + rt2x00_set_field32(&word, TXWI_W1_MPDU_TOTAL_BYTE_COUNT, + txdesc->length); +- rt2x00_set_field32(&word, TXWI_W1_PACKETID_QUEUE, entry->queue->qid); ++ rt2x00_set_field32(&word, TXWI_W1_PACKETID_QUEUE, ++ rt2x00_ac_to_hwq(entry->queue->qid)); + rt2x00_set_field32(&word, TXWI_W1_PACKETID_ENTRY, (entry->entry_idx % 3) + 1); + rt2x00_desc_write(txwi, 1, word); + +@@ -1125,6 +1126,12 @@ void rt2800_txdone(struct rt2x00_dev *rt + u32 reg; + u8 qid; + bool match; ++ static const u8 rt2ac[] = { ++ IEEE80211_AC_BE, ++ IEEE80211_AC_BK, ++ IEEE80211_AC_VI, ++ IEEE80211_AC_VO, ++ }; + + while (quota-- > 0 && kfifo_get(&rt2x00dev->txstatus_fifo, ®)) { + /* +@@ -1132,6 +1139,8 @@ void rt2800_txdone(struct rt2x00_dev *rt + * guaranteed to be one of the TX QIDs . + */ + qid = rt2x00_get_field32(reg, TX_STA_FIFO_PID_QUEUE); ++ /* Convert Ralink hardware queue index to IEEE80211 queue id. */ ++ qid = rt2ac[qid]; + queue = rt2x00queue_get_tx_queue(rt2x00dev, qid); + + if (unlikely(rt2x00queue_empty(queue))) { +@@ -12188,8 +12197,9 @@ int rt2800_conf_tx(struct ieee80211_hw * + queue = rt2x00queue_get_tx_queue(rt2x00dev, queue_idx); + + /* Update WMM TXOP register */ +- offset = WMM_TXOP0_CFG + (sizeof(u32) * (!!(queue_idx & 2))); +- field.bit_offset = (queue_idx & 1) * 16; ++ offset = WMM_TXOP0_CFG + ++ (sizeof(u32) * (!!(rt2x00_ac_to_hwq(queue_idx) & 2))); ++ field.bit_offset = (rt2x00_ac_to_hwq(queue_idx) & 1) * 16; + field.bit_mask = 0xffff << field.bit_offset; + + reg = rt2800_register_read(rt2x00dev, offset); +@@ -12197,7 +12207,7 @@ int rt2800_conf_tx(struct ieee80211_hw * + rt2800_register_write(rt2x00dev, offset, reg); + + /* Update WMM registers */ +- field.bit_offset = queue_idx * 4; ++ field.bit_offset = rt2x00_ac_to_hwq(queue_idx) * 4; + field.bit_mask = 0xf << field.bit_offset; + + reg = rt2800_register_read(rt2x00dev, WMM_AIFSN_CFG); +@@ -12213,7 +12223,7 @@ int rt2800_conf_tx(struct ieee80211_hw * + rt2800_register_write(rt2x00dev, WMM_CWMAX_CFG, reg); + + /* Update EDCA registers */ +- offset = EDCA_AC0_CFG + (sizeof(u32) * queue_idx); ++ offset = EDCA_AC0_CFG + (sizeof(u32) * rt2x00_ac_to_hwq(queue_idx)); + + reg = rt2800_register_read(rt2x00dev, offset); + rt2x00_set_field32(®, EDCA_AC0_CFG_TX_OP, queue->txop); +--- a/drivers/net/wireless/ralink/rt2x00/rt2800mmio.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2800mmio.c +@@ -35,7 +35,7 @@ unsigned int rt2800mmio_get_dma_done(str + case QID_AC_VI: + case QID_AC_BE: + case QID_AC_BK: +- qid = queue->qid; ++ qid = rt2x00_ac_to_hwq(queue->qid); + idx = rt2x00mmio_register_read(rt2x00dev, TX_DTX_IDX(qid)); + break; + case QID_MGMT: +@@ -456,6 +456,7 @@ void rt2800mmio_kick_queue(struct data_q + { + struct rt2x00_dev *rt2x00dev = queue->rt2x00dev; + struct queue_entry *entry; ++ u8 qid; + + switch (queue->qid) { + case QID_AC_VO: +@@ -464,7 +465,8 @@ void rt2800mmio_kick_queue(struct data_q + case QID_AC_BK: + WARN_ON_ONCE(rt2x00queue_empty(queue)); + entry = rt2x00queue_get_entry(queue, Q_INDEX); +- rt2x00mmio_register_write(rt2x00dev, TX_CTX_IDX(queue->qid), ++ qid = rt2x00_ac_to_hwq(queue->qid); ++ rt2x00mmio_register_write(rt2x00dev, TX_CTX_IDX(qid), + entry->entry_idx); + hrtimer_start(&rt2x00dev->txstatus_timer, + TXSTATUS_TIMEOUT, HRTIMER_MODE_REL); +@@ -666,36 +668,36 @@ int rt2800mmio_init_queues(struct rt2x00 + * Initialize registers. + */ + entry_priv = rt2x00dev->tx[0].entries[0].priv_data; +- rt2x00mmio_register_write(rt2x00dev, TX_BASE_PTR0, ++ rt2x00mmio_register_write(rt2x00dev, TX_BASE_PTR3, + entry_priv->desc_dma); +- rt2x00mmio_register_write(rt2x00dev, TX_MAX_CNT0, ++ rt2x00mmio_register_write(rt2x00dev, TX_MAX_CNT3, + rt2x00dev->tx[0].limit); +- rt2x00mmio_register_write(rt2x00dev, TX_CTX_IDX0, 0); +- rt2x00mmio_register_write(rt2x00dev, TX_DTX_IDX0, 0); ++ rt2x00mmio_register_write(rt2x00dev, TX_CTX_IDX3, 0); ++ rt2x00mmio_register_write(rt2x00dev, TX_DTX_IDX3, 0); + + entry_priv = rt2x00dev->tx[1].entries[0].priv_data; +- rt2x00mmio_register_write(rt2x00dev, TX_BASE_PTR1, ++ rt2x00mmio_register_write(rt2x00dev, TX_BASE_PTR2, + entry_priv->desc_dma); +- rt2x00mmio_register_write(rt2x00dev, TX_MAX_CNT1, ++ rt2x00mmio_register_write(rt2x00dev, TX_MAX_CNT2, + rt2x00dev->tx[1].limit); +- rt2x00mmio_register_write(rt2x00dev, TX_CTX_IDX1, 0); +- rt2x00mmio_register_write(rt2x00dev, TX_DTX_IDX1, 0); ++ rt2x00mmio_register_write(rt2x00dev, TX_CTX_IDX2, 0); ++ rt2x00mmio_register_write(rt2x00dev, TX_DTX_IDX2, 0); + + entry_priv = rt2x00dev->tx[2].entries[0].priv_data; +- rt2x00mmio_register_write(rt2x00dev, TX_BASE_PTR2, ++ rt2x00mmio_register_write(rt2x00dev, TX_BASE_PTR0, + entry_priv->desc_dma); +- rt2x00mmio_register_write(rt2x00dev, TX_MAX_CNT2, ++ rt2x00mmio_register_write(rt2x00dev, TX_MAX_CNT0, + rt2x00dev->tx[2].limit); +- rt2x00mmio_register_write(rt2x00dev, TX_CTX_IDX2, 0); +- rt2x00mmio_register_write(rt2x00dev, TX_DTX_IDX2, 0); ++ rt2x00mmio_register_write(rt2x00dev, TX_CTX_IDX0, 0); ++ rt2x00mmio_register_write(rt2x00dev, TX_DTX_IDX0, 0); + + entry_priv = rt2x00dev->tx[3].entries[0].priv_data; +- rt2x00mmio_register_write(rt2x00dev, TX_BASE_PTR3, ++ rt2x00mmio_register_write(rt2x00dev, TX_BASE_PTR1, + entry_priv->desc_dma); +- rt2x00mmio_register_write(rt2x00dev, TX_MAX_CNT3, ++ rt2x00mmio_register_write(rt2x00dev, TX_MAX_CNT1, + rt2x00dev->tx[3].limit); +- rt2x00mmio_register_write(rt2x00dev, TX_CTX_IDX3, 0); +- rt2x00mmio_register_write(rt2x00dev, TX_DTX_IDX3, 0); ++ rt2x00mmio_register_write(rt2x00dev, TX_CTX_IDX1, 0); ++ rt2x00mmio_register_write(rt2x00dev, TX_DTX_IDX1, 0); + + rt2x00mmio_register_write(rt2x00dev, TX_BASE_PTR4, 0); + rt2x00mmio_register_write(rt2x00dev, TX_MAX_CNT4, 0); +--- a/drivers/net/wireless/ralink/rt2x00/rt2x00queue.h ++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00queue.h +@@ -57,6 +57,26 @@ enum data_queue_qid { + }; + + /** ++ * rt2x00_ac_to_hwq - Convert IEEE80211 queue id to Ralink hardware ++ * queue register index. ++ * @ac: TX queue id. ++ */ ++static inline u8 rt2x00_ac_to_hwq(enum data_queue_qid ac) ++{ ++ static const u8 ralink_queue_map[] = { ++ [IEEE80211_AC_BE] = 0, ++ [IEEE80211_AC_BK] = 1, ++ [IEEE80211_AC_VI] = 2, ++ [IEEE80211_AC_VO] = 3, ++ }; ++ ++ if (unlikely(ac >= IEEE80211_NUM_ACS)) ++ return ac; ++ ++ return ralink_queue_map[ac]; ++} ++ ++/** + * enum skb_frame_desc_flags: Flags for &struct skb_frame_desc + * + * @SKBDESC_DMA_MAPPED_RX: &skb_dma field has been mapped for RX diff --git a/package/kernel/mac80211/patches/rt2x00/620-02-rt2x00-increase-the-watchdog-sampling-frequency.patch b/package/kernel/mac80211/patches/rt2x00/620-02-rt2x00-increase-the-watchdog-sampling-frequency.patch new file mode 100644 index 00000000000000..c60d2ad54a93fe --- /dev/null +++ b/package/kernel/mac80211/patches/rt2x00/620-02-rt2x00-increase-the-watchdog-sampling-frequency.patch @@ -0,0 +1,74 @@ +From aec50d1a30349759de0ac535f54c3441bf7ebef7 Mon Sep 17 00:00:00 2001 +From: Shiji Yang +Date: Sun, 22 Dec 2024 17:06:59 +0800 +Subject: [PATCH 2/2] rt2x00: increase the watchdog sampling frequency + +Increase the sampling frequency of the watchdog when the hung +counter reaches the threshold to avoid some unnecessary resets. + +Signed-off-by: Shiji Yang +--- + .../net/wireless/ralink/rt2x00/rt2800lib.c | 45 +++++++++++++------ + 1 file changed, 32 insertions(+), 13 deletions(-) + +--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +@@ -1320,26 +1320,45 @@ static bool rt2800_watchdog_hung(struct + return true; + } + ++static inline bool check_dma_busy_rx(u32 reg_cfg, u32 reg_int) ++{ ++ return (rt2x00_get_field32(reg_cfg, WPDMA_GLO_CFG_RX_DMA_BUSY) && ++ rt2x00_get_field32(reg_int, INT_SOURCE_CSR_RX_COHERENT)); ++} ++ ++static inline bool check_dma_busy_tx(u32 reg_cfg, u32 reg_int) ++{ ++ return (rt2x00_get_field32(reg_cfg, WPDMA_GLO_CFG_TX_DMA_BUSY) && ++ rt2x00_get_field32(reg_int, INT_SOURCE_CSR_TX_COHERENT)); ++} ++ + static bool rt2800_watchdog_dma_busy(struct rt2x00_dev *rt2x00dev) + { + bool busy_rx, busy_tx; + u32 reg_cfg = rt2800_register_read(rt2x00dev, WPDMA_GLO_CFG); + u32 reg_int = rt2800_register_read(rt2x00dev, INT_SOURCE_CSR); + +- if (rt2x00_get_field32(reg_cfg, WPDMA_GLO_CFG_RX_DMA_BUSY) && +- rt2x00_get_field32(reg_int, INT_SOURCE_CSR_RX_COHERENT)) +- rt2x00dev->rxdma_busy++; +- else +- rt2x00dev->rxdma_busy = 0; +- +- if (rt2x00_get_field32(reg_cfg, WPDMA_GLO_CFG_TX_DMA_BUSY) && +- rt2x00_get_field32(reg_int, INT_SOURCE_CSR_TX_COHERENT)) +- rt2x00dev->txdma_busy++; +- else +- rt2x00dev->txdma_busy = 0; ++ rt2x00dev->rxdma_busy = check_dma_busy_rx(reg_cfg, reg_int) ? ++ rt2x00dev->rxdma_busy + 1 : 0; ++ rt2x00dev->txdma_busy = check_dma_busy_tx(reg_cfg, reg_int) ? ++ rt2x00dev->txdma_busy + 1 : 0; ++ ++ if (rt2x00dev->rxdma_busy > 25 || rt2x00dev->txdma_busy > 25) { ++ int cnt; ++ for (cnt = 0; cnt < 10; cnt++) { ++ msleep(5); ++ reg_cfg = rt2800_register_read(rt2x00dev, WPDMA_GLO_CFG); ++ reg_int = rt2800_register_read(rt2x00dev, INT_SOURCE_CSR); ++ ++ if (!check_dma_busy_rx(reg_cfg, reg_int)) ++ rt2x00dev->rxdma_busy = 0; ++ if (!check_dma_busy_tx(reg_cfg, reg_int)) ++ rt2x00dev->txdma_busy = 0; ++ } ++ } + +- busy_rx = rt2x00dev->rxdma_busy > 30; +- busy_tx = rt2x00dev->txdma_busy > 30; ++ busy_rx = rt2x00dev->rxdma_busy > 40; ++ busy_tx = rt2x00dev->txdma_busy > 40; + + if (!busy_rx && !busy_tx) + return false; diff --git a/package/kernel/mac80211/patches/rt2x00/621-01-rt2x00-always-calibrate-MT7620-when-switching-channe.patch b/package/kernel/mac80211/patches/rt2x00/621-01-rt2x00-always-calibrate-MT7620-when-switching-channe.patch new file mode 100644 index 00000000000000..e66fbd43694cae --- /dev/null +++ b/package/kernel/mac80211/patches/rt2x00/621-01-rt2x00-always-calibrate-MT7620-when-switching-channe.patch @@ -0,0 +1,77 @@ +From 2c5aad0f9990724cce48e0a53b66bc0438e4603d Mon Sep 17 00:00:00 2001 +From: Shiji Yang +Date: Sun, 22 Dec 2024 17:06:59 +0800 +Subject: [PATCH 1/4] rt2x00: always calibrate MT7620 when switching channel + +Perform calibration work after each channel switching operation. +This should help improve the rx/tx signal strength for MT7620. + +Signed-off-by: Shiji Yang +--- + .../net/wireless/ralink/rt2x00/rt2800lib.c | 24 ++++++++++++++----- + 1 file changed, 18 insertions(+), 6 deletions(-) + +--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +@@ -5704,6 +5704,9 @@ static void rt2800_config_ps(struct rt2x + } + } + ++static void rt2800_calibration_rt6352_stage1(struct rt2x00_dev *rt2x00dev); ++static void rt2800_calibration_rt6352_stage2(struct rt2x00_dev *rt2x00dev); ++ + void rt2800_config(struct rt2x00_dev *rt2x00dev, + struct rt2x00lib_conf *libconf, + const unsigned int flags) +@@ -5718,10 +5721,18 @@ void rt2800_config(struct rt2x00_dev *rt + */ + rt2800_update_survey(rt2x00dev); + ++ if (rt2x00_rt(rt2x00dev, RT6352) && ++ !test_bit(DEVICE_STATE_SCANNING, &rt2x00dev->flags)) ++ rt2800_calibration_rt6352_stage1(rt2x00dev); ++ + rt2800_config_channel(rt2x00dev, libconf->conf, + &libconf->rf, &libconf->channel); + rt2800_config_txpower(rt2x00dev, libconf->conf->chandef.chan, + libconf->conf->power_level); ++ ++ if (rt2x00_rt(rt2x00dev, RT6352) && ++ !test_bit(DEVICE_STATE_SCANNING, &rt2x00dev->flags)) ++ rt2800_calibration_rt6352_stage2(rt2x00dev); + } + if (flags & IEEE80211_CONF_CHANGE_POWER) + rt2800_config_txpower(rt2x00dev, libconf->conf->chandef.chan, +@@ -10427,15 +10438,19 @@ static void rt2800_restore_rf_bbp_rt6352 + } + } + +-static void rt2800_calibration_rt6352(struct rt2x00_dev *rt2x00dev) ++static void rt2800_calibration_rt6352_stage1(struct rt2x00_dev *rt2x00dev) + { +- u32 reg; +- + if (rt2x00_has_cap_external_pa(rt2x00dev) || + rt2x00_has_cap_external_lna_bg(rt2x00dev)) + rt2800_restore_rf_bbp_rt6352(rt2x00dev); + + rt2800_r_calibration(rt2x00dev); ++} ++ ++static void rt2800_calibration_rt6352_stage2(struct rt2x00_dev *rt2x00dev) ++{ ++ u32 reg; ++ + rt2800_rf_self_txdc_cal(rt2x00dev); + rt2800_rxdcoc_calibration(rt2x00dev); + rt2800_bw_filter_calibration(rt2x00dev, true); +@@ -10766,9 +10781,6 @@ static void rt2800_init_rfcsr_6352(struc + + rt2800_rfcsr_write_dccal(rt2x00dev, 5, 0x00); + rt2800_rfcsr_write_dccal(rt2x00dev, 17, 0x7C); +- +- /* Do calibration and init PA/LNA */ +- rt2800_calibration_rt6352(rt2x00dev); + } + + static void rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev) diff --git a/package/kernel/mac80211/patches/rt2x00/621-02-rt2x00-rework-link-tuner-for-MT7620.patch b/package/kernel/mac80211/patches/rt2x00/621-02-rt2x00-rework-link-tuner-for-MT7620.patch new file mode 100644 index 00000000000000..f7e7a8e5ffad9a --- /dev/null +++ b/package/kernel/mac80211/patches/rt2x00/621-02-rt2x00-rework-link-tuner-for-MT7620.patch @@ -0,0 +1,48 @@ +From aaa57924324c1ee77afa5e3effc95cc86158ddcc Mon Sep 17 00:00:00 2001 +From: Shiji Yang +Date: Sun, 22 Dec 2024 17:06:59 +0800 +Subject: [PATCH 2/4] rt2x00: rework link tuner for MT7620 + +Correct the VGC gain value for MT7620 and only do gain calibration +for supported devices. + +Signed-off-by: Shiji Yang +--- + drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 11 ++++++++--- + 1 file changed, 8 insertions(+), 3 deletions(-) + +--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +@@ -5561,6 +5561,9 @@ static void rt2800_config_txpower(struct + + void rt2800_gain_calibration(struct rt2x00_dev *rt2x00dev) + { ++ if (rt2x00_rt(rt2x00dev, RT6352)) ++ return; ++ + rt2800_config_txpower(rt2x00dev, rt2x00dev->hw->conf.chandef.chan, + rt2x00dev->tx_power); + } +@@ -5773,9 +5776,10 @@ static u8 rt2800_get_default_vgc(struct + rt2x00_rt(rt2x00dev, RT3593) || + rt2x00_rt(rt2x00dev, RT5390) || + rt2x00_rt(rt2x00dev, RT5392) || +- rt2x00_rt(rt2x00dev, RT5592) || +- rt2x00_rt(rt2x00dev, RT6352)) ++ rt2x00_rt(rt2x00dev, RT5592)) + vgc = 0x1c + (2 * rt2x00dev->lna_gain); ++ else if(rt2x00_rt(rt2x00dev, RT6352)) ++ vgc = 0x04 + (2 * rt2x00dev->lna_gain); + else + vgc = 0x2e + rt2x00dev->lna_gain; + } else { /* 5GHZ band */ +@@ -5828,7 +5832,8 @@ void rt2800_link_tuner(struct rt2x00_dev + { + u8 vgc; + +- if (rt2x00_rt_rev(rt2x00dev, RT2860, REV_RT2860C)) ++ if (rt2x00_rt_rev(rt2x00dev, RT2860, REV_RT2860C) || ++ rt2x00_rt(rt2x00dev, RT6352)) + return; + + /* When RSSI is better than a certain threshold, increase VGC diff --git a/package/kernel/mac80211/patches/rt2x00/621-03-rt2x00-correct-MT7620-SDM-mode-register-value.patch b/package/kernel/mac80211/patches/rt2x00/621-03-rt2x00-correct-MT7620-SDM-mode-register-value.patch new file mode 100644 index 00000000000000..7c376df197a011 --- /dev/null +++ b/package/kernel/mac80211/patches/rt2x00/621-03-rt2x00-correct-MT7620-SDM-mode-register-value.patch @@ -0,0 +1,25 @@ +From b672507ca9f06bb17213036b16bc4f5c5bc65357 Mon Sep 17 00:00:00 2001 +From: Shiji Yang +Date: Sun, 22 Dec 2024 17:06:59 +0800 +Subject: [PATCH 3/4] rt2x00: correct MT7620 SDM mode register value + +rt2x00_set_field8() is a mask writing function. If we want to set +the BIT(7) for the SDM mode register here, we only need to fill "4" +in the mask. + +Signed-off-by: Shiji Yang +--- + drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +@@ -3848,7 +3848,7 @@ static void rt2800_config_channel_rf7620 + + /* Default: XO=20MHz , SDM mode */ + rfcsr = rt2800_rfcsr_read(rt2x00dev, 16); +- rt2x00_set_field8(&rfcsr, RFCSR16_SDM_MODE_MT7620, 0x80); ++ rt2x00_set_field8(&rfcsr, RFCSR16_SDM_MODE_MT7620, 4); + rt2800_rfcsr_write(rt2x00dev, 16, rfcsr); + + rfcsr = rt2800_rfcsr_read(rt2x00dev, 21); diff --git a/package/kernel/mac80211/patches/rt2x00/621-04-rt2x00-fix-register-operation-on-RXIQ-calibration.patch b/package/kernel/mac80211/patches/rt2x00/621-04-rt2x00-fix-register-operation-on-RXIQ-calibration.patch new file mode 100644 index 00000000000000..aa6f9c437c6447 --- /dev/null +++ b/package/kernel/mac80211/patches/rt2x00/621-04-rt2x00-fix-register-operation-on-RXIQ-calibration.patch @@ -0,0 +1,60 @@ +From 2585ada646e4dcf152ab813a24d667e6903105f4 Mon Sep 17 00:00:00 2001 +From: Shiji Yang +Date: Sun, 22 Dec 2024 17:06:59 +0800 +Subject: [PATCH 4/4] rt2x00: fix register operation on RXIQ calibration + +In rt2800_rxiq_calibration(), some variables are overwritten +before being used. Based on the values of the relevant registers +in other functions, I believe the correct operation should be +bit mask writing. + +Signed-off-by: Shiji Yang +--- + drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 14 +++++++------- + 1 file changed, 7 insertions(+), 7 deletions(-) + +--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +@@ -8846,7 +8846,7 @@ static void rt2800_rxiq_calibration(stru + rt2x00_warn(rt2x00dev, "Timeout waiting for MAC status in RXIQ calibration\n"); + + bbpval = bbp4 & (~0x18); +- bbpval = bbp4 | 0x00; ++ bbpval = bbpval | 0x00; + rt2800_bbp_write(rt2x00dev, 4, bbpval); + + bbpval = rt2800_bbp_read(rt2x00dev, 21); +@@ -8928,13 +8928,13 @@ static void rt2800_rxiq_calibration(stru + for (ch_idx = 0; ch_idx < 2; ch_idx = ch_idx + 1) { + if (ch_idx == 0) { + rfval = rfb0r1 & (~0x3); +- rfval = rfb0r1 | 0x1; ++ rfval = rfval | 0x1; + rt2800_rfcsr_write_bank(rt2x00dev, 0, 1, rfval); + rfval = rfb0r2 & (~0x33); +- rfval = rfb0r2 | 0x11; ++ rfval = rfval | 0x11; + rt2800_rfcsr_write_bank(rt2x00dev, 0, 2, rfval); + rfval = rfb0r42 & (~0x50); +- rfval = rfb0r42 | 0x10; ++ rfval = rfval | 0x10; + rt2800_rfcsr_write_bank(rt2x00dev, 0, 42, rfval); + + rt2800_register_write(rt2x00dev, RF_CONTROL0, 0x00001006); +@@ -8947,13 +8947,13 @@ static void rt2800_rxiq_calibration(stru + rt2800_bbp_dcoc_write(rt2x00dev, 1, 0x00); + } else { + rfval = rfb0r1 & (~0x3); +- rfval = rfb0r1 | 0x2; ++ rfval = rfval | 0x2; + rt2800_rfcsr_write_bank(rt2x00dev, 0, 1, rfval); + rfval = rfb0r2 & (~0x33); +- rfval = rfb0r2 | 0x22; ++ rfval = rfval | 0x22; + rt2800_rfcsr_write_bank(rt2x00dev, 0, 2, rfval); + rfval = rfb0r42 & (~0x50); +- rfval = rfb0r42 | 0x40; ++ rfval = rfval | 0x40; + rt2800_rfcsr_write_bank(rt2x00dev, 0, 42, rfval); + + rt2800_register_write(rt2x00dev, RF_CONTROL0, 0x00002006); diff --git a/package/kernel/mac80211/patches/rt2x00/622-01-rt2x00-fix-RFCSR-register-init-values-for-RT5592.patch b/package/kernel/mac80211/patches/rt2x00/622-01-rt2x00-fix-RFCSR-register-init-values-for-RT5592.patch new file mode 100644 index 00000000000000..15d1601eef1f8d --- /dev/null +++ b/package/kernel/mac80211/patches/rt2x00/622-01-rt2x00-fix-RFCSR-register-init-values-for-RT5592.patch @@ -0,0 +1,230 @@ +From b48887d5de9921d0ff9e88068e3cd555a383d702 Mon Sep 17 00:00:00 2001 +From: Shiji Yang +Date: Sun, 22 Dec 2024 17:06:59 +0800 +Subject: [PATCH 1/2] rt2x00: fix RFCSR register init values for RT5592 + +Based on Raink proprietary driver 2.7.1.5, correct the initial +values of some RFCSR registers for RT5592. + +Signed-off-by: Shiji Yang +--- + .../net/wireless/ralink/rt2x00/rt2800lib.c | 122 ++++++++---------- + 1 file changed, 53 insertions(+), 69 deletions(-) + +--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +@@ -3576,9 +3576,8 @@ static void rt2800_config_channel_rf55xx + + /* TODO RF27 <- tssi */ + +- rfcsr = rf->channel <= 10 ? 0x07 : 0x06; +- rt2800_rfcsr_write(rt2x00dev, 23, rfcsr); +- rt2800_rfcsr_write(rt2x00dev, 59, rfcsr); ++ rt2800_rfcsr_write(rt2x00dev, 23, rf->channel <= 10 ? 0x08 : 0x07); ++ rt2800_rfcsr_write(rt2x00dev, 59, rf->channel <= 4 ? 0x06 : 0x04); + + if (is_11b) { + /* CCK */ +@@ -3599,7 +3598,7 @@ static void rt2800_config_channel_rf55xx + power_bound = POWER_BOUND; + ep_reg = 0x2; + } else { +- rt2800_rfcsr_write(rt2x00dev, 10, 0x97); ++ rt2800_rfcsr_write(rt2x00dev, 10, 0x95); + /* FIMXE: RF11 overwrite */ + rt2800_rfcsr_write(rt2x00dev, 11, 0x40); + rt2800_rfcsr_write(rt2x00dev, 25, 0xBF); +@@ -3608,13 +3607,15 @@ static void rt2800_config_channel_rf55xx + rt2800_rfcsr_write(rt2x00dev, 37, 0x04); + rt2800_rfcsr_write(rt2x00dev, 38, 0x85); + rt2800_rfcsr_write(rt2x00dev, 40, 0x42); +- rt2800_rfcsr_write(rt2x00dev, 41, 0xBB); ++ rt2800_rfcsr_write(rt2x00dev, 41, 0xAB); + rt2800_rfcsr_write(rt2x00dev, 42, 0xD7); +- rt2800_rfcsr_write(rt2x00dev, 45, 0x41); ++ rt2800_rfcsr_write(rt2x00dev, 45, 0x01); + rt2800_rfcsr_write(rt2x00dev, 48, 0x00); + rt2800_rfcsr_write(rt2x00dev, 57, 0x77); ++ rt2800_rfcsr_write(rt2x00dev, 58, 0x19); + rt2800_rfcsr_write(rt2x00dev, 60, 0x05); + rt2800_rfcsr_write(rt2x00dev, 61, 0x01); ++ rt2800_rfcsr_write(rt2x00dev, 62, 0x19); + + /* TODO RF27 <- tssi */ + +@@ -3623,82 +3624,59 @@ static void rt2800_config_channel_rf55xx + rt2800_rfcsr_write(rt2x00dev, 12, 0x2E); + rt2800_rfcsr_write(rt2x00dev, 13, 0x22); + rt2800_rfcsr_write(rt2x00dev, 22, 0x60); +- rt2800_rfcsr_write(rt2x00dev, 23, 0x7F); +- if (rf->channel <= 50) +- rt2800_rfcsr_write(rt2x00dev, 24, 0x09); +- else if (rf->channel >= 52) +- rt2800_rfcsr_write(rt2x00dev, 24, 0x07); ++ rt2800_rfcsr_write(rt2x00dev, 23, 0x7E); ++ rt2800_rfcsr_write(rt2x00dev, 24, 0x07); + rt2800_rfcsr_write(rt2x00dev, 39, 0x1C); + rt2800_rfcsr_write(rt2x00dev, 43, 0x5B); +- rt2800_rfcsr_write(rt2x00dev, 44, 0X40); + rt2800_rfcsr_write(rt2x00dev, 46, 0X00); +- rt2800_rfcsr_write(rt2x00dev, 51, 0xFE); +- rt2800_rfcsr_write(rt2x00dev, 52, 0x0C); +- rt2800_rfcsr_write(rt2x00dev, 54, 0xF8); ++ rt2800_rfcsr_write(rt2x00dev, 51, 0xFD); ++ rt2800_rfcsr_write(rt2x00dev, 52, 0x0E); ++ rt2800_rfcsr_write(rt2x00dev, 55, 0x04); ++ rt2800_rfcsr_write(rt2x00dev, 56, 0xBB); ++ rt2800_rfcsr_write(rt2x00dev, 59, 0x7C); ++ + if (rf->channel <= 50) { +- rt2800_rfcsr_write(rt2x00dev, 55, 0x06), +- rt2800_rfcsr_write(rt2x00dev, 56, 0xD3); ++ rt2800_rfcsr_write(rt2x00dev, 44, 0X32); ++ rt2800_rfcsr_write(rt2x00dev, 54, 0xF9); + } else if (rf->channel >= 52) { +- rt2800_rfcsr_write(rt2x00dev, 55, 0x04); +- rt2800_rfcsr_write(rt2x00dev, 56, 0xBB); ++ rt2800_rfcsr_write(rt2x00dev, 44, 0X2A); ++ rt2800_rfcsr_write(rt2x00dev, 54, 0xF8); + } +- +- rt2800_rfcsr_write(rt2x00dev, 58, 0x15); +- rt2800_rfcsr_write(rt2x00dev, 59, 0x7F); +- rt2800_rfcsr_write(rt2x00dev, 62, 0x15); +- + } else if (rf->channel >= 100 && rf->channel <= 165) { +- + rt2800_rfcsr_write(rt2x00dev, 12, 0x0E); + rt2800_rfcsr_write(rt2x00dev, 13, 0x42); + rt2800_rfcsr_write(rt2x00dev, 22, 0x40); +- if (rf->channel <= 153) { +- rt2800_rfcsr_write(rt2x00dev, 23, 0x3C); +- rt2800_rfcsr_write(rt2x00dev, 24, 0x06); +- } else if (rf->channel >= 155) { +- rt2800_rfcsr_write(rt2x00dev, 23, 0x38); +- rt2800_rfcsr_write(rt2x00dev, 24, 0x05); +- } ++ rt2800_rfcsr_write(rt2x00dev, 52, 0x06); ++ rt2800_rfcsr_write(rt2x00dev, 55, 0x01); ++ + if (rf->channel <= 138) { ++ rt2800_rfcsr_write(rt2x00dev, 23, 0x7C); + rt2800_rfcsr_write(rt2x00dev, 39, 0x1A); + rt2800_rfcsr_write(rt2x00dev, 43, 0x3B); +- rt2800_rfcsr_write(rt2x00dev, 44, 0x20); + rt2800_rfcsr_write(rt2x00dev, 46, 0x18); +- } else if (rf->channel >= 140) { ++ } else { ++ rt2800_rfcsr_write(rt2x00dev, 23, 0x78); + rt2800_rfcsr_write(rt2x00dev, 39, 0x18); + rt2800_rfcsr_write(rt2x00dev, 43, 0x1B); +- rt2800_rfcsr_write(rt2x00dev, 44, 0x10); + rt2800_rfcsr_write(rt2x00dev, 46, 0X08); + } +- if (rf->channel <= 124) +- rt2800_rfcsr_write(rt2x00dev, 51, 0xFC); +- else if (rf->channel >= 126) +- rt2800_rfcsr_write(rt2x00dev, 51, 0xEC); +- if (rf->channel <= 138) +- rt2800_rfcsr_write(rt2x00dev, 52, 0x06); +- else if (rf->channel >= 140) +- rt2800_rfcsr_write(rt2x00dev, 52, 0x06); +- rt2800_rfcsr_write(rt2x00dev, 54, 0xEB); +- if (rf->channel <= 138) +- rt2800_rfcsr_write(rt2x00dev, 55, 0x01); +- else if (rf->channel >= 140) +- rt2800_rfcsr_write(rt2x00dev, 55, 0x00); +- if (rf->channel <= 128) +- rt2800_rfcsr_write(rt2x00dev, 56, 0xBB); +- else if (rf->channel >= 130) +- rt2800_rfcsr_write(rt2x00dev, 56, 0xAB); +- if (rf->channel <= 116) +- rt2800_rfcsr_write(rt2x00dev, 58, 0x1D); +- else if (rf->channel >= 118) +- rt2800_rfcsr_write(rt2x00dev, 58, 0x15); +- if (rf->channel <= 138) +- rt2800_rfcsr_write(rt2x00dev, 59, 0x3F); +- else if (rf->channel >= 140) +- rt2800_rfcsr_write(rt2x00dev, 59, 0x7C); +- if (rf->channel <= 116) +- rt2800_rfcsr_write(rt2x00dev, 62, 0x1D); +- else if (rf->channel >= 118) +- rt2800_rfcsr_write(rt2x00dev, 62, 0x15); ++ ++ if (rf->channel <= 114) { ++ rt2800_rfcsr_write(rt2x00dev, 24, 0x02); ++ rt2800_rfcsr_write(rt2x00dev, 44, 0x1A); ++ rt2800_rfcsr_write(rt2x00dev, 54, 0xEA); ++ rt2800_rfcsr_write(rt2x00dev, 56, 0xB3); ++ } else { ++ rt2800_rfcsr_write(rt2x00dev, 24, 0x03); ++ rt2800_rfcsr_write(rt2x00dev, 44, 0x0A); ++ rt2800_rfcsr_write(rt2x00dev, 54, 0xF9); ++ rt2800_rfcsr_write(rt2x00dev, 56, 0x9B); ++ } ++ ++ rt2800_rfcsr_write(rt2x00dev, 51, rf->channel <= 124 ? 0xFC : 0xEC); ++ rt2800_rfcsr_write(rt2x00dev, 58, rf->channel <= 116 ? 0x1D : 0x15); ++ rfcsr = (rf->channel >= 116 && rf->channel <= 138) ? 0x7E : 0x7C; ++ rt2800_rfcsr_write(rt2x00dev, 59, rfcsr); + } + + power_bound = POWER_BOUND_5G; +@@ -3710,7 +3688,7 @@ static void rt2800_config_channel_rf55xx + rt2x00_set_field8(&rfcsr, RFCSR49_TX, power_bound); + else + rt2x00_set_field8(&rfcsr, RFCSR49_TX, info->default_power1); +- if (is_type_ep) ++ if (!is_type_ep) + rt2x00_set_field8(&rfcsr, RFCSR49_EP, ep_reg); + rt2800_rfcsr_write(rt2x00dev, 49, rfcsr); + +@@ -3719,7 +3697,7 @@ static void rt2800_config_channel_rf55xx + rt2x00_set_field8(&rfcsr, RFCSR50_TX, power_bound); + else + rt2x00_set_field8(&rfcsr, RFCSR50_TX, info->default_power2); +- if (is_type_ep) ++ if (!is_type_ep) + rt2x00_set_field8(&rfcsr, RFCSR50_EP, ep_reg); + rt2800_rfcsr_write(rt2x00dev, 50, rfcsr); + +@@ -3740,7 +3718,6 @@ static void rt2800_config_channel_rf55xx + rt2x00_set_field8(&rfcsr, RFCSR1_RX2_PD, 0); + + rt2800_rfcsr_write(rt2x00dev, 1, rfcsr); +- rt2800_rfcsr_write(rt2x00dev, 6, 0xe4); + + if (conf_is_ht40(conf)) + rt2800_rfcsr_write(rt2x00dev, 30, 0x16); +@@ -8505,12 +8482,15 @@ static void rt2800_init_rfcsr_5392(struc + + static void rt2800_init_rfcsr_5592(struct rt2x00_dev *rt2x00dev) + { ++ u16 eeprom; ++ + rt2800_rf_init_calibration(rt2x00dev, 30); + + rt2800_rfcsr_write(rt2x00dev, 1, 0x3F); ++ rt2800_rfcsr_write(rt2x00dev, 2, 0x80); + rt2800_rfcsr_write(rt2x00dev, 3, 0x08); + rt2800_rfcsr_write(rt2x00dev, 5, 0x10); +- rt2800_rfcsr_write(rt2x00dev, 6, 0xE4); ++ rt2800_rfcsr_write(rt2x00dev, 6, 0xE0); + rt2800_rfcsr_write(rt2x00dev, 7, 0x00); + rt2800_rfcsr_write(rt2x00dev, 14, 0x00); + rt2800_rfcsr_write(rt2x00dev, 15, 0x00); +@@ -8526,9 +8506,13 @@ static void rt2800_init_rfcsr_5592(struc + rt2800_rfcsr_write(rt2x00dev, 34, 0x07); + rt2800_rfcsr_write(rt2x00dev, 35, 0x12); + rt2800_rfcsr_write(rt2x00dev, 47, 0x0C); +- rt2800_rfcsr_write(rt2x00dev, 53, 0x22); ++ rt2800_rfcsr_write(rt2x00dev, 53, 0x44); + rt2800_rfcsr_write(rt2x00dev, 63, 0x07); + ++ eeprom = rt2800_eeprom_read(rt2x00dev, EEPROM_NIC_CONF2); ++ if (!rt2x00_get_field16(eeprom, EEPROM_NIC_CONF2_CRYSTAL)) ++ rt2800_rfcsr_write(rt2x00dev, 6, 0xE4); ++ + rt2800_rfcsr_write(rt2x00dev, 2, 0x80); + msleep(1); + diff --git a/package/kernel/mac80211/patches/rt2x00/622-02-rt2x00-fix-BBP-register-init-values-for-RT5592.patch b/package/kernel/mac80211/patches/rt2x00/622-02-rt2x00-fix-BBP-register-init-values-for-RT5592.patch new file mode 100644 index 00000000000000..19d1951b7b51d8 --- /dev/null +++ b/package/kernel/mac80211/patches/rt2x00/622-02-rt2x00-fix-BBP-register-init-values-for-RT5592.patch @@ -0,0 +1,119 @@ +From 1847d817df5585f9d957d16ed2a56ceb41cf6df7 Mon Sep 17 00:00:00 2001 +From: Shiji Yang +Date: Sun, 22 Dec 2024 17:06:59 +0800 +Subject: [PATCH 2/2] rt2x00: fix BBP register init values for RT5592 + +Based on Raink proprietary driver 2.7.1.5, correct the initial +values of some BBP registers for RT5592. + +Signed-off-by: Shiji Yang +--- + .../net/wireless/ralink/rt2x00/rt2800lib.c | 32 +++++++++---------- + 1 file changed, 15 insertions(+), 17 deletions(-) + +--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +@@ -3746,6 +3746,7 @@ static void rt2800_config_channel_rf55xx + rt2800_bbp_write(rt2x00dev, 80, (rf->channel <= 14) ? 0x0E : 0x08); + rt2800_bbp_write(rt2x00dev, 81, (rf->channel <= 14) ? 0x3A : 0x38); + rt2800_bbp_write(rt2x00dev, 82, (rf->channel <= 14) ? 0x62 : 0x92); ++ rt2800_bbp_write(rt2x00dev, 95, (rf->channel <= 14) ? 0x9A : 0x1A); + + /* GLRT band configuration */ + rt2800_bbp_write(rt2x00dev, 195, 128); +@@ -3758,7 +3759,7 @@ static void rt2800_config_channel_rf55xx + rt2800_bbp_write(rt2x00dev, 196, (rf->channel <= 14) ? 0x32 : 0x20); + rt2800_bbp_write(rt2x00dev, 195, 133); + rt2800_bbp_write(rt2x00dev, 196, (rf->channel <= 14) ? 0x28 : 0x7F); +- rt2800_bbp_write(rt2x00dev, 195, 124); ++ rt2800_bbp_write(rt2x00dev, 195, 134); + rt2800_bbp_write(rt2x00dev, 196, (rf->channel <= 14) ? 0x19 : 0x7F); + } + +@@ -4304,7 +4305,8 @@ static void rt2800_config_channel(struct + rt2800_bbp_write(rt2x00dev, 62, 0x37 - rt2x00dev->lna_gain); + rt2800_bbp_write(rt2x00dev, 63, 0x37 - rt2x00dev->lna_gain); + rt2800_bbp_write(rt2x00dev, 64, 0x37 - rt2x00dev->lna_gain); +- if (rt2x00_rt(rt2x00dev, RT6352)) ++ if (rt2x00_rt(rt2x00dev, RT5592) || ++ rt2x00_rt(rt2x00dev, RT6352)) + rt2800_bbp_write(rt2x00dev, 86, 0x38); + else + rt2800_bbp_write(rt2x00dev, 86, 0); +@@ -4313,6 +4315,7 @@ static void rt2800_config_channel(struct + if (rf->channel <= 14) { + if (!rt2x00_rt(rt2x00dev, RT5390) && + !rt2x00_rt(rt2x00dev, RT5392) && ++ !rt2x00_rt(rt2x00dev, RT5592) && + !rt2x00_rt(rt2x00dev, RT6352)) { + if (rt2x00_has_cap_external_lna_bg(rt2x00dev)) { + rt2800_bbp_write(rt2x00dev, 82, 0x62); +@@ -4336,17 +4339,20 @@ static void rt2800_config_channel(struct + else if (rt2x00_rt(rt2x00dev, RT3593) || + rt2x00_rt(rt2x00dev, RT3883)) + rt2800_bbp_write(rt2x00dev, 82, 0x82); +- else if (!rt2x00_rt(rt2x00dev, RT6352)) ++ else if (!rt2x00_rt(rt2x00dev, RT5592) && ++ !rt2x00_rt(rt2x00dev, RT6352)) + rt2800_bbp_write(rt2x00dev, 82, 0xf2); + + if (rt2x00_rt(rt2x00dev, RT3593) || + rt2x00_rt(rt2x00dev, RT3883)) + rt2800_bbp_write(rt2x00dev, 83, 0x9a); + +- if (rt2x00_has_cap_external_lna_a(rt2x00dev)) +- rt2800_bbp_write(rt2x00dev, 75, 0x46); +- else +- rt2800_bbp_write(rt2x00dev, 75, 0x50); ++ if (!rt2x00_rt(rt2x00dev, RT5592)) { ++ if (rt2x00_has_cap_external_lna_a(rt2x00dev)) ++ rt2800_bbp_write(rt2x00dev, 75, 0x46); ++ else ++ rt2800_bbp_write(rt2x00dev, 75, 0x50); ++ } + } + + reg = rt2800_register_read(rt2x00dev, TX_BAND_CFG); +@@ -5783,12 +5789,10 @@ static inline void rt2800_set_vgc(struct + if (rt2x00_rt(rt2x00dev, RT3572) || + rt2x00_rt(rt2x00dev, RT3593) || + rt2x00_rt(rt2x00dev, RT3883) || ++ rt2x00_rt(rt2x00dev, RT5592) || + rt2x00_rt(rt2x00dev, RT6352)) { + rt2800_bbp_write_with_rx_chain(rt2x00dev, 66, + vgc_level); +- } else if (rt2x00_rt(rt2x00dev, RT5592)) { +- rt2800_bbp_write(rt2x00dev, 83, qual->rssi > -65 ? 0x4a : 0x7a); +- rt2800_bbp_write_with_rx_chain(rt2x00dev, 66, vgc_level); + } else { + rt2800_bbp_write(rt2x00dev, 66, vgc_level); + } +@@ -7016,7 +7020,6 @@ static void rt2800_init_bbp_5592(struct + rt2800_bbp_write(rt2x00dev, 88, 0x90); + rt2800_bbp_write(rt2x00dev, 91, 0x04); + rt2800_bbp_write(rt2x00dev, 92, 0x02); +- rt2800_bbp_write(rt2x00dev, 95, 0x9a); + rt2800_bbp_write(rt2x00dev, 98, 0x12); + rt2800_bbp_write(rt2x00dev, 103, 0xC0); + rt2800_bbp_write(rt2x00dev, 104, 0x92); +@@ -7027,6 +7030,7 @@ static void rt2800_init_bbp_5592(struct + rt2800_bbp_write(rt2x00dev, 134, 0xD0); + rt2800_bbp_write(rt2x00dev, 135, 0xF6); + rt2800_bbp_write(rt2x00dev, 137, 0x0F); ++ rt2800_bbp_write(rt2x00dev, 148, 0x84); + + /* Initialize GLRT (Generalized Likehood Radio Test) */ + rt2800_init_bbp_5592_glrt(rt2x00dev); +@@ -7051,12 +7055,6 @@ static void rt2800_init_bbp_5592(struct + rt2x00_set_field8(&value, BBP254_BIT7, 1); + rt2800_bbp_write(rt2x00dev, 254, value); + } +- +- rt2800_init_freq_calibration(rt2x00dev); +- +- rt2800_bbp_write(rt2x00dev, 84, 0x19); +- if (rt2x00_rt_rev_gte(rt2x00dev, RT5592, REV_RT5592C)) +- rt2800_bbp_write(rt2x00dev, 103, 0xc0); + } + + static void rt2800_init_bbp_6352(struct rt2x00_dev *rt2x00dev) diff --git a/package/kernel/mac80211/patches/rt2x00/994-rt2x00-import-support-for-external-LNA-on-MT7620.patch b/package/kernel/mac80211/patches/rt2x00/994-rt2x00-import-support-for-external-LNA-on-MT7620.patch index bb3f8197020b81..88a72fd03ec31b 100644 --- a/package/kernel/mac80211/patches/rt2x00/994-rt2x00-import-support-for-external-LNA-on-MT7620.patch +++ b/package/kernel/mac80211/patches/rt2x00/994-rt2x00-import-support-for-external-LNA-on-MT7620.patch @@ -52,9 +52,9 @@ Signed-off-by: Daniel Golle static const unsigned int rt2800_eeprom_map[EEPROM_WORD_COUNT] = { [EEPROM_CHIP_ID] = 0x0000, [EEPROM_VERSION] = 0x0001, -@@ -10404,8 +10422,10 @@ static void rt2800_calibration_rt6352(st - u32 reg; - +@@ -10428,8 +10446,10 @@ static void rt2800_restore_rf_bbp_rt6352 + static void rt2800_calibration_rt6352_stage1(struct rt2x00_dev *rt2x00dev) + { if (rt2x00_has_cap_external_pa(rt2x00dev) || - rt2x00_has_cap_external_lna_bg(rt2x00dev)) + rt2x00_has_cap_external_lna_bg(rt2x00dev)) { @@ -63,8 +63,8 @@ Signed-off-by: Daniel Golle + } rt2800_r_calibration(rt2x00dev); - rt2800_rf_self_txdc_cal(rt2x00dev); -@@ -10423,6 +10443,8 @@ static void rt2800_calibration_rt6352(st + } +@@ -10453,6 +10473,8 @@ static void rt2800_calibration_rt6352_st !rt2x00_has_cap_external_lna_bg(rt2x00dev)) return; diff --git a/package/kernel/mac80211/patches/rt2x00/996-rt2x00-mt7620-differentiate-based-on-SoC-CHIP_VER.patch b/package/kernel/mac80211/patches/rt2x00/996-rt2x00-mt7620-differentiate-based-on-SoC-CHIP_VER.patch index 4c07a105906957..eb0237a389381e 100644 --- a/package/kernel/mac80211/patches/rt2x00/996-rt2x00-mt7620-differentiate-based-on-SoC-CHIP_VER.patch +++ b/package/kernel/mac80211/patches/rt2x00/996-rt2x00-mt7620-differentiate-based-on-SoC-CHIP_VER.patch @@ -14,13 +14,13 @@ */ --- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c -@@ -3836,14 +3836,16 @@ static void rt2800_config_channel_rf7620 +@@ -3842,14 +3842,16 @@ static void rt2800_config_channel_rf7620 rt2x00_set_field8(&rfcsr, RFCSR19_K, rf->rf4); rt2800_rfcsr_write(rt2x00dev, 19, rfcsr); - /* Default: XO=20MHz , SDM mode */ - rfcsr = rt2800_rfcsr_read(rt2x00dev, 16); -- rt2x00_set_field8(&rfcsr, RFCSR16_SDM_MODE_MT7620, 0x80); +- rt2x00_set_field8(&rfcsr, RFCSR16_SDM_MODE_MT7620, 4); - rt2800_rfcsr_write(rt2x00dev, 16, rfcsr); - - rfcsr = rt2800_rfcsr_read(rt2x00dev, 21); @@ -29,7 +29,7 @@ + if (rt2800_hw_get_chipver(rt2x00dev) > 1) { + /* Default: XO=20MHz , SDM mode */ + rfcsr = rt2800_rfcsr_read(rt2x00dev, 16); -+ rt2x00_set_field8(&rfcsr, RFCSR16_SDM_MODE_MT7620, 0x80); ++ rt2x00_set_field8(&rfcsr, RFCSR16_SDM_MODE_MT7620, 4); + rt2800_rfcsr_write(rt2x00dev, 16, rfcsr); + + rfcsr = rt2800_rfcsr_read(rt2x00dev, 21); @@ -39,7 +39,7 @@ rfcsr = rt2800_rfcsr_read(rt2x00dev, 1); rt2x00_set_field8(&rfcsr, RFCSR1_TX2_EN_MT7620, -@@ -3877,18 +3879,23 @@ static void rt2800_config_channel_rf7620 +@@ -3883,18 +3885,23 @@ static void rt2800_config_channel_rf7620 rt2800_rfcsr_write_dccal(rt2x00dev, 59, 0x20); } @@ -73,7 +73,7 @@ if (!test_bit(DEVICE_STATE_SCANNING, &rt2x00dev->flags)) { if (conf_is_ht40(conf)) { -@@ -4002,25 +4009,29 @@ static void rt2800_config_alc_rt6352(str +@@ -4008,25 +4015,29 @@ static void rt2800_config_alc_rt6352(str if (unlikely(rt2800_wait_bbp_rf_ready(rt2x00dev, MAC_STATUS_CFG_BBP_RF_BUSY))) rt2x00_warn(rt2x00dev, "RF busy while configuring ALC\n"); @@ -121,7 +121,7 @@ rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, mac_sys_ctrl); rt2800_vco_calibration(rt2x00dev); -@@ -4513,7 +4524,8 @@ static void rt2800_config_channel(struct +@@ -4524,7 +4535,8 @@ static void rt2800_config_channel(struct if (rt2x00_rt(rt2x00dev, RT6352)) { /* BBP for GLRT BW */ bbp = conf_is_ht40(conf) ? @@ -131,7 +131,7 @@ 0x15 : 0x1a; rt2800_bbp_glrt_write(rt2x00dev, 141, bbp); -@@ -6017,18 +6029,33 @@ static int rt2800_init_registers(struct +@@ -6042,18 +6054,34 @@ static int rt2800_init_registers(struct } else if (rt2x00_rt(rt2x00dev, RT5350)) { rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000404); } else if (rt2x00_rt(rt2x00dev, RT6352)) { @@ -162,7 +162,8 @@ + rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000401); + rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x000C0001); + rt2800_register_write(rt2x00dev, TX_SW_CFG2, 0x00000000); -+ rt2800_register_write(rt2x00dev, TX_ALC_VGA3, 0x00000000); ++ rt2800_register_write(rt2x00dev, TX_PIN_CFG, 0x00150f0f); ++ rt2800_register_write(rt2x00dev, TX_ALC_VGA3, 0x06060606); + rt2800_register_write(rt2x00dev, TX0_BB_GAIN_ATTEN, 0x0); + rt2800_register_write(rt2x00dev, TX1_BB_GAIN_ATTEN, 0x0); + rt2800_register_write(rt2x00dev, TX0_RF_GAIN_ATTEN, @@ -177,7 +178,7 @@ reg = rt2800_register_read(rt2x00dev, TX_ALC_CFG_1); rt2x00_set_field32(®, TX_ALC_CFG_1_ROS_BUSY_EN, 0); rt2800_register_write(rt2x00dev, TX_ALC_CFG_1, reg); -@@ -7141,14 +7168,16 @@ static void rt2800_init_bbp_6352(struct +@@ -7160,14 +7188,16 @@ static void rt2800_init_bbp_6352(struct rt2800_bbp_write(rt2x00dev, 188, 0x00); rt2800_bbp_write(rt2x00dev, 189, 0x00); @@ -202,7 +203,7 @@ /* BBP for G band GLRT function (BBP_128 ~ BBP_221) */ rt2800_bbp_glrt_write(rt2x00dev, 0, 0x00); -@@ -10378,6 +10407,9 @@ static void rt2800_restore_rf_bbp_rt6352 +@@ -10404,6 +10434,9 @@ static void rt2800_restore_rf_bbp_rt6352 rt2800_register_write(rt2x00dev, RF_BYPASS3, 0x0); } @@ -212,7 +213,7 @@ if (rt2x00_has_cap_external_lna_bg(rt2x00dev)) { rt2800_rfcsr_write_chanreg(rt2x00dev, 14, 0x16); rt2800_rfcsr_write_chanreg(rt2x00dev, 17, 0x23); -@@ -10455,6 +10487,9 @@ static void rt2800_calibration_rt6352(st +@@ -10485,6 +10518,9 @@ static void rt2800_calibration_rt6352_st rt2800_register_write(rt2x00dev, RF_BYPASS3, reg); } @@ -222,7 +223,7 @@ if (rt2x00_has_cap_external_lna_bg(rt2x00dev)) { rt2800_rfcsr_write_chanreg(rt2x00dev, 14, 0x66); rt2800_rfcsr_write_chanreg(rt2x00dev, 17, 0x20); -@@ -10545,31 +10580,36 @@ static void rt2800_init_rfcsr_6352(struc +@@ -10575,31 +10611,36 @@ static void rt2800_init_rfcsr_6352(struc rt2800_rfcsr_write(rt2x00dev, 42, 0x5B); rt2800_rfcsr_write(rt2x00dev, 43, 0x00); @@ -284,7 +285,7 @@ /* Initialize RF channel register to default value */ rt2800_rfcsr_write_chanreg(rt2x00dev, 0, 0x03); -@@ -10635,63 +10675,71 @@ static void rt2800_init_rfcsr_6352(struc +@@ -10665,63 +10706,71 @@ static void rt2800_init_rfcsr_6352(struc rt2800_rfcsr_write_bank(rt2x00dev, 6, 45, 0xC5); @@ -411,7 +412,7 @@ /* Initialize RF DC calibration register to default value */ rt2800_rfcsr_write_dccal(rt2x00dev, 0, 0x47); -@@ -10754,12 +10802,17 @@ static void rt2800_init_rfcsr_6352(struc +@@ -10784,12 +10833,17 @@ static void rt2800_init_rfcsr_6352(struc rt2800_rfcsr_write_dccal(rt2x00dev, 62, 0x00); rt2800_rfcsr_write_dccal(rt2x00dev, 63, 0x00); @@ -431,6 +432,6 @@ + rt2800_rfcsr_write_dccal(rt2x00dev, 5, 0x00); + rt2800_rfcsr_write_dccal(rt2x00dev, 17, 0x7C); + } + } - /* Do calibration and init PA/LNA */ - rt2800_calibration_rt6352(rt2x00dev); + static void rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev) diff --git a/package/kernel/mac80211/patches/rt2x00/997-rt2x00-use-remove_new.patch b/package/kernel/mac80211/patches/rt2x00/997-rt2x00-use-remove_new.patch new file mode 100644 index 00000000000000..f857301e6f3d7e --- /dev/null +++ b/package/kernel/mac80211/patches/rt2x00/997-rt2x00-use-remove_new.patch @@ -0,0 +1,26 @@ +Switch rt2800soc from .remove to .remove_new callback + +The rt2x00soc_remove() function was converted to the new .remove API. +Kernel 6.6 still uses the old .remove API, switch to .remove_new. + +rt2800soc was switched in upstream commit: +https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?h=linux-6.12.y&id=06c566371f8afd582b9080f2d076509a4c78ae60 + +This fixes the following build problem: +``` +/drivers/net/wireless/ralink/rt2x00/rt2800soc.c:276:27: error: initialization of 'int (*)(struct platform_device *)' from incompatible pointer type 'void (*)(struct platform_device *)' [-Werror=incompatible-pointer-types] + 276 | .remove = rt2x00soc_remove, + | ^~~~~~~~~~~~~~~~ +``` + +--- a/drivers/net/wireless/ralink/rt2x00/rt2800soc.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2800soc.c +@@ -273,7 +273,7 @@ static struct platform_driver rt2800soc_ + .of_match_table = rt2880_wmac_match, + }, + .probe = rt2800soc_probe, +- .remove = rt2x00soc_remove, ++ .remove_new = rt2x00soc_remove, + .suspend = rt2x00soc_suspend, + .resume = rt2x00soc_resume, + }; diff --git a/package/kernel/mac80211/patches/rtl/017-v6.13-wifi-rtw88-Constify-some-arrays-and-structs.patch b/package/kernel/mac80211/patches/rtl/017-v6.13-wifi-rtw88-Constify-some-arrays-and-structs.patch new file mode 100644 index 00000000000000..04b5d4cd79402e --- /dev/null +++ b/package/kernel/mac80211/patches/rtl/017-v6.13-wifi-rtw88-Constify-some-arrays-and-structs.patch @@ -0,0 +1,374 @@ +From 140403599b74839b0a57c5397b7e8579e5332364 Mon Sep 17 00:00:00 2001 +From: Bitterblue Smith +Date: Wed, 18 Sep 2024 01:53:55 +0300 +Subject: [PATCH] wifi: rtw88: Constify some arrays and structs + +These are never modified, so make them const: + +card_enable_flow_8703b +card_disable_flow_8703b +rtw8703b_ops + +rtw8723d_ops +card_enable_flow_8723d +card_disable_flow_8723d + +trans_carddis_to_cardemu_8821c +trans_cardemu_to_act_8821c +trans_act_to_cardemu_8821c +trans_cardemu_to_carddis_8821c +card_enable_flow_8821c +card_disable_flow_8821c +rtw8821c_dig +page_table_8821c +rqpn_table_8821c +prioq_addrs_8821c +rtw8821c_ops + +card_enable_flow_8822b +card_disable_flow_8822b +prioq_addrs_8822b +rtw8822b_ops +rtw8822b_edcca_th + +card_enable_flow_8822c +card_disable_flow_8822c +prioq_addrs_8822c +rtw8822c_ops +rtw8822c_edcca_th + +Signed-off-by: Bitterblue Smith +Acked-by: Ping-Ke Shih +Signed-off-by: Ping-Ke Shih +Link: https://patch.msgid.link/dae7994f-3491-40de-b537-ebf68df084bb@gmail.com +--- + drivers/net/wireless/realtek/rtw88/fw.c | 2 +- + drivers/net/wireless/realtek/rtw88/mac.c | 4 ++-- + drivers/net/wireless/realtek/rtw88/main.h | 8 +++---- + drivers/net/wireless/realtek/rtw88/phy.c | 2 +- + drivers/net/wireless/realtek/rtw88/rtw8703b.c | 6 ++--- + drivers/net/wireless/realtek/rtw88/rtw8723d.c | 6 ++--- + drivers/net/wireless/realtek/rtw88/rtw8821c.c | 22 +++++++++---------- + drivers/net/wireless/realtek/rtw88/rtw8822b.c | 10 ++++----- + drivers/net/wireless/realtek/rtw88/rtw8822c.c | 10 ++++----- + 9 files changed, 35 insertions(+), 35 deletions(-) + +--- a/drivers/net/wireless/realtek/rtw88/fw.c ++++ b/drivers/net/wireless/realtek/rtw88/fw.c +@@ -267,7 +267,7 @@ static void rtw_fw_scan_result(struct rt + static void rtw_fw_adaptivity_result(struct rtw_dev *rtwdev, u8 *payload, + u8 length) + { +- struct rtw_hw_reg_offset *edcca_th = rtwdev->chip->edcca_th; ++ const struct rtw_hw_reg_offset *edcca_th = rtwdev->chip->edcca_th; + struct rtw_c2h_adaptivity *result = (struct rtw_c2h_adaptivity *)payload; + + rtw_dbg(rtwdev, RTW_DBG_ADAPTIVITY, +--- a/drivers/net/wireless/realtek/rtw88/mac.c ++++ b/drivers/net/wireless/realtek/rtw88/mac.c +@@ -228,7 +228,7 @@ static int rtw_sub_pwr_seq_parser(struct + } + + static int rtw_pwr_seq_parser(struct rtw_dev *rtwdev, +- const struct rtw_pwr_seq_cmd **cmd_seq) ++ const struct rtw_pwr_seq_cmd * const *cmd_seq) + { + u8 cut_mask; + u8 intf_mask; +@@ -271,7 +271,7 @@ static int rtw_pwr_seq_parser(struct rtw + static int rtw_mac_power_switch(struct rtw_dev *rtwdev, bool pwr_on) + { + const struct rtw_chip_info *chip = rtwdev->chip; +- const struct rtw_pwr_seq_cmd **pwr_seq; ++ const struct rtw_pwr_seq_cmd * const *pwr_seq; + u32 imr = 0; + u8 rpwm; + bool cur_pwr; +--- a/drivers/net/wireless/realtek/rtw88/main.h ++++ b/drivers/net/wireless/realtek/rtw88/main.h +@@ -1167,7 +1167,7 @@ enum rtw_fwcd_item { + + /* hardware configuration for each IC */ + struct rtw_chip_info { +- struct rtw_chip_ops *ops; ++ const struct rtw_chip_ops *ops; + u8 id; + + const char *fw_name; +@@ -1209,8 +1209,8 @@ struct rtw_chip_info { + + /* init values */ + u8 sys_func_en; +- const struct rtw_pwr_seq_cmd **pwr_on_seq; +- const struct rtw_pwr_seq_cmd **pwr_off_seq; ++ const struct rtw_pwr_seq_cmd * const *pwr_on_seq; ++ const struct rtw_pwr_seq_cmd * const *pwr_off_seq; + const struct rtw_rqpn *rqpn_table; + const struct rtw_prioq_addrs *prioq_addrs; + const struct rtw_page_table *page_table; +@@ -1242,7 +1242,7 @@ struct rtw_chip_info { + u8 bfer_su_max_num; + u8 bfer_mu_max_num; + +- struct rtw_hw_reg_offset *edcca_th; ++ const struct rtw_hw_reg_offset *edcca_th; + s8 l2h_th_ini_cs; + s8 l2h_th_ini_ad; + +--- a/drivers/net/wireless/realtek/rtw88/phy.c ++++ b/drivers/net/wireless/realtek/rtw88/phy.c +@@ -123,7 +123,7 @@ static void rtw_phy_cck_pd_init(struct r + + void rtw_phy_set_edcca_th(struct rtw_dev *rtwdev, u8 l2h, u8 h2l) + { +- struct rtw_hw_reg_offset *edcca_th = rtwdev->chip->edcca_th; ++ const struct rtw_hw_reg_offset *edcca_th = rtwdev->chip->edcca_th; + + rtw_write32_mask(rtwdev, + edcca_th[EDCCA_TH_L2H_IDX].hw_reg.addr, +--- a/drivers/net/wireless/realtek/rtw88/rtw8703b.c ++++ b/drivers/net/wireless/realtek/rtw88/rtw8703b.c +@@ -481,14 +481,14 @@ static const struct rtw_pwr_seq_cmd tran + {TRANS_SEQ_END}, + }; + +-static const struct rtw_pwr_seq_cmd *card_enable_flow_8703b[] = { ++static const struct rtw_pwr_seq_cmd * const card_enable_flow_8703b[] = { + trans_pre_enable_8703b, + trans_carddis_to_cardemu_8703b, + trans_cardemu_to_act_8703b, + NULL + }; + +-static const struct rtw_pwr_seq_cmd *card_disable_flow_8703b[] = { ++static const struct rtw_pwr_seq_cmd * const card_disable_flow_8703b[] = { + trans_act_to_lps_8703b, + trans_act_to_reset_mcu_8703b, + trans_act_to_cardemu_8703b, +@@ -1941,7 +1941,7 @@ static const struct coex_tdma_para tdma_ + { {0x61, 0x08, 0x03, 0x11, 0x11} }, + }; + +-static struct rtw_chip_ops rtw8703b_ops = { ++static const struct rtw_chip_ops rtw8703b_ops = { + .mac_init = rtw8723x_mac_init, + .dump_fw_crash = NULL, + .shutdown = NULL, +--- a/drivers/net/wireless/realtek/rtw88/rtw8723d.c ++++ b/drivers/net/wireless/realtek/rtw88/rtw8723d.c +@@ -1430,7 +1430,7 @@ static void rtw8723d_pwr_track(struct rt + dm_info->pwr_trk_triggered = false; + } + +-static struct rtw_chip_ops rtw8723d_ops = { ++static const struct rtw_chip_ops rtw8723d_ops = { + .phy_set_param = rtw8723d_phy_set_param, + .read_efuse = rtw8723x_read_efuse, + .query_rx_desc = rtw8723d_query_rx_desc, +@@ -1788,7 +1788,7 @@ static const struct rtw_pwr_seq_cmd tran + RTW_PWR_CMD_END, 0, 0}, + }; + +-static const struct rtw_pwr_seq_cmd *card_enable_flow_8723d[] = { ++static const struct rtw_pwr_seq_cmd * const card_enable_flow_8723d[] = { + trans_carddis_to_cardemu_8723d, + trans_cardemu_to_act_8723d, + NULL +@@ -2004,7 +2004,7 @@ static const struct rtw_pwr_seq_cmd tran + RTW_PWR_CMD_END, 0, 0}, + }; + +-static const struct rtw_pwr_seq_cmd *card_disable_flow_8723d[] = { ++static const struct rtw_pwr_seq_cmd * const card_disable_flow_8723d[] = { + trans_act_to_lps_8723d, + trans_act_to_pre_carddis_8723d, + trans_act_to_cardemu_8723d, +--- a/drivers/net/wireless/realtek/rtw88/rtw8821c.c ++++ b/drivers/net/wireless/realtek/rtw88/rtw8821c.c +@@ -1254,7 +1254,7 @@ static void rtw8821c_fill_txdesc_checksu + fill_txdesc_checksum_common(txdesc, 16); + } + +-static struct rtw_pwr_seq_cmd trans_carddis_to_cardemu_8821c[] = { ++static const struct rtw_pwr_seq_cmd trans_carddis_to_cardemu_8821c[] = { + {0x0086, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_SDIO_MSK, +@@ -1292,7 +1292,7 @@ static struct rtw_pwr_seq_cmd trans_card + RTW_PWR_CMD_END, 0, 0}, + }; + +-static struct rtw_pwr_seq_cmd trans_cardemu_to_act_8821c[] = { ++static const struct rtw_pwr_seq_cmd trans_cardemu_to_act_8821c[] = { + {0x0020, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK, +@@ -1396,7 +1396,7 @@ static struct rtw_pwr_seq_cmd trans_card + RTW_PWR_CMD_END, 0, 0}, + }; + +-static struct rtw_pwr_seq_cmd trans_act_to_cardemu_8821c[] = { ++static const struct rtw_pwr_seq_cmd trans_act_to_cardemu_8821c[] = { + {0x0093, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, +@@ -1454,7 +1454,7 @@ static struct rtw_pwr_seq_cmd trans_act_ + RTW_PWR_CMD_END, 0, 0}, + }; + +-static struct rtw_pwr_seq_cmd trans_cardemu_to_carddis_8821c[] = { ++static const struct rtw_pwr_seq_cmd trans_cardemu_to_carddis_8821c[] = { + {0x0007, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK, +@@ -1567,13 +1567,13 @@ static struct rtw_pwr_seq_cmd trans_card + RTW_PWR_CMD_END, 0, 0}, + }; + +-static const struct rtw_pwr_seq_cmd *card_enable_flow_8821c[] = { ++static const struct rtw_pwr_seq_cmd * const card_enable_flow_8821c[] = { + trans_carddis_to_cardemu_8821c, + trans_cardemu_to_act_8821c, + NULL + }; + +-static const struct rtw_pwr_seq_cmd *card_disable_flow_8821c[] = { ++static const struct rtw_pwr_seq_cmd * const card_disable_flow_8821c[] = { + trans_act_to_cardemu_8821c, + trans_cardemu_to_carddis_8821c, + NULL +@@ -1629,7 +1629,7 @@ static const struct rtw_rfe_def rtw8821c + [6] = RTW_DEF_RFE(8821c, 0, 0), + }; + +-static struct rtw_hw_reg rtw8821c_dig[] = { ++static const struct rtw_hw_reg rtw8821c_dig[] = { + [0] = { .addr = 0xc50, .mask = 0x7f }, + }; + +@@ -1639,7 +1639,7 @@ static const struct rtw_ltecoex_addr rtw + .rdata = LTECOEX_READ_DATA, + }; + +-static struct rtw_page_table page_table_8821c[] = { ++static const struct rtw_page_table page_table_8821c[] = { + /* not sure what [0] stands for */ + {16, 16, 16, 14, 1}, + {16, 16, 16, 14, 1}, +@@ -1648,7 +1648,7 @@ static struct rtw_page_table page_table_ + {16, 16, 16, 14, 1}, + }; + +-static struct rtw_rqpn rqpn_table_8821c[] = { ++static const struct rtw_rqpn rqpn_table_8821c[] = { + /* not sure what [0] stands for */ + {RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL, + RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW, +@@ -1667,7 +1667,7 @@ static struct rtw_rqpn rqpn_table_8821c[ + RTW_DMA_MAPPING_EXTRA, RTW_DMA_MAPPING_HIGH}, + }; + +-static struct rtw_prioq_addrs prioq_addrs_8821c = { ++static const struct rtw_prioq_addrs prioq_addrs_8821c = { + .prio[RTW_DMA_MAPPING_EXTRA] = { + .rsvd = REG_FIFOPAGE_INFO_4, .avail = REG_FIFOPAGE_INFO_4 + 2, + }, +@@ -1683,7 +1683,7 @@ static struct rtw_prioq_addrs prioq_addr + .wsize = true, + }; + +-static struct rtw_chip_ops rtw8821c_ops = { ++static const struct rtw_chip_ops rtw8821c_ops = { + .phy_set_param = rtw8821c_phy_set_param, + .read_efuse = rtw8821c_read_efuse, + .query_rx_desc = rtw8821c_query_rx_desc, +--- a/drivers/net/wireless/realtek/rtw88/rtw8822b.c ++++ b/drivers/net/wireless/realtek/rtw88/rtw8822b.c +@@ -1980,13 +1980,13 @@ static const struct rtw_pwr_seq_cmd tran + RTW_PWR_CMD_END, 0, 0}, + }; + +-static const struct rtw_pwr_seq_cmd *card_enable_flow_8822b[] = { ++static const struct rtw_pwr_seq_cmd * const card_enable_flow_8822b[] = { + trans_carddis_to_cardemu_8822b, + trans_cardemu_to_act_8822b, + NULL + }; + +-static const struct rtw_pwr_seq_cmd *card_disable_flow_8822b[] = { ++static const struct rtw_pwr_seq_cmd * const card_disable_flow_8822b[] = { + trans_act_to_cardemu_8822b, + trans_cardemu_to_carddis_8822b, + NULL +@@ -2158,7 +2158,7 @@ static const struct rtw_rqpn rqpn_table_ + RTW_DMA_MAPPING_EXTRA, RTW_DMA_MAPPING_HIGH}, + }; + +-static struct rtw_prioq_addrs prioq_addrs_8822b = { ++static const struct rtw_prioq_addrs prioq_addrs_8822b = { + .prio[RTW_DMA_MAPPING_EXTRA] = { + .rsvd = REG_FIFOPAGE_INFO_4, .avail = REG_FIFOPAGE_INFO_4 + 2, + }, +@@ -2174,7 +2174,7 @@ static struct rtw_prioq_addrs prioq_addr + .wsize = true, + }; + +-static struct rtw_chip_ops rtw8822b_ops = { ++static const struct rtw_chip_ops rtw8822b_ops = { + .phy_set_param = rtw8822b_phy_set_param, + .read_efuse = rtw8822b_read_efuse, + .query_rx_desc = rtw8822b_query_rx_desc, +@@ -2523,7 +2523,7 @@ static const struct rtw_reg_domain coex_ + {0xc50, MASKBYTE0, RTW_REG_DOMAIN_MAC8}, + }; + +-static struct rtw_hw_reg_offset rtw8822b_edcca_th[] = { ++static const struct rtw_hw_reg_offset rtw8822b_edcca_th[] = { + [EDCCA_TH_L2H_IDX] = {{.addr = 0x8a4, .mask = MASKBYTE0}, .offset = 0}, + [EDCCA_TH_H2L_IDX] = {{.addr = 0x8a4, .mask = MASKBYTE1}, .offset = 0}, + }; +--- a/drivers/net/wireless/realtek/rtw88/rtw8822c.c ++++ b/drivers/net/wireless/realtek/rtw88/rtw8822c.c +@@ -4875,13 +4875,13 @@ static const struct rtw_pwr_seq_cmd tran + RTW_PWR_CMD_END, 0, 0}, + }; + +-static const struct rtw_pwr_seq_cmd *card_enable_flow_8822c[] = { ++static const struct rtw_pwr_seq_cmd * const card_enable_flow_8822c[] = { + trans_carddis_to_cardemu_8822c, + trans_cardemu_to_act_8822c, + NULL + }; + +-static const struct rtw_pwr_seq_cmd *card_disable_flow_8822c[] = { ++static const struct rtw_pwr_seq_cmd * const card_disable_flow_8822c[] = { + trans_act_to_cardemu_8822c, + trans_cardemu_to_carddis_8822c, + NULL +@@ -4973,7 +4973,7 @@ static const struct rtw_rqpn rqpn_table_ + RTW_DMA_MAPPING_EXTRA, RTW_DMA_MAPPING_HIGH}, + }; + +-static struct rtw_prioq_addrs prioq_addrs_8822c = { ++static const struct rtw_prioq_addrs prioq_addrs_8822c = { + .prio[RTW_DMA_MAPPING_EXTRA] = { + .rsvd = REG_FIFOPAGE_INFO_4, .avail = REG_FIFOPAGE_INFO_4 + 2, + }, +@@ -4989,7 +4989,7 @@ static struct rtw_prioq_addrs prioq_addr + .wsize = true, + }; + +-static struct rtw_chip_ops rtw8822c_ops = { ++static const struct rtw_chip_ops rtw8822c_ops = { + .phy_set_param = rtw8822c_phy_set_param, + .read_efuse = rtw8822c_read_efuse, + .query_rx_desc = rtw8822c_query_rx_desc, +@@ -5302,7 +5302,7 @@ static const struct rtw_pwr_track_tbl rt + .pwrtrk_2g_ccka_p = rtw8822c_pwrtrk_2g_cck_a_p, + }; + +-static struct rtw_hw_reg_offset rtw8822c_edcca_th[] = { ++static const struct rtw_hw_reg_offset rtw8822c_edcca_th[] = { + [EDCCA_TH_L2H_IDX] = { + {.addr = 0x84c, .mask = MASKBYTE2}, .offset = 0x80 + }, diff --git a/package/kernel/mac80211/patches/rtl/019-v6.13-wifi-rtw88-Parse-the-RX-descriptor-with-a-single-fun.patch b/package/kernel/mac80211/patches/rtl/019-v6.13-wifi-rtw88-Parse-the-RX-descriptor-with-a-single-fun.patch new file mode 100644 index 00000000000000..4c6966a3c6c09f --- /dev/null +++ b/package/kernel/mac80211/patches/rtl/019-v6.13-wifi-rtw88-Parse-the-RX-descriptor-with-a-single-fun.patch @@ -0,0 +1,560 @@ +From bbb6f9be7f99464d5ab7e2f321fa728d33eeec9a Mon Sep 17 00:00:00 2001 +From: Bitterblue Smith +Date: Fri, 20 Sep 2024 22:27:30 +0300 +Subject: [PATCH] wifi: rtw88: Parse the RX descriptor with a single function + +rtw8703b_query_rx_desc(), rtw8723d_query_rx_desc(), +rtw8821c_query_rx_desc(), rtw8822b_query_rx_desc(), and +rtw8822c_query_rx_desc() are almost identical, so replace them all with +a single function, rtw_rx_query_rx_desc(). + +Also, access the RX descriptor using a struct with __le32 members and +le32_get_bits(). + +Tested with RTL8811CU, RTL8811AU, and RTL8812AU. + +Signed-off-by: Bitterblue Smith +Tested-by: Ping-Ke Shih # RTL8723DE and RTL8822CE +Acked-by: Ping-Ke Shih +Signed-off-by: Ping-Ke Shih +Link: https://patch.msgid.link/913f1747-38fc-4409-85a4-57bb9cee506b@gmail.com +--- + drivers/net/wireless/realtek/rtw88/main.h | 5 +- + drivers/net/wireless/realtek/rtw88/pci.c | 2 +- + drivers/net/wireless/realtek/rtw88/rtw8703b.c | 56 +-------------- + drivers/net/wireless/realtek/rtw88/rtw8723d.c | 43 +----------- + drivers/net/wireless/realtek/rtw88/rtw8821c.c | 43 +----------- + drivers/net/wireless/realtek/rtw88/rtw8822b.c | 43 +----------- + drivers/net/wireless/realtek/rtw88/rtw8822c.c | 44 +----------- + drivers/net/wireless/realtek/rtw88/rx.c | 70 +++++++++++++++++-- + drivers/net/wireless/realtek/rtw88/rx.h | 64 ++++++++--------- + drivers/net/wireless/realtek/rtw88/sdio.c | 3 +- + drivers/net/wireless/realtek/rtw88/usb.c | 4 +- + 11 files changed, 106 insertions(+), 271 deletions(-) + +--- a/drivers/net/wireless/realtek/rtw88/main.h ++++ b/drivers/net/wireless/realtek/rtw88/main.h +@@ -848,9 +848,8 @@ struct rtw_chip_ops { + void (*phy_set_param)(struct rtw_dev *rtwdev); + void (*set_channel)(struct rtw_dev *rtwdev, u8 channel, + u8 bandwidth, u8 primary_chan_idx); +- void (*query_rx_desc)(struct rtw_dev *rtwdev, u8 *rx_desc, +- struct rtw_rx_pkt_stat *pkt_stat, +- struct ieee80211_rx_status *rx_status); ++ void (*query_phy_status)(struct rtw_dev *rtwdev, u8 *phy_status, ++ struct rtw_rx_pkt_stat *pkt_stat); + u32 (*read_rf)(struct rtw_dev *rtwdev, enum rtw_rf_path rf_path, + u32 addr, u32 mask); + bool (*write_rf)(struct rtw_dev *rtwdev, enum rtw_rf_path rf_path, +--- a/drivers/net/wireless/realtek/rtw88/pci.c ++++ b/drivers/net/wireless/realtek/rtw88/pci.c +@@ -1066,7 +1066,7 @@ static u32 rtw_pci_rx_napi(struct rtw_de + dma_sync_single_for_cpu(rtwdev->dev, dma, RTK_PCI_RX_BUF_SIZE, + DMA_FROM_DEVICE); + rx_desc = skb->data; +- chip->ops->query_rx_desc(rtwdev, rx_desc, &pkt_stat, &rx_status); ++ rtw_rx_query_rx_desc(rtwdev, rx_desc, &pkt_stat, &rx_status); + + /* offset from rx_desc to payload */ + pkt_offset = pkt_desc_sz + pkt_stat.drv_info_sz + +--- a/drivers/net/wireless/realtek/rtw88/rtw8703b.c ++++ b/drivers/net/wireless/realtek/rtw88/rtw8703b.c +@@ -29,9 +29,6 @@ + #define TBTT_PROHIBIT_HOLD_TIME 0x80 + #define TBTT_PROHIBIT_HOLD_TIME_STOP_BCN 0x64 + +-/* raw pkt_stat->drv_info_sz is in unit of 8-bytes */ +-#define RX_DRV_INFO_SZ_UNIT_8703B 8 +- + #define TRANS_SEQ_END \ + 0xFFFF, \ + RTW_PWR_CUT_ALL_MSK, \ +@@ -1032,57 +1029,6 @@ static void query_phy_status(struct rtw_ + query_phy_status_ofdm(rtwdev, phy_status, pkt_stat); + } + +-static void rtw8703b_query_rx_desc(struct rtw_dev *rtwdev, u8 *rx_desc, +- struct rtw_rx_pkt_stat *pkt_stat, +- struct ieee80211_rx_status *rx_status) +-{ +- struct ieee80211_hdr *hdr; +- u32 desc_sz = rtwdev->chip->rx_pkt_desc_sz; +- u8 *phy_status = NULL; +- +- memset(pkt_stat, 0, sizeof(*pkt_stat)); +- +- pkt_stat->phy_status = GET_RX_DESC_PHYST(rx_desc); +- pkt_stat->icv_err = GET_RX_DESC_ICV_ERR(rx_desc); +- pkt_stat->crc_err = GET_RX_DESC_CRC32(rx_desc); +- pkt_stat->decrypted = !GET_RX_DESC_SWDEC(rx_desc) && +- GET_RX_DESC_ENC_TYPE(rx_desc) != RX_DESC_ENC_NONE; +- pkt_stat->is_c2h = GET_RX_DESC_C2H(rx_desc); +- pkt_stat->pkt_len = GET_RX_DESC_PKT_LEN(rx_desc); +- pkt_stat->drv_info_sz = GET_RX_DESC_DRV_INFO_SIZE(rx_desc); +- pkt_stat->shift = GET_RX_DESC_SHIFT(rx_desc); +- pkt_stat->rate = GET_RX_DESC_RX_RATE(rx_desc); +- pkt_stat->cam_id = GET_RX_DESC_MACID(rx_desc); +- pkt_stat->ppdu_cnt = 0; +- pkt_stat->tsf_low = GET_RX_DESC_TSFL(rx_desc); +- +- pkt_stat->drv_info_sz *= RX_DRV_INFO_SZ_UNIT_8703B; +- +- if (pkt_stat->is_c2h) +- return; +- +- hdr = (struct ieee80211_hdr *)(rx_desc + desc_sz + pkt_stat->shift + +- pkt_stat->drv_info_sz); +- +- pkt_stat->bw = GET_RX_DESC_BW(rx_desc); +- +- if (pkt_stat->phy_status) { +- phy_status = rx_desc + desc_sz + pkt_stat->shift; +- query_phy_status(rtwdev, phy_status, pkt_stat); +- } +- +- rtw_rx_fill_rx_status(rtwdev, pkt_stat, hdr, rx_status, phy_status); +- +- /* Rtl8723cs driver checks for size < 14 or size > 8192 and +- * simply drops the packet. Maybe this should go into +- * rtw_rx_fill_rx_status()? +- */ +- if (pkt_stat->pkt_len == 0) { +- rx_status->flag |= RX_FLAG_NO_PSDU; +- rtw_dbg(rtwdev, RTW_DBG_RX, "zero length packet"); +- } +-} +- + #define ADDA_ON_VAL_8703B 0x03c00014 + + static +@@ -1948,7 +1894,7 @@ static const struct rtw_chip_ops rtw8703 + .read_efuse = rtw8703b_read_efuse, + .phy_set_param = rtw8703b_phy_set_param, + .set_channel = rtw8703b_set_channel, +- .query_rx_desc = rtw8703b_query_rx_desc, ++ .query_phy_status = query_phy_status, + .read_rf = rtw_phy_read_rf_sipi, + .write_rf = rtw_phy_write_rf_reg_sipi, + .set_tx_power_index = rtw8723x_set_tx_power_index, +--- a/drivers/net/wireless/realtek/rtw88/rtw8723d.c ++++ b/drivers/net/wireless/realtek/rtw88/rtw8723d.c +@@ -227,47 +227,6 @@ static void query_phy_status(struct rtw_ + } + } + +-static void rtw8723d_query_rx_desc(struct rtw_dev *rtwdev, u8 *rx_desc, +- struct rtw_rx_pkt_stat *pkt_stat, +- struct ieee80211_rx_status *rx_status) +-{ +- struct ieee80211_hdr *hdr; +- u32 desc_sz = rtwdev->chip->rx_pkt_desc_sz; +- u8 *phy_status = NULL; +- +- memset(pkt_stat, 0, sizeof(*pkt_stat)); +- +- pkt_stat->phy_status = GET_RX_DESC_PHYST(rx_desc); +- pkt_stat->icv_err = GET_RX_DESC_ICV_ERR(rx_desc); +- pkt_stat->crc_err = GET_RX_DESC_CRC32(rx_desc); +- pkt_stat->decrypted = !GET_RX_DESC_SWDEC(rx_desc) && +- GET_RX_DESC_ENC_TYPE(rx_desc) != RX_DESC_ENC_NONE; +- pkt_stat->is_c2h = GET_RX_DESC_C2H(rx_desc); +- pkt_stat->pkt_len = GET_RX_DESC_PKT_LEN(rx_desc); +- pkt_stat->drv_info_sz = GET_RX_DESC_DRV_INFO_SIZE(rx_desc); +- pkt_stat->shift = GET_RX_DESC_SHIFT(rx_desc); +- pkt_stat->rate = GET_RX_DESC_RX_RATE(rx_desc); +- pkt_stat->cam_id = GET_RX_DESC_MACID(rx_desc); +- pkt_stat->ppdu_cnt = 0; +- pkt_stat->tsf_low = GET_RX_DESC_TSFL(rx_desc); +- +- /* drv_info_sz is in unit of 8-bytes */ +- pkt_stat->drv_info_sz *= 8; +- +- /* c2h cmd pkt's rx/phy status is not interested */ +- if (pkt_stat->is_c2h) +- return; +- +- hdr = (struct ieee80211_hdr *)(rx_desc + desc_sz + pkt_stat->shift + +- pkt_stat->drv_info_sz); +- if (pkt_stat->phy_status) { +- phy_status = rx_desc + desc_sz + pkt_stat->shift; +- query_phy_status(rtwdev, phy_status, pkt_stat); +- } +- +- rtw_rx_fill_rx_status(rtwdev, pkt_stat, hdr, rx_status, phy_status); +-} +- + static bool rtw8723d_check_spur_ov_thres(struct rtw_dev *rtwdev, + u8 channel, u32 thres) + { +@@ -1433,7 +1392,7 @@ static void rtw8723d_pwr_track(struct rt + static const struct rtw_chip_ops rtw8723d_ops = { + .phy_set_param = rtw8723d_phy_set_param, + .read_efuse = rtw8723x_read_efuse, +- .query_rx_desc = rtw8723d_query_rx_desc, ++ .query_phy_status = query_phy_status, + .set_channel = rtw8723d_set_channel, + .mac_init = rtw8723x_mac_init, + .shutdown = rtw8723d_shutdown, +--- a/drivers/net/wireless/realtek/rtw88/rtw8821c.c ++++ b/drivers/net/wireless/realtek/rtw88/rtw8821c.c +@@ -679,47 +679,6 @@ static void query_phy_status(struct rtw_ + } + } + +-static void rtw8821c_query_rx_desc(struct rtw_dev *rtwdev, u8 *rx_desc, +- struct rtw_rx_pkt_stat *pkt_stat, +- struct ieee80211_rx_status *rx_status) +-{ +- struct ieee80211_hdr *hdr; +- u32 desc_sz = rtwdev->chip->rx_pkt_desc_sz; +- u8 *phy_status = NULL; +- +- memset(pkt_stat, 0, sizeof(*pkt_stat)); +- +- pkt_stat->phy_status = GET_RX_DESC_PHYST(rx_desc); +- pkt_stat->icv_err = GET_RX_DESC_ICV_ERR(rx_desc); +- pkt_stat->crc_err = GET_RX_DESC_CRC32(rx_desc); +- pkt_stat->decrypted = !GET_RX_DESC_SWDEC(rx_desc) && +- GET_RX_DESC_ENC_TYPE(rx_desc) != RX_DESC_ENC_NONE; +- pkt_stat->is_c2h = GET_RX_DESC_C2H(rx_desc); +- pkt_stat->pkt_len = GET_RX_DESC_PKT_LEN(rx_desc); +- pkt_stat->drv_info_sz = GET_RX_DESC_DRV_INFO_SIZE(rx_desc); +- pkt_stat->shift = GET_RX_DESC_SHIFT(rx_desc); +- pkt_stat->rate = GET_RX_DESC_RX_RATE(rx_desc); +- pkt_stat->cam_id = GET_RX_DESC_MACID(rx_desc); +- pkt_stat->ppdu_cnt = GET_RX_DESC_PPDU_CNT(rx_desc); +- pkt_stat->tsf_low = GET_RX_DESC_TSFL(rx_desc); +- +- /* drv_info_sz is in unit of 8-bytes */ +- pkt_stat->drv_info_sz *= 8; +- +- /* c2h cmd pkt's rx/phy status is not interested */ +- if (pkt_stat->is_c2h) +- return; +- +- hdr = (struct ieee80211_hdr *)(rx_desc + desc_sz + pkt_stat->shift + +- pkt_stat->drv_info_sz); +- if (pkt_stat->phy_status) { +- phy_status = rx_desc + desc_sz + pkt_stat->shift; +- query_phy_status(rtwdev, phy_status, pkt_stat); +- } +- +- rtw_rx_fill_rx_status(rtwdev, pkt_stat, hdr, rx_status, phy_status); +-} +- + static void + rtw8821c_set_tx_power_index_by_rate(struct rtw_dev *rtwdev, u8 path, u8 rs) + { +@@ -1686,7 +1645,7 @@ static const struct rtw_prioq_addrs prio + static const struct rtw_chip_ops rtw8821c_ops = { + .phy_set_param = rtw8821c_phy_set_param, + .read_efuse = rtw8821c_read_efuse, +- .query_rx_desc = rtw8821c_query_rx_desc, ++ .query_phy_status = query_phy_status, + .set_channel = rtw8821c_set_channel, + .mac_init = rtw8821c_mac_init, + .read_rf = rtw_phy_read_rf, +--- a/drivers/net/wireless/realtek/rtw88/rtw8822b.c ++++ b/drivers/net/wireless/realtek/rtw88/rtw8822b.c +@@ -934,47 +934,6 @@ static void query_phy_status(struct rtw_ + } + } + +-static void rtw8822b_query_rx_desc(struct rtw_dev *rtwdev, u8 *rx_desc, +- struct rtw_rx_pkt_stat *pkt_stat, +- struct ieee80211_rx_status *rx_status) +-{ +- struct ieee80211_hdr *hdr; +- u32 desc_sz = rtwdev->chip->rx_pkt_desc_sz; +- u8 *phy_status = NULL; +- +- memset(pkt_stat, 0, sizeof(*pkt_stat)); +- +- pkt_stat->phy_status = GET_RX_DESC_PHYST(rx_desc); +- pkt_stat->icv_err = GET_RX_DESC_ICV_ERR(rx_desc); +- pkt_stat->crc_err = GET_RX_DESC_CRC32(rx_desc); +- pkt_stat->decrypted = !GET_RX_DESC_SWDEC(rx_desc) && +- GET_RX_DESC_ENC_TYPE(rx_desc) != RX_DESC_ENC_NONE; +- pkt_stat->is_c2h = GET_RX_DESC_C2H(rx_desc); +- pkt_stat->pkt_len = GET_RX_DESC_PKT_LEN(rx_desc); +- pkt_stat->drv_info_sz = GET_RX_DESC_DRV_INFO_SIZE(rx_desc); +- pkt_stat->shift = GET_RX_DESC_SHIFT(rx_desc); +- pkt_stat->rate = GET_RX_DESC_RX_RATE(rx_desc); +- pkt_stat->cam_id = GET_RX_DESC_MACID(rx_desc); +- pkt_stat->ppdu_cnt = GET_RX_DESC_PPDU_CNT(rx_desc); +- pkt_stat->tsf_low = GET_RX_DESC_TSFL(rx_desc); +- +- /* drv_info_sz is in unit of 8-bytes */ +- pkt_stat->drv_info_sz *= 8; +- +- /* c2h cmd pkt's rx/phy status is not interested */ +- if (pkt_stat->is_c2h) +- return; +- +- hdr = (struct ieee80211_hdr *)(rx_desc + desc_sz + pkt_stat->shift + +- pkt_stat->drv_info_sz); +- if (pkt_stat->phy_status) { +- phy_status = rx_desc + desc_sz + pkt_stat->shift; +- query_phy_status(rtwdev, phy_status, pkt_stat); +- } +- +- rtw_rx_fill_rx_status(rtwdev, pkt_stat, hdr, rx_status, phy_status); +-} +- + static void + rtw8822b_set_tx_power_index_by_rate(struct rtw_dev *rtwdev, u8 path, + u8 rs, u32 *phy_pwr_idx) +@@ -2177,7 +2136,7 @@ static const struct rtw_prioq_addrs prio + static const struct rtw_chip_ops rtw8822b_ops = { + .phy_set_param = rtw8822b_phy_set_param, + .read_efuse = rtw8822b_read_efuse, +- .query_rx_desc = rtw8822b_query_rx_desc, ++ .query_phy_status = query_phy_status, + .set_channel = rtw8822b_set_channel, + .mac_init = rtw8822b_mac_init, + .read_rf = rtw_phy_read_rf, +--- a/drivers/net/wireless/realtek/rtw88/rtw8822c.c ++++ b/drivers/net/wireless/realtek/rtw88/rtw8822c.c +@@ -2690,48 +2690,6 @@ static void query_phy_status(struct rtw_ + } + } + +-static void rtw8822c_query_rx_desc(struct rtw_dev *rtwdev, u8 *rx_desc, +- struct rtw_rx_pkt_stat *pkt_stat, +- struct ieee80211_rx_status *rx_status) +-{ +- struct ieee80211_hdr *hdr; +- u32 desc_sz = rtwdev->chip->rx_pkt_desc_sz; +- u8 *phy_status = NULL; +- +- memset(pkt_stat, 0, sizeof(*pkt_stat)); +- +- pkt_stat->phy_status = GET_RX_DESC_PHYST(rx_desc); +- pkt_stat->icv_err = GET_RX_DESC_ICV_ERR(rx_desc); +- pkt_stat->crc_err = GET_RX_DESC_CRC32(rx_desc); +- pkt_stat->decrypted = !GET_RX_DESC_SWDEC(rx_desc) && +- GET_RX_DESC_ENC_TYPE(rx_desc) != RX_DESC_ENC_NONE; +- pkt_stat->is_c2h = GET_RX_DESC_C2H(rx_desc); +- pkt_stat->pkt_len = GET_RX_DESC_PKT_LEN(rx_desc); +- pkt_stat->drv_info_sz = GET_RX_DESC_DRV_INFO_SIZE(rx_desc); +- pkt_stat->shift = GET_RX_DESC_SHIFT(rx_desc); +- pkt_stat->rate = GET_RX_DESC_RX_RATE(rx_desc); +- pkt_stat->cam_id = GET_RX_DESC_MACID(rx_desc); +- pkt_stat->ppdu_cnt = GET_RX_DESC_PPDU_CNT(rx_desc); +- pkt_stat->tsf_low = GET_RX_DESC_TSFL(rx_desc); +- +- /* drv_info_sz is in unit of 8-bytes */ +- pkt_stat->drv_info_sz *= 8; +- +- /* c2h cmd pkt's rx/phy status is not interested */ +- if (pkt_stat->is_c2h) +- return; +- +- hdr = (struct ieee80211_hdr *)(rx_desc + desc_sz + pkt_stat->shift + +- pkt_stat->drv_info_sz); +- pkt_stat->hdr = hdr; +- if (pkt_stat->phy_status) { +- phy_status = rx_desc + desc_sz + pkt_stat->shift; +- query_phy_status(rtwdev, phy_status, pkt_stat); +- } +- +- rtw_rx_fill_rx_status(rtwdev, pkt_stat, hdr, rx_status, phy_status); +-} +- + static void + rtw8822c_set_write_tx_power_ref(struct rtw_dev *rtwdev, u8 *tx_pwr_ref_cck, + u8 *tx_pwr_ref_ofdm) +@@ -4992,7 +4950,7 @@ static const struct rtw_prioq_addrs prio + static const struct rtw_chip_ops rtw8822c_ops = { + .phy_set_param = rtw8822c_phy_set_param, + .read_efuse = rtw8822c_read_efuse, +- .query_rx_desc = rtw8822c_query_rx_desc, ++ .query_phy_status = query_phy_status, + .set_channel = rtw8822c_set_channel, + .mac_init = rtw8822c_mac_init, + .dump_fw_crash = rtw8822c_dump_fw_crash, +--- a/drivers/net/wireless/realtek/rtw88/rx.c ++++ b/drivers/net/wireless/realtek/rtw88/rx.c +@@ -187,11 +187,10 @@ fill_rx_status: + } + EXPORT_SYMBOL(rtw_update_rx_freq_from_ie); + +-void rtw_rx_fill_rx_status(struct rtw_dev *rtwdev, +- struct rtw_rx_pkt_stat *pkt_stat, +- struct ieee80211_hdr *hdr, +- struct ieee80211_rx_status *rx_status, +- u8 *phy_status) ++static void rtw_rx_fill_rx_status(struct rtw_dev *rtwdev, ++ struct rtw_rx_pkt_stat *pkt_stat, ++ struct ieee80211_hdr *hdr, ++ struct ieee80211_rx_status *rx_status) + { + struct ieee80211_hw *hw = rtwdev->hw; + u8 path; +@@ -242,5 +241,64 @@ void rtw_rx_fill_rx_status(struct rtw_de + } + + rtw_rx_addr_match(rtwdev, pkt_stat, hdr); ++ ++ /* Rtl8723cs driver checks for size < 14 or size > 8192 and ++ * simply drops the packet. ++ */ ++ if (rtwdev->chip->id == RTW_CHIP_TYPE_8703B && pkt_stat->pkt_len == 0) { ++ rx_status->flag |= RX_FLAG_NO_PSDU; ++ rtw_dbg(rtwdev, RTW_DBG_RX, "zero length packet"); ++ } ++} ++ ++void rtw_rx_query_rx_desc(struct rtw_dev *rtwdev, void *rx_desc8, ++ struct rtw_rx_pkt_stat *pkt_stat, ++ struct ieee80211_rx_status *rx_status) ++{ ++ u32 desc_sz = rtwdev->chip->rx_pkt_desc_sz; ++ struct rtw_rx_desc *rx_desc = rx_desc8; ++ struct ieee80211_hdr *hdr; ++ u32 enc_type, swdec; ++ void *phy_status; ++ ++ memset(pkt_stat, 0, sizeof(*pkt_stat)); ++ ++ pkt_stat->pkt_len = le32_get_bits(rx_desc->w0, RTW_RX_DESC_W0_PKT_LEN); ++ pkt_stat->crc_err = le32_get_bits(rx_desc->w0, RTW_RX_DESC_W0_CRC32); ++ pkt_stat->icv_err = le32_get_bits(rx_desc->w0, RTW_RX_DESC_W0_ICV_ERR); ++ pkt_stat->drv_info_sz = le32_get_bits(rx_desc->w0, ++ RTW_RX_DESC_W0_DRV_INFO_SIZE); ++ enc_type = le32_get_bits(rx_desc->w0, RTW_RX_DESC_W0_ENC_TYPE); ++ pkt_stat->shift = le32_get_bits(rx_desc->w0, RTW_RX_DESC_W0_SHIFT); ++ pkt_stat->phy_status = le32_get_bits(rx_desc->w0, RTW_RX_DESC_W0_PHYST); ++ swdec = le32_get_bits(rx_desc->w0, RTW_RX_DESC_W0_SWDEC); ++ pkt_stat->decrypted = !swdec && enc_type != RX_DESC_ENC_NONE; ++ ++ pkt_stat->cam_id = le32_get_bits(rx_desc->w1, RTW_RX_DESC_W1_MACID); ++ ++ pkt_stat->is_c2h = le32_get_bits(rx_desc->w2, RTW_RX_DESC_W2_C2H); ++ pkt_stat->ppdu_cnt = le32_get_bits(rx_desc->w2, RTW_RX_DESC_W2_PPDU_CNT); ++ ++ pkt_stat->rate = le32_get_bits(rx_desc->w3, RTW_RX_DESC_W3_RX_RATE); ++ ++ pkt_stat->bw = le32_get_bits(rx_desc->w4, RTW_RX_DESC_W4_BW); ++ ++ pkt_stat->tsf_low = le32_get_bits(rx_desc->w5, RTW_RX_DESC_W5_TSFL); ++ ++ /* drv_info_sz is in unit of 8-bytes */ ++ pkt_stat->drv_info_sz *= 8; ++ ++ /* c2h cmd pkt's rx/phy status is not interested */ ++ if (pkt_stat->is_c2h) ++ return; ++ ++ phy_status = rx_desc8 + desc_sz + pkt_stat->shift; ++ hdr = phy_status + pkt_stat->drv_info_sz; ++ pkt_stat->hdr = hdr; ++ ++ if (pkt_stat->phy_status) ++ rtwdev->chip->ops->query_phy_status(rtwdev, phy_status, pkt_stat); ++ ++ rtw_rx_fill_rx_status(rtwdev, pkt_stat, hdr, rx_status); + } +-EXPORT_SYMBOL(rtw_rx_fill_rx_status); ++EXPORT_SYMBOL(rtw_rx_query_rx_desc); +--- a/drivers/net/wireless/realtek/rtw88/rx.h ++++ b/drivers/net/wireless/realtek/rtw88/rx.h +@@ -14,42 +14,40 @@ enum rtw_rx_desc_enc { + RX_DESC_ENC_WEP104 = 5, + }; + +-#define GET_RX_DESC_PHYST(rxdesc) \ +- le32_get_bits(*((__le32 *)(rxdesc) + 0x00), BIT(26)) +-#define GET_RX_DESC_ICV_ERR(rxdesc) \ +- le32_get_bits(*((__le32 *)(rxdesc) + 0x00), BIT(15)) +-#define GET_RX_DESC_CRC32(rxdesc) \ +- le32_get_bits(*((__le32 *)(rxdesc) + 0x00), BIT(14)) +-#define GET_RX_DESC_SWDEC(rxdesc) \ +- le32_get_bits(*((__le32 *)(rxdesc) + 0x00), BIT(27)) +-#define GET_RX_DESC_C2H(rxdesc) \ +- le32_get_bits(*((__le32 *)(rxdesc) + 0x02), BIT(28)) +-#define GET_RX_DESC_PKT_LEN(rxdesc) \ +- le32_get_bits(*((__le32 *)(rxdesc) + 0x00), GENMASK(13, 0)) +-#define GET_RX_DESC_DRV_INFO_SIZE(rxdesc) \ +- le32_get_bits(*((__le32 *)(rxdesc) + 0x00), GENMASK(19, 16)) +-#define GET_RX_DESC_SHIFT(rxdesc) \ +- le32_get_bits(*((__le32 *)(rxdesc) + 0x00), GENMASK(25, 24)) +-#define GET_RX_DESC_ENC_TYPE(rxdesc) \ +- le32_get_bits(*((__le32 *)(rxdesc) + 0x00), GENMASK(22, 20)) +-#define GET_RX_DESC_RX_RATE(rxdesc) \ +- le32_get_bits(*((__le32 *)(rxdesc) + 0x03), GENMASK(6, 0)) +-#define GET_RX_DESC_MACID(rxdesc) \ +- le32_get_bits(*((__le32 *)(rxdesc) + 0x01), GENMASK(6, 0)) +-#define GET_RX_DESC_PPDU_CNT(rxdesc) \ +- le32_get_bits(*((__le32 *)(rxdesc) + 0x02), GENMASK(30, 29)) +-#define GET_RX_DESC_TSFL(rxdesc) \ +- le32_get_bits(*((__le32 *)(rxdesc) + 0x05), GENMASK(31, 0)) +-#define GET_RX_DESC_BW(rxdesc) \ +- (le32_get_bits(*((__le32 *)(rxdesc) + 0x04), GENMASK(5, 4))) ++struct rtw_rx_desc { ++ __le32 w0; ++ __le32 w1; ++ __le32 w2; ++ __le32 w3; ++ __le32 w4; ++ __le32 w5; ++} __packed; ++ ++#define RTW_RX_DESC_W0_PKT_LEN GENMASK(13, 0) ++#define RTW_RX_DESC_W0_CRC32 BIT(14) ++#define RTW_RX_DESC_W0_ICV_ERR BIT(15) ++#define RTW_RX_DESC_W0_DRV_INFO_SIZE GENMASK(19, 16) ++#define RTW_RX_DESC_W0_ENC_TYPE GENMASK(22, 20) ++#define RTW_RX_DESC_W0_SHIFT GENMASK(25, 24) ++#define RTW_RX_DESC_W0_PHYST BIT(26) ++#define RTW_RX_DESC_W0_SWDEC BIT(27) ++ ++#define RTW_RX_DESC_W1_MACID GENMASK(6, 0) ++ ++#define RTW_RX_DESC_W2_C2H BIT(28) ++#define RTW_RX_DESC_W2_PPDU_CNT GENMASK(30, 29) ++ ++#define RTW_RX_DESC_W3_RX_RATE GENMASK(6, 0) ++ ++#define RTW_RX_DESC_W4_BW GENMASK(5, 4) ++ ++#define RTW_RX_DESC_W5_TSFL GENMASK(31, 0) + + void rtw_rx_stats(struct rtw_dev *rtwdev, struct ieee80211_vif *vif, + struct sk_buff *skb); +-void rtw_rx_fill_rx_status(struct rtw_dev *rtwdev, +- struct rtw_rx_pkt_stat *pkt_stat, +- struct ieee80211_hdr *hdr, +- struct ieee80211_rx_status *rx_status, +- u8 *phy_status); ++void rtw_rx_query_rx_desc(struct rtw_dev *rtwdev, void *rx_desc8, ++ struct rtw_rx_pkt_stat *pkt_stat, ++ struct ieee80211_rx_status *rx_status); + void rtw_update_rx_freq_from_ie(struct rtw_dev *rtwdev, struct sk_buff *skb, + struct ieee80211_rx_status *rx_status, + struct rtw_rx_pkt_stat *pkt_stat); +--- a/drivers/net/wireless/realtek/rtw88/sdio.c ++++ b/drivers/net/wireless/realtek/rtw88/sdio.c +@@ -979,8 +979,7 @@ static void rtw_sdio_rxfifo_recv(struct + + while (true) { + rx_desc = skb->data; +- chip->ops->query_rx_desc(rtwdev, rx_desc, &pkt_stat, +- &rx_status); ++ rtw_rx_query_rx_desc(rtwdev, rx_desc, &pkt_stat, &rx_status); + pkt_offset = pkt_desc_sz + pkt_stat.drv_info_sz + + pkt_stat.shift; + +--- a/drivers/net/wireless/realtek/rtw88/usb.c ++++ b/drivers/net/wireless/realtek/rtw88/usb.c +@@ -625,8 +625,8 @@ static void rtw_usb_rx_handler(struct wo + + do { + rx_desc = skb->data; +- chip->ops->query_rx_desc(rtwdev, rx_desc, &pkt_stat, +- &rx_status); ++ rtw_rx_query_rx_desc(rtwdev, rx_desc, &pkt_stat, ++ &rx_status); + pkt_offset = pkt_desc_sz + pkt_stat.drv_info_sz + + pkt_stat.shift; + diff --git a/package/kernel/mac80211/patches/rtl/022-v6.13-wifi-rtw88-Refactor-looping-in-rtw_phy_store_tx_powe.patch b/package/kernel/mac80211/patches/rtl/022-v6.13-wifi-rtw88-Refactor-looping-in-rtw_phy_store_tx_powe.patch new file mode 100644 index 00000000000000..4f019617d4799f --- /dev/null +++ b/package/kernel/mac80211/patches/rtl/022-v6.13-wifi-rtw88-Refactor-looping-in-rtw_phy_store_tx_powe.patch @@ -0,0 +1,34 @@ +From 7846f0b63562f4db45f712cc7dab091985baf07b Mon Sep 17 00:00:00 2001 +From: Mohammed Anees +Date: Thu, 17 Oct 2024 13:36:38 +0530 +Subject: [PATCH] wifi: rtw88: Refactor looping in + rtw_phy_store_tx_power_by_rate + +The previous implementation included an unnecessary else +condition paired with a continue statement. Since a check +is already performed to determine if the band is either +2G or 5G, the else condition will never be triggered. +We can remove this check. + +Signed-off-by: Mohammed Anees +Acked-by: Ping-Ke Shih +Signed-off-by: Ping-Ke Shih +Link: https://patch.msgid.link/20241017080638.13074-1-pvmohammedanees2003@gmail.com +--- + drivers/net/wireless/realtek/rtw88/phy.c | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +--- a/drivers/net/wireless/realtek/rtw88/phy.c ++++ b/drivers/net/wireless/realtek/rtw88/phy.c +@@ -1470,10 +1470,8 @@ static void rtw_phy_store_tx_power_by_ra + rate = rates[i]; + if (band == PHY_BAND_2G) + hal->tx_pwr_by_rate_offset_2g[rfpath][rate] = offset; +- else if (band == PHY_BAND_5G) +- hal->tx_pwr_by_rate_offset_5g[rfpath][rate] = offset; + else +- continue; ++ hal->tx_pwr_by_rate_offset_5g[rfpath][rate] = offset; + } + } + diff --git a/package/kernel/mac80211/patches/rtl/023-v6.13-wifi-rtw88-Report-the-signal-strength-only-if-it-s-k.patch b/package/kernel/mac80211/patches/rtl/023-v6.13-wifi-rtw88-Report-the-signal-strength-only-if-it-s-k.patch new file mode 100644 index 00000000000000..accbf2b484f7f1 --- /dev/null +++ b/package/kernel/mac80211/patches/rtl/023-v6.13-wifi-rtw88-Report-the-signal-strength-only-if-it-s-k.patch @@ -0,0 +1,39 @@ +From 47f754b3f838205f3b25c4839f74801d180995bf Mon Sep 17 00:00:00 2001 +From: Bitterblue Smith +Date: Tue, 22 Oct 2024 20:20:26 +0300 +Subject: [PATCH] wifi: rtw88: Report the signal strength only if it's known + +RTL8811CU doesn't report the signal strength for many (any?) data +frames. When the signal strength is not known, set +RX_FLAG_NO_SIGNAL_VAL in order to avoid reporting a signal +strength of 0. + +Signed-off-by: Bitterblue Smith +Acked-by: Ping-Ke Shih +Signed-off-by: Ping-Ke Shih +Link: https://patch.msgid.link/f7e1e448-2c9b-498f-b8b1-a14dd967d7d3@gmail.com +--- + drivers/net/wireless/realtek/rtw88/rx.c | 12 ++++++++---- + 1 file changed, 8 insertions(+), 4 deletions(-) + +--- a/drivers/net/wireless/realtek/rtw88/rx.c ++++ b/drivers/net/wireless/realtek/rtw88/rx.c +@@ -234,10 +234,14 @@ static void rtw_rx_fill_rx_status(struct + else + rx_status->bw = RATE_INFO_BW_20; + +- rx_status->signal = pkt_stat->signal_power; +- for (path = 0; path < rtwdev->hal.rf_path_num; path++) { +- rx_status->chains |= BIT(path); +- rx_status->chain_signal[path] = pkt_stat->rx_power[path]; ++ if (pkt_stat->phy_status) { ++ rx_status->signal = pkt_stat->signal_power; ++ for (path = 0; path < rtwdev->hal.rf_path_num; path++) { ++ rx_status->chains |= BIT(path); ++ rx_status->chain_signal[path] = pkt_stat->rx_power[path]; ++ } ++ } else { ++ rx_status->flag |= RX_FLAG_NO_SIGNAL_VAL; + } + + rtw_rx_addr_match(rtwdev, pkt_stat, hdr); diff --git a/package/kernel/mac80211/patches/rtl/024-v6.13-wifi-rtw88-Add-some-definitions-for-RTL8821AU-RTL881.patch b/package/kernel/mac80211/patches/rtl/024-v6.13-wifi-rtw88-Add-some-definitions-for-RTL8821AU-RTL881.patch new file mode 100644 index 00000000000000..8d63717c59ff93 --- /dev/null +++ b/package/kernel/mac80211/patches/rtl/024-v6.13-wifi-rtw88-Add-some-definitions-for-RTL8821AU-RTL881.patch @@ -0,0 +1,490 @@ +From d12722830ea4f562e91586927ec21b64d0369544 Mon Sep 17 00:00:00 2001 +From: Bitterblue Smith +Date: Wed, 23 Oct 2024 17:00:59 +0300 +Subject: [PATCH] wifi: rtw88: Add some definitions for RTL8821AU/RTL8812AU + +Add 8821A and 8812A chip type enums. + +Add cck_high_power member to struct rtw_hal. This will be used to +calculate the RX signal strength of RTL8812AU. + +Add various register definitions which will be used by the new drivers. + +Move some existing register definitions from rtw8821c.h and rtw8822b.h. +They were duplicated in those headers and will also be used by the new +drivers. + +Signed-off-by: Bitterblue Smith +Signed-off-by: Ping-Ke Shih +Link: https://patch.msgid.link/9279a9cd-6f86-4dc3-a095-7c36cb9b9d06@gmail.com +--- + drivers/net/wireless/realtek/rtw88/main.h | 3 + + drivers/net/wireless/realtek/rtw88/reg.h | 174 ++++++++++++++++++ + drivers/net/wireless/realtek/rtw88/rtw8821c.h | 24 --- + drivers/net/wireless/realtek/rtw88/rtw8822b.h | 12 -- + 4 files changed, 177 insertions(+), 36 deletions(-) + +--- a/drivers/net/wireless/realtek/rtw88/main.h ++++ b/drivers/net/wireless/realtek/rtw88/main.h +@@ -189,6 +189,8 @@ enum rtw_chip_type { + RTW_CHIP_TYPE_8723D, + RTW_CHIP_TYPE_8821C, + RTW_CHIP_TYPE_8703B, ++ RTW_CHIP_TYPE_8821A, ++ RTW_CHIP_TYPE_8812A, + }; + + enum rtw_tx_queue_type { +@@ -1934,6 +1936,7 @@ struct rtw_hal { + u32 antenna_rx; + u8 bfee_sts_cap; + bool txrx_1ss; ++ bool cck_high_power; + + /* protect tx power section */ + struct mutex tx_power_mutex; +--- a/drivers/net/wireless/realtek/rtw88/reg.h ++++ b/drivers/net/wireless/realtek/rtw88/reg.h +@@ -9,6 +9,7 @@ + #define BIT_FEN_EN_25_1 BIT(13) + #define BIT_FEN_ELDR BIT(12) + #define BIT_FEN_CPUEN BIT(2) ++#define BIT_FEN_USBA BIT(2) + #define BIT_FEN_BB_GLB_RST BIT(1) + #define BIT_FEN_BB_RSTB BIT(0) + #define BIT_R_DIS_PRST BIT(6) +@@ -16,6 +17,10 @@ + #define REG_SYS_PW_CTRL 0x0004 + #define BIT_PFM_WOWL BIT(3) + #define BIT_APFM_OFFMAC BIT(9) ++#define REG_APS_FSMCO 0x0004 ++#define APS_FSMCO_MAC_ENABLE BIT(8) ++#define APS_FSMCO_MAC_OFF BIT(9) ++#define APS_FSMCO_HW_POWERDOWN BIT(15) + #define REG_SYS_CLK_CTRL 0x0008 + #define BIT_CPU_CLK_EN BIT(14) + +@@ -58,6 +63,8 @@ + #define BIT_SHIFT_LDO25_VOLTAGE 4 + #define BIT_LDO25_EN BIT(7) + ++#define REG_ACLK_MON 0x3e ++ + #define REG_GPIO_MUXCFG 0x0040 + #define BIT_FSPI_EN BIT(19) + #define BIT_EN_SIC BIT(12) +@@ -90,6 +97,8 @@ + #define BIT_USB_SUS_DIS BIT(8) + #define BIT_SDIO_PAD_E5 BIT(18) + ++#define REG_RF_B_CTRL 0x76 ++ + #define REG_AFE_CTRL_4 0x0078 + #define BIT_CK320M_AFE_EN BIT(4) + #define BIT_EN_SYN BIT(15) +@@ -135,6 +144,11 @@ + #define REG_PMC_DBG_CTRL1 0xa8 + #define BITS_PMC_BT_IQK_STS GENMASK(22, 21) + ++#define REG_HIMR0 0xb0 ++#define REG_HISR0 0xb4 ++#define REG_HIMR1 0xb8 ++#define REG_HISR1 0xbc ++ + #define REG_PAD_CTRL2 0x00C4 + #define BIT_RSM_EN_V1 BIT(16) + #define BIT_NO_PDN_CHIPOFF_V1 BIT(17) +@@ -186,6 +200,15 @@ + #define MAC_TRX_ENABLE (BIT_HCI_TXDMA_EN | BIT_HCI_RXDMA_EN | BIT_TXDMA_EN | \ + BIT_RXDMA_EN | BIT_PROTOCOL_EN | BIT_SCHEDULE_EN | \ + BIT_MACTXEN | BIT_MACRXEN) ++#define REG_PBP 0x104 ++#define PBP_RX_MASK 0x0f ++#define PBP_TX_MASK 0xf0 ++#define PBP_64 0x0 ++#define PBP_128 0x1 ++#define PBP_256 0x2 ++#define PBP_512 0x3 ++#define PBP_1024 0x4 ++ + #define BIT_SHIFT_TXDMA_VOQ_MAP 4 + #define BIT_MASK_TXDMA_VOQ_MAP 0x3 + #define BIT_TXDMA_VOQ_MAP(x) \ +@@ -257,6 +280,8 @@ + #define REG_HMEBOX1 0x01D4 + #define REG_HMEBOX2 0x01D8 + #define REG_HMEBOX3 0x01DC ++#define REG_LLT_INIT 0x01E0 ++#define BIT_LLT_WRITE_ACCESS BIT(30) + #define REG_HMEBOX0_EX 0x01F0 + #define REG_HMEBOX1_EX 0x01F4 + #define REG_HMEBOX2_EX 0x01F8 +@@ -299,6 +324,7 @@ + + #define REG_AUTO_LLT 0x0224 + #define BIT_AUTO_INIT_LLT BIT(16) ++#define REG_DWBCN1_CTRL 0x0228 + #define REG_RQPN_CTRL_1 0x0228 + #define REG_RQPN_CTRL_2 0x022C + #define BIT_LD_RQPN BIT(31) +@@ -330,6 +356,7 @@ + #define BIT_DMA_BURST_SIZE_1024 0 + + #define REG_RXPKTNUM 0x02B0 ++#define REG_EARLY_MODE_CONTROL 0x02BC + + #define REG_INT_MIG 0x0304 + #define REG_HCI_MIX_CFG 0x03FC +@@ -337,6 +364,7 @@ + + #define REG_BCNQ_INFO 0x0418 + #define BIT_MGQ_CPU_EMPTY BIT(24) ++#define REG_TXPKT_EMPTY 0x041A + #define REG_FWHW_TXQ_CTRL 0x0420 + #define BIT_EN_BCNQ_DL BIT(22) + #define BIT_EN_WR_FREE_TAIL BIT(20) +@@ -363,10 +391,12 @@ + #define REG_AMPDU_MAX_TIME_V1 0x0455 + #define REG_BCNQ1_BDNY_V1 0x0456 + #define REG_AMPDU_MAX_TIME 0x0456 ++#define REG_AMPDU_MAX_LENGTH 0x0458 + #define REG_WMAC_LBK_BF_HD 0x045D + #define REG_TX_HANG_CTRL 0x045E + #define BIT_EN_GNT_BT_AWAKE BIT(3) + #define BIT_EN_EOF_V1 BIT(2) ++#define REG_FAST_EDCA_CTRL 0x0460 + #define REG_DATA_SC 0x0483 + #define REG_ARFR2_V1 0x048C + #define REG_ARFRH2_V1 0x0490 +@@ -391,6 +421,8 @@ + #define REG_PRECNT_CTRL 0x04E5 + #define BIT_BTCCA_CTRL (BIT(0) | BIT(1)) + #define BIT_EN_PRECNT BIT(11) ++#define REG_TX_RPT_CTRL 0x04EC ++#define REG_TX_RPT_TIME 0x04F0 + #define REG_DUMMY_PAGE4_V1 0x04FC + + #define REG_EDCA_VO_PARAM 0x0500 +@@ -401,6 +433,7 @@ + #define BIT_MASK_CWMAX GENMASK(15, 12) + #define BIT_MASK_CWMIN GENMASK(11, 8) + #define BIT_MASK_AIFS GENMASK(7, 0) ++#define REG_BCNTCFG 0x0510 + #define REG_PIFS 0x0512 + #define REG_SIFS 0x0514 + #define BIT_SHIFT_SIFS_OFDM_CTX 8 +@@ -527,6 +560,8 @@ + #define REG_BT_COEX_V2 0x0762 + #define BIT_GNT_BT_POLARITY BIT(12) + #define BIT_LTE_COEX_EN BIT(7) ++#define REG_GNT_BT 0x0765 ++#define BIT_PTA_SW_CTL GENMASK(4, 3) + #define REG_BT_COEX_ENH_INTR_CTRL 0x76E + #define BIT_R_GRANTALL_WLMASK BIT(3) + #define BIT_STATIS_BT_EN BIT(2) +@@ -544,14 +579,43 @@ + #define REG_FPGA0_RFMOD 0x0800 + #define BIT_CCKEN BIT(24) + #define BIT_OFDMEN BIT(25) ++#define REG_CCK_RPT_FORMAT 0x0804 ++#define BIT_CCK_RPT_FORMAT BIT(16) ++#define REG_RXPSEL 0x0808 ++#define BIT_RX_PSEL_RST (BIT(28) | BIT(29)) ++#define REG_TXPSEL 0x080C + #define REG_RX_GAIN_EN 0x081c ++#define REG_CCASEL 0x082C ++#define REG_PDMFTH 0x0830 ++#define REG_BWINDICATION 0x0834 ++#define REG_CCA2ND 0x0838 ++#define REG_L1PKTH 0x0848 ++#define REG_CLKTRK 0x0860 ++#define REG_ADCCLK 0x08AC ++#define REG_HSSI_READ 0x08B0 ++#define REG_FPGA0_XCD_RF_PARA 0x08B4 ++#define REG_RX_MCS_LIMIT 0x08BC ++#define REG_ADC160 0x08C4 ++#define REG_ANTSEL_SW 0x0900 ++#define REG_DAC_RSTB 0x090c ++#define REG_SINGLE_TONE_CONT_TX 0x0914 + + #define REG_RFE_CTRL_E 0x0974 + #define REG_2ND_CCA_CTRL 0x0976 ++#define REG_IQK_COM00 0x0978 ++#define REG_IQK_COM32 0x097c ++#define REG_IQK_COM64 0x0980 ++#define REG_IQK_COM96 0x0984 ++ ++#define REG_FAS 0x09a4 ++#define REG_RXSB 0x0a00 ++#define REG_CCK_RX 0x0a04 ++#define REG_CCK_PD_TH 0x0a0a + + #define REG_CCK0_FAREPORT 0xa2c + #define BIT_CCK0_2RX BIT(18) + #define BIT_CCK0_MRC BIT(22) ++#define REG_FA_CCK 0x0a5c + + #define REG_DIS_DPD 0x0a70 + #define DIS_DPD_MASK GENMASK(9, 0) +@@ -567,13 +631,109 @@ + #define DIS_DPD_RATEVHT2SS_MCS1 BIT(9) + #define DIS_DPD_RATEALL GENMASK(9, 0) + ++#define REG_CNTRST 0x0b58 ++ ++#define REG_3WIRE_SWA 0x0c00 ++#define REG_RX_IQC_AB_A 0x0c10 ++#define REG_TXSCALE_A 0x0c1c ++#define BB_SWING_MASK GENMASK(31, 21) ++#define REG_TX_AGC_A_CCK_11_CCK_1 0xc20 ++#define REG_TX_AGC_A_OFDM18_OFDM6 0xc24 ++#define REG_TX_AGC_A_OFDM54_OFDM24 0xc28 ++#define REG_TX_AGC_A_MCS3_MCS0 0xc2c ++#define REG_TX_AGC_A_MCS7_MCS4 0xc30 ++#define REG_TX_AGC_A_MCS11_MCS8 0xc34 ++#define REG_TX_AGC_A_MCS15_MCS12 0xc38 ++#define REG_TX_AGC_A_NSS1_INDEX3_NSS1_INDEX0 0xc3c ++#define REG_TX_AGC_A_NSS1_INDEX7_NSS1_INDEX4 0xc40 ++#define REG_TX_AGC_A_NSS2_INDEX1_NSS1_INDEX8 0xc44 ++#define REG_TX_AGC_A_NSS2_INDEX5_NSS2_INDEX2 0xc48 ++#define REG_TX_AGC_A_NSS2_INDEX9_NSS2_INDEX6 0xc4c ++#define REG_RXIGI_A 0x0c50 ++#define REG_TX_PWR_TRAINING_A 0x0c54 ++#define REG_CK_MONHA 0x0c5c ++#define REG_AFE_PWR1_A 0x0c60 ++#define REG_AFE_PWR2_A 0x0c64 ++#define REG_RX_WAIT_CCA_TX_CCK_RFON_A 0x0c68 ++#define REG_OFDM0_XA_TX_IQ_IMBALANCE 0x0c80 ++#define REG_OFDM0_A_TX_AFE 0x0c84 ++#define REG_OFDM0_XB_TX_IQ_IMBALANCE 0x0c88 ++#define REG_TSSI_TRK_SW 0x0c8c ++#define REG_LSSI_WRITE_A 0x0c90 ++#define REG_PREDISTA 0x0c90 ++#define REG_TXAGCIDX 0x0c94 ++ ++#define REG_RFE_PINMUX_A 0x0cb0 ++#define REG_RFE_INV_A 0x0cb4 + #define REG_RFE_CTRL8 0x0cb4 + #define BIT_MASK_RFE_SEL89 GENMASK(7, 0) ++#define PTA_CTRL_PIN 0x66 ++#define DPDT_CTRL_PIN 0x77 ++#define RFE_INV_MASK 0x3ff00000 ++#define REG_RFECTL_A 0x0cb8 + #define REG_RFE_INV8 0x0cbd + #define BIT_MASK_RFE_INV89 GENMASK(1, 0) + #define REG_RFE_INV16 0x0cbe + #define BIT_RFE_BUF_EN BIT(3) + ++#define REG_IQK_DPD_CFG 0x0cc4 ++#define REG_CFG_PMPD 0x0cc8 ++#define REG_IQC_Y 0x0ccc ++#define REG_IQC_X 0x0cd4 ++#define REG_INTPO_SETA 0x0ce8 ++ ++#define REG_IQKA_END 0x0d00 ++#define REG_PI_READ_A 0x0d04 ++#define REG_SI_READ_A 0x0d08 ++#define REG_IQKB_END 0x0d40 ++#define REG_PI_READ_B 0x0d44 ++#define REG_SI_READ_B 0x0d48 ++ ++#define REG_3WIRE_SWB 0x0e00 ++#define REG_RX_IQC_AB_B 0x0e10 ++#define REG_TXSCALE_B 0x0e1c ++#define REG_TX_AGC_B_CCK_11_CCK_1 0xe20 ++#define REG_TX_AGC_B_OFDM18_OFDM6 0xe24 ++#define REG_TX_AGC_B_OFDM54_OFDM24 0xe28 ++#define REG_TX_AGC_B_MCS3_MCS0 0xe2c ++#define REG_TX_AGC_B_MCS7_MCS4 0xe30 ++#define REG_TX_AGC_B_MCS11_MCS8 0xe34 ++#define REG_TX_AGC_B_MCS15_MCS12 0xe38 ++#define REG_TX_AGC_B_NSS1_INDEX3_NSS1_INDEX0 0xe3c ++#define REG_TX_AGC_B_NSS1_INDEX7_NSS1_INDEX4 0xe40 ++#define REG_TX_AGC_B_NSS2_INDEX1_NSS1_INDEX8 0xe44 ++#define REG_TX_AGC_B_NSS2_INDEX5_NSS2_INDEX2 0xe48 ++#define REG_TX_AGC_B_NSS2_INDEX9_NSS2_INDEX6 0xe4c ++#define REG_RXIGI_B 0x0e50 ++#define REG_TX_PWR_TRAINING_B 0x0e54 ++#define REG_CK_MONHB 0x0e5c ++#define REG_AFE_PWR1_B 0x0e60 ++#define REG_AFE_PWR2_B 0x0e64 ++#define REG_RX_WAIT_CCA_TX_CCK_RFON_B 0x0e68 ++#define REG_TXTONEB 0x0e80 ++#define REG_RXTONEB 0x0e84 ++#define REG_TXPITMB 0x0e88 ++#define REG_RXPITMB 0x0e8c ++#define REG_LSSI_WRITE_B 0x0e90 ++#define REG_PREDISTB 0x0e90 ++#define REG_INIDLYB 0x0e94 ++#define REG_RFE_PINMUX_B 0x0eb0 ++#define REG_RFE_INV_B 0x0eb4 ++#define REG_RFECTL_B 0x0eb8 ++#define REG_BPBDB 0x0ec4 ++#define REG_PHYTXONB 0x0ec8 ++#define REG_IQKYB 0x0ecc ++#define REG_IQKXB 0x0ed4 ++#define REG_INTPO_SETB 0x0ee8 ++ ++#define REG_CRC_CCK 0x0f04 ++#define REG_CCA_OFDM 0x0f08 ++#define REG_CRC_VHT 0x0f0c ++#define REG_CRC_HT 0x0f10 ++#define REG_CRC_OFDM 0x0f14 ++#define REG_FA_OFDM 0x0f48 ++#define REG_CCA_CCK 0x0fcc ++ + #define REG_ANAPARSW_MAC_0 0x1010 + #define BIT_CF_L_V2 GENMASK(29, 28) + +@@ -710,6 +870,10 @@ + + #define REG_IGN_GNTBT4 0x4160 + ++#define REG_USB_MOD 0xf008 ++#define REG_USB3_RXITV 0xf050 ++#define REG_USB_HRPWM 0xfe58 ++ + #define RF_MODE 0x00 + #define RF_MODOPT 0x01 + #define RF_WLINT 0x01 +@@ -717,7 +881,13 @@ + #define RF_DTXLOK 0x08 + #define RF_CFGCH 0x18 + #define BIT_BAND GENMASK(18, 16) ++#define RF18_BAND_MASK (BIT(16) | BIT(9) | BIT(8)) ++#define RF18_CHANNEL_MASK (MASKBYTE0) ++#define RF18_RFSI_MASK (BIT(18) | BIT(17)) + #define RF_RCK 0x1d ++#define RF_MODE_TABLE_ADDR 0x30 ++#define RF_MODE_TABLE_DATA0 0x31 ++#define RF_MODE_TABLE_DATA1 0x32 + #define RF_LUTWA 0x33 + #define RF_LUTWD1 0x3e + #define RF_LUTWD0 0x3f +@@ -726,10 +896,14 @@ + #define RF_T_METER 0x42 + #define RF_BSPAD 0x54 + #define RF_GAINTX 0x56 ++#define RF_TXMOD 0x58 + #define RF_TXATANK 0x64 ++#define RF_TXA_PREPAD 0x65 + #define RF_TRXIQ 0x66 + #define RF_RXIQGEN 0x8d ++#define RF_RXBB2 0x8f + #define RF_SYN_PFD 0xb0 ++#define RF_LCK 0xb4 + #define RF_XTALX2 0xb8 + #define RF_SYN_CTRL 0xbb + #define RF_MALSEL 0xbe +--- a/drivers/net/wireless/realtek/rtw88/rtw8821c.h ++++ b/drivers/net/wireless/realtek/rtw88/rtw8821c.h +@@ -215,19 +215,10 @@ extern const struct rtw_chip_info rtw882 + #define BIT_FEN_EN BIT(26) + #define REG_INIRTS_RATE_SEL 0x0480 + #define REG_HTSTFWT 0x800 +-#define REG_RXPSEL 0x808 +-#define BIT_RX_PSEL_RST (BIT(28) | BIT(29)) +-#define REG_TXPSEL 0x80c + #define REG_RXCCAMSK 0x814 +-#define REG_CCASEL 0x82c +-#define REG_PDMFTH 0x830 +-#define REG_CCA2ND 0x838 + #define REG_L1WT 0x83c + #define REG_L1PKWT 0x840 + #define REG_MRC 0x850 +-#define REG_CLKTRK 0x860 +-#define REG_ADCCLK 0x8ac +-#define REG_ADC160 0x8c4 + #define REG_ADC40 0x8c8 + #define REG_CHFIR 0x8f0 + #define REG_CDDTXP 0x93c +@@ -235,14 +226,11 @@ extern const struct rtw_chip_info rtw882 + #define REG_ACBB0 0x948 + #define REG_ACBBRXFIR 0x94c + #define REG_ACGG2TBL 0x958 +-#define REG_FAS 0x9a4 +-#define REG_RXSB 0xa00 + #define REG_ADCINI 0xa04 + #define REG_PWRTH 0xa08 + #define REG_CCA_FLTR 0xa20 + #define REG_TXSF2 0xa24 + #define REG_TXSF6 0xa28 +-#define REG_FA_CCK 0xa5c + #define REG_RXDESC 0xa2c + #define REG_ENTXCCK 0xa80 + #define BTG_LNA 0xfc84 +@@ -253,12 +241,8 @@ extern const struct rtw_chip_info rtw882 + #define REG_PWRTH2 0xaa8 + #define REG_CSRATIO 0xaaa + #define REG_TXFILTER 0xaac +-#define REG_CNTRST 0xb58 + #define REG_AGCTR_A 0xc08 +-#define REG_TXSCALE_A 0xc1c + #define REG_TXDFIR 0xc20 +-#define REG_RXIGI_A 0xc50 +-#define REG_TXAGCIDX 0xc94 + #define REG_TRSW 0xca0 + #define REG_RFESEL0 0xcb0 + #define REG_RFESEL8 0xcb4 +@@ -270,14 +254,6 @@ extern const struct rtw_chip_info rtw882 + #define B_WLA_SWITCH BIT(23) + #define REG_RFEINV 0xcbc + #define REG_AGCTR_B 0xe08 +-#define REG_RXIGI_B 0xe50 +-#define REG_CRC_CCK 0xf04 +-#define REG_CRC_OFDM 0xf14 +-#define REG_CRC_HT 0xf10 +-#define REG_CRC_VHT 0xf0c +-#define REG_CCA_OFDM 0xf08 +-#define REG_FA_OFDM 0xf48 +-#define REG_CCA_CCK 0xfcc + #define REG_DMEM_CTRL 0x1080 + #define BIT_WL_RST BIT(16) + #define REG_ANTWT 0x1904 +--- a/drivers/net/wireless/realtek/rtw88/rtw8822b.h ++++ b/drivers/net/wireless/realtek/rtw88/rtw8822b.h +@@ -152,21 +152,12 @@ _rtw_write32s_mask(struct rtw_dev *rtwde + #define RTW8822B_EDCCA_MAX 0x7f + #define RTW8822B_EDCCA_SRC_DEF 1 + #define REG_HTSTFWT 0x800 +-#define REG_RXPSEL 0x808 +-#define BIT_RX_PSEL_RST (BIT(28) | BIT(29)) +-#define REG_TXPSEL 0x80c + #define REG_RXCCAMSK 0x814 +-#define REG_CCASEL 0x82c +-#define REG_PDMFTH 0x830 +-#define REG_CCA2ND 0x838 + #define REG_L1WT 0x83c + #define REG_L1PKWT 0x840 + #define REG_MRC 0x850 +-#define REG_CLKTRK 0x860 + #define REG_EDCCA_POW_MA 0x8a0 + #define BIT_MA_LEVEL GENMASK(1, 0) +-#define REG_ADCCLK 0x8ac +-#define REG_ADC160 0x8c4 + #define REG_ADC40 0x8c8 + #define REG_EDCCA_DECISION 0x8dc + #define BIT_EDCCA_OPTION BIT(5) +@@ -177,7 +168,6 @@ _rtw_write32s_mask(struct rtw_dev *rtwde + #define REG_ACBB0 0x948 + #define REG_ACBBRXFIR 0x94c + #define REG_ACGG2TBL 0x958 +-#define REG_RXSB 0xa00 + #define REG_ADCINI 0xa04 + #define REG_TXSF2 0xa24 + #define REG_TXSF6 0xa28 +@@ -185,14 +175,12 @@ _rtw_write32s_mask(struct rtw_dev *rtwde + #define REG_ENTXCCK 0xa80 + #define REG_AGCTR_A 0xc08 + #define REG_TXDFIR 0xc20 +-#define REG_RXIGI_A 0xc50 + #define REG_TRSW 0xca0 + #define REG_RFESEL0 0xcb0 + #define REG_RFESEL8 0xcb4 + #define REG_RFECTL 0xcb8 + #define REG_RFEINV 0xcbc + #define REG_AGCTR_B 0xe08 +-#define REG_RXIGI_B 0xe50 + #define REG_ANTWT 0x1904 + #define REG_IQKFAILMSK 0x1bf0 + diff --git a/package/kernel/mac80211/patches/rtl/025-v6.13-wifi-rtw88-Dump-the-HW-features-only-for-some-chips.patch b/package/kernel/mac80211/patches/rtl/025-v6.13-wifi-rtw88-Dump-the-HW-features-only-for-some-chips.patch new file mode 100644 index 00000000000000..7c949ef79caa79 --- /dev/null +++ b/package/kernel/mac80211/patches/rtl/025-v6.13-wifi-rtw88-Dump-the-HW-features-only-for-some-chips.patch @@ -0,0 +1,93 @@ +From 87341ca1eac9a3bac23bd41f6e24f3c93b77452f Mon Sep 17 00:00:00 2001 +From: Bitterblue Smith +Date: Wed, 23 Oct 2024 17:02:05 +0300 +Subject: [PATCH] wifi: rtw88: Dump the HW features only for some chips + +RTL8821AU and RTL8812AU don't support this. They hit the "failed to read +hw feature report" error. + +Signed-off-by: Bitterblue Smith +Signed-off-by: Ping-Ke Shih +Link: https://patch.msgid.link/8becd851-8760-4480-8e8c-c4869ce72507@gmail.com +--- + drivers/net/wireless/realtek/rtw88/main.c | 3 +++ + drivers/net/wireless/realtek/rtw88/main.h | 1 + + drivers/net/wireless/realtek/rtw88/rtw8703b.c | 1 + + drivers/net/wireless/realtek/rtw88/rtw8723d.c | 1 + + drivers/net/wireless/realtek/rtw88/rtw8821c.c | 1 + + drivers/net/wireless/realtek/rtw88/rtw8822b.c | 1 + + drivers/net/wireless/realtek/rtw88/rtw8822c.c | 1 + + 7 files changed, 9 insertions(+) + +--- a/drivers/net/wireless/realtek/rtw88/main.c ++++ b/drivers/net/wireless/realtek/rtw88/main.c +@@ -1907,6 +1907,9 @@ static int rtw_dump_hw_feature(struct rt + u8 bw; + int i; + ++ if (!rtwdev->chip->hw_feature_report) ++ return 0; ++ + id = rtw_read8(rtwdev, REG_C2HEVT); + if (id != C2H_HW_FEATURE_REPORT) { + rtw_err(rtwdev, "failed to read hw feature report\n"); +--- a/drivers/net/wireless/realtek/rtw88/main.h ++++ b/drivers/net/wireless/realtek/rtw88/main.h +@@ -1200,6 +1200,7 @@ struct rtw_chip_info { + const struct rtw_fwcd_segs *fwcd_segs; + + u8 usb_tx_agg_desc_num; ++ bool hw_feature_report; + + u8 default_1ss_tx_path; + +--- a/drivers/net/wireless/realtek/rtw88/rtw8703b.c ++++ b/drivers/net/wireless/realtek/rtw88/rtw8703b.c +@@ -1960,6 +1960,7 @@ const struct rtw_chip_info rtw8703b_hw_s + .max_power_index = 0x3f, + .ampdu_density = IEEE80211_HT_MPDU_DENSITY_16, + .usb_tx_agg_desc_num = 1, /* Not sure if this chip has USB interface */ ++ .hw_feature_report = true, + + .path_div_supported = false, + .ht_supported = true, +--- a/drivers/net/wireless/realtek/rtw88/rtw8723d.c ++++ b/drivers/net/wireless/realtek/rtw88/rtw8723d.c +@@ -2131,6 +2131,7 @@ const struct rtw_chip_info rtw8723d_hw_s + .page_size = TX_PAGE_SIZE, + .dig_min = 0x20, + .usb_tx_agg_desc_num = 1, ++ .hw_feature_report = true, + .ht_supported = true, + .vht_supported = false, + .lps_deep_mode_supported = 0, +--- a/drivers/net/wireless/realtek/rtw88/rtw8821c.c ++++ b/drivers/net/wireless/realtek/rtw88/rtw8821c.c +@@ -1968,6 +1968,7 @@ const struct rtw_chip_info rtw8821c_hw_s + .page_size = TX_PAGE_SIZE, + .dig_min = 0x1c, + .usb_tx_agg_desc_num = 3, ++ .hw_feature_report = true, + .ht_supported = true, + .vht_supported = true, + .lps_deep_mode_supported = BIT(LPS_DEEP_MODE_LCLK), +--- a/drivers/net/wireless/realtek/rtw88/rtw8822b.c ++++ b/drivers/net/wireless/realtek/rtw88/rtw8822b.c +@@ -2511,6 +2511,7 @@ const struct rtw_chip_info rtw8822b_hw_s + .page_size = TX_PAGE_SIZE, + .dig_min = 0x1c, + .usb_tx_agg_desc_num = 3, ++ .hw_feature_report = true, + .ht_supported = true, + .vht_supported = true, + .lps_deep_mode_supported = BIT(LPS_DEEP_MODE_LCLK), +--- a/drivers/net/wireless/realtek/rtw88/rtw8822c.c ++++ b/drivers/net/wireless/realtek/rtw88/rtw8822c.c +@@ -5330,6 +5330,7 @@ const struct rtw_chip_info rtw8822c_hw_s + .page_size = TX_PAGE_SIZE, + .dig_min = 0x20, + .usb_tx_agg_desc_num = 3, ++ .hw_feature_report = true, + .default_1ss_tx_path = BB_PATH_A, + .path_div_supported = true, + .ht_supported = true, diff --git a/package/kernel/mac80211/patches/rtl/026-v6.13-wifi-rtw88-Allow-different-C2H-RA-report-sizes.patch b/package/kernel/mac80211/patches/rtl/026-v6.13-wifi-rtw88-Allow-different-C2H-RA-report-sizes.patch new file mode 100644 index 00000000000000..fb69a06d64e586 --- /dev/null +++ b/package/kernel/mac80211/patches/rtl/026-v6.13-wifi-rtw88-Allow-different-C2H-RA-report-sizes.patch @@ -0,0 +1,175 @@ +From d9018f4373517d4560ce2ebf12684f77f5fbdad6 Mon Sep 17 00:00:00 2001 +From: Bitterblue Smith +Date: Wed, 23 Oct 2024 17:06:14 +0300 +Subject: [PATCH] wifi: rtw88: Allow different C2H RA report sizes + +The RTL8821AU and RTL8812AU have smaller RA report size, only 4 bytes. +Avoid the "invalid ra report c2h length" error. + +Also, use a struct and u8_get_bits() to access the RA report C2H. + +Signed-off-by: Bitterblue Smith +Signed-off-by: Ping-Ke Shih +Link: https://patch.msgid.link/c3e73c3a-fb2f-4013-9f06-d5274211e282@gmail.com +--- + drivers/net/wireless/realtek/rtw88/fw.c | 21 +++++++++++++------ + drivers/net/wireless/realtek/rtw88/fw.h | 17 +++++++++++---- + drivers/net/wireless/realtek/rtw88/main.h | 1 + + drivers/net/wireless/realtek/rtw88/rtw8703b.c | 1 + + drivers/net/wireless/realtek/rtw88/rtw8723d.c | 1 + + drivers/net/wireless/realtek/rtw88/rtw8821c.c | 1 + + drivers/net/wireless/realtek/rtw88/rtw8822b.c | 1 + + drivers/net/wireless/realtek/rtw88/rtw8822c.c | 1 + + 8 files changed, 34 insertions(+), 10 deletions(-) + +--- a/drivers/net/wireless/realtek/rtw88/fw.c ++++ b/drivers/net/wireless/realtek/rtw88/fw.c +@@ -139,25 +139,30 @@ static u16 get_max_amsdu_len(u32 bit_rat + struct rtw_fw_iter_ra_data { + struct rtw_dev *rtwdev; + u8 *payload; ++ u8 length; + }; + + static void rtw_fw_ra_report_iter(void *data, struct ieee80211_sta *sta) + { + struct rtw_fw_iter_ra_data *ra_data = data; ++ struct rtw_c2h_ra_rpt *ra_rpt = (struct rtw_c2h_ra_rpt *)ra_data->payload; + struct rtw_sta_info *si = (struct rtw_sta_info *)sta->drv_priv; + u8 mac_id, rate, sgi, bw; + u8 mcs, nss; + u32 bit_rate; + +- mac_id = GET_RA_REPORT_MACID(ra_data->payload); ++ mac_id = ra_rpt->mac_id; + if (si->mac_id != mac_id) + return; + + si->ra_report.txrate.flags = 0; + +- rate = GET_RA_REPORT_RATE(ra_data->payload); +- sgi = GET_RA_REPORT_SGI(ra_data->payload); +- bw = GET_RA_REPORT_BW(ra_data->payload); ++ rate = u8_get_bits(ra_rpt->rate_sgi, RTW_C2H_RA_RPT_RATE); ++ sgi = u8_get_bits(ra_rpt->rate_sgi, RTW_C2H_RA_RPT_SGI); ++ if (ra_data->length >= offsetofend(typeof(*ra_rpt), bw)) ++ bw = ra_rpt->bw; ++ else ++ bw = si->bw_mode; + + if (rate < DESC_RATEMCS0) { + si->ra_report.txrate.legacy = rtw_desc_to_bitrate(rate); +@@ -197,14 +202,18 @@ legacy: + static void rtw_fw_ra_report_handle(struct rtw_dev *rtwdev, u8 *payload, + u8 length) + { ++ struct rtw_c2h_ra_rpt *ra_rpt = (struct rtw_c2h_ra_rpt *)payload; + struct rtw_fw_iter_ra_data ra_data; + +- if (WARN(length < 7, "invalid ra report c2h length\n")) ++ if (WARN(length < rtwdev->chip->c2h_ra_report_size, ++ "invalid ra report c2h length %d\n", length)) + return; + +- rtwdev->dm_info.tx_rate = GET_RA_REPORT_RATE(payload); ++ rtwdev->dm_info.tx_rate = u8_get_bits(ra_rpt->rate_sgi, ++ RTW_C2H_RA_RPT_RATE); + ra_data.rtwdev = rtwdev; + ra_data.payload = payload; ++ ra_data.length = length; + rtw_iterate_stas_atomic(rtwdev, rtw_fw_ra_report_iter, &ra_data); + } + +--- a/drivers/net/wireless/realtek/rtw88/fw.h ++++ b/drivers/net/wireless/realtek/rtw88/fw.h +@@ -85,6 +85,19 @@ struct rtw_c2h_adaptivity { + u8 option; + } __packed; + ++struct rtw_c2h_ra_rpt { ++ u8 rate_sgi; ++ u8 mac_id; ++ u8 byte2; ++ u8 status; ++ u8 byte4; ++ u8 ra_ratio; ++ u8 bw; ++} __packed; ++ ++#define RTW_C2H_RA_RPT_RATE GENMASK(6, 0) ++#define RTW_C2H_RA_RPT_SGI BIT(7) ++ + struct rtw_h2c_register { + u32 w0; + u32 w1; +@@ -364,10 +377,6 @@ struct rtw_fw_hdr_legacy { + #define GET_CHAN_SWITCH_CENTRAL_CH(c2h_payload) (c2h_payload[2]) + #define GET_CHAN_SWITCH_ID(c2h_payload) (c2h_payload[3]) + #define GET_CHAN_SWITCH_STATUS(c2h_payload) (c2h_payload[4]) +-#define GET_RA_REPORT_RATE(c2h_payload) (c2h_payload[0] & 0x7f) +-#define GET_RA_REPORT_SGI(c2h_payload) ((c2h_payload[0] & 0x80) >> 7) +-#define GET_RA_REPORT_BW(c2h_payload) (c2h_payload[6]) +-#define GET_RA_REPORT_MACID(c2h_payload) (c2h_payload[1]) + + #define GET_BCN_FILTER_NOTIFY_TYPE(c2h_payload) (c2h_payload[1] & 0xf) + #define GET_BCN_FILTER_NOTIFY_EVENT(c2h_payload) (c2h_payload[1] & 0x10) +--- a/drivers/net/wireless/realtek/rtw88/main.h ++++ b/drivers/net/wireless/realtek/rtw88/main.h +@@ -1201,6 +1201,7 @@ struct rtw_chip_info { + + u8 usb_tx_agg_desc_num; + bool hw_feature_report; ++ u8 c2h_ra_report_size; + + u8 default_1ss_tx_path; + +--- a/drivers/net/wireless/realtek/rtw88/rtw8703b.c ++++ b/drivers/net/wireless/realtek/rtw88/rtw8703b.c +@@ -1961,6 +1961,7 @@ const struct rtw_chip_info rtw8703b_hw_s + .ampdu_density = IEEE80211_HT_MPDU_DENSITY_16, + .usb_tx_agg_desc_num = 1, /* Not sure if this chip has USB interface */ + .hw_feature_report = true, ++ .c2h_ra_report_size = 7, + + .path_div_supported = false, + .ht_supported = true, +--- a/drivers/net/wireless/realtek/rtw88/rtw8723d.c ++++ b/drivers/net/wireless/realtek/rtw88/rtw8723d.c +@@ -2132,6 +2132,7 @@ const struct rtw_chip_info rtw8723d_hw_s + .dig_min = 0x20, + .usb_tx_agg_desc_num = 1, + .hw_feature_report = true, ++ .c2h_ra_report_size = 7, + .ht_supported = true, + .vht_supported = false, + .lps_deep_mode_supported = 0, +--- a/drivers/net/wireless/realtek/rtw88/rtw8821c.c ++++ b/drivers/net/wireless/realtek/rtw88/rtw8821c.c +@@ -1969,6 +1969,7 @@ const struct rtw_chip_info rtw8821c_hw_s + .dig_min = 0x1c, + .usb_tx_agg_desc_num = 3, + .hw_feature_report = true, ++ .c2h_ra_report_size = 7, + .ht_supported = true, + .vht_supported = true, + .lps_deep_mode_supported = BIT(LPS_DEEP_MODE_LCLK), +--- a/drivers/net/wireless/realtek/rtw88/rtw8822b.c ++++ b/drivers/net/wireless/realtek/rtw88/rtw8822b.c +@@ -2512,6 +2512,7 @@ const struct rtw_chip_info rtw8822b_hw_s + .dig_min = 0x1c, + .usb_tx_agg_desc_num = 3, + .hw_feature_report = true, ++ .c2h_ra_report_size = 7, + .ht_supported = true, + .vht_supported = true, + .lps_deep_mode_supported = BIT(LPS_DEEP_MODE_LCLK), +--- a/drivers/net/wireless/realtek/rtw88/rtw8822c.c ++++ b/drivers/net/wireless/realtek/rtw88/rtw8822c.c +@@ -5331,6 +5331,7 @@ const struct rtw_chip_info rtw8822c_hw_s + .dig_min = 0x20, + .usb_tx_agg_desc_num = 3, + .hw_feature_report = true, ++ .c2h_ra_report_size = 7, + .default_1ss_tx_path = BB_PATH_A, + .path_div_supported = true, + .ht_supported = true, diff --git a/package/kernel/mac80211/patches/rtl/027-v6.13-wifi-rtw88-Extend-the-init-table-parsing-for-RTL8812.patch b/package/kernel/mac80211/patches/rtl/027-v6.13-wifi-rtw88-Extend-the-init-table-parsing-for-RTL8812.patch new file mode 100644 index 00000000000000..aec2e6aaecf6a7 --- /dev/null +++ b/package/kernel/mac80211/patches/rtl/027-v6.13-wifi-rtw88-Extend-the-init-table-parsing-for-RTL8812.patch @@ -0,0 +1,165 @@ +From 95a772e30b60e7954d03f3372268722475aa303f Mon Sep 17 00:00:00 2001 +From: Bitterblue Smith +Date: Wed, 23 Oct 2024 17:08:24 +0300 +Subject: [PATCH] wifi: rtw88: Extend the init table parsing for RTL8812AU + +The chips supported so far only use the first condition, and so the +parsing code ignores the second condition. RTL8812AU's init tables use +the second condition also. Make the parsing code check it. + +Signed-off-by: Bitterblue Smith +Signed-off-by: Ping-Ke Shih +Link: https://patch.msgid.link/1bee6b74-6eab-44a3-9f40-794ca006c72d@gmail.com +--- + drivers/net/wireless/realtek/rtw88/main.h | 15 ++++++ + drivers/net/wireless/realtek/rtw88/phy.c | 62 ++++++++++++++++++++--- + 2 files changed, 69 insertions(+), 8 deletions(-) + +--- a/drivers/net/wireless/realtek/rtw88/main.h ++++ b/drivers/net/wireless/realtek/rtw88/main.h +@@ -1835,6 +1835,20 @@ struct rtw_phy_cond { + #define BRANCH_ENDIF 3 + }; + ++struct rtw_phy_cond2 { ++#ifdef __LITTLE_ENDIAN ++ u8 type_glna; ++ u8 type_gpa; ++ u8 type_alna; ++ u8 type_apa; ++#else ++ u8 type_apa; ++ u8 type_alna; ++ u8 type_gpa; ++ u8 type_glna; ++#endif ++}; ++ + struct rtw_fifo_conf { + /* tx fifo information */ + u16 rsvd_boundary; +@@ -1916,6 +1930,7 @@ struct rtw_hal { + u8 oem_id; + u8 pkg_type; + struct rtw_phy_cond phy_cond; ++ struct rtw_phy_cond2 phy_cond2; + bool rfe_btg; + + u8 ps_mode; +--- a/drivers/net/wireless/realtek/rtw88/phy.c ++++ b/drivers/net/wireless/realtek/rtw88/phy.c +@@ -18,7 +18,10 @@ struct phy_cfg_pair { + }; + + union phy_table_tile { +- struct rtw_phy_cond cond; ++ struct { ++ struct rtw_phy_cond cond; ++ struct rtw_phy_cond2 cond2; ++ } __packed; + struct phy_cfg_pair cfg; + }; + +@@ -1041,7 +1044,8 @@ void rtw_phy_setup_phy_cond(struct rtw_d + { + struct rtw_hal *hal = &rtwdev->hal; + struct rtw_efuse *efuse = &rtwdev->efuse; +- struct rtw_phy_cond cond = {0}; ++ struct rtw_phy_cond cond = {}; ++ struct rtw_phy_cond2 cond2 = {}; + + cond.cut = hal->cut_version ? hal->cut_version : 15; + cond.pkg = pkg ? pkg : 15; +@@ -1061,15 +1065,34 @@ void rtw_phy_setup_phy_cond(struct rtw_d + break; + } + ++ if (rtwdev->chip->id == RTW_CHIP_TYPE_8812A || ++ rtwdev->chip->id == RTW_CHIP_TYPE_8821A) { ++ cond.rfe = 0; ++ cond.rfe |= efuse->ext_lna_2g; ++ cond.rfe |= efuse->ext_pa_2g << 1; ++ cond.rfe |= efuse->ext_lna_5g << 2; ++ cond.rfe |= efuse->ext_pa_5g << 3; ++ cond.rfe |= efuse->btcoex << 4; ++ ++ cond2.type_alna = efuse->alna_type; ++ cond2.type_glna = efuse->glna_type; ++ cond2.type_apa = efuse->apa_type; ++ cond2.type_gpa = efuse->gpa_type; ++ } ++ + hal->phy_cond = cond; ++ hal->phy_cond2 = cond2; + +- rtw_dbg(rtwdev, RTW_DBG_PHY, "phy cond=0x%08x\n", *((u32 *)&hal->phy_cond)); ++ rtw_dbg(rtwdev, RTW_DBG_PHY, "phy cond=0x%08x cond2=0x%08x\n", ++ *((u32 *)&hal->phy_cond), *((u32 *)&hal->phy_cond2)); + } + +-static bool check_positive(struct rtw_dev *rtwdev, struct rtw_phy_cond cond) ++static bool check_positive(struct rtw_dev *rtwdev, struct rtw_phy_cond cond, ++ struct rtw_phy_cond2 cond2) + { + struct rtw_hal *hal = &rtwdev->hal; + struct rtw_phy_cond drv_cond = hal->phy_cond; ++ struct rtw_phy_cond2 drv_cond2 = hal->phy_cond2; + + if (cond.cut && cond.cut != drv_cond.cut) + return false; +@@ -1080,8 +1103,29 @@ static bool check_positive(struct rtw_de + if (cond.intf && cond.intf != drv_cond.intf) + return false; + +- if (cond.rfe != drv_cond.rfe) +- return false; ++ if (rtwdev->chip->id == RTW_CHIP_TYPE_8812A || ++ rtwdev->chip->id == RTW_CHIP_TYPE_8821A) { ++ if (!(cond.rfe & 0x0f)) ++ return true; ++ ++ if ((cond.rfe & drv_cond.rfe) != cond.rfe) ++ return false; ++ ++ if ((cond.rfe & BIT(0)) && cond2.type_glna != drv_cond2.type_glna) ++ return false; ++ ++ if ((cond.rfe & BIT(1)) && cond2.type_gpa != drv_cond2.type_gpa) ++ return false; ++ ++ if ((cond.rfe & BIT(2)) && cond2.type_alna != drv_cond2.type_alna) ++ return false; ++ ++ if ((cond.rfe & BIT(3)) && cond2.type_apa != drv_cond2.type_apa) ++ return false; ++ } else { ++ if (cond.rfe != drv_cond.rfe) ++ return false; ++ } + + return true; + } +@@ -1090,7 +1134,8 @@ void rtw_parse_tbl_phy_cond(struct rtw_d + { + const union phy_table_tile *p = tbl->data; + const union phy_table_tile *end = p + tbl->size / 2; +- struct rtw_phy_cond pos_cond = {0}; ++ struct rtw_phy_cond pos_cond = {}; ++ struct rtw_phy_cond2 pos_cond2 = {}; + bool is_matched = true, is_skipped = false; + + BUILD_BUG_ON(sizeof(union phy_table_tile) != sizeof(struct phy_cfg_pair)); +@@ -1109,11 +1154,12 @@ void rtw_parse_tbl_phy_cond(struct rtw_d + case BRANCH_ELIF: + default: + pos_cond = p->cond; ++ pos_cond2 = p->cond2; + break; + } + } else if (p->cond.neg) { + if (!is_skipped) { +- if (check_positive(rtwdev, pos_cond)) { ++ if (check_positive(rtwdev, pos_cond, pos_cond2)) { + is_matched = true; + is_skipped = true; + } else { diff --git a/package/kernel/mac80211/patches/rtl/028-v6.13-wifi-rtw88-Allow-rtw_chip_info.ltecoex_addr-to-be-NU.patch b/package/kernel/mac80211/patches/rtl/028-v6.13-wifi-rtw88-Allow-rtw_chip_info.ltecoex_addr-to-be-NU.patch new file mode 100644 index 00000000000000..5486fb2d25e099 --- /dev/null +++ b/package/kernel/mac80211/patches/rtl/028-v6.13-wifi-rtw88-Allow-rtw_chip_info.ltecoex_addr-to-be-NU.patch @@ -0,0 +1,58 @@ +From 7c5bbeba7c36575a3a57ef4be775b2f3fb68c3f9 Mon Sep 17 00:00:00 2001 +From: Bitterblue Smith +Date: Wed, 23 Oct 2024 17:09:04 +0300 +Subject: [PATCH] wifi: rtw88: Allow rtw_chip_info.ltecoex_addr to be NULL + +RTL8821A doesn't have this. Trying to use it results in error messages, +so don't try if ltecoex_addr is NULL. + +Signed-off-by: Bitterblue Smith +Signed-off-by: Ping-Ke Shih +Link: https://patch.msgid.link/d1004817-1760-41d1-9136-3d799757c444@gmail.com +--- + drivers/net/wireless/realtek/rtw88/coex.c | 14 +++++++++++--- + 1 file changed, 11 insertions(+), 3 deletions(-) + +--- a/drivers/net/wireless/realtek/rtw88/coex.c ++++ b/drivers/net/wireless/realtek/rtw88/coex.c +@@ -950,12 +950,18 @@ static void rtw_coex_coex_ctrl_owner(str + + static void rtw_coex_set_gnt_bt(struct rtw_dev *rtwdev, u8 state) + { ++ if (!rtwdev->chip->ltecoex_addr) ++ return; ++ + rtw_coex_write_indirect_reg(rtwdev, LTE_COEX_CTRL, 0xc000, state); + rtw_coex_write_indirect_reg(rtwdev, LTE_COEX_CTRL, 0x0c00, state); + } + + static void rtw_coex_set_gnt_wl(struct rtw_dev *rtwdev, u8 state) + { ++ if (!rtwdev->chip->ltecoex_addr) ++ return; ++ + rtw_coex_write_indirect_reg(rtwdev, LTE_COEX_CTRL, 0x3000, state); + rtw_coex_write_indirect_reg(rtwdev, LTE_COEX_CTRL, 0x0300, state); + } +@@ -3904,7 +3910,7 @@ void rtw_coex_display_coex_info(struct r + u8 sys_lte; + u16 score_board_WB, score_board_BW; + u32 wl_reg_6c0, wl_reg_6c4, wl_reg_6c8, wl_reg_778, wl_reg_6cc; +- u32 lte_coex, bt_coex; ++ u32 lte_coex = 0, bt_coex = 0; + int i; + + score_board_BW = rtw_coex_read_scbd(rtwdev); +@@ -3916,8 +3922,10 @@ void rtw_coex_display_coex_info(struct r + wl_reg_778 = rtw_read8(rtwdev, REG_BT_STAT_CTRL); + + sys_lte = rtw_read8(rtwdev, 0x73); +- lte_coex = rtw_coex_read_indirect_reg(rtwdev, 0x38); +- bt_coex = rtw_coex_read_indirect_reg(rtwdev, 0x54); ++ if (rtwdev->chip->ltecoex_addr) { ++ lte_coex = rtw_coex_read_indirect_reg(rtwdev, 0x38); ++ bt_coex = rtw_coex_read_indirect_reg(rtwdev, 0x54); ++ } + + if (!coex_stat->wl_under_ips && + (!coex_stat->wl_under_lps || coex_stat->wl_force_lps_ctrl) && diff --git a/package/kernel/mac80211/patches/rtl/029-v6.13-wifi-rtw88-Let-each-driver-control-the-power-on-off-.patch b/package/kernel/mac80211/patches/rtl/029-v6.13-wifi-rtw88-Let-each-driver-control-the-power-on-off-.patch new file mode 100644 index 00000000000000..5e9aee9bde400f --- /dev/null +++ b/package/kernel/mac80211/patches/rtl/029-v6.13-wifi-rtw88-Let-each-driver-control-the-power-on-off-.patch @@ -0,0 +1,274 @@ +From fbb5e1b3637a720c83c91a7b1476ab0429bfc747 Mon Sep 17 00:00:00 2001 +From: Bitterblue Smith +Date: Wed, 23 Oct 2024 17:09:47 +0300 +Subject: [PATCH] wifi: rtw88: Let each driver control the power on/off process + +RTL8821AU and RTL8812AU have to do some things differently, so let +them have full control. + +The other chips use the same functions as before. + +Signed-off-by: Bitterblue Smith +Signed-off-by: Ping-Ke Shih +Link: https://patch.msgid.link/98ab839f-9100-44ae-9551-9af743a4aa3a@gmail.com +--- + drivers/net/wireless/realtek/rtw88/coex.c | 3 +++ + drivers/net/wireless/realtek/rtw88/mac.c | 11 +++++++---- + drivers/net/wireless/realtek/rtw88/mac.h | 3 +++ + drivers/net/wireless/realtek/rtw88/main.c | 13 ++++++++----- + drivers/net/wireless/realtek/rtw88/main.h | 5 +++++ + drivers/net/wireless/realtek/rtw88/rtw8703b.c | 2 ++ + drivers/net/wireless/realtek/rtw88/rtw8723d.c | 2 ++ + drivers/net/wireless/realtek/rtw88/rtw8821c.c | 2 ++ + drivers/net/wireless/realtek/rtw88/rtw8822b.c | 2 ++ + drivers/net/wireless/realtek/rtw88/rtw8822c.c | 2 ++ + 10 files changed, 36 insertions(+), 9 deletions(-) + +--- a/drivers/net/wireless/realtek/rtw88/coex.c ++++ b/drivers/net/wireless/realtek/rtw88/coex.c +@@ -2753,16 +2753,19 @@ void rtw_coex_power_on_setting(struct rt + rtw_write8(rtwdev, 0xff1a, 0x0); + rtw_coex_set_gnt_debug(rtwdev); + } ++EXPORT_SYMBOL(rtw_coex_power_on_setting); + + void rtw_coex_power_off_setting(struct rtw_dev *rtwdev) + { + rtw_write16(rtwdev, REG_WIFI_BT_INFO, BIT_BT_INT_EN); + } ++EXPORT_SYMBOL(rtw_coex_power_off_setting); + + void rtw_coex_init_hw_config(struct rtw_dev *rtwdev, bool wifi_only) + { + __rtw_coex_init_hw_config(rtwdev, wifi_only); + } ++EXPORT_SYMBOL(rtw_coex_init_hw_config); + + void rtw_coex_ips_notify(struct rtw_dev *rtwdev, u8 type) + { +--- a/drivers/net/wireless/realtek/rtw88/mac.c ++++ b/drivers/net/wireless/realtek/rtw88/mac.c +@@ -227,8 +227,8 @@ static int rtw_sub_pwr_seq_parser(struct + return 0; + } + +-static int rtw_pwr_seq_parser(struct rtw_dev *rtwdev, +- const struct rtw_pwr_seq_cmd * const *cmd_seq) ++int rtw_pwr_seq_parser(struct rtw_dev *rtwdev, ++ const struct rtw_pwr_seq_cmd * const *cmd_seq) + { + u8 cut_mask; + u8 intf_mask; +@@ -267,6 +267,7 @@ static int rtw_pwr_seq_parser(struct rtw + + return 0; + } ++EXPORT_SYMBOL(rtw_pwr_seq_parser); + + static int rtw_mac_power_switch(struct rtw_dev *rtwdev, bool pwr_on) + { +@@ -999,6 +1000,7 @@ int rtw_download_firmware(struct rtw_dev + + return 0; + } ++EXPORT_SYMBOL(rtw_download_firmware); + + static u32 get_priority_queues(struct rtw_dev *rtwdev, u32 queues) + { +@@ -1132,7 +1134,7 @@ static int txdma_queue_mapping(struct rt + return 0; + } + +-static int set_trx_fifo_info(struct rtw_dev *rtwdev) ++int rtw_set_trx_fifo_info(struct rtw_dev *rtwdev) + { + const struct rtw_chip_info *chip = rtwdev->chip; + struct rtw_fifo_conf *fifo = &rtwdev->fifo; +@@ -1184,6 +1186,7 @@ static int set_trx_fifo_info(struct rtw_ + + return 0; + } ++EXPORT_SYMBOL(rtw_set_trx_fifo_info); + + static int __priority_queue_cfg(struct rtw_dev *rtwdev, + const struct rtw_page_table *pg_tbl, +@@ -1261,7 +1264,7 @@ static int priority_queue_cfg(struct rtw + u16 pubq_num; + int ret; + +- ret = set_trx_fifo_info(rtwdev); ++ ret = rtw_set_trx_fifo_info(rtwdev); + if (ret) + return ret; + +--- a/drivers/net/wireless/realtek/rtw88/mac.h ++++ b/drivers/net/wireless/realtek/rtw88/mac.h +@@ -30,6 +30,8 @@ + + void rtw_set_channel_mac(struct rtw_dev *rtwdev, u8 channel, u8 bw, + u8 primary_ch_idx); ++int rtw_pwr_seq_parser(struct rtw_dev *rtwdev, ++ const struct rtw_pwr_seq_cmd * const *cmd_seq); + int rtw_mac_power_on(struct rtw_dev *rtwdev); + void rtw_mac_power_off(struct rtw_dev *rtwdev); + void rtw_write_firmware_page(struct rtw_dev *rtwdev, u32 page, +@@ -37,6 +39,7 @@ void rtw_write_firmware_page(struct rtw_ + int rtw_download_firmware(struct rtw_dev *rtwdev, struct rtw_fw_state *fw); + int rtw_mac_init(struct rtw_dev *rtwdev); + void rtw_mac_flush_queues(struct rtw_dev *rtwdev, u32 queues, bool drop); ++int rtw_set_trx_fifo_info(struct rtw_dev *rtwdev); + int rtw_ddma_to_fw_fifo(struct rtw_dev *rtwdev, u32 ocp_src, u32 size); + + static inline void rtw_mac_flush_all_queues(struct rtw_dev *rtwdev, bool drop) +--- a/drivers/net/wireless/realtek/rtw88/main.c ++++ b/drivers/net/wireless/realtek/rtw88/main.c +@@ -1309,7 +1309,7 @@ void rtw_update_sta_info(struct rtw_dev + rtw_fw_send_ra_info(rtwdev, si, reset_ra_mask); + } + +-static int rtw_wait_firmware_completion(struct rtw_dev *rtwdev) ++int rtw_wait_firmware_completion(struct rtw_dev *rtwdev) + { + const struct rtw_chip_info *chip = rtwdev->chip; + struct rtw_fw_state *fw; +@@ -1329,6 +1329,7 @@ static int rtw_wait_firmware_completion( + + return ret; + } ++EXPORT_SYMBOL(rtw_wait_firmware_completion); + + static enum rtw_lps_deep_mode rtw_update_lps_deep_mode(struct rtw_dev *rtwdev, + struct rtw_fw_state *fw) +@@ -1350,7 +1351,7 @@ static enum rtw_lps_deep_mode rtw_update + return LPS_DEEP_MODE_NONE; + } + +-static int rtw_power_on(struct rtw_dev *rtwdev) ++int rtw_power_on(struct rtw_dev *rtwdev) + { + const struct rtw_chip_info *chip = rtwdev->chip; + struct rtw_fw_state *fw = &rtwdev->fw; +@@ -1413,6 +1414,7 @@ err_off: + err: + return ret; + } ++EXPORT_SYMBOL(rtw_power_on); + + void rtw_core_fw_scan_notify(struct rtw_dev *rtwdev, bool start) + { +@@ -1485,7 +1487,7 @@ int rtw_core_start(struct rtw_dev *rtwde + { + int ret; + +- ret = rtw_power_on(rtwdev); ++ ret = rtwdev->chip->ops->power_on(rtwdev); + if (ret) + return ret; + +@@ -1505,12 +1507,13 @@ int rtw_core_start(struct rtw_dev *rtwde + return 0; + } + +-static void rtw_power_off(struct rtw_dev *rtwdev) ++void rtw_power_off(struct rtw_dev *rtwdev) + { + rtw_hci_stop(rtwdev); + rtw_coex_power_off_setting(rtwdev); + rtw_mac_power_off(rtwdev); + } ++EXPORT_SYMBOL(rtw_power_off); + + void rtw_core_stop(struct rtw_dev *rtwdev) + { +@@ -1535,7 +1538,7 @@ void rtw_core_stop(struct rtw_dev *rtwde + + mutex_lock(&rtwdev->mutex); + +- rtw_power_off(rtwdev); ++ rtwdev->chip->ops->power_off(rtwdev); + } + + static void rtw_init_ht_cap(struct rtw_dev *rtwdev, +--- a/drivers/net/wireless/realtek/rtw88/main.h ++++ b/drivers/net/wireless/realtek/rtw88/main.h +@@ -843,6 +843,8 @@ struct rtw_regd { + }; + + struct rtw_chip_ops { ++ int (*power_on)(struct rtw_dev *rtwdev); ++ void (*power_off)(struct rtw_dev *rtwdev); + int (*mac_init)(struct rtw_dev *rtwdev); + int (*dump_fw_crash)(struct rtw_dev *rtwdev); + void (*shutdown)(struct rtw_dev *rtwdev); +@@ -2209,6 +2211,7 @@ void rtw_core_scan_start(struct rtw_dev + void rtw_core_scan_complete(struct rtw_dev *rtwdev, struct ieee80211_vif *vif, + bool hw_scan); + int rtw_core_start(struct rtw_dev *rtwdev); ++void rtw_power_off(struct rtw_dev *rtwdev); + void rtw_core_stop(struct rtw_dev *rtwdev); + int rtw_chip_info_setup(struct rtw_dev *rtwdev); + int rtw_core_init(struct rtw_dev *rtwdev); +@@ -2223,6 +2226,8 @@ int rtw_sta_add(struct rtw_dev *rtwdev, + void rtw_sta_remove(struct rtw_dev *rtwdev, struct ieee80211_sta *sta, + bool fw_exist); + void rtw_fw_recovery(struct rtw_dev *rtwdev); ++int rtw_wait_firmware_completion(struct rtw_dev *rtwdev); ++int rtw_power_on(struct rtw_dev *rtwdev); + void rtw_core_fw_scan_notify(struct rtw_dev *rtwdev, bool start); + int rtw_dump_fw(struct rtw_dev *rtwdev, const u32 ocp_src, u32 size, + u32 fwcd_item); +--- a/drivers/net/wireless/realtek/rtw88/rtw8703b.c ++++ b/drivers/net/wireless/realtek/rtw88/rtw8703b.c +@@ -1888,6 +1888,8 @@ static const struct coex_tdma_para tdma_ + }; + + static const struct rtw_chip_ops rtw8703b_ops = { ++ .power_on = rtw_power_on, ++ .power_off = rtw_power_off, + .mac_init = rtw8723x_mac_init, + .dump_fw_crash = NULL, + .shutdown = NULL, +--- a/drivers/net/wireless/realtek/rtw88/rtw8723d.c ++++ b/drivers/net/wireless/realtek/rtw88/rtw8723d.c +@@ -1390,6 +1390,8 @@ static void rtw8723d_pwr_track(struct rt + } + + static const struct rtw_chip_ops rtw8723d_ops = { ++ .power_on = rtw_power_on, ++ .power_off = rtw_power_off, + .phy_set_param = rtw8723d_phy_set_param, + .read_efuse = rtw8723x_read_efuse, + .query_phy_status = query_phy_status, +--- a/drivers/net/wireless/realtek/rtw88/rtw8821c.c ++++ b/drivers/net/wireless/realtek/rtw88/rtw8821c.c +@@ -1643,6 +1643,8 @@ static const struct rtw_prioq_addrs prio + }; + + static const struct rtw_chip_ops rtw8821c_ops = { ++ .power_on = rtw_power_on, ++ .power_off = rtw_power_off, + .phy_set_param = rtw8821c_phy_set_param, + .read_efuse = rtw8821c_read_efuse, + .query_phy_status = query_phy_status, +--- a/drivers/net/wireless/realtek/rtw88/rtw8822b.c ++++ b/drivers/net/wireless/realtek/rtw88/rtw8822b.c +@@ -2134,6 +2134,8 @@ static const struct rtw_prioq_addrs prio + }; + + static const struct rtw_chip_ops rtw8822b_ops = { ++ .power_on = rtw_power_on, ++ .power_off = rtw_power_off, + .phy_set_param = rtw8822b_phy_set_param, + .read_efuse = rtw8822b_read_efuse, + .query_phy_status = query_phy_status, +--- a/drivers/net/wireless/realtek/rtw88/rtw8822c.c ++++ b/drivers/net/wireless/realtek/rtw88/rtw8822c.c +@@ -4948,6 +4948,8 @@ static const struct rtw_prioq_addrs prio + }; + + static const struct rtw_chip_ops rtw8822c_ops = { ++ .power_on = rtw_power_on, ++ .power_off = rtw_power_off, + .phy_set_param = rtw8822c_phy_set_param, + .read_efuse = rtw8822c_read_efuse, + .query_phy_status = query_phy_status, diff --git a/package/kernel/mac80211/patches/rtl/030-v6.13-wifi-rtw88-Enable-data-rate-fallback-for-older-chips.patch b/package/kernel/mac80211/patches/rtl/030-v6.13-wifi-rtw88-Enable-data-rate-fallback-for-older-chips.patch new file mode 100644 index 00000000000000..9c3bf29321142a --- /dev/null +++ b/package/kernel/mac80211/patches/rtl/030-v6.13-wifi-rtw88-Enable-data-rate-fallback-for-older-chips.patch @@ -0,0 +1,194 @@ +From c7706b1173c77185a2ef40c7d1811021566563f3 Mon Sep 17 00:00:00 2001 +From: Bitterblue Smith +Date: Wed, 23 Oct 2024 17:10:32 +0300 +Subject: [PATCH] wifi: rtw88: Enable data rate fallback for older chips + +RTL8811AU fails to perform the 4-way handshake when the AP is too far +because it transmits the EAPOL frames at MCS9 and when that doesn't +work it retries 48 times with the same rate, to no avail. + +Retrying 48 times with the same rate seems pointless. Set the +appropriate field in the TX descriptor to allow it to use lower rates +when retrying. + +Set it for RTL8723D and RTL8703B because they interpret this field the +same way as RTL8811A. + +The newer RTL8822C, RTL8822B, RTL8821C seem to interpret this field in +the TX descriptor differently, so leave it alone for those chips. + +Tested with RTL8811AU and RTL8723DU. + +Signed-off-by: Bitterblue Smith +Signed-off-by: Ping-Ke Shih +Link: https://patch.msgid.link/2b3e3e6f-541b-4a3b-8ca3-65b267e6a95a@gmail.com +--- + drivers/net/wireless/realtek/rtw88/fw.c | 2 +- + drivers/net/wireless/realtek/rtw88/main.h | 1 + + drivers/net/wireless/realtek/rtw88/pci.c | 2 +- + drivers/net/wireless/realtek/rtw88/rtw8703b.c | 1 + + drivers/net/wireless/realtek/rtw88/rtw8723d.c | 1 + + drivers/net/wireless/realtek/rtw88/rtw8821c.c | 1 + + drivers/net/wireless/realtek/rtw88/rtw8822b.c | 1 + + drivers/net/wireless/realtek/rtw88/rtw8822c.c | 1 + + drivers/net/wireless/realtek/rtw88/sdio.c | 2 +- + drivers/net/wireless/realtek/rtw88/tx.c | 6 +++++- + drivers/net/wireless/realtek/rtw88/tx.h | 4 +++- + drivers/net/wireless/realtek/rtw88/usb.c | 4 ++-- + 12 files changed, 19 insertions(+), 7 deletions(-) + +--- a/drivers/net/wireless/realtek/rtw88/fw.c ++++ b/drivers/net/wireless/realtek/rtw88/fw.c +@@ -1290,7 +1290,7 @@ static void rtw_fill_rsvd_page_desc(stru + rtw_tx_rsvd_page_pkt_info_update(rtwdev, &pkt_info, skb, type); + pkt_desc = skb_push(skb, chip->tx_pkt_desc_sz); + memset(pkt_desc, 0, chip->tx_pkt_desc_sz); +- rtw_tx_fill_tx_desc(&pkt_info, skb); ++ rtw_tx_fill_tx_desc(rtwdev, &pkt_info, skb); + } + + static inline u8 rtw_len_to_page(unsigned int len, u8 page_size) +--- a/drivers/net/wireless/realtek/rtw88/main.h ++++ b/drivers/net/wireless/realtek/rtw88/main.h +@@ -1204,6 +1204,7 @@ struct rtw_chip_info { + u8 usb_tx_agg_desc_num; + bool hw_feature_report; + u8 c2h_ra_report_size; ++ bool old_datarate_fb_limit; + + u8 default_1ss_tx_path; + +--- a/drivers/net/wireless/realtek/rtw88/pci.c ++++ b/drivers/net/wireless/realtek/rtw88/pci.c +@@ -825,7 +825,7 @@ static int rtw_pci_tx_write_data(struct + pkt_desc = skb_push(skb, chip->tx_pkt_desc_sz); + memset(pkt_desc, 0, tx_pkt_desc_sz); + pkt_info->qsel = rtw_pci_get_tx_qsel(skb, queue); +- rtw_tx_fill_tx_desc(pkt_info, skb); ++ rtw_tx_fill_tx_desc(rtwdev, pkt_info, skb); + dma = dma_map_single(&rtwpci->pdev->dev, skb->data, skb->len, + DMA_TO_DEVICE); + if (dma_mapping_error(&rtwpci->pdev->dev, dma)) +--- a/drivers/net/wireless/realtek/rtw88/rtw8703b.c ++++ b/drivers/net/wireless/realtek/rtw88/rtw8703b.c +@@ -1964,6 +1964,7 @@ const struct rtw_chip_info rtw8703b_hw_s + .usb_tx_agg_desc_num = 1, /* Not sure if this chip has USB interface */ + .hw_feature_report = true, + .c2h_ra_report_size = 7, ++ .old_datarate_fb_limit = true, + + .path_div_supported = false, + .ht_supported = true, +--- a/drivers/net/wireless/realtek/rtw88/rtw8723d.c ++++ b/drivers/net/wireless/realtek/rtw88/rtw8723d.c +@@ -2135,6 +2135,7 @@ const struct rtw_chip_info rtw8723d_hw_s + .usb_tx_agg_desc_num = 1, + .hw_feature_report = true, + .c2h_ra_report_size = 7, ++ .old_datarate_fb_limit = true, + .ht_supported = true, + .vht_supported = false, + .lps_deep_mode_supported = 0, +--- a/drivers/net/wireless/realtek/rtw88/rtw8821c.c ++++ b/drivers/net/wireless/realtek/rtw88/rtw8821c.c +@@ -1972,6 +1972,7 @@ const struct rtw_chip_info rtw8821c_hw_s + .usb_tx_agg_desc_num = 3, + .hw_feature_report = true, + .c2h_ra_report_size = 7, ++ .old_datarate_fb_limit = false, + .ht_supported = true, + .vht_supported = true, + .lps_deep_mode_supported = BIT(LPS_DEEP_MODE_LCLK), +--- a/drivers/net/wireless/realtek/rtw88/rtw8822b.c ++++ b/drivers/net/wireless/realtek/rtw88/rtw8822b.c +@@ -2515,6 +2515,7 @@ const struct rtw_chip_info rtw8822b_hw_s + .usb_tx_agg_desc_num = 3, + .hw_feature_report = true, + .c2h_ra_report_size = 7, ++ .old_datarate_fb_limit = false, + .ht_supported = true, + .vht_supported = true, + .lps_deep_mode_supported = BIT(LPS_DEEP_MODE_LCLK), +--- a/drivers/net/wireless/realtek/rtw88/rtw8822c.c ++++ b/drivers/net/wireless/realtek/rtw88/rtw8822c.c +@@ -5334,6 +5334,7 @@ const struct rtw_chip_info rtw8822c_hw_s + .usb_tx_agg_desc_num = 3, + .hw_feature_report = true, + .c2h_ra_report_size = 7, ++ .old_datarate_fb_limit = false, + .default_1ss_tx_path = BB_PATH_A, + .path_div_supported = true, + .ht_supported = true, +--- a/drivers/net/wireless/realtek/rtw88/sdio.c ++++ b/drivers/net/wireless/realtek/rtw88/sdio.c +@@ -862,7 +862,7 @@ static void rtw_sdio_tx_skb_prepare(stru + + pkt_info->qsel = rtw_sdio_get_tx_qsel(rtwdev, skb, queue); + +- rtw_tx_fill_tx_desc(pkt_info, skb); ++ rtw_tx_fill_tx_desc(rtwdev, pkt_info, skb); + rtw_tx_fill_txdesc_checksum(rtwdev, pkt_info, pkt_desc); + } + +--- a/drivers/net/wireless/realtek/rtw88/tx.c ++++ b/drivers/net/wireless/realtek/rtw88/tx.c +@@ -32,7 +32,8 @@ void rtw_tx_stats(struct rtw_dev *rtwdev + } + } + +-void rtw_tx_fill_tx_desc(struct rtw_tx_pkt_info *pkt_info, struct sk_buff *skb) ++void rtw_tx_fill_tx_desc(struct rtw_dev *rtwdev, ++ struct rtw_tx_pkt_info *pkt_info, struct sk_buff *skb) + { + struct rtw_tx_desc *tx_desc = (struct rtw_tx_desc *)skb->data; + bool more_data = false; +@@ -67,6 +68,9 @@ void rtw_tx_fill_tx_desc(struct rtw_tx_p + + tx_desc->w4 = le32_encode_bits(pkt_info->rate, RTW_TX_DESC_W4_DATARATE); + ++ if (rtwdev->chip->old_datarate_fb_limit) ++ tx_desc->w4 |= le32_encode_bits(0x1f, RTW_TX_DESC_W4_DATARATE_FB_LIMIT); ++ + tx_desc->w5 = le32_encode_bits(pkt_info->short_gi, RTW_TX_DESC_W5_DATA_SHORT) | + le32_encode_bits(pkt_info->bw, RTW_TX_DESC_W5_DATA_BW) | + le32_encode_bits(pkt_info->ldpc, RTW_TX_DESC_W5_DATA_LDPC) | +--- a/drivers/net/wireless/realtek/rtw88/tx.h ++++ b/drivers/net/wireless/realtek/rtw88/tx.h +@@ -44,6 +44,7 @@ struct rtw_tx_desc { + #define RTW_TX_DESC_W3_NAVUSEHDR BIT(15) + #define RTW_TX_DESC_W3_MAX_AGG_NUM GENMASK(21, 17) + #define RTW_TX_DESC_W4_DATARATE GENMASK(6, 0) ++#define RTW_TX_DESC_W4_DATARATE_FB_LIMIT GENMASK(12, 8) + #define RTW_TX_DESC_W4_RTSRATE GENMASK(28, 24) + #define RTW_TX_DESC_W5_DATA_SHORT BIT(4) + #define RTW_TX_DESC_W5_DATA_BW GENMASK(6, 5) +@@ -94,7 +95,8 @@ void rtw_tx_pkt_info_update(struct rtw_d + struct rtw_tx_pkt_info *pkt_info, + struct ieee80211_sta *sta, + struct sk_buff *skb); +-void rtw_tx_fill_tx_desc(struct rtw_tx_pkt_info *pkt_info, struct sk_buff *skb); ++void rtw_tx_fill_tx_desc(struct rtw_dev *rtwdev, ++ struct rtw_tx_pkt_info *pkt_info, struct sk_buff *skb); + void rtw_tx_report_enqueue(struct rtw_dev *rtwdev, struct sk_buff *skb, u8 sn); + void rtw_tx_report_handle(struct rtw_dev *rtwdev, struct sk_buff *skb, int src); + void rtw_tx_rsvd_page_pkt_info_update(struct rtw_dev *rtwdev, +--- a/drivers/net/wireless/realtek/rtw88/usb.c ++++ b/drivers/net/wireless/realtek/rtw88/usb.c +@@ -512,7 +512,7 @@ static int rtw_usb_write_data(struct rtw + skb_put_data(skb, buf, size); + skb_push(skb, chip->tx_pkt_desc_sz); + memset(skb->data, 0, chip->tx_pkt_desc_sz); +- rtw_tx_fill_tx_desc(pkt_info, skb); ++ rtw_tx_fill_tx_desc(rtwdev, pkt_info, skb); + rtw_tx_fill_txdesc_checksum(rtwdev, pkt_info, skb->data); + + ret = rtw_usb_write_port(rtwdev, qsel, skb, +@@ -579,7 +579,7 @@ static int rtw_usb_tx_write(struct rtw_d + pkt_desc = skb_push(skb, chip->tx_pkt_desc_sz); + memset(pkt_desc, 0, chip->tx_pkt_desc_sz); + ep = qsel_to_ep(rtwusb, pkt_info->qsel); +- rtw_tx_fill_tx_desc(pkt_info, skb); ++ rtw_tx_fill_tx_desc(rtwdev, pkt_info, skb); + rtw_tx_fill_txdesc_checksum(rtwdev, pkt_info, skb->data); + tx_data = rtw_usb_get_tx_data(skb); + tx_data->sn = pkt_info->sn; diff --git a/package/kernel/mac80211/patches/rtl/031-v6.13-wifi-rtw88-Make-txagc_remnant_ofdm-an-array.patch b/package/kernel/mac80211/patches/rtl/031-v6.13-wifi-rtw88-Make-txagc_remnant_ofdm-an-array.patch new file mode 100644 index 00000000000000..10fc773b47fe5c --- /dev/null +++ b/package/kernel/mac80211/patches/rtl/031-v6.13-wifi-rtw88-Make-txagc_remnant_ofdm-an-array.patch @@ -0,0 +1,85 @@ +From abb0f19492ba6289ffba6ec1057c0426240958af Mon Sep 17 00:00:00 2001 +From: Bitterblue Smith +Date: Wed, 23 Oct 2024 17:10:54 +0300 +Subject: [PATCH] wifi: rtw88: Make txagc_remnant_ofdm an array + +txagc_remnant_ofdm member of struct rtw_dm_info should be different for +each RF path, so make it an array of size RTW_RF_PATH_MAX (4). + +Until now all the chips using this had only one RF path, but RTL8812AU +has two, and RTL8814AU has four. + +Signed-off-by: Bitterblue Smith +Signed-off-by: Ping-Ke Shih +Link: https://patch.msgid.link/68571ba9-e504-4b2d-bfa1-62f468753649@gmail.com +--- + drivers/net/wireless/realtek/rtw88/main.h | 2 +- + drivers/net/wireless/realtek/rtw88/phy.c | 4 ++-- + drivers/net/wireless/realtek/rtw88/rtw8703b.c | 4 ++-- + drivers/net/wireless/realtek/rtw88/rtw8723d.c | 4 ++-- + 4 files changed, 7 insertions(+), 7 deletions(-) + +--- a/drivers/net/wireless/realtek/rtw88/main.h ++++ b/drivers/net/wireless/realtek/rtw88/main.h +@@ -1715,7 +1715,7 @@ struct rtw_dm_info { + bool pwr_trk_init_trigger; + struct ewma_thermal avg_thermal[RTW_RF_PATH_MAX]; + s8 txagc_remnant_cck; +- s8 txagc_remnant_ofdm; ++ s8 txagc_remnant_ofdm[RTW_RF_PATH_MAX]; + u8 rx_cck_agc_report_type; + + /* backup dack results for each path and I/Q */ +--- a/drivers/net/wireless/realtek/rtw88/phy.c ++++ b/drivers/net/wireless/realtek/rtw88/phy.c +@@ -2169,8 +2169,8 @@ void rtw_get_tx_power_params(struct rtw_ + + *limit = rtw_phy_get_tx_power_limit(rtwdev, band, bw, path, + rate, ch, regd); +- *remnant = (rate <= DESC_RATE11M ? dm_info->txagc_remnant_cck : +- dm_info->txagc_remnant_ofdm); ++ *remnant = rate <= DESC_RATE11M ? dm_info->txagc_remnant_cck : ++ dm_info->txagc_remnant_ofdm[path]; + *sar = rtw_phy_get_tx_power_sar(rtwdev, hal->sar_band, path, rate); + } + +--- a/drivers/net/wireless/realtek/rtw88/rtw8703b.c ++++ b/drivers/net/wireless/realtek/rtw88/rtw8703b.c +@@ -637,7 +637,7 @@ static void rtw8703b_pwrtrack_init(struc + dm_info->pwr_trk_init_trigger = true; + dm_info->thermal_meter_k = rtwdev->efuse.thermal_meter_k; + dm_info->txagc_remnant_cck = 0; +- dm_info->txagc_remnant_ofdm = 0; ++ dm_info->txagc_remnant_ofdm[RF_PATH_A] = 0; + } + + static void rtw8703b_phy_set_param(struct rtw_dev *rtwdev) +@@ -1589,7 +1589,7 @@ static void rtw8703b_pwrtrack_set_ofdm_p + { + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + +- dm_info->txagc_remnant_ofdm = txagc_idx; ++ dm_info->txagc_remnant_ofdm[RF_PATH_A] = txagc_idx; + + /* Only path A is calibrated for rtl8703b */ + rtw8703b_set_iqk_matrix(rtwdev, swing_idx, RF_PATH_A); +--- a/drivers/net/wireless/realtek/rtw88/rtw8723d.c ++++ b/drivers/net/wireless/realtek/rtw88/rtw8723d.c +@@ -79,7 +79,7 @@ static void rtw8723d_pwrtrack_init(struc + dm_info->pwr_trk_init_trigger = true; + dm_info->thermal_meter_k = rtwdev->efuse.thermal_meter_k; + dm_info->txagc_remnant_cck = 0; +- dm_info->txagc_remnant_ofdm = 0; ++ dm_info->txagc_remnant_ofdm[RF_PATH_A] = 0; + } + + static void rtw8723d_phy_set_param(struct rtw_dev *rtwdev) +@@ -1265,7 +1265,7 @@ static void rtw8723d_pwrtrack_set_ofdm_p + { + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + +- dm_info->txagc_remnant_ofdm = txagc_idx; ++ dm_info->txagc_remnant_ofdm[RF_PATH_A] = txagc_idx; + + rtw8723d_set_iqk_matrix(rtwdev, swing_idx, RF_PATH_A); + rtw8723d_set_iqk_matrix(rtwdev, swing_idx, RF_PATH_B); diff --git a/package/kernel/mac80211/patches/rtl/032-v6.13-wifi-rtw88-Support-TX-page-sizes-bigger-than-128.patch b/package/kernel/mac80211/patches/rtl/032-v6.13-wifi-rtw88-Support-TX-page-sizes-bigger-than-128.patch new file mode 100644 index 00000000000000..c2c57cac9ffb76 --- /dev/null +++ b/package/kernel/mac80211/patches/rtl/032-v6.13-wifi-rtw88-Support-TX-page-sizes-bigger-than-128.patch @@ -0,0 +1,115 @@ +From 82a617413e8545775ec03a1970809ac5f549ef32 Mon Sep 17 00:00:00 2001 +From: Bitterblue Smith +Date: Wed, 23 Oct 2024 17:12:06 +0300 +Subject: [PATCH] wifi: rtw88: Support TX page sizes bigger than 128 + +All the chips supported so far have a TX page size of 128 bytes. + +Change the type of the page_size member of struct rtw_chip_info from u8 +to u16 in order to support RTL8821AU (page size of 256 bytes) and +RTL8812AU (page size of 512 bytes). Also change the types of several +related variables and function parameters from u8 to u16. + +The TX page size is used, among other things, to construct the beacon, +null data, QOS null data, and PS poll templates which are uploaded to +the chip's reserved page. Each template needs to be aligned on a +multiple of the TX page size. Power saving can't work if the TX page +size is wrong. + +Signed-off-by: Bitterblue Smith +Signed-off-by: Ping-Ke Shih +Link: https://patch.msgid.link/acdefbb1-3daf-4349-9e03-9472754d5f1e@gmail.com +--- + drivers/net/wireless/realtek/rtw88/debug.c | 2 +- + drivers/net/wireless/realtek/rtw88/fw.c | 21 +++++++++++---------- + drivers/net/wireless/realtek/rtw88/mac.c | 2 +- + drivers/net/wireless/realtek/rtw88/main.h | 2 +- + 4 files changed, 14 insertions(+), 13 deletions(-) + +--- a/drivers/net/wireless/realtek/rtw88/debug.c ++++ b/drivers/net/wireless/realtek/rtw88/debug.c +@@ -308,7 +308,7 @@ static int rtw_debugfs_get_rsvd_page(str + { + struct rtw_debugfs_priv *debugfs_priv = m->private; + struct rtw_dev *rtwdev = debugfs_priv->rtwdev; +- u8 page_size = rtwdev->chip->page_size; ++ u16 page_size = rtwdev->chip->page_size; + u32 buf_size = debugfs_priv->rsvd_page.page_num * page_size; + u32 offset = debugfs_priv->rsvd_page.page_offset * page_size; + u8 *buf; +--- a/drivers/net/wireless/realtek/rtw88/fw.c ++++ b/drivers/net/wireless/realtek/rtw88/fw.c +@@ -1293,13 +1293,13 @@ static void rtw_fill_rsvd_page_desc(stru + rtw_tx_fill_tx_desc(rtwdev, &pkt_info, skb); + } + +-static inline u8 rtw_len_to_page(unsigned int len, u8 page_size) ++static inline u8 rtw_len_to_page(unsigned int len, u16 page_size) + { + return DIV_ROUND_UP(len, page_size); + } + +-static void rtw_rsvd_page_list_to_buf(struct rtw_dev *rtwdev, u8 page_size, +- u8 page_margin, u32 page, u8 *buf, ++static void rtw_rsvd_page_list_to_buf(struct rtw_dev *rtwdev, u16 page_size, ++ u16 page_margin, u32 page, u8 *buf, + struct rtw_rsvd_page *rsvd_pkt) + { + struct sk_buff *skb = rsvd_pkt->skb; +@@ -1601,13 +1601,13 @@ static int __rtw_build_rsvd_page_from_v + + static u8 *rtw_build_rsvd_page(struct rtw_dev *rtwdev, u32 *size) + { +- struct ieee80211_hw *hw = rtwdev->hw; + const struct rtw_chip_info *chip = rtwdev->chip; +- struct sk_buff *iter; ++ struct ieee80211_hw *hw = rtwdev->hw; + struct rtw_rsvd_page *rsvd_pkt; +- u32 page = 0; ++ struct sk_buff *iter; ++ u16 page_size, page_margin, tx_desc_sz; + u8 total_page = 0; +- u8 page_size, page_margin, tx_desc_sz; ++ u32 page = 0; + u8 *buf; + int ret; + +@@ -2013,12 +2013,13 @@ static int _rtw_hw_scan_update_probe_req + { + const struct rtw_chip_info *chip = rtwdev->chip; + struct sk_buff *skb, *tmp; +- u8 page_offset = 1, *buf, page_size = chip->page_size; + u16 pg_addr = rtwdev->fifo.rsvd_h2c_info_addr, loc; +- u16 buf_offset = page_size * page_offset; + u8 tx_desc_sz = chip->tx_pkt_desc_sz; +- u8 page_cnt, pages; ++ u16 page_size = chip->page_size; ++ u8 page_offset = 1, *buf; ++ u16 buf_offset = page_size * page_offset; + unsigned int pkt_len; ++ u8 page_cnt, pages; + int ret; + + if (rtw_fw_feature_ext_check(&rtwdev->fw, FW_FEATURE_EXT_OLD_PAGE_NUM)) +--- a/drivers/net/wireless/realtek/rtw88/mac.c ++++ b/drivers/net/wireless/realtek/rtw88/mac.c +@@ -1143,7 +1143,7 @@ int rtw_set_trx_fifo_info(struct rtw_dev + + /* config rsvd page num */ + fifo->rsvd_drv_pg_num = chip->rsvd_drv_pg_num; +- fifo->txff_pg_num = chip->txff_size >> 7; ++ fifo->txff_pg_num = chip->txff_size / chip->page_size; + if (rtw_chip_wcpu_11n(rtwdev)) + fifo->rsvd_pg_num = fifo->rsvd_drv_pg_num; + else +--- a/drivers/net/wireless/realtek/rtw88/main.h ++++ b/drivers/net/wireless/realtek/rtw88/main.h +@@ -1187,7 +1187,7 @@ struct rtw_chip_info { + u32 fw_rxff_size; + u16 rsvd_drv_pg_num; + u8 band; +- u8 page_size; ++ u16 page_size; + u8 csi_buf_pg_num; + u8 dig_max; + u8 dig_min; diff --git a/package/kernel/mac80211/patches/rtl/033-v6.13-wifi-rtw88-Move-pwr_track_tbl-to-struct-rtw_rfe_def.patch b/package/kernel/mac80211/patches/rtl/033-v6.13-wifi-rtw88-Move-pwr_track_tbl-to-struct-rtw_rfe_def.patch new file mode 100644 index 00000000000000..09bf846a6d60a0 --- /dev/null +++ b/package/kernel/mac80211/patches/rtl/033-v6.13-wifi-rtw88-Move-pwr_track_tbl-to-struct-rtw_rfe_def.patch @@ -0,0 +1,297 @@ +From 67d915604e6993ff627ac001983a2de63ff71b13 Mon Sep 17 00:00:00 2001 +From: Bitterblue Smith +Date: Wed, 23 Oct 2024 17:12:39 +0300 +Subject: [PATCH] wifi: rtw88: Move pwr_track_tbl to struct rtw_rfe_def + +RTL8812AU uses one set of TX power tracking tables for RFE 3, and +another set for everything else. + +Move pwr_track_tbl from struct rtw_chip_info to struct rtw_rfe_def in +order to load the right set of tables for each RFE (RF front end) type. + +Signed-off-by: Bitterblue Smith +Signed-off-by: Ping-Ke Shih +Link: https://patch.msgid.link/904d0ab1-c046-40cd-a3a3-d4fdcf663c9d@gmail.com +--- + drivers/net/wireless/realtek/rtw88/main.h | 8 ++++--- + drivers/net/wireless/realtek/rtw88/phy.c | 3 ++- + drivers/net/wireless/realtek/rtw88/rtw8703b.c | 12 +++++----- + drivers/net/wireless/realtek/rtw88/rtw8723d.c | 12 +++++----- + drivers/net/wireless/realtek/rtw88/rtw8723x.c | 3 ++- + drivers/net/wireless/realtek/rtw88/rtw8821c.c | 17 +++++++------- + drivers/net/wireless/realtek/rtw88/rtw8822b.c | 15 ++++++------ + drivers/net/wireless/realtek/rtw88/rtw8822c.c | 23 +++++++++---------- + 8 files changed, 47 insertions(+), 46 deletions(-) + +--- a/drivers/net/wireless/realtek/rtw88/main.h ++++ b/drivers/net/wireless/realtek/rtw88/main.h +@@ -1099,17 +1099,20 @@ enum rtw_rfe_fem { + struct rtw_rfe_def { + const struct rtw_table *phy_pg_tbl; + const struct rtw_table *txpwr_lmt_tbl; ++ const struct rtw_pwr_track_tbl *pwr_track_tbl; + const struct rtw_table *agc_btg_tbl; + }; + +-#define RTW_DEF_RFE(chip, bb_pg, pwrlmt) { \ ++#define RTW_DEF_RFE(chip, bb_pg, pwrlmt, track) { \ + .phy_pg_tbl = &rtw ## chip ## _bb_pg_type ## bb_pg ## _tbl, \ + .txpwr_lmt_tbl = &rtw ## chip ## _txpwr_lmt_type ## pwrlmt ## _tbl, \ ++ .pwr_track_tbl = &rtw ## chip ## _pwr_track_type ## track ## _tbl, \ + } + +-#define RTW_DEF_RFE_EXT(chip, bb_pg, pwrlmt, btg) { \ ++#define RTW_DEF_RFE_EXT(chip, bb_pg, pwrlmt, track, btg) { \ + .phy_pg_tbl = &rtw ## chip ## _bb_pg_type ## bb_pg ## _tbl, \ + .txpwr_lmt_tbl = &rtw ## chip ## _txpwr_lmt_type ## pwrlmt ## _tbl, \ ++ .pwr_track_tbl = &rtw ## chip ## _pwr_track_type ## track ## _tbl, \ + .agc_btg_tbl = &rtw ## chip ## _agc_btg_type ## btg ## _tbl, \ + } + +@@ -1243,7 +1246,6 @@ struct rtw_chip_info { + u16 dpd_ratemask; + u8 iqk_threshold; + u8 lck_threshold; +- const struct rtw_pwr_track_tbl *pwr_track_tbl; + + u8 bfer_su_max_num; + u8 bfer_mu_max_num; +--- a/drivers/net/wireless/realtek/rtw88/phy.c ++++ b/drivers/net/wireless/realtek/rtw88/phy.c +@@ -2384,7 +2384,8 @@ void rtw_phy_init_tx_power(struct rtw_de + void rtw_phy_config_swing_table(struct rtw_dev *rtwdev, + struct rtw_swing_table *swing_table) + { +- const struct rtw_pwr_track_tbl *tbl = rtwdev->chip->pwr_track_tbl; ++ const struct rtw_rfe_def *rfe_def = rtw_get_rfe_def(rtwdev); ++ const struct rtw_pwr_track_tbl *tbl = rfe_def->pwr_track_tbl; + u8 channel = rtwdev->hal.current_channel; + + if (IS_CH_2G_BAND(channel)) { +--- a/drivers/net/wireless/realtek/rtw88/rtw8703b.c ++++ b/drivers/net/wireless/realtek/rtw88/rtw8703b.c +@@ -493,11 +493,6 @@ static const struct rtw_pwr_seq_cmd * co + NULL + }; + +-static const struct rtw_rfe_def rtw8703b_rfe_defs[] = { +- [0] = { .phy_pg_tbl = &rtw8703b_bb_pg_tbl, +- .txpwr_lmt_tbl = &rtw8703b_txpwr_lmt_tbl,}, +-}; +- + static const struct rtw_page_table page_table_8703b[] = { + {12, 2, 2, 0, 1}, + {12, 2, 2, 0, 1}, +@@ -1818,6 +1813,12 @@ static const struct rtw_pwr_track_tbl rt + .pwrtrk_xtal_p = rtw8703b_pwrtrk_xtal_p, + }; + ++static const struct rtw_rfe_def rtw8703b_rfe_defs[] = { ++ [0] = { .phy_pg_tbl = &rtw8703b_bb_pg_tbl, ++ .txpwr_lmt_tbl = &rtw8703b_txpwr_lmt_tbl, ++ .pwr_track_tbl = &rtw8703b_rtw_pwr_track_tbl, }, ++}; ++ + /* Shared-Antenna Coex Table */ + static const struct coex_table_para table_sant_8703b[] = { + {0xffffffff, 0xffffffff}, /* case-0 */ +@@ -1997,7 +1998,6 @@ const struct rtw_chip_info rtw8703b_hw_s + .rfe_defs_size = ARRAY_SIZE(rtw8703b_rfe_defs), + + .iqk_threshold = 8, +- .pwr_track_tbl = &rtw8703b_rtw_pwr_track_tbl, + + /* WOWLAN firmware exists, but not implemented yet */ + .wow_fw_name = "rtw88/rtw8703b_wow_fw.bin", +--- a/drivers/net/wireless/realtek/rtw88/rtw8723d.c ++++ b/drivers/net/wireless/realtek/rtw88/rtw8723d.c +@@ -2020,11 +2020,6 @@ static const struct rtw_intf_phy_para_ta + .n_gen1_para = ARRAY_SIZE(pcie_gen1_param_8723d), + }; + +-static const struct rtw_rfe_def rtw8723d_rfe_defs[] = { +- [0] = { .phy_pg_tbl = &rtw8723d_bb_pg_tbl, +- .txpwr_lmt_tbl = &rtw8723d_txpwr_lmt_tbl,}, +-}; +- + static const u8 rtw8723d_pwrtrk_2gb_n[] = { + 0, 0, 1, 1, 1, 2, 2, 3, 4, 4, 4, 4, 5, 5, 5, + 6, 6, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10, 10, 10 +@@ -2088,6 +2083,12 @@ static const struct rtw_pwr_track_tbl rt + .pwrtrk_xtal_n = rtw8723d_pwrtrk_xtal_n, + }; + ++static const struct rtw_rfe_def rtw8723d_rfe_defs[] = { ++ [0] = { .phy_pg_tbl = &rtw8723d_bb_pg_tbl, ++ .txpwr_lmt_tbl = &rtw8723d_txpwr_lmt_tbl, ++ .pwr_track_tbl = &rtw8723d_rtw_pwr_track_tbl, }, ++}; ++ + static const struct rtw_reg_domain coex_info_hw_regs_8723d[] = { + {0x948, MASKDWORD, RTW_REG_DOMAIN_MAC32}, + {0x67, BIT(7), RTW_REG_DOMAIN_MAC8}, +@@ -2159,7 +2160,6 @@ const struct rtw_chip_info rtw8723d_hw_s + .rfe_defs = rtw8723d_rfe_defs, + .rfe_defs_size = ARRAY_SIZE(rtw8723d_rfe_defs), + .rx_ldpc = false, +- .pwr_track_tbl = &rtw8723d_rtw_pwr_track_tbl, + .iqk_threshold = 8, + .ampdu_density = IEEE80211_HT_MPDU_DENSITY_16, + .max_scan_ie_len = IEEE80211_MAX_DATA_LEN, +--- a/drivers/net/wireless/realtek/rtw88/rtw8723x.c ++++ b/drivers/net/wireless/realtek/rtw88/rtw8723x.c +@@ -595,7 +595,8 @@ void __rtw8723x_pwrtrack_set_xtal(struct + u8 delta) + { + struct rtw_dm_info *dm_info = &rtwdev->dm_info; +- const struct rtw_pwr_track_tbl *tbl = rtwdev->chip->pwr_track_tbl; ++ const struct rtw_rfe_def *rfe_def = rtw_get_rfe_def(rtwdev); ++ const struct rtw_pwr_track_tbl *tbl = rfe_def->pwr_track_tbl; + const s8 *pwrtrk_xtal; + s8 xtal_cap; + +--- a/drivers/net/wireless/realtek/rtw88/rtw8821c.c ++++ b/drivers/net/wireless/realtek/rtw88/rtw8821c.c +@@ -1581,13 +1581,6 @@ static const struct rtw_intf_phy_para_ta + .n_gen2_para = ARRAY_SIZE(pcie_gen2_param_8821c), + }; + +-static const struct rtw_rfe_def rtw8821c_rfe_defs[] = { +- [0] = RTW_DEF_RFE(8821c, 0, 0), +- [2] = RTW_DEF_RFE_EXT(8821c, 0, 0, 2), +- [4] = RTW_DEF_RFE_EXT(8821c, 0, 0, 2), +- [6] = RTW_DEF_RFE(8821c, 0, 0), +-}; +- + static const struct rtw_hw_reg rtw8821c_dig[] = { + [0] = { .addr = 0xc50, .mask = 0x7f }, + }; +@@ -1899,7 +1892,7 @@ static const u8 rtw8821c_pwrtrk_2g_cck_a + 5, 6, 6, 7, 7, 7, 8, 8, 9, 9, 9, 9, 9, 9 + }; + +-static const struct rtw_pwr_track_tbl rtw8821c_rtw_pwr_track_tbl = { ++static const struct rtw_pwr_track_tbl rtw8821c_pwr_track_type0_tbl = { + .pwrtrk_5gb_n[0] = rtw8821c_pwrtrk_5gb_n[0], + .pwrtrk_5gb_n[1] = rtw8821c_pwrtrk_5gb_n[1], + .pwrtrk_5gb_n[2] = rtw8821c_pwrtrk_5gb_n[2], +@@ -1922,6 +1915,13 @@ static const struct rtw_pwr_track_tbl rt + .pwrtrk_2g_ccka_p = rtw8821c_pwrtrk_2g_cck_a_p, + }; + ++static const struct rtw_rfe_def rtw8821c_rfe_defs[] = { ++ [0] = RTW_DEF_RFE(8821c, 0, 0, 0), ++ [2] = RTW_DEF_RFE_EXT(8821c, 0, 0, 0, 2), ++ [4] = RTW_DEF_RFE_EXT(8821c, 0, 0, 0, 2), ++ [6] = RTW_DEF_RFE(8821c, 0, 0, 0), ++}; ++ + static const struct rtw_reg_domain coex_info_hw_regs_8821c[] = { + {0xCB0, MASKDWORD, RTW_REG_DOMAIN_MAC32}, + {0xCB4, MASKDWORD, RTW_REG_DOMAIN_MAC32}, +@@ -1994,7 +1994,6 @@ const struct rtw_chip_info rtw8821c_hw_s + .rfe_defs = rtw8821c_rfe_defs, + .rfe_defs_size = ARRAY_SIZE(rtw8821c_rfe_defs), + .rx_ldpc = false, +- .pwr_track_tbl = &rtw8821c_rtw_pwr_track_tbl, + .iqk_threshold = 8, + .bfer_su_max_num = 2, + .bfer_mu_max_num = 1, +--- a/drivers/net/wireless/realtek/rtw88/rtw8822b.c ++++ b/drivers/net/wireless/realtek/rtw88/rtw8822b.c +@@ -2074,12 +2074,6 @@ static const struct rtw_intf_phy_para_ta + .n_gen2_para = ARRAY_SIZE(pcie_gen2_param_8822b), + }; + +-static const struct rtw_rfe_def rtw8822b_rfe_defs[] = { +- [2] = RTW_DEF_RFE(8822b, 2, 2), +- [3] = RTW_DEF_RFE(8822b, 3, 0), +- [5] = RTW_DEF_RFE(8822b, 5, 5), +-}; +- + static const struct rtw_hw_reg rtw8822b_dig[] = { + [0] = { .addr = 0xc50, .mask = 0x7f }, + [1] = { .addr = 0xe50, .mask = 0x7f }, +@@ -2434,7 +2428,7 @@ static const u8 rtw8822b_pwrtrk_2g_cck_a + 10, 11, 11, 12, 12, 13, 13, 14, 14, 15 + }; + +-static const struct rtw_pwr_track_tbl rtw8822b_rtw_pwr_track_tbl = { ++static const struct rtw_pwr_track_tbl rtw8822b_pwr_track_type0_tbl = { + .pwrtrk_5gb_n[RTW_PWR_TRK_5G_1] = rtw8822b_pwrtrk_5gb_n[RTW_PWR_TRK_5G_1], + .pwrtrk_5gb_n[RTW_PWR_TRK_5G_2] = rtw8822b_pwrtrk_5gb_n[RTW_PWR_TRK_5G_2], + .pwrtrk_5gb_n[RTW_PWR_TRK_5G_3] = rtw8822b_pwrtrk_5gb_n[RTW_PWR_TRK_5G_3], +@@ -2457,6 +2451,12 @@ static const struct rtw_pwr_track_tbl rt + .pwrtrk_2g_ccka_p = rtw8822b_pwrtrk_2g_cck_a_p, + }; + ++static const struct rtw_rfe_def rtw8822b_rfe_defs[] = { ++ [2] = RTW_DEF_RFE(8822b, 2, 2, 0), ++ [3] = RTW_DEF_RFE(8822b, 3, 0, 0), ++ [5] = RTW_DEF_RFE(8822b, 5, 5, 0), ++}; ++ + static const struct rtw_reg_domain coex_info_hw_regs_8822b[] = { + {0xcb0, MASKDWORD, RTW_REG_DOMAIN_MAC32}, + {0xcb4, MASKDWORD, RTW_REG_DOMAIN_MAC32}, +@@ -2537,7 +2537,6 @@ const struct rtw_chip_info rtw8822b_hw_s + .rf_tbl = {&rtw8822b_rf_a_tbl, &rtw8822b_rf_b_tbl}, + .rfe_defs = rtw8822b_rfe_defs, + .rfe_defs_size = ARRAY_SIZE(rtw8822b_rfe_defs), +- .pwr_track_tbl = &rtw8822b_rtw_pwr_track_tbl, + .iqk_threshold = 8, + .bfer_su_max_num = 2, + .bfer_mu_max_num = 1, +--- a/drivers/net/wireless/realtek/rtw88/rtw8822c.c ++++ b/drivers/net/wireless/realtek/rtw88/rtw8822c.c +@@ -4884,16 +4884,6 @@ static const struct rtw_intf_phy_para_ta + .n_gen2_para = ARRAY_SIZE(pcie_gen2_param_8822c), + }; + +-static const struct rtw_rfe_def rtw8822c_rfe_defs[] = { +- [0] = RTW_DEF_RFE(8822c, 0, 0), +- [1] = RTW_DEF_RFE(8822c, 0, 0), +- [2] = RTW_DEF_RFE(8822c, 0, 0), +- [3] = RTW_DEF_RFE(8822c, 0, 0), +- [4] = RTW_DEF_RFE(8822c, 0, 0), +- [5] = RTW_DEF_RFE(8822c, 0, 5), +- [6] = RTW_DEF_RFE(8822c, 0, 0), +-}; +- + static const struct rtw_hw_reg rtw8822c_dig[] = { + [0] = { .addr = 0x1d70, .mask = 0x7f }, + [1] = { .addr = 0x1d70, .mask = 0x7f00 }, +@@ -5239,7 +5229,7 @@ static const u8 rtw8822c_pwrtrk_2g_cck_a + 18, 18, 19, 20, 21, 22, 23, 24, 24, 25 + }; + +-static const struct rtw_pwr_track_tbl rtw8822c_rtw_pwr_track_tbl = { ++static const struct rtw_pwr_track_tbl rtw8822c_pwr_track_type0_tbl = { + .pwrtrk_5gb_n[RTW_PWR_TRK_5G_1] = rtw8822c_pwrtrk_5gb_n[RTW_PWR_TRK_5G_1], + .pwrtrk_5gb_n[RTW_PWR_TRK_5G_2] = rtw8822c_pwrtrk_5gb_n[RTW_PWR_TRK_5G_2], + .pwrtrk_5gb_n[RTW_PWR_TRK_5G_3] = rtw8822c_pwrtrk_5gb_n[RTW_PWR_TRK_5G_3], +@@ -5262,6 +5252,16 @@ static const struct rtw_pwr_track_tbl rt + .pwrtrk_2g_ccka_p = rtw8822c_pwrtrk_2g_cck_a_p, + }; + ++static const struct rtw_rfe_def rtw8822c_rfe_defs[] = { ++ [0] = RTW_DEF_RFE(8822c, 0, 0, 0), ++ [1] = RTW_DEF_RFE(8822c, 0, 0, 0), ++ [2] = RTW_DEF_RFE(8822c, 0, 0, 0), ++ [3] = RTW_DEF_RFE(8822c, 0, 0, 0), ++ [4] = RTW_DEF_RFE(8822c, 0, 0, 0), ++ [5] = RTW_DEF_RFE(8822c, 0, 5, 0), ++ [6] = RTW_DEF_RFE(8822c, 0, 0, 0), ++}; ++ + static const struct rtw_hw_reg_offset rtw8822c_edcca_th[] = { + [EDCCA_TH_L2H_IDX] = { + {.addr = 0x84c, .mask = MASKBYTE2}, .offset = 0x80 +@@ -5361,7 +5361,6 @@ const struct rtw_chip_info rtw8822c_hw_s + .rfe_defs_size = ARRAY_SIZE(rtw8822c_rfe_defs), + .en_dis_dpd = true, + .dpd_ratemask = DIS_DPD_RATEALL, +- .pwr_track_tbl = &rtw8822c_rtw_pwr_track_tbl, + .iqk_threshold = 8, + .lck_threshold = 8, + .bfer_su_max_num = 2, diff --git a/package/kernel/mac80211/patches/rtl/034-v6.13-wifi-rtw88-usb-Set-pkt_info.ls-for-the-reserved-page.patch b/package/kernel/mac80211/patches/rtl/034-v6.13-wifi-rtw88-usb-Set-pkt_info.ls-for-the-reserved-page.patch new file mode 100644 index 00000000000000..2a8d15dfae5951 --- /dev/null +++ b/package/kernel/mac80211/patches/rtl/034-v6.13-wifi-rtw88-usb-Set-pkt_info.ls-for-the-reserved-page.patch @@ -0,0 +1,27 @@ +From 85bf3041a0ea40a60b5295749268e179f056546a Mon Sep 17 00:00:00 2001 +From: Bitterblue Smith +Date: Wed, 23 Oct 2024 17:13:10 +0300 +Subject: [PATCH] wifi: rtw88: usb: Set pkt_info.ls for the reserved page + +"ls" meaning "last segment". Without this RTL8812AU can't upload the +reserved page in USB 2 mode. (Somehow it's fine in USB 3 mode.) + +Also tested with RTL8822CU, RTL8812BU, RTL8811CU, RTL8723DU, RTL8811AU. + +Signed-off-by: Bitterblue Smith +Signed-off-by: Ping-Ke Shih +Link: https://patch.msgid.link/e443f5d9-4b53-4f64-985c-64313ec80bef@gmail.com +--- + drivers/net/wireless/realtek/rtw88/usb.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/net/wireless/realtek/rtw88/usb.c ++++ b/drivers/net/wireless/realtek/rtw88/usb.c +@@ -532,6 +532,7 @@ static int rtw_usb_write_data_rsvd_page( + pkt_info.tx_pkt_size = size; + pkt_info.qsel = TX_DESC_QSEL_BEACON; + pkt_info.offset = chip->tx_pkt_desc_sz; ++ pkt_info.ls = true; + + return rtw_usb_write_data(rtwdev, &pkt_info, buf); + } diff --git a/package/kernel/mac80211/patches/rtl/035-v6.13-wifi-rtw88-Detect-beacon-loss-with-chips-other-than-.patch b/package/kernel/mac80211/patches/rtl/035-v6.13-wifi-rtw88-Detect-beacon-loss-with-chips-other-than-.patch new file mode 100644 index 00000000000000..de64f33e43e5b4 --- /dev/null +++ b/package/kernel/mac80211/patches/rtl/035-v6.13-wifi-rtw88-Detect-beacon-loss-with-chips-other-than-.patch @@ -0,0 +1,63 @@ +From 57289d30cd2ae315ab9b28213d63d1dbf8570cf3 Mon Sep 17 00:00:00 2001 +From: Bitterblue Smith +Date: Wed, 23 Oct 2024 17:13:45 +0300 +Subject: [PATCH] wifi: rtw88: Detect beacon loss with chips other than 8822c + +The driver is supposed to avoid entering LPS (power saving) when there +is beacon loss, but only RTL8822C detects the beacon loss (because it +has beacon filtering in the firmware). + +Detect beacon loss with the other chips by checking if we received less +than half the expected number of beacons in the last 2-second interval. + +This gets rid of the occasional "failed to get tx report from firmware" +warnings with RTL8821AU. It may also avoid some disconnections. + +Signed-off-by: Bitterblue Smith +Signed-off-by: Ping-Ke Shih +Link: https://patch.msgid.link/f52b2fcf-bf94-48bc-89bd-e55ebc3a2f2d@gmail.com +--- + drivers/net/wireless/realtek/rtw88/main.c | 18 ++++++++++++++++++ + 1 file changed, 18 insertions(+) + +--- a/drivers/net/wireless/realtek/rtw88/main.c ++++ b/drivers/net/wireless/realtek/rtw88/main.c +@@ -202,6 +202,21 @@ static void rtw_vif_watch_dog_iter(void + rtwvif->stats.rx_cnt = 0; + } + ++static void rtw_sw_beacon_loss_check(struct rtw_dev *rtwdev, ++ struct rtw_vif *rtwvif, int received_beacons) ++{ ++ int watchdog_delay = 2000000 / 1024; /* TU */ ++ int beacon_int, expected_beacons; ++ ++ if (rtw_fw_feature_check(&rtwdev->fw, FW_FEATURE_BCN_FILTER) || !rtwvif) ++ return; ++ ++ beacon_int = rtwvif_to_vif(rtwvif)->bss_conf.beacon_int; ++ expected_beacons = DIV_ROUND_UP(watchdog_delay, beacon_int); ++ ++ rtwdev->beacon_loss = received_beacons < expected_beacons / 2; ++} ++ + /* process TX/RX statistics periodically for hardware, + * the information helps hardware to enhance performance + */ +@@ -212,6 +227,7 @@ static void rtw_watch_dog_work(struct wo + struct rtw_traffic_stats *stats = &rtwdev->stats; + struct rtw_watch_dog_iter_data data = {}; + bool busy_traffic = test_bit(RTW_FLAG_BUSY_TRAFFIC, rtwdev->flags); ++ int received_beacons = rtwdev->dm_info.cur_pkt_count.num_bcn_pkt; + u32 tx_unicast_mbps, rx_unicast_mbps; + bool ps_active; + +@@ -270,6 +286,8 @@ static void rtw_watch_dog_work(struct wo + */ + rtw_iterate_vifs(rtwdev, rtw_vif_watch_dog_iter, &data); + ++ rtw_sw_beacon_loss_check(rtwdev, data.rtwvif, received_beacons); ++ + /* fw supports only one station associated to enter lps, if there are + * more than two stations associated to the AP, then we can not enter + * lps, because fw does not handle the overlapped beacon interval diff --git a/package/kernel/mac80211/patches/rtl/036-v6.13-wifi-rtw88-coex-Support-chips-without-a-scoreboard.patch b/package/kernel/mac80211/patches/rtl/036-v6.13-wifi-rtw88-coex-Support-chips-without-a-scoreboard.patch new file mode 100644 index 00000000000000..b2fb04fd31c325 --- /dev/null +++ b/package/kernel/mac80211/patches/rtl/036-v6.13-wifi-rtw88-coex-Support-chips-without-a-scoreboard.patch @@ -0,0 +1,66 @@ +From b19840afc05121293ae59f017cb9924814eb5d77 Mon Sep 17 00:00:00 2001 +From: Bitterblue Smith +Date: Wed, 23 Oct 2024 17:14:12 +0300 +Subject: [PATCH] wifi: rtw88: coex: Support chips without a scoreboard + +All the chips currently supported have a "scoreboard": the chip keeps +track of certain things related to bluetooth, for example, whether +bluetooth is active. The information can be read from register 0xaa. + +RTL8821AU doesn't have this. Implement bluetooth activity detection in +rtw_coex_monitor_bt_enable() based on the bluetooth TX/RX counters. + +This is mostly important for RTL8811AU, the version of RTL8821AU without +bluetooth. Without this change, the driver thinks bluetooth is active +and the wifi speeds are low. + +Signed-off-by: Bitterblue Smith +Signed-off-by: Ping-Ke Shih +Link: https://patch.msgid.link/5058f23d-2086-42cd-82ad-eef31a348467@gmail.com +--- + drivers/net/wireless/realtek/rtw88/coex.c | 18 ++++++++++++++++++ + drivers/net/wireless/realtek/rtw88/main.h | 1 + + 2 files changed, 19 insertions(+) + +--- a/drivers/net/wireless/realtek/rtw88/coex.c ++++ b/drivers/net/wireless/realtek/rtw88/coex.c +@@ -494,11 +494,29 @@ static void rtw_coex_monitor_bt_enable(s + struct rtw_coex_stat *coex_stat = &coex->stat; + struct rtw_coex_dm *coex_dm = &coex->dm; + bool bt_disabled = false; ++ bool bt_active = true; + u16 score_board; + + if (chip->scbd_support) { + score_board = rtw_coex_read_scbd(rtwdev); + bt_disabled = !(score_board & COEX_SCBD_ONOFF); ++ } else { ++ if (coex_stat->hi_pri_tx == 0 && coex_stat->hi_pri_rx == 0 && ++ coex_stat->lo_pri_tx == 0 && coex_stat->lo_pri_rx == 0) ++ bt_active = false; ++ ++ if (coex_stat->hi_pri_tx == 0xffff && coex_stat->hi_pri_rx == 0xffff && ++ coex_stat->lo_pri_tx == 0xffff && coex_stat->lo_pri_rx == 0xffff) ++ bt_active = false; ++ ++ if (bt_active) { ++ coex_stat->bt_disable_cnt = 0; ++ bt_disabled = false; ++ } else { ++ coex_stat->bt_disable_cnt++; ++ if (coex_stat->bt_disable_cnt >= 10) ++ bt_disabled = true; ++ } + } + + if (coex_stat->bt_disabled != bt_disabled) { +--- a/drivers/net/wireless/realtek/rtw88/main.h ++++ b/drivers/net/wireless/realtek/rtw88/main.h +@@ -1494,6 +1494,7 @@ struct rtw_coex_stat { + u8 bt_hid_slot; + u8 bt_a2dp_bitpool; + u8 bt_iqk_state; ++ u8 bt_disable_cnt; + + u16 wl_beacon_interval; + u8 wl_noisy_level; diff --git a/package/kernel/mac80211/patches/rtl/037-v6.13-wifi-rtw88-8821a-Regularly-ask-for-BT-info-updates.patch b/package/kernel/mac80211/patches/rtl/037-v6.13-wifi-rtw88-8821a-Regularly-ask-for-BT-info-updates.patch new file mode 100644 index 00000000000000..e0e840f0fadfeb --- /dev/null +++ b/package/kernel/mac80211/patches/rtl/037-v6.13-wifi-rtw88-8821a-Regularly-ask-for-BT-info-updates.patch @@ -0,0 +1,67 @@ +From bfcee5ee924fc5f706d20f5dc31586ca47912304 Mon Sep 17 00:00:00 2001 +From: Bitterblue Smith +Date: Wed, 23 Oct 2024 17:14:45 +0300 +Subject: [PATCH] wifi: rtw88: 8821a: Regularly ask for BT info updates + +The RTL8821AU firmware sends C2H_BT_INFO by itself when bluetooth +headphones are connected, but not when they are disconnected. This leads +to the coexistence code still using the A2DP algorithm long after the +headphones are disconnected, which means the wifi speeds are much lower +than they should be. Work around this by asking for updates every two +seconds if the chip is RTL8821AU. + +Signed-off-by: Bitterblue Smith +Signed-off-by: Ping-Ke Shih +Link: https://patch.msgid.link/358acdd2-6aae-46c1-9c66-fcce4e700b96@gmail.com +--- + drivers/net/wireless/realtek/rtw88/coex.c | 2 +- + drivers/net/wireless/realtek/rtw88/coex.h | 11 +++++++++++ + drivers/net/wireless/realtek/rtw88/main.c | 1 + + 3 files changed, 13 insertions(+), 1 deletion(-) + +--- a/drivers/net/wireless/realtek/rtw88/coex.c ++++ b/drivers/net/wireless/realtek/rtw88/coex.c +@@ -446,7 +446,7 @@ static void rtw_coex_check_rfk(struct rt + } + } + +-static void rtw_coex_query_bt_info(struct rtw_dev *rtwdev) ++void rtw_coex_query_bt_info(struct rtw_dev *rtwdev) + { + struct rtw_coex *coex = &rtwdev->coex; + struct rtw_coex_stat *coex_stat = &coex->stat; +--- a/drivers/net/wireless/realtek/rtw88/coex.h ++++ b/drivers/net/wireless/realtek/rtw88/coex.h +@@ -384,6 +384,7 @@ u32 rtw_coex_read_indirect_reg(struct rt + void rtw_coex_write_indirect_reg(struct rtw_dev *rtwdev, u16 addr, + u32 mask, u32 val); + void rtw_coex_write_scbd(struct rtw_dev *rtwdev, u16 bitpos, bool set); ++void rtw_coex_query_bt_info(struct rtw_dev *rtwdev); + + void rtw_coex_bt_relink_work(struct work_struct *work); + void rtw_coex_bt_reenable_work(struct work_struct *work); +@@ -419,4 +420,14 @@ static inline bool rtw_coex_disabled(str + return coex_stat->bt_disabled; + } + ++static inline void rtw_coex_active_query_bt_info(struct rtw_dev *rtwdev) ++{ ++ /* The RTL8821AU firmware doesn't send C2H_BT_INFO by itself ++ * when bluetooth headphones are disconnected, so we have to ++ * ask for it regularly. ++ */ ++ if (rtwdev->chip->id == RTW_CHIP_TYPE_8821A && rtwdev->efuse.btcoex) ++ rtw_coex_query_bt_info(rtwdev); ++} ++ + #endif +--- a/drivers/net/wireless/realtek/rtw88/main.c ++++ b/drivers/net/wireless/realtek/rtw88/main.c +@@ -274,6 +274,7 @@ static void rtw_watch_dog_work(struct wo + rtw_leave_lps(rtwdev); + rtw_coex_wl_status_check(rtwdev); + rtw_coex_query_bt_hid_list(rtwdev); ++ rtw_coex_active_query_bt_info(rtwdev); + + rtw_phy_dynamic_mechanism(rtwdev); + diff --git a/package/kernel/mac80211/patches/rtl/038-v6.13-wifi-rtw88-8812a-Mitigate-beacon-loss.patch b/package/kernel/mac80211/patches/rtl/038-v6.13-wifi-rtw88-8812a-Mitigate-beacon-loss.patch new file mode 100644 index 00000000000000..f862f80460df36 --- /dev/null +++ b/package/kernel/mac80211/patches/rtl/038-v6.13-wifi-rtw88-8812a-Mitigate-beacon-loss.patch @@ -0,0 +1,37 @@ +From f9e0189cbc2d6447dde392944c769546cdf48140 Mon Sep 17 00:00:00 2001 +From: Bitterblue Smith +Date: Wed, 23 Oct 2024 17:15:13 +0300 +Subject: [PATCH] wifi: rtw88: 8812a: Mitigate beacon loss + +The RTL8812AU has a reception problem, maybe only in the 5 GHz band. +Sometimes, in some positions, it stops receiving anything even though +the distance to the AP is only ~3 meters and there are no obstacles. +Moving it a few centimeters fixes it. + +Switch the initial gain to maximum coverage when there is beacon loss. +This only helps sometimes. This is similar to what the official driver +does. + +Signed-off-by: Bitterblue Smith +Signed-off-by: Ping-Ke Shih +Link: https://patch.msgid.link/203f5043-4fe1-4f35-8b8f-d3b6f44e1fd9@gmail.com +--- + drivers/net/wireless/realtek/rtw88/phy.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +--- a/drivers/net/wireless/realtek/rtw88/phy.c ++++ b/drivers/net/wireless/realtek/rtw88/phy.c +@@ -530,6 +530,13 @@ static void rtw_phy_dig(struct rtw_dev * + */ + rtw_phy_dig_recorder(dm_info, cur_igi, fa_cnt); + ++ /* Mitigate beacon loss and connectivity issues, mainly (only?) ++ * in the 5 GHz band ++ */ ++ if (rtwdev->chip->id == RTW_CHIP_TYPE_8812A && rtwdev->beacon_loss && ++ linked && dm_info->total_fa_cnt < DIG_PERF_FA_TH_EXTRA_HIGH) ++ cur_igi = DIG_CVRG_MIN; ++ + if (cur_igi != pre_igi) + rtw_phy_dig_write(rtwdev, cur_igi); + } diff --git a/package/kernel/mac80211/patches/rtl/039-v6.13-wifi-rtw88-Add-rtw8812a_table.-c-h.patch b/package/kernel/mac80211/patches/rtl/039-v6.13-wifi-rtw88-Add-rtw8812a_table.-c-h.patch new file mode 100644 index 00000000000000..59a04b4d16b579 --- /dev/null +++ b/package/kernel/mac80211/patches/rtl/039-v6.13-wifi-rtw88-Add-rtw8812a_table.-c-h.patch @@ -0,0 +1,2862 @@ +From 528f902ecc0eb8fb766bde519421255729623dd8 Mon Sep 17 00:00:00 2001 +From: Bitterblue Smith +Date: Wed, 30 Oct 2024 20:24:33 +0200 +Subject: [PATCH] wifi: rtw88: Add rtw8812a_table.{c,h} + +These contain various arrays for initialising RTL8812AU. Also TX power +limits. + +Signed-off-by: Bitterblue Smith +Signed-off-by: Ping-Ke Shih +Link: https://patch.msgid.link/086f476c-e832-4867-963c-a64a63252fd6@gmail.com +--- + .../wireless/realtek/rtw88/rtw8812a_table.c | 2812 +++++++++++++++++ + .../wireless/realtek/rtw88/rtw8812a_table.h | 26 + + 2 files changed, 2838 insertions(+) + create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8812a_table.c + create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8812a_table.h + +--- /dev/null ++++ b/drivers/net/wireless/realtek/rtw88/rtw8812a_table.c +@@ -0,0 +1,2812 @@ ++// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause ++/* Copyright(c) 2024 Realtek Corporation ++ */ ++ ++#include "main.h" ++#include "phy.h" ++#include "rtw8812a_table.h" ++ ++static const u32 rtw8812a_mac[] = { ++ 0x010, 0x0000000C, ++ 0x80000200, 0x00000000, 0x40000000, 0x00000000, ++ 0x011, 0x00000066, ++ 0xA0000000, 0x00000000, ++ 0x011, 0x0000005A, ++ 0xB0000000, 0x00000000, ++ 0x025, 0x0000000F, ++ 0x072, 0x00000000, ++ 0x420, 0x00000080, ++ 0x428, 0x0000000A, ++ 0x429, 0x00000010, ++ 0x430, 0x00000000, ++ 0x431, 0x00000000, ++ 0x432, 0x00000000, ++ 0x433, 0x00000001, ++ 0x434, 0x00000002, ++ 0x435, 0x00000003, ++ 0x436, 0x00000005, ++ 0x437, 0x00000007, ++ 0x438, 0x00000000, ++ 0x439, 0x00000000, ++ 0x43A, 0x00000000, ++ 0x43B, 0x00000001, ++ 0x43C, 0x00000002, ++ 0x43D, 0x00000003, ++ 0x43E, 0x00000005, ++ 0x43F, 0x00000007, ++ 0x440, 0x0000005D, ++ 0x441, 0x00000001, ++ 0x442, 0x00000000, ++ 0x444, 0x00000010, ++ 0x445, 0x00000000, ++ 0x446, 0x00000000, ++ 0x447, 0x00000000, ++ 0x448, 0x00000000, ++ 0x449, 0x000000F0, ++ 0x44A, 0x0000000F, ++ 0x44B, 0x0000003E, ++ 0x44C, 0x00000010, ++ 0x44D, 0x00000000, ++ 0x44E, 0x00000000, ++ 0x44F, 0x00000000, ++ 0x450, 0x00000000, ++ 0x451, 0x000000F0, ++ 0x452, 0x0000000F, ++ 0x453, 0x00000000, ++ 0x45B, 0x00000080, ++ 0x460, 0x00000066, ++ 0x461, 0x00000066, ++ 0x4C8, 0x000000FF, ++ 0x4C9, 0x00000008, ++ 0x4CC, 0x000000FF, ++ 0x4CD, 0x000000FF, ++ 0x4CE, 0x00000001, ++ 0x500, 0x00000026, ++ 0x501, 0x000000A2, ++ 0x502, 0x0000002F, ++ 0x503, 0x00000000, ++ 0x504, 0x00000028, ++ 0x505, 0x000000A3, ++ 0x506, 0x0000005E, ++ 0x507, 0x00000000, ++ 0x508, 0x0000002B, ++ 0x509, 0x000000A4, ++ 0x50A, 0x0000005E, ++ 0x50B, 0x00000000, ++ 0x50C, 0x0000004F, ++ 0x50D, 0x000000A4, ++ 0x50E, 0x00000000, ++ 0x50F, 0x00000000, ++ 0x512, 0x0000001C, ++ 0x514, 0x0000000A, ++ 0x516, 0x0000000A, ++ 0x525, 0x0000004F, ++ 0x550, 0x00000010, ++ 0x551, 0x00000010, ++ 0x559, 0x00000002, ++ 0x55C, 0x00000050, ++ 0x55D, 0x000000FF, ++ 0x604, 0x00000009, ++ 0x605, 0x00000030, ++ 0x607, 0x00000003, ++ 0x608, 0x0000000E, ++ 0x609, 0x0000002A, ++ 0x620, 0x000000FF, ++ 0x621, 0x000000FF, ++ 0x622, 0x000000FF, ++ 0x623, 0x000000FF, ++ 0x624, 0x000000FF, ++ 0x625, 0x000000FF, ++ 0x626, 0x000000FF, ++ 0x627, 0x000000FF, ++ 0x638, 0x00000050, ++ 0x63C, 0x0000000A, ++ 0x63D, 0x0000000A, ++ 0x63E, 0x0000000E, ++ 0x63F, 0x0000000E, ++ 0x640, 0x00000080, ++ 0x642, 0x00000040, ++ 0x643, 0x00000000, ++ 0x652, 0x000000C8, ++ 0x66E, 0x00000005, ++ 0x700, 0x00000021, ++ 0x701, 0x00000043, ++ 0x702, 0x00000065, ++ 0x703, 0x00000087, ++ 0x708, 0x00000021, ++ 0x709, 0x00000043, ++ 0x70A, 0x00000065, ++ 0x70B, 0x00000087, ++ 0x718, 0x00000040, ++}; ++ ++RTW_DECL_TABLE_PHY_COND(rtw8812a_mac, rtw_phy_cfg_mac); ++ ++static const u32 rtw8812a_agc[] = { ++ 0x80000001, 0x00000000, 0x40000000, 0x00000000, ++ 0x81C, 0xFC000001, ++ 0x81C, 0xFB020001, ++ 0x81C, 0xFA040001, ++ 0x81C, 0xF9060001, ++ 0x81C, 0xF8080001, ++ 0x81C, 0xF70A0001, ++ 0x81C, 0xF60C0001, ++ 0x81C, 0xF50E0001, ++ 0x81C, 0xF4100001, ++ 0x81C, 0xF3120001, ++ 0x81C, 0xF2140001, ++ 0x81C, 0xF1160001, ++ 0x81C, 0xF0180001, ++ 0x81C, 0xEF1A0001, ++ 0x81C, 0xEE1C0001, ++ 0x81C, 0xED1E0001, ++ 0x81C, 0xEC200001, ++ 0x81C, 0xEB220001, ++ 0x81C, 0xEA240001, ++ 0x81C, 0xCD260001, ++ 0x81C, 0xCC280001, ++ 0x81C, 0xCB2A0001, ++ 0x81C, 0xCA2C0001, ++ 0x81C, 0xC92E0001, ++ 0x81C, 0xC8300001, ++ 0x81C, 0xA6320001, ++ 0x81C, 0xA5340001, ++ 0x81C, 0xA4360001, ++ 0x81C, 0xA3380001, ++ 0x81C, 0xA23A0001, ++ 0x81C, 0x883C0001, ++ 0x81C, 0x873E0001, ++ 0x81C, 0x86400001, ++ 0x81C, 0x85420001, ++ 0x81C, 0x84440001, ++ 0x81C, 0x83460001, ++ 0x81C, 0x82480001, ++ 0x81C, 0x814A0001, ++ 0x81C, 0x484C0001, ++ 0x81C, 0x474E0001, ++ 0x81C, 0x46500001, ++ 0x81C, 0x45520001, ++ 0x81C, 0x44540001, ++ 0x81C, 0x43560001, ++ 0x81C, 0x42580001, ++ 0x81C, 0x415A0001, ++ 0x81C, 0x255C0001, ++ 0x81C, 0x245E0001, ++ 0x81C, 0x23600001, ++ 0x81C, 0x22620001, ++ 0x81C, 0x21640001, ++ 0x81C, 0x21660001, ++ 0x81C, 0x21680001, ++ 0x81C, 0x216A0001, ++ 0x81C, 0x216C0001, ++ 0x81C, 0x216E0001, ++ 0x81C, 0x21700001, ++ 0x81C, 0x21720001, ++ 0x81C, 0x21740001, ++ 0x81C, 0x21760001, ++ 0x81C, 0x21780001, ++ 0x81C, 0x217A0001, ++ 0x81C, 0x217C0001, ++ 0x81C, 0x217E0001, ++ 0x90000001, 0x00000005, 0x40000000, 0x00000000, ++ 0x81C, 0xF9000001, ++ 0x81C, 0xF8020001, ++ 0x81C, 0xF7040001, ++ 0x81C, 0xF6060001, ++ 0x81C, 0xF5080001, ++ 0x81C, 0xF40A0001, ++ 0x81C, 0xF30C0001, ++ 0x81C, 0xF20E0001, ++ 0x81C, 0xF1100001, ++ 0x81C, 0xF0120001, ++ 0x81C, 0xEF140001, ++ 0x81C, 0xEE160001, ++ 0x81C, 0xED180001, ++ 0x81C, 0xEC1A0001, ++ 0x81C, 0xEB1C0001, ++ 0x81C, 0xEA1E0001, ++ 0x81C, 0xCD200001, ++ 0x81C, 0xCC220001, ++ 0x81C, 0xCB240001, ++ 0x81C, 0xCA260001, ++ 0x81C, 0xC9280001, ++ 0x81C, 0xC82A0001, ++ 0x81C, 0xC72C0001, ++ 0x81C, 0xC62E0001, ++ 0x81C, 0xA5300001, ++ 0x81C, 0xA4320001, ++ 0x81C, 0xA3340001, ++ 0x81C, 0xA2360001, ++ 0x81C, 0x88380001, ++ 0x81C, 0x873A0001, ++ 0x81C, 0x863C0001, ++ 0x81C, 0x853E0001, ++ 0x81C, 0x84400001, ++ 0x81C, 0x83420001, ++ 0x81C, 0x82440001, ++ 0x81C, 0x81460001, ++ 0x81C, 0x48480001, ++ 0x81C, 0x474A0001, ++ 0x81C, 0x464C0001, ++ 0x81C, 0x454E0001, ++ 0x81C, 0x44500001, ++ 0x81C, 0x43520001, ++ 0x81C, 0x42540001, ++ 0x81C, 0x41560001, ++ 0x81C, 0x25580001, ++ 0x81C, 0x245A0001, ++ 0x81C, 0x235C0001, ++ 0x81C, 0x225E0001, ++ 0x81C, 0x21600001, ++ 0x81C, 0x21620001, ++ 0x81C, 0x21640001, ++ 0x81C, 0x21660001, ++ 0x81C, 0x21680001, ++ 0x81C, 0x216A0001, ++ 0x81C, 0x236C0001, ++ 0x81C, 0x226E0001, ++ 0x81C, 0x21700001, ++ 0x81C, 0x21720001, ++ 0x81C, 0x21740001, ++ 0x81C, 0x21760001, ++ 0x81C, 0x21780001, ++ 0x81C, 0x217A0001, ++ 0x81C, 0x217C0001, ++ 0x81C, 0x217E0001, ++ 0xA0000000, 0x00000000, ++ 0x81C, 0xFF000001, ++ 0x81C, 0xFF020001, ++ 0x81C, 0xFF040001, ++ 0x81C, 0xFF060001, ++ 0x81C, 0xFF080001, ++ 0x81C, 0xFE0A0001, ++ 0x81C, 0xFD0C0001, ++ 0x81C, 0xFC0E0001, ++ 0x81C, 0xFB100001, ++ 0x81C, 0xFA120001, ++ 0x81C, 0xF9140001, ++ 0x81C, 0xF8160001, ++ 0x81C, 0xF7180001, ++ 0x81C, 0xF61A0001, ++ 0x81C, 0xF51C0001, ++ 0x81C, 0xF41E0001, ++ 0x81C, 0xF3200001, ++ 0x81C, 0xF2220001, ++ 0x81C, 0xF1240001, ++ 0x81C, 0xF0260001, ++ 0x81C, 0xEF280001, ++ 0x81C, 0xEE2A0001, ++ 0x81C, 0xED2C0001, ++ 0x81C, 0xEC2E0001, ++ 0x81C, 0xEB300001, ++ 0x81C, 0xEA320001, ++ 0x81C, 0xE9340001, ++ 0x81C, 0xE8360001, ++ 0x81C, 0xE7380001, ++ 0x81C, 0xE63A0001, ++ 0x81C, 0xE53C0001, ++ 0x81C, 0xC73E0001, ++ 0x81C, 0xC6400001, ++ 0x81C, 0xC5420001, ++ 0x81C, 0xC4440001, ++ 0x81C, 0xC3460001, ++ 0x81C, 0xC2480001, ++ 0x81C, 0xC14A0001, ++ 0x81C, 0xA74C0001, ++ 0x81C, 0xA64E0001, ++ 0x81C, 0xA5500001, ++ 0x81C, 0xA4520001, ++ 0x81C, 0xA3540001, ++ 0x81C, 0xA2560001, ++ 0x81C, 0xA1580001, ++ 0x81C, 0x675A0001, ++ 0x81C, 0x665C0001, ++ 0x81C, 0x655E0001, ++ 0x81C, 0x64600001, ++ 0x81C, 0x63620001, ++ 0x81C, 0x48640001, ++ 0x81C, 0x47660001, ++ 0x81C, 0x46680001, ++ 0x81C, 0x456A0001, ++ 0x81C, 0x446C0001, ++ 0x81C, 0x436E0001, ++ 0x81C, 0x42700001, ++ 0x81C, 0x41720001, ++ 0x81C, 0x41740001, ++ 0x81C, 0x41760001, ++ 0x81C, 0x41780001, ++ 0x81C, 0x417A0001, ++ 0x81C, 0x417C0001, ++ 0x81C, 0x417E0001, ++ 0xB0000000, 0x00000000, ++ 0x80000004, 0x00000000, 0x40000000, 0x00000000, ++ 0x81C, 0xFC800001, ++ 0x81C, 0xFB820001, ++ 0x81C, 0xFA840001, ++ 0x81C, 0xF9860001, ++ 0x81C, 0xF8880001, ++ 0x81C, 0xF78A0001, ++ 0x81C, 0xF68C0001, ++ 0x81C, 0xF58E0001, ++ 0x81C, 0xF4900001, ++ 0x81C, 0xF3920001, ++ 0x81C, 0xF2940001, ++ 0x81C, 0xF1960001, ++ 0x81C, 0xF0980001, ++ 0x81C, 0xEF9A0001, ++ 0x81C, 0xEE9C0001, ++ 0x81C, 0xED9E0001, ++ 0x81C, 0xECA00001, ++ 0x81C, 0xEBA20001, ++ 0x81C, 0xEAA40001, ++ 0x81C, 0xE9A60001, ++ 0x81C, 0xE8A80001, ++ 0x81C, 0xE7AA0001, ++ 0x81C, 0xE6AC0001, ++ 0x81C, 0xE5AE0001, ++ 0x81C, 0xE4B00001, ++ 0x81C, 0xE3B20001, ++ 0x81C, 0xA8B40001, ++ 0x81C, 0xA7B60001, ++ 0x81C, 0xA6B80001, ++ 0x81C, 0xA5BA0001, ++ 0x81C, 0xA4BC0001, ++ 0x81C, 0xA3BE0001, ++ 0x81C, 0xA2C00001, ++ 0x81C, 0xA1C20001, ++ 0x81C, 0x68C40001, ++ 0x81C, 0x67C60001, ++ 0x81C, 0x66C80001, ++ 0x81C, 0x65CA0001, ++ 0x81C, 0x64CC0001, ++ 0x81C, 0x47CE0001, ++ 0x81C, 0x46D00001, ++ 0x81C, 0x45D20001, ++ 0x81C, 0x44D40001, ++ 0x81C, 0x43D60001, ++ 0x81C, 0x42D80001, ++ 0x81C, 0x08DA0001, ++ 0x81C, 0x07DC0001, ++ 0x81C, 0x06DE0001, ++ 0x81C, 0x05E00001, ++ 0x81C, 0x04E20001, ++ 0x81C, 0x03E40001, ++ 0x81C, 0x02E60001, ++ 0x81C, 0x01E80001, ++ 0x81C, 0x01EA0001, ++ 0x81C, 0x01EC0001, ++ 0x81C, 0x01EE0001, ++ 0x81C, 0x01F00001, ++ 0x81C, 0x01F20001, ++ 0x81C, 0x01F40001, ++ 0x81C, 0x01F60001, ++ 0x81C, 0x01F80001, ++ 0x81C, 0x01FA0001, ++ 0x81C, 0x01FC0001, ++ 0x81C, 0x01FE0001, ++ 0xA0000000, 0x00000000, ++ 0x81C, 0xFF800001, ++ 0x81C, 0xFF820001, ++ 0x81C, 0xFF840001, ++ 0x81C, 0xFE860001, ++ 0x81C, 0xFD880001, ++ 0x81C, 0xFC8A0001, ++ 0x81C, 0xFB8C0001, ++ 0x81C, 0xFA8E0001, ++ 0x81C, 0xF9900001, ++ 0x81C, 0xF8920001, ++ 0x81C, 0xF7940001, ++ 0x81C, 0xF6960001, ++ 0x81C, 0xF5980001, ++ 0x81C, 0xF49A0001, ++ 0x81C, 0xF39C0001, ++ 0x81C, 0xF29E0001, ++ 0x81C, 0xF1A00001, ++ 0x81C, 0xF0A20001, ++ 0x81C, 0xEFA40001, ++ 0x81C, 0xEEA60001, ++ 0x81C, 0xEDA80001, ++ 0x81C, 0xECAA0001, ++ 0x81C, 0xEBAC0001, ++ 0x81C, 0xEAAE0001, ++ 0x81C, 0xE9B00001, ++ 0x81C, 0xE8B20001, ++ 0x81C, 0xE7B40001, ++ 0x81C, 0xE6B60001, ++ 0x81C, 0xE5B80001, ++ 0x81C, 0xE4BA0001, ++ 0x81C, 0xE3BC0001, ++ 0x81C, 0xA8BE0001, ++ 0x81C, 0xA7C00001, ++ 0x81C, 0xA6C20001, ++ 0x81C, 0xA5C40001, ++ 0x81C, 0xA4C60001, ++ 0x81C, 0xA3C80001, ++ 0x81C, 0xA2CA0001, ++ 0x81C, 0xA1CC0001, ++ 0x81C, 0x68CE0001, ++ 0x81C, 0x67D00001, ++ 0x81C, 0x66D20001, ++ 0x81C, 0x65D40001, ++ 0x81C, 0x64D60001, ++ 0x81C, 0x47D80001, ++ 0x81C, 0x46DA0001, ++ 0x81C, 0x45DC0001, ++ 0x81C, 0x44DE0001, ++ 0x81C, 0x43E00001, ++ 0x81C, 0x42E20001, ++ 0x81C, 0x08E40001, ++ 0x81C, 0x07E60001, ++ 0x81C, 0x06E80001, ++ 0x81C, 0x05EA0001, ++ 0x81C, 0x04EC0001, ++ 0x81C, 0x03EE0001, ++ 0x81C, 0x02F00001, ++ 0x81C, 0x01F20001, ++ 0x81C, 0x01F40001, ++ 0x81C, 0x01F60001, ++ 0x81C, 0x01F80001, ++ 0x81C, 0x01FA0001, ++ 0x81C, 0x01FC0001, ++ 0x81C, 0x01FE0001, ++ 0xB0000000, 0x00000000, ++ 0xC50, 0x00000022, ++ 0xC50, 0x00000020, ++ 0xE50, 0x00000022, ++ 0xE50, 0x00000020, ++}; ++ ++RTW_DECL_TABLE_PHY_COND(rtw8812a_agc, rtw_phy_cfg_agc); ++ ++static const u32 rtw8812a_agc_diff_lb[] = { ++ 0x80000004, 0x00000000, 0x40000000, 0x00000000, ++ 0x81C, 0x47CE0001, ++ 0x81C, 0x46D00001, ++ 0x81C, 0x45D20001, ++ 0x81C, 0x44D40001, ++ 0x81C, 0x43D60001, ++ 0x81C, 0x42D80001, ++ 0x81C, 0x08DA0001, ++ 0x81C, 0x07DC0001, ++ 0x81C, 0x06DE0001, ++ 0x81C, 0x05E00001, ++ 0x81C, 0x04E20001, ++ 0x81C, 0x03E40001, ++ 0x81C, 0x02E60001, ++ 0xA0000000, 0x00000000, ++ 0x81C, 0x47D80001, ++ 0x81C, 0x46DA0001, ++ 0x81C, 0x45DC0001, ++ 0x81C, 0x44DE0001, ++ 0x81C, 0x43E00001, ++ 0x81C, 0x42E20001, ++ 0x81C, 0x08E40001, ++ 0x81C, 0x07E60001, ++ 0x81C, 0x06E80001, ++ 0x81C, 0x05EA0001, ++ 0x81C, 0x04EC0001, ++ 0x81C, 0x03EE0001, ++ 0x81C, 0x02F00001, ++ 0xB0000000, 0x00000000, ++}; ++ ++RTW_DECL_TABLE_PHY_COND(rtw8812a_agc_diff_lb, rtw_phy_cfg_agc); ++ ++static const u32 rtw8812a_agc_diff_hb[] = { ++ 0x80000004, 0x00000000, 0x40000000, 0x00000000, ++ 0x81C, 0x45CE0001, ++ 0x81C, 0x44D00001, ++ 0x81C, 0x43D20001, ++ 0x81C, 0x42D40001, ++ 0x81C, 0x08D60001, ++ 0x81C, 0x07D80001, ++ 0x81C, 0x06DA0001, ++ 0x81C, 0x05DC0001, ++ 0x81C, 0x04DE0001, ++ 0x81C, 0x03E00001, ++ 0x81C, 0x02E20001, ++ 0x81C, 0x01E40001, ++ 0x81C, 0x01E60001, ++ 0xA0000000, 0x00000000, ++ 0x81C, 0x45D80001, ++ 0x81C, 0x44DA0001, ++ 0x81C, 0x43DC0001, ++ 0x81C, 0x42DE0001, ++ 0x81C, 0x08E00001, ++ 0x81C, 0x07E20001, ++ 0x81C, 0x06E40001, ++ 0x81C, 0x05E60001, ++ 0x81C, 0x04E80001, ++ 0x81C, 0x03EA0001, ++ 0x81C, 0x02EC0001, ++ 0x81C, 0x01EE0001, ++ 0x81C, 0x01F00001, ++ 0xB0000000, 0x00000000, ++}; ++ ++RTW_DECL_TABLE_PHY_COND(rtw8812a_agc_diff_hb, rtw_phy_cfg_agc); ++ ++static const u32 rtw8812a_bb[] = { ++ 0x800, 0x8020D010, ++ 0x804, 0x080112E0, ++ 0x808, 0x0E028233, ++ 0x80C, 0x12131113, ++ 0x810, 0x20101263, ++ 0x814, 0x020C3D10, ++ 0x818, 0x03A00385, ++ 0x820, 0x00000000, ++ 0x824, 0x00030FE0, ++ 0x828, 0x00000000, ++ 0x82C, 0x002083DD, ++ 0x830, 0x2EAAEEB8, ++ 0x834, 0x0037A706, ++ 0x838, 0x06C89B44, ++ 0x83C, 0x0000095B, ++ 0x840, 0xC0000001, ++ 0x844, 0x40003CDE, ++ 0x848, 0x6210FF8B, ++ 0x84C, 0x6CFDFFB8, ++ 0x850, 0x28874706, ++ 0x854, 0x0001520C, ++ 0x858, 0x8060E000, ++ 0x85C, 0x74210168, ++ 0x860, 0x6929C321, ++ 0x864, 0x79727432, ++ 0x868, 0x8CA7A314, ++ 0x86C, 0x338C2878, ++ 0x870, 0x03333333, ++ 0x874, 0x31602C2E, ++ 0x878, 0x00003152, ++ 0x87C, 0x000FC000, ++ 0x8A0, 0x00000013, ++ 0x8A4, 0x7F7F7F7F, ++ 0x8A8, 0xA202033E, ++ 0x8AC, 0x0FF0FA0A, ++ 0x8B0, 0x00000600, ++ 0x8B4, 0x000FC080, ++ 0x8B8, 0x6C10D7FF, ++ 0x8BC, 0x4CA520A3, ++ 0x8C0, 0x27F00020, ++ 0x8C4, 0x00000000, ++ 0x8C8, 0x00012D69, ++ 0x8CC, 0x08248492, ++ 0x8D0, 0x0000B800, ++ 0x8DC, 0x00000000, ++ 0x8D4, 0x940008A0, ++ 0x8D8, 0x290B5612, ++ 0x8F8, 0x400002C0, ++ 0x8FC, 0x00000000, ++ 0x900, 0x00000701, ++ 0x90C, 0x00000000, ++ 0x910, 0x0000FC00, ++ 0x914, 0x00000404, ++ 0x918, 0x1C1028C0, ++ 0x91C, 0x64B11A1C, ++ 0x920, 0xE0767233, ++ 0x924, 0x055AA500, ++ 0x928, 0x00000004, ++ 0x92C, 0xFFFE0000, ++ 0x930, 0xFFFFFFFE, ++ 0x934, 0x001FFFFF, ++ 0x960, 0x00000000, ++ 0x964, 0x00000000, ++ 0x968, 0x00000000, ++ 0x96C, 0x00000000, ++ 0x970, 0x801FFFFF, ++ 0x978, 0x00000000, ++ 0x97C, 0x00000000, ++ 0x980, 0x00000000, ++ 0x984, 0x00000000, ++ 0x988, 0x00000000, ++ 0x990, 0x27100000, ++ 0x994, 0xFFFF0100, ++ 0x998, 0xFFFFFF5C, ++ 0x99C, 0xFFFFFFFF, ++ 0x9A0, 0x000000FF, ++ 0x9A4, 0x00080080, ++ 0x9A8, 0x00000000, ++ 0x9AC, 0x00000000, ++ 0x9B0, 0x81081008, ++ 0x9B4, 0x00000000, ++ 0x9B8, 0x01081008, ++ 0x9BC, 0x01081008, ++ 0x9D0, 0x00000000, ++ 0x9D4, 0x00000000, ++ 0x9D8, 0x00000000, ++ 0x9DC, 0x00000000, ++ 0x9E4, 0x00000003, ++ 0x9E8, 0x000002D5, ++ 0xA00, 0x00D047C8, ++ 0xA04, 0x01FF000C, ++ 0xA08, 0x8C838300, ++ 0xA0C, 0x2E7F000F, ++ 0xA10, 0x9500BB78, ++ 0xA14, 0x11144028, ++ 0xA18, 0x00881117, ++ 0xA1C, 0x89140F00, ++ 0xA20, 0x1A1B0000, ++ 0xA24, 0x090E1217, ++ 0xA28, 0x00000305, ++ 0xA2C, 0x00900000, ++ 0xA70, 0x101FFF00, ++ 0xA74, 0x00000008, ++ 0xA78, 0x00000900, ++ 0xA7C, 0x225B0606, ++ 0xA80, 0x218075B2, ++ 0xA84, 0x001F8C80, ++ 0xB00, 0x03100000, ++ 0xB04, 0x0000B000, ++ 0xB08, 0xAE0201EB, ++ 0xB0C, 0x01003207, ++ 0xB10, 0x00009807, ++ 0xB14, 0x01000000, ++ 0xB18, 0x00000002, ++ 0xB1C, 0x00000002, ++ 0xB20, 0x0000001F, ++ 0xB24, 0x03020100, ++ 0xB28, 0x07060504, ++ 0xB2C, 0x0B0A0908, ++ 0xB30, 0x0F0E0D0C, ++ 0xB34, 0x13121110, ++ 0xB38, 0x17161514, ++ 0xB3C, 0x0000003A, ++ 0xB40, 0x00000000, ++ 0xB44, 0x00000000, ++ 0xB48, 0x13000032, ++ 0xB4C, 0x48080000, ++ 0xB50, 0x00000000, ++ 0xB54, 0x00000000, ++ 0xB58, 0x00000000, ++ 0xB5C, 0x00000000, ++ 0xC00, 0x00000007, ++ 0xC04, 0x00042020, ++ 0xC08, 0x80410231, ++ 0xC0C, 0x00000000, ++ 0xC10, 0x00000100, ++ 0xC14, 0x01000000, ++ 0xC1C, 0x40000003, ++ 0xC20, 0x12121212, ++ 0xC24, 0x12121212, ++ 0xC28, 0x12121212, ++ 0xC2C, 0x12121212, ++ 0xC30, 0x12121212, ++ 0xC34, 0x12121212, ++ 0xC38, 0x12121212, ++ 0xC3C, 0x12121212, ++ 0xC40, 0x12121212, ++ 0xC44, 0x12121212, ++ 0xC48, 0x12121212, ++ 0xC4C, 0x12121212, ++ 0xC50, 0x00000020, ++ 0xC54, 0x0008121C, ++ 0xC58, 0x30000C1C, ++ 0xC5C, 0x00000058, ++ 0xC60, 0x34344443, ++ 0xC64, 0x07003333, ++ 0x80000008, 0x00000000, 0x40000000, 0x00000000, ++ 0xC68, 0x59791979, ++ 0x90000008, 0x05000000, 0x40000000, 0x00000000, ++ 0xC68, 0x59791979, ++ 0x90000002, 0x00000000, 0x40000000, 0x00000000, ++ 0xC68, 0x59791979, ++ 0x90000004, 0x00000000, 0x40000000, 0x00000000, ++ 0xC68, 0x59791979, ++ 0x90000001, 0x00000000, 0x40000000, 0x00000000, ++ 0xC68, 0x59791979, ++ 0x90000001, 0x00000005, 0x40000000, 0x00000000, ++ 0xC68, 0x59791979, ++ 0xA0000000, 0x00000000, ++ 0xC68, 0x59799979, ++ 0xB0000000, 0x00000000, ++ 0xC6C, 0x59795979, ++ 0xC70, 0x19795979, ++ 0xC74, 0x19795979, ++ 0xC78, 0x19791979, ++ 0xC7C, 0x19791979, ++ 0xC80, 0x19791979, ++ 0xC84, 0x19791979, ++ 0xC94, 0x0100005C, ++ 0xC98, 0x00000000, ++ 0xC9C, 0x00000000, ++ 0xCA0, 0x00000029, ++ 0xCA4, 0x08040201, ++ 0xCA8, 0x80402010, ++ 0xCB0, 0x77547777, ++ 0xCB4, 0x00000077, ++ 0xCB8, 0x00508242, ++ 0xE00, 0x00000007, ++ 0xE04, 0x00042020, ++ 0xE08, 0x80410231, ++ 0xE0C, 0x00000000, ++ 0xE10, 0x00000100, ++ 0xE14, 0x01000000, ++ 0xE1C, 0x40000003, ++ 0xE20, 0x12121212, ++ 0xE24, 0x12121212, ++ 0xE28, 0x12121212, ++ 0xE2C, 0x12121212, ++ 0xE30, 0x12121212, ++ 0xE34, 0x12121212, ++ 0xE38, 0x12121212, ++ 0xE3C, 0x12121212, ++ 0xE40, 0x12121212, ++ 0xE44, 0x12121212, ++ 0xE48, 0x12121212, ++ 0xE4C, 0x12121212, ++ 0xE50, 0x00000020, ++ 0xE54, 0x0008121C, ++ 0xE58, 0x30000C1C, ++ 0xE5C, 0x00000058, ++ 0xE60, 0x34344443, ++ 0xE64, 0x07003333, ++ 0xE68, 0x59791979, ++ 0xE6C, 0x59795979, ++ 0xE70, 0x19795979, ++ 0xE74, 0x19795979, ++ 0xE78, 0x19791979, ++ 0xE7C, 0x19791979, ++ 0xE80, 0x19791979, ++ 0xE84, 0x19791979, ++ 0xE94, 0x0100005C, ++ 0xE98, 0x00000000, ++ 0xE9C, 0x00000000, ++ 0xEA0, 0x00000029, ++ 0xEA4, 0x08040201, ++ 0xEA8, 0x80402010, ++ 0xEB0, 0x77547777, ++ 0xEB4, 0x00000077, ++ 0xEB8, 0x00508242, ++}; ++ ++RTW_DECL_TABLE_PHY_COND(rtw8812a_bb, rtw_phy_cfg_bb); ++ ++static const struct rtw_phy_pg_cfg_pair rtw8812a_bb_pg[] = { ++ { 0, 0, 0, 0x00000c20, 0xffffffff, 0x34363840, }, ++ { 0, 0, 0, 0x00000c24, 0xffffffff, 0x42424444, }, ++ { 0, 0, 0, 0x00000c28, 0xffffffff, 0x30323638, }, ++ { 0, 0, 0, 0x00000c2c, 0xffffffff, 0x40424444, }, ++ { 0, 0, 0, 0x00000c30, 0xffffffff, 0x28303236, }, ++ { 0, 0, 1, 0x00000c34, 0xffffffff, 0x38404242, }, ++ { 0, 0, 1, 0x00000c38, 0xffffffff, 0x26283034, }, ++ { 0, 0, 0, 0x00000c3c, 0xffffffff, 0x40424444, }, ++ { 0, 0, 0, 0x00000c40, 0xffffffff, 0x28303236, }, ++ { 0, 0, 0, 0x00000c44, 0xffffffff, 0x42422426, }, ++ { 0, 0, 1, 0x00000c48, 0xffffffff, 0x30343840, }, ++ { 0, 0, 1, 0x00000c4c, 0xffffffff, 0x22242628, }, ++ { 0, 1, 0, 0x00000e20, 0xffffffff, 0x34363840, }, ++ { 0, 1, 0, 0x00000e24, 0xffffffff, 0x42424444, }, ++ { 0, 1, 0, 0x00000e28, 0xffffffff, 0x30323638, }, ++ { 0, 1, 0, 0x00000e2c, 0xffffffff, 0x40424444, }, ++ { 0, 1, 0, 0x00000e30, 0xffffffff, 0x28303236, }, ++ { 0, 1, 1, 0x00000e34, 0xffffffff, 0x38404242, }, ++ { 0, 1, 1, 0x00000e38, 0xffffffff, 0x26283034, }, ++ { 0, 1, 0, 0x00000e3c, 0xffffffff, 0x40424444, }, ++ { 0, 1, 0, 0x00000e40, 0xffffffff, 0x28303236, }, ++ { 0, 1, 0, 0x00000e44, 0xffffffff, 0x42422426, }, ++ { 0, 1, 1, 0x00000e48, 0xffffffff, 0x30343840, }, ++ { 0, 1, 1, 0x00000e4c, 0xffffffff, 0x22242628, }, ++ { 1, 0, 0, 0x00000c24, 0xffffffff, 0x42424444, }, ++ { 1, 0, 0, 0x00000c28, 0xffffffff, 0x30323640, }, ++ { 1, 0, 0, 0x00000c2c, 0xffffffff, 0x40424444, }, ++ { 1, 0, 0, 0x00000c30, 0xffffffff, 0x28303236, }, ++ { 1, 0, 1, 0x00000c34, 0xffffffff, 0x38404242, }, ++ { 1, 0, 1, 0x00000c38, 0xffffffff, 0x26283034, }, ++ { 1, 0, 0, 0x00000c3c, 0xffffffff, 0x40424444, }, ++ { 1, 0, 0, 0x00000c40, 0xffffffff, 0x28303236, }, ++ { 1, 0, 0, 0x00000c44, 0xffffffff, 0x42422426, }, ++ { 1, 0, 1, 0x00000c48, 0xffffffff, 0x30343840, }, ++ { 1, 0, 1, 0x00000c4c, 0xffffffff, 0x22242628, }, ++ { 1, 1, 0, 0x00000e24, 0xffffffff, 0x42424444, }, ++ { 1, 1, 0, 0x00000e28, 0xffffffff, 0x30323640, }, ++ { 1, 1, 0, 0x00000e2c, 0xffffffff, 0x40424444, }, ++ { 1, 1, 0, 0x00000e30, 0xffffffff, 0x28303236, }, ++ { 1, 1, 1, 0x00000e34, 0xffffffff, 0x38404242, }, ++ { 1, 1, 1, 0x00000e38, 0xffffffff, 0x26283034, }, ++ { 1, 1, 0, 0x00000e3c, 0xffffffff, 0x40424444, }, ++ { 1, 1, 0, 0x00000e40, 0xffffffff, 0x28303236, }, ++ { 1, 1, 0, 0x00000e44, 0xffffffff, 0x42422426, }, ++ { 1, 1, 1, 0x00000e48, 0xffffffff, 0x30343840, }, ++ { 1, 1, 1, 0x00000e4c, 0xffffffff, 0x22242628, }, ++}; ++ ++RTW_DECL_TABLE_BB_PG(rtw8812a_bb_pg); ++ ++static const struct rtw_phy_pg_cfg_pair rtw8812a_bb_pg_rfe3[] = { ++ { 0, 0, 0, 0x00000c20, 0xffffffff, 0x34343434, }, ++ { 0, 0, 0, 0x00000c24, 0xffffffff, 0x32323232, }, ++ { 0, 0, 0, 0x00000c28, 0xffffffff, 0x28303232, }, ++ { 0, 0, 0, 0x00000c2c, 0xffffffff, 0x32323232, }, ++ { 0, 0, 0, 0x00000c30, 0xffffffff, 0x28303232, }, ++ { 0, 0, 1, 0x00000c34, 0xffffffff, 0x32323232, }, ++ { 0, 0, 1, 0x00000c38, 0xffffffff, 0x26283032, }, ++ { 0, 0, 0, 0x00000c3c, 0xffffffff, 0x32323232, }, ++ { 0, 0, 0, 0x00000c40, 0xffffffff, 0x28303232, }, ++ { 0, 0, 0, 0x00000c44, 0xffffffff, 0x32322426, }, ++ { 0, 0, 1, 0x00000c48, 0xffffffff, 0x32323232, }, ++ { 0, 0, 1, 0x00000c4c, 0xffffffff, 0x24262830, }, ++ { 0, 1, 0, 0x00000e20, 0xffffffff, 0x34343434, }, ++ { 0, 1, 0, 0x00000e24, 0xffffffff, 0x32323232, }, ++ { 0, 1, 0, 0x00000e28, 0xffffffff, 0x28303232, }, ++ { 0, 1, 0, 0x00000e2c, 0xffffffff, 0x32323232, }, ++ { 0, 1, 0, 0x00000e30, 0xffffffff, 0x28303232, }, ++ { 0, 1, 1, 0x00000e34, 0xffffffff, 0x32323232, }, ++ { 0, 1, 1, 0x00000e38, 0xffffffff, 0x26283032, }, ++ { 0, 1, 0, 0x00000e3c, 0xffffffff, 0x32323232, }, ++ { 0, 1, 0, 0x00000e40, 0xffffffff, 0x28303232, }, ++ { 0, 1, 0, 0x00000e44, 0xffffffff, 0x32322426, }, ++ { 0, 1, 1, 0x00000e48, 0xffffffff, 0x32323232, }, ++ { 0, 1, 1, 0x00000e4c, 0xffffffff, 0x24262830, }, ++ { 1, 0, 0, 0x00000c24, 0xffffffff, 0x32323232, }, ++ { 1, 0, 0, 0x00000c28, 0xffffffff, 0x28303232, }, ++ { 1, 0, 0, 0x00000c2c, 0xffffffff, 0x32323232, }, ++ { 1, 0, 0, 0x00000c30, 0xffffffff, 0x24262830, }, ++ { 1, 0, 1, 0x00000c34, 0xffffffff, 0x32323232, }, ++ { 1, 0, 1, 0x00000c38, 0xffffffff, 0x24262830, }, ++ { 1, 0, 0, 0x00000c3c, 0xffffffff, 0x32323232, }, ++ { 1, 0, 0, 0x00000c40, 0xffffffff, 0x24262830, }, ++ { 1, 0, 0, 0x00000c44, 0xffffffff, 0x32322222, }, ++ { 1, 0, 1, 0x00000c48, 0xffffffff, 0x28303232, }, ++ { 1, 0, 1, 0x00000c4c, 0xffffffff, 0x22222426, }, ++ { 1, 1, 0, 0x00000e24, 0xffffffff, 0x32323232, }, ++ { 1, 1, 0, 0x00000e28, 0xffffffff, 0x28303232, }, ++ { 1, 1, 0, 0x00000e2c, 0xffffffff, 0x32323232, }, ++ { 1, 1, 0, 0x00000e30, 0xffffffff, 0x24262830, }, ++ { 1, 1, 1, 0x00000e34, 0xffffffff, 0x32323232, }, ++ { 1, 1, 1, 0x00000e38, 0xffffffff, 0x24262830, }, ++ { 1, 1, 0, 0x00000e3c, 0xffffffff, 0x32323232, }, ++ { 1, 1, 0, 0x00000e40, 0xffffffff, 0x24262830, }, ++ { 1, 1, 0, 0x00000e44, 0xffffffff, 0x32322222, }, ++ { 1, 1, 1, 0x00000e48, 0xffffffff, 0x28303232, }, ++ { 1, 1, 1, 0x00000e4c, 0xffffffff, 0x22222426, }, ++}; ++ ++RTW_DECL_TABLE_BB_PG(rtw8812a_bb_pg_rfe3); ++ ++static const u32 rtw8812a_rf_a[] = { ++ 0x000, 0x00010000, ++ 0x018, 0x0001712A, ++ 0x056, 0x00051CF2, ++ 0x066, 0x00040000, ++ 0x01E, 0x00080000, ++ 0x089, 0x00000080, ++ 0x80000001, 0x00000000, 0x40000000, 0x00000000, ++ 0x086, 0x00014B3A, ++ 0x90000001, 0x00000005, 0x40000000, 0x00000000, ++ 0x086, 0x00014B3A, ++ 0xA0000000, 0x00000000, ++ 0x086, 0x00014B38, ++ 0xB0000000, 0x00000000, ++ 0x80000004, 0x00000000, 0x40000000, 0x00000000, ++ 0x08B, 0x00080180, ++ 0xA0000000, 0x00000000, ++ 0x08B, 0x00087180, ++ 0xB0000000, 0x00000000, ++ 0x0B1, 0x0001FC1A, ++ 0x0B3, 0x000F0810, ++ 0x0B4, 0x0001A78D, ++ 0x0BA, 0x00086180, ++ 0x018, 0x00000006, ++ 0x0EF, 0x00002000, ++ 0x80000001, 0x00000000, 0x40000000, 0x00000000, ++ 0x03B, 0x0003F218, ++ 0x03B, 0x00030A58, ++ 0x03B, 0x0002FA58, ++ 0x03B, 0x00022590, ++ 0x03B, 0x0001FA50, ++ 0x03B, 0x00010248, ++ 0x03B, 0x00008240, ++ 0x90000001, 0x00000005, 0x40000000, 0x00000000, ++ 0x03B, 0x0003F218, ++ 0x03B, 0x00030A58, ++ 0x03B, 0x0002FA58, ++ 0x03B, 0x00022590, ++ 0x03B, 0x0001FA50, ++ 0x03B, 0x00010248, ++ 0x03B, 0x00008240, ++ 0xA0000000, 0x00000000, ++ 0x03B, 0x00038A58, ++ 0x03B, 0x00037A58, ++ 0x03B, 0x0002A590, ++ 0x03B, 0x00027A50, ++ 0x03B, 0x00018248, ++ 0x03B, 0x00010240, ++ 0x03B, 0x00008240, ++ 0xB0000000, 0x00000000, ++ 0x0EF, 0x00000100, ++ 0x80000002, 0x00000000, 0x40000000, 0x00000000, ++ 0x034, 0x0000A4EE, ++ 0x034, 0x00009076, ++ 0x034, 0x00008073, ++ 0x034, 0x00007070, ++ 0x034, 0x0000606D, ++ 0x034, 0x0000506A, ++ 0x034, 0x00004049, ++ 0x034, 0x00003046, ++ 0x034, 0x00002028, ++ 0x034, 0x00001025, ++ 0x034, 0x00000022, ++ 0xA0000000, 0x00000000, ++ 0x034, 0x0000ADF4, ++ 0x034, 0x00009DF1, ++ 0x034, 0x00008DEE, ++ 0x034, 0x00007DEB, ++ 0x034, 0x00006DE8, ++ 0x034, 0x00005DE5, ++ 0x034, 0x00004DE2, ++ 0x034, 0x00003CE6, ++ 0x034, 0x000024E7, ++ 0x034, 0x000014E4, ++ 0x034, 0x000004E1, ++ 0xB0000000, 0x00000000, ++ 0x0EF, 0x00000000, ++ 0x0EF, 0x000020A2, ++ 0x0DF, 0x00000080, ++ 0x035, 0x00000192, ++ 0x035, 0x00008192, ++ 0x035, 0x00010192, ++ 0x036, 0x00000024, ++ 0x036, 0x00008024, ++ 0x036, 0x00010024, ++ 0x036, 0x00018024, ++ 0x0EF, 0x00000000, ++ 0x051, 0x00000C21, ++ 0x052, 0x000006D9, ++ 0x053, 0x000FC649, ++ 0x054, 0x0000017E, ++ 0x0EF, 0x00000002, ++ 0x008, 0x00008400, ++ 0x018, 0x0001712A, ++ 0x0EF, 0x00001000, ++ 0x03A, 0x00000080, ++ 0x03B, 0x0003A02C, ++ 0x03C, 0x00004000, ++ 0x03A, 0x00000400, ++ 0x03B, 0x0003202C, ++ 0x03C, 0x00010000, ++ 0x03A, 0x000000A0, ++ 0x03B, 0x0002B064, ++ 0x03C, 0x00004000, ++ 0x03A, 0x000000D8, ++ 0x03B, 0x00023070, ++ 0x03C, 0x00004000, ++ 0x03A, 0x00000468, ++ 0x03B, 0x0001B870, ++ 0x03C, 0x00010000, ++ 0x03A, 0x00000098, ++ 0x03B, 0x00012085, ++ 0x03C, 0x000E4000, ++ 0x03A, 0x00000418, ++ 0x03B, 0x0000A080, ++ 0x03C, 0x000F0000, ++ 0x03A, 0x00000418, ++ 0x03B, 0x00002080, ++ 0x03C, 0x00010000, ++ 0x03A, 0x00000080, ++ 0x03B, 0x0007A02C, ++ 0x03C, 0x00004000, ++ 0x03A, 0x00000400, ++ 0x03B, 0x0007202C, ++ 0x03C, 0x00010000, ++ 0x03A, 0x000000A0, ++ 0x03B, 0x0006B064, ++ 0x03C, 0x00004000, ++ 0x03A, 0x000000D8, ++ 0x03B, 0x00063070, ++ 0x03C, 0x00004000, ++ 0x03A, 0x00000468, ++ 0x03B, 0x0005B870, ++ 0x03C, 0x00010000, ++ 0x03A, 0x00000098, ++ 0x03B, 0x00052085, ++ 0x03C, 0x000E4000, ++ 0x03A, 0x00000418, ++ 0x03B, 0x0004A080, ++ 0x03C, 0x000F0000, ++ 0x03A, 0x00000418, ++ 0x03B, 0x00042080, ++ 0x03C, 0x00010000, ++ 0x03A, 0x00000080, ++ 0x03B, 0x000BA02C, ++ 0x03C, 0x00004000, ++ 0x03A, 0x00000400, ++ 0x03B, 0x000B202C, ++ 0x03C, 0x00010000, ++ 0x03A, 0x000000A0, ++ 0x03B, 0x000AB064, ++ 0x03C, 0x00004000, ++ 0x03A, 0x000000D8, ++ 0x03B, 0x000A3070, ++ 0x03C, 0x00004000, ++ 0x03A, 0x00000468, ++ 0x03B, 0x0009B870, ++ 0x03C, 0x00010000, ++ 0x03A, 0x00000098, ++ 0x03B, 0x00092085, ++ 0x03C, 0x000E4000, ++ 0x03A, 0x00000418, ++ 0x03B, 0x0008A080, ++ 0x03C, 0x000F0000, ++ 0x03A, 0x00000418, ++ 0x03B, 0x00082080, ++ 0x03C, 0x00010000, ++ 0x0EF, 0x00001100, ++ 0x80000008, 0x00000000, 0x40000000, 0x00000000, ++ 0x034, 0x0004A0B2, ++ 0x034, 0x000490AF, ++ 0x034, 0x00048070, ++ 0x034, 0x0004706D, ++ 0x034, 0x00046050, ++ 0x034, 0x0004504D, ++ 0x034, 0x0004404A, ++ 0x034, 0x00043047, ++ 0x034, 0x0004200A, ++ 0x034, 0x00041007, ++ 0x034, 0x00040004, ++ 0x90000008, 0x05000000, 0x40000000, 0x00000000, ++ 0x034, 0x0004A0B2, ++ 0x034, 0x000490AF, ++ 0x034, 0x00048070, ++ 0x034, 0x0004706D, ++ 0x034, 0x0004604D, ++ 0x034, 0x0004504A, ++ 0x034, 0x00044047, ++ 0x034, 0x00043044, ++ 0x034, 0x00042007, ++ 0x034, 0x00041004, ++ 0x034, 0x00040001, ++ 0xA0000000, 0x00000000, ++ 0x034, 0x0004ADF5, ++ 0x034, 0x00049DF2, ++ 0x034, 0x00048DEF, ++ 0x034, 0x00047DEC, ++ 0x034, 0x00046DE9, ++ 0x034, 0x00045DE6, ++ 0x034, 0x00044DE3, ++ 0x034, 0x000438C8, ++ 0x034, 0x000428C5, ++ 0x034, 0x000418C2, ++ 0x034, 0x000408C0, ++ 0xB0000000, 0x00000000, ++ 0x80000008, 0x00000000, 0x40000000, 0x00000000, ++ 0x034, 0x0002A0B2, ++ 0x034, 0x000290AF, ++ 0x034, 0x00028070, ++ 0x034, 0x0002706D, ++ 0x034, 0x00026050, ++ 0x034, 0x0002504D, ++ 0x034, 0x0002404A, ++ 0x034, 0x00023047, ++ 0x034, 0x0002200A, ++ 0x034, 0x00021007, ++ 0x034, 0x00020004, ++ 0x90000008, 0x05000000, 0x40000000, 0x00000000, ++ 0x034, 0x0002A0B4, ++ 0x034, 0x000290B1, ++ 0x034, 0x00028072, ++ 0x034, 0x0002706F, ++ 0x034, 0x0002604F, ++ 0x034, 0x0002504C, ++ 0x034, 0x00024049, ++ 0x034, 0x00023046, ++ 0x034, 0x00022009, ++ 0x034, 0x00021006, ++ 0x034, 0x00020003, ++ 0xA0000000, 0x00000000, ++ 0x034, 0x0002ADF5, ++ 0x034, 0x00029DF2, ++ 0x034, 0x00028DEF, ++ 0x034, 0x00027DEC, ++ 0x034, 0x00026DE9, ++ 0x034, 0x00025DE6, ++ 0x034, 0x00024DE3, ++ 0x034, 0x000238C8, ++ 0x034, 0x000228C5, ++ 0x034, 0x000218C2, ++ 0x034, 0x000208C0, ++ 0xB0000000, 0x00000000, ++ 0x80000008, 0x00000000, 0x40000000, 0x00000000, ++ 0x034, 0x0000A0B2, ++ 0x034, 0x000090AF, ++ 0x034, 0x00008070, ++ 0x034, 0x0000706D, ++ 0x034, 0x00006050, ++ 0x034, 0x0000504D, ++ 0x034, 0x0000404A, ++ 0x034, 0x00003047, ++ 0x034, 0x0000200A, ++ 0x034, 0x00001007, ++ 0x034, 0x00000004, ++ 0x90000008, 0x05000000, 0x40000000, 0x00000000, ++ 0x034, 0x0000A0B2, ++ 0x034, 0x000090AF, ++ 0x034, 0x00008070, ++ 0x034, 0x0000706D, ++ 0x034, 0x0000604D, ++ 0x034, 0x0000504A, ++ 0x034, 0x00004047, ++ 0x034, 0x00003044, ++ 0x034, 0x00002007, ++ 0x034, 0x00001004, ++ 0x034, 0x00000001, ++ 0xA0000000, 0x00000000, ++ 0x034, 0x0000AFF7, ++ 0x034, 0x00009DF7, ++ 0x034, 0x00008DF4, ++ 0x034, 0x00007DF1, ++ 0x034, 0x00006DEE, ++ 0x034, 0x00005DEB, ++ 0x034, 0x00004DE8, ++ 0x034, 0x000038CC, ++ 0x034, 0x000028C9, ++ 0x034, 0x000018C6, ++ 0x034, 0x000008C3, ++ 0xB0000000, 0x00000000, ++ 0x0EF, 0x00000000, ++ 0x80000008, 0x00000000, 0x40000000, 0x00000000, ++ 0x018, 0x0001712A, ++ 0x0EF, 0x00000040, ++ 0x035, 0x000001D4, ++ 0x035, 0x000081D4, ++ 0x035, 0x000101D4, ++ 0x035, 0x000201B4, ++ 0x035, 0x000281B4, ++ 0x035, 0x000301B4, ++ 0x035, 0x000401B4, ++ 0x035, 0x000481B4, ++ 0x035, 0x000501B4, ++ 0x90000008, 0x05000000, 0x40000000, 0x00000000, ++ 0x018, 0x0001712A, ++ 0x0EF, 0x00000040, ++ 0x035, 0x000001D4, ++ 0x035, 0x000081D4, ++ 0x035, 0x000101D4, ++ 0x035, 0x000201B4, ++ 0x035, 0x000281B4, ++ 0x035, 0x000301B4, ++ 0x035, 0x000401B4, ++ 0x035, 0x000481B4, ++ 0x035, 0x000501B4, ++ 0xA0000000, 0x00000000, ++ 0x018, 0x0001712A, ++ 0x0EF, 0x00000040, ++ 0x035, 0x00000188, ++ 0x035, 0x00008147, ++ 0x035, 0x00010147, ++ 0x035, 0x000201D7, ++ 0x035, 0x000281D7, ++ 0x035, 0x000301D7, ++ 0x035, 0x000401D8, ++ 0x035, 0x000481D8, ++ 0x035, 0x000501D8, ++ 0xB0000000, 0x00000000, ++ 0x0EF, 0x00000000, ++ 0x80000008, 0x00000000, 0x40000000, 0x00000000, ++ 0x018, 0x0001712A, ++ 0x0EF, 0x00000010, ++ 0x036, 0x00004BFB, ++ 0x036, 0x0000CBFB, ++ 0x036, 0x00014BFB, ++ 0x036, 0x0001CBFB, ++ 0x036, 0x00024F4B, ++ 0x036, 0x0002CF4B, ++ 0x036, 0x00034F4B, ++ 0x036, 0x0003CF4B, ++ 0x036, 0x00044F4B, ++ 0x036, 0x0004CF4B, ++ 0x036, 0x00054F4B, ++ 0x036, 0x0005CF4B, ++ 0x90000008, 0x05000000, 0x40000000, 0x00000000, ++ 0x018, 0x0001712A, ++ 0x0EF, 0x00000010, ++ 0x036, 0x00004BFB, ++ 0x036, 0x0000CBFB, ++ 0x036, 0x00014BFB, ++ 0x036, 0x0001CBFB, ++ 0x036, 0x00024F4B, ++ 0x036, 0x0002CF4B, ++ 0x036, 0x00034F4B, ++ 0x036, 0x0003CF4B, ++ 0x036, 0x00044F4B, ++ 0x036, 0x0004CF4B, ++ 0x036, 0x00054F4B, ++ 0x036, 0x0005CF4B, ++ 0xA0000000, 0x00000000, ++ 0x018, 0x0001712A, ++ 0x0EF, 0x00000010, ++ 0x036, 0x00084EB4, ++ 0x036, 0x0008CC35, ++ 0x036, 0x00094C35, ++ 0x036, 0x0009CC35, ++ 0x036, 0x000A4C35, ++ 0x036, 0x000ACC35, ++ 0x036, 0x000B4C35, ++ 0x036, 0x000BCC35, ++ 0x036, 0x000C4C34, ++ 0x036, 0x000CCC35, ++ 0x036, 0x000D4C35, ++ 0x036, 0x000DCC35, ++ 0xB0000000, 0x00000000, ++ 0x0EF, 0x00000000, ++ 0x0EF, 0x00000008, ++ 0x80000008, 0x00000000, 0x40000000, 0x00000000, ++ 0x03C, 0x000002CC, ++ 0x03C, 0x00000522, ++ 0x03C, 0x00000902, ++ 0x90000008, 0x05000000, 0x40000000, 0x00000000, ++ 0x03C, 0x000002CC, ++ 0x03C, 0x00000522, ++ 0x03C, 0x00000902, ++ 0xA0000000, 0x00000000, ++ 0x03C, 0x000002A8, ++ 0x03C, 0x000005A2, ++ 0x03C, 0x00000880, ++ 0xB0000000, 0x00000000, ++ 0x0EF, 0x00000000, ++ 0x018, 0x0001712A, ++ 0x0EF, 0x00000002, ++ 0x0DF, 0x00000080, ++ 0x01F, 0x00000064, ++ 0x80000008, 0x00000000, 0x40000000, 0x00000000, ++ 0x061, 0x000FDD43, ++ 0x062, 0x00038F4B, ++ 0x063, 0x00032117, ++ 0x064, 0x000194AC, ++ 0x065, 0x000931D1, ++ 0x90000008, 0x05000000, 0x40000000, 0x00000000, ++ 0x061, 0x000FDD43, ++ 0x062, 0x00038F4B, ++ 0x063, 0x00032117, ++ 0x064, 0x000194AC, ++ 0x065, 0x000931D2, ++ 0xA0000000, 0x00000000, ++ 0x061, 0x000E5D53, ++ 0x062, 0x00038FCD, ++ 0x063, 0x000114EB, ++ 0x064, 0x000196AC, ++ 0x065, 0x000911D7, ++ 0xB0000000, 0x00000000, ++ 0x008, 0x00008400, ++ 0x01C, 0x000739D2, ++ 0x0B4, 0x0001E78D, ++ 0x018, 0x0001F12A, ++ 0xFFE, 0x00000000, ++ 0xFFE, 0x00000000, ++ 0xFFE, 0x00000000, ++ 0xFFE, 0x00000000, ++ 0x0B4, 0x0001A78D, ++ 0x018, 0x0001712A, ++}; ++ ++RTW_DECL_TABLE_RF_RADIO(rtw8812a_rf_a, A); ++ ++static const u32 rtw8812a_rf_b[] = { ++ 0x056, 0x00051CF2, ++ 0x066, 0x00040000, ++ 0x089, 0x00000080, ++ 0x80000001, 0x00000000, 0x40000000, 0x00000000, ++ 0x086, 0x00014B3A, ++ 0x90000001, 0x00000005, 0x40000000, 0x00000000, ++ 0x086, 0x00014B3A, ++ 0xA0000000, 0x00000000, ++ 0x086, 0x00014B38, ++ 0xB0000000, 0x00000000, ++ 0x80000004, 0x00000000, 0x40000000, 0x00000000, ++ 0x08B, 0x00080180, ++ 0xA0000000, 0x00000000, ++ 0x08B, 0x00087180, ++ 0xB0000000, 0x00000000, ++ 0x018, 0x00000006, ++ 0x0EF, 0x00002000, ++ 0x80000001, 0x00000000, 0x40000000, 0x00000000, ++ 0x03B, 0x0003F218, ++ 0x03B, 0x00030A58, ++ 0x03B, 0x0002FA58, ++ 0x03B, 0x00022590, ++ 0x03B, 0x0001FA50, ++ 0x03B, 0x00010248, ++ 0x03B, 0x00008240, ++ 0x90000001, 0x00000005, 0x40000000, 0x00000000, ++ 0x03B, 0x0003F218, ++ 0x03B, 0x00030A58, ++ 0x03B, 0x0002FA58, ++ 0x03B, 0x00022590, ++ 0x03B, 0x0001FA50, ++ 0x03B, 0x00010248, ++ 0x03B, 0x00008240, ++ 0xA0000000, 0x00000000, ++ 0x03B, 0x00038A58, ++ 0x03B, 0x00037A58, ++ 0x03B, 0x0002A590, ++ 0x03B, 0x00027A50, ++ 0x03B, 0x00018248, ++ 0x03B, 0x00010240, ++ 0x03B, 0x00008240, ++ 0xB0000000, 0x00000000, ++ 0x0EF, 0x00000100, ++ 0x80000002, 0x00000000, 0x40000000, 0x00000000, ++ 0x034, 0x0000A4EE, ++ 0x034, 0x00009076, ++ 0x034, 0x00008073, ++ 0x034, 0x00007070, ++ 0x034, 0x0000606D, ++ 0x034, 0x0000506A, ++ 0x034, 0x00004049, ++ 0x034, 0x00003046, ++ 0x034, 0x00002028, ++ 0x034, 0x00001025, ++ 0x034, 0x00000022, ++ 0xA0000000, 0x00000000, ++ 0x034, 0x0000ADF4, ++ 0x034, 0x00009DF1, ++ 0x034, 0x00008DEE, ++ 0x034, 0x00007DEB, ++ 0x034, 0x00006DE8, ++ 0x034, 0x00005DE5, ++ 0x034, 0x00004DE2, ++ 0x034, 0x00003CE6, ++ 0x034, 0x000024E7, ++ 0x034, 0x000014E4, ++ 0x034, 0x000004E1, ++ 0xB0000000, 0x00000000, ++ 0x0EF, 0x00000000, ++ 0x0EF, 0x000020A2, ++ 0x0DF, 0x00000080, ++ 0x035, 0x00000192, ++ 0x035, 0x00008192, ++ 0x035, 0x00010192, ++ 0x036, 0x00000024, ++ 0x036, 0x00008024, ++ 0x036, 0x00010024, ++ 0x036, 0x00018024, ++ 0x0EF, 0x00000000, ++ 0x051, 0x00000C21, ++ 0x052, 0x000006D9, ++ 0x053, 0x000FC649, ++ 0x054, 0x0000017E, ++ 0x0EF, 0x00000002, ++ 0x008, 0x00008400, ++ 0x018, 0x0001712A, ++ 0x0EF, 0x00001000, ++ 0x03A, 0x00000080, ++ 0x03B, 0x0003A02C, ++ 0x03C, 0x00004000, ++ 0x03A, 0x00000400, ++ 0x03B, 0x0003202C, ++ 0x03C, 0x00010000, ++ 0x03A, 0x000000A0, ++ 0x03B, 0x0002B064, ++ 0x03C, 0x00004000, ++ 0x03A, 0x000000D8, ++ 0x03B, 0x00023070, ++ 0x03C, 0x00004000, ++ 0x03A, 0x00000468, ++ 0x03B, 0x0001B870, ++ 0x03C, 0x00010000, ++ 0x03A, 0x00000098, ++ 0x03B, 0x00012085, ++ 0x03C, 0x000E4000, ++ 0x03A, 0x00000418, ++ 0x03B, 0x0000A080, ++ 0x03C, 0x000F0000, ++ 0x03A, 0x00000418, ++ 0x03B, 0x00002080, ++ 0x03C, 0x00010000, ++ 0x03A, 0x00000080, ++ 0x03B, 0x0007A02C, ++ 0x03C, 0x00004000, ++ 0x03A, 0x00000400, ++ 0x03B, 0x0007202C, ++ 0x03C, 0x00010000, ++ 0x03A, 0x000000A0, ++ 0x03B, 0x0006B064, ++ 0x03C, 0x00004000, ++ 0x03A, 0x000000D8, ++ 0x03B, 0x00063070, ++ 0x03C, 0x00004000, ++ 0x03A, 0x00000468, ++ 0x03B, 0x0005B870, ++ 0x03C, 0x00010000, ++ 0x03A, 0x00000098, ++ 0x03B, 0x00052085, ++ 0x03C, 0x000E4000, ++ 0x03A, 0x00000418, ++ 0x03B, 0x0004A080, ++ 0x03C, 0x000F0000, ++ 0x03A, 0x00000418, ++ 0x03B, 0x00042080, ++ 0x03C, 0x00010000, ++ 0x03A, 0x00000080, ++ 0x03B, 0x000BA02C, ++ 0x03C, 0x00004000, ++ 0x03A, 0x00000400, ++ 0x03B, 0x000B202C, ++ 0x03C, 0x00010000, ++ 0x03A, 0x000000A0, ++ 0x03B, 0x000AB064, ++ 0x03C, 0x00004000, ++ 0x03A, 0x000000D8, ++ 0x03B, 0x000A3070, ++ 0x03C, 0x00004000, ++ 0x03A, 0x00000468, ++ 0x03B, 0x0009B870, ++ 0x03C, 0x00010000, ++ 0x03A, 0x00000098, ++ 0x03B, 0x00092085, ++ 0x03C, 0x000E4000, ++ 0x03A, 0x00000418, ++ 0x03B, 0x0008A080, ++ 0x03C, 0x000F0000, ++ 0x03A, 0x00000418, ++ 0x03B, 0x00082080, ++ 0x03C, 0x00010000, ++ 0x0EF, 0x00001100, ++ 0x80000008, 0x00000000, 0x40000000, 0x00000000, ++ 0x034, 0x0004A0B2, ++ 0x034, 0x000490AF, ++ 0x034, 0x00048070, ++ 0x034, 0x0004706D, ++ 0x034, 0x00046050, ++ 0x034, 0x0004504D, ++ 0x034, 0x0004404A, ++ 0x034, 0x00043047, ++ 0x034, 0x0004200A, ++ 0x034, 0x00041007, ++ 0x034, 0x00040004, ++ 0x90000008, 0x05000000, 0x40000000, 0x00000000, ++ 0x034, 0x0004A0B1, ++ 0x034, 0x000490AE, ++ 0x034, 0x0004806F, ++ 0x034, 0x0004706C, ++ 0x034, 0x0004604C, ++ 0x034, 0x00045049, ++ 0x034, 0x00044046, ++ 0x034, 0x00043043, ++ 0x034, 0x00042006, ++ 0x034, 0x00041003, ++ 0x034, 0x00040000, ++ 0xA0000000, 0x00000000, ++ 0x034, 0x0004ADF5, ++ 0x034, 0x00049DF2, ++ 0x034, 0x00048DEF, ++ 0x034, 0x00047DEC, ++ 0x034, 0x00046DE9, ++ 0x034, 0x00045DE6, ++ 0x034, 0x00044DE3, ++ 0x034, 0x000438C8, ++ 0x034, 0x000428C5, ++ 0x034, 0x000418C2, ++ 0x034, 0x000408C0, ++ 0xB0000000, 0x00000000, ++ 0x80000008, 0x00000000, 0x40000000, 0x00000000, ++ 0x034, 0x0002A0B2, ++ 0x034, 0x000290AF, ++ 0x034, 0x00028070, ++ 0x034, 0x0002706D, ++ 0x034, 0x00026050, ++ 0x034, 0x0002504D, ++ 0x034, 0x0002404A, ++ 0x034, 0x00023047, ++ 0x034, 0x0002200A, ++ 0x034, 0x00021007, ++ 0x034, 0x00020004, ++ 0x90000008, 0x05000000, 0x40000000, 0x00000000, ++ 0x034, 0x0002A0B3, ++ 0x034, 0x000290B0, ++ 0x034, 0x00028071, ++ 0x034, 0x0002706E, ++ 0x034, 0x0002604E, ++ 0x034, 0x0002504B, ++ 0x034, 0x00024048, ++ 0x034, 0x00023045, ++ 0x034, 0x00022008, ++ 0x034, 0x00021005, ++ 0x034, 0x00020002, ++ 0xA0000000, 0x00000000, ++ 0x034, 0x0002ADF5, ++ 0x034, 0x00029DF2, ++ 0x034, 0x00028DEF, ++ 0x034, 0x00027DEC, ++ 0x034, 0x00026DE9, ++ 0x034, 0x00025DE6, ++ 0x034, 0x00024DE3, ++ 0x034, 0x000238C8, ++ 0x034, 0x000228C5, ++ 0x034, 0x000218C2, ++ 0x034, 0x000208C0, ++ 0xB0000000, 0x00000000, ++ 0x80000008, 0x00000000, 0x40000000, 0x00000000, ++ 0x034, 0x0000A0B2, ++ 0x034, 0x000090AF, ++ 0x034, 0x00008070, ++ 0x034, 0x0000706D, ++ 0x034, 0x00006050, ++ 0x034, 0x0000504D, ++ 0x034, 0x0000404A, ++ 0x034, 0x00003047, ++ 0x034, 0x0000200A, ++ 0x034, 0x00001007, ++ 0x034, 0x00000004, ++ 0x90000008, 0x05000000, 0x40000000, 0x00000000, ++ 0x034, 0x0000A0B3, ++ 0x034, 0x000090B0, ++ 0x034, 0x00008070, ++ 0x034, 0x0000706D, ++ 0x034, 0x0000604D, ++ 0x034, 0x0000504A, ++ 0x034, 0x00004047, ++ 0x034, 0x00003044, ++ 0x034, 0x00002007, ++ 0x034, 0x00001004, ++ 0x034, 0x00000001, ++ 0xA0000000, 0x00000000, ++ 0x034, 0x0000AFF7, ++ 0x034, 0x00009DF7, ++ 0x034, 0x00008DF4, ++ 0x034, 0x00007DF1, ++ 0x034, 0x00006DEE, ++ 0x034, 0x00005DEB, ++ 0x034, 0x00004DE8, ++ 0x034, 0x000038CC, ++ 0x034, 0x000028C9, ++ 0x034, 0x000018C6, ++ 0x034, 0x000008C3, ++ 0xB0000000, 0x00000000, ++ 0x0EF, 0x00000000, ++ 0x80000008, 0x00000000, 0x40000000, 0x00000000, ++ 0x018, 0x0001712A, ++ 0x0EF, 0x00000040, ++ 0x035, 0x000001C5, ++ 0x035, 0x000081C5, ++ 0x035, 0x000101C5, ++ 0x035, 0x00020174, ++ 0x035, 0x00028174, ++ 0x035, 0x00030174, ++ 0x035, 0x00040185, ++ 0x035, 0x00048185, ++ 0x035, 0x00050185, ++ 0x0EF, 0x00000000, ++ 0x90000008, 0x05000000, 0x40000000, 0x00000000, ++ 0x018, 0x0001712A, ++ 0x0EF, 0x00000040, ++ 0x035, 0x000001C5, ++ 0x035, 0x000081C5, ++ 0x035, 0x000101C5, ++ 0x035, 0x00020174, ++ 0x035, 0x00028174, ++ 0x035, 0x00030174, ++ 0x035, 0x00040185, ++ 0x035, 0x00048185, ++ 0x035, 0x00050185, ++ 0x0EF, 0x00000000, ++ 0xA0000000, 0x00000000, ++ 0x018, 0x0001712A, ++ 0x0EF, 0x00000040, ++ 0x035, 0x00000188, ++ 0x035, 0x00008147, ++ 0x035, 0x00010147, ++ 0x035, 0x000201D7, ++ 0x035, 0x000281D7, ++ 0x035, 0x000301D7, ++ 0x035, 0x000401D8, ++ 0x035, 0x000481D8, ++ 0x035, 0x000501D8, ++ 0x0EF, 0x00000000, ++ 0xB0000000, 0x00000000, ++ 0x80000008, 0x00000000, 0x40000000, 0x00000000, ++ 0x018, 0x0001712A, ++ 0x0EF, 0x00000010, ++ 0x036, 0x00005B8B, ++ 0x036, 0x0000DB8B, ++ 0x036, 0x00015B8B, ++ 0x036, 0x0001DB8B, ++ 0x036, 0x000262DB, ++ 0x036, 0x0002E2DB, ++ 0x036, 0x000362DB, ++ 0x036, 0x0003E2DB, ++ 0x036, 0x0004553B, ++ 0x036, 0x0004D53B, ++ 0x036, 0x0005553B, ++ 0x036, 0x0005D53B, ++ 0x90000008, 0x05000000, 0x40000000, 0x00000000, ++ 0x018, 0x0001712A, ++ 0x0EF, 0x00000010, ++ 0x036, 0x00005B8B, ++ 0x036, 0x0000DB8B, ++ 0x036, 0x00015B8B, ++ 0x036, 0x0001DB8B, ++ 0x036, 0x000262DB, ++ 0x036, 0x0002E2DB, ++ 0x036, 0x000362DB, ++ 0x036, 0x0003E2DB, ++ 0x036, 0x0004553B, ++ 0x036, 0x0004D53B, ++ 0x036, 0x0005553B, ++ 0x036, 0x0005D53B, ++ 0xA0000000, 0x00000000, ++ 0x018, 0x0001712A, ++ 0x0EF, 0x00000010, ++ 0x036, 0x00084EB4, ++ 0x036, 0x0008CC35, ++ 0x036, 0x00094C35, ++ 0x036, 0x0009CC35, ++ 0x036, 0x000A4C35, ++ 0x036, 0x000ACC35, ++ 0x036, 0x000B4C35, ++ 0x036, 0x000BCC35, ++ 0x036, 0x000C4C34, ++ 0x036, 0x000CCC35, ++ 0x036, 0x000D4C35, ++ 0x036, 0x000DCC35, ++ 0xB0000000, 0x00000000, ++ 0x0EF, 0x00000000, ++ 0x0EF, 0x00000008, ++ 0x80000008, 0x00000000, 0x40000000, 0x00000000, ++ 0x03C, 0x000002DC, ++ 0x03C, 0x00000524, ++ 0x03C, 0x00000902, ++ 0x90000008, 0x05000000, 0x40000000, 0x00000000, ++ 0x03C, 0x000002DC, ++ 0x03C, 0x00000524, ++ 0x03C, 0x00000902, ++ 0xA0000000, 0x00000000, ++ 0x03C, 0x000002A8, ++ 0x03C, 0x000005A2, ++ 0x03C, 0x00000880, ++ 0xB0000000, 0x00000000, ++ 0x0EF, 0x00000000, ++ 0x018, 0x0001712A, ++ 0x0EF, 0x00000002, ++ 0x0DF, 0x00000080, ++ 0x80000008, 0x00000000, 0x40000000, 0x00000000, ++ 0x061, 0x000EAC43, ++ 0x062, 0x00038F47, ++ 0x063, 0x00031157, ++ 0x064, 0x0001C4AC, ++ 0x065, 0x000931D1, ++ 0x90000008, 0x05000000, 0x40000000, 0x00000000, ++ 0x061, 0x000EAC43, ++ 0x062, 0x00038F47, ++ 0x063, 0x00031157, ++ 0x064, 0x0001C4AC, ++ 0x065, 0x000931D2, ++ 0x90000002, 0x00000000, 0x40000000, 0x00000000, ++ 0x061, 0x000EAC43, ++ 0x062, 0x00038F47, ++ 0x063, 0x00031157, ++ 0x064, 0x0001C4AC, ++ 0x065, 0x000931D1, ++ 0xA0000000, 0x00000000, ++ 0x061, 0x000E5D53, ++ 0x062, 0x00038FCD, ++ 0x063, 0x000114EB, ++ 0x064, 0x000196AC, ++ 0x065, 0x000911D7, ++ 0xB0000000, 0x00000000, ++ 0x008, 0x00008400, ++}; ++ ++RTW_DECL_TABLE_RF_RADIO(rtw8812a_rf_b, B); ++ ++static const struct rtw_txpwr_lmt_cfg_pair rtw8812a_txpwr_lmt[] = { ++ { 0, 0, 0, 0, 1, 36, }, ++ { 2, 0, 0, 0, 1, 32, }, ++ { 1, 0, 0, 0, 1, 32, }, ++ { 0, 0, 0, 0, 2, 36, }, ++ { 2, 0, 0, 0, 2, 32, }, ++ { 1, 0, 0, 0, 2, 32, }, ++ { 0, 0, 0, 0, 3, 36, }, ++ { 2, 0, 0, 0, 3, 32, }, ++ { 1, 0, 0, 0, 3, 32, }, ++ { 0, 0, 0, 0, 4, 36, }, ++ { 2, 0, 0, 0, 4, 32, }, ++ { 1, 0, 0, 0, 4, 32, }, ++ { 0, 0, 0, 0, 5, 36, }, ++ { 2, 0, 0, 0, 5, 32, }, ++ { 1, 0, 0, 0, 5, 32, }, ++ { 0, 0, 0, 0, 6, 36, }, ++ { 2, 0, 0, 0, 6, 32, }, ++ { 1, 0, 0, 0, 6, 32, }, ++ { 0, 0, 0, 0, 7, 36, }, ++ { 2, 0, 0, 0, 7, 32, }, ++ { 1, 0, 0, 0, 7, 32, }, ++ { 0, 0, 0, 0, 8, 36, }, ++ { 2, 0, 0, 0, 8, 32, }, ++ { 1, 0, 0, 0, 8, 32, }, ++ { 0, 0, 0, 0, 9, 36, }, ++ { 2, 0, 0, 0, 9, 32, }, ++ { 1, 0, 0, 0, 9, 32, }, ++ { 0, 0, 0, 0, 10, 36, }, ++ { 2, 0, 0, 0, 10, 32, }, ++ { 1, 0, 0, 0, 10, 32, }, ++ { 0, 0, 0, 0, 11, 36, }, ++ { 2, 0, 0, 0, 11, 32, }, ++ { 1, 0, 0, 0, 11, 32, }, ++ { 0, 0, 0, 0, 12, 63, }, ++ { 2, 0, 0, 0, 12, 32, }, ++ { 1, 0, 0, 0, 12, 32, }, ++ { 0, 0, 0, 0, 13, 63, }, ++ { 2, 0, 0, 0, 13, 32, }, ++ { 1, 0, 0, 0, 13, 32, }, ++ { 0, 0, 0, 0, 14, 63, }, ++ { 2, 0, 0, 0, 14, 63, }, ++ { 1, 0, 0, 0, 14, 32, }, ++ { 0, 0, 0, 1, 1, 34, }, ++ { 2, 0, 0, 1, 1, 32, }, ++ { 1, 0, 0, 1, 1, 32, }, ++ { 0, 0, 0, 1, 2, 36, }, ++ { 2, 0, 0, 1, 2, 32, }, ++ { 1, 0, 0, 1, 2, 32, }, ++ { 0, 0, 0, 1, 3, 36, }, ++ { 2, 0, 0, 1, 3, 32, }, ++ { 1, 0, 0, 1, 3, 32, }, ++ { 0, 0, 0, 1, 4, 36, }, ++ { 2, 0, 0, 1, 4, 32, }, ++ { 1, 0, 0, 1, 4, 32, }, ++ { 0, 0, 0, 1, 5, 36, }, ++ { 2, 0, 0, 1, 5, 32, }, ++ { 1, 0, 0, 1, 5, 32, }, ++ { 0, 0, 0, 1, 6, 36, }, ++ { 2, 0, 0, 1, 6, 32, }, ++ { 1, 0, 0, 1, 6, 32, }, ++ { 0, 0, 0, 1, 7, 36, }, ++ { 2, 0, 0, 1, 7, 32, }, ++ { 1, 0, 0, 1, 7, 32, }, ++ { 0, 0, 0, 1, 8, 36, }, ++ { 2, 0, 0, 1, 8, 32, }, ++ { 1, 0, 0, 1, 8, 32, }, ++ { 0, 0, 0, 1, 9, 36, }, ++ { 2, 0, 0, 1, 9, 32, }, ++ { 1, 0, 0, 1, 9, 32, }, ++ { 0, 0, 0, 1, 10, 36, }, ++ { 2, 0, 0, 1, 10, 32, }, ++ { 1, 0, 0, 1, 10, 32, }, ++ { 0, 0, 0, 1, 11, 32, }, ++ { 2, 0, 0, 1, 11, 32, }, ++ { 1, 0, 0, 1, 11, 32, }, ++ { 0, 0, 0, 1, 12, 63, }, ++ { 2, 0, 0, 1, 12, 32, }, ++ { 1, 0, 0, 1, 12, 32, }, ++ { 0, 0, 0, 1, 13, 63, }, ++ { 2, 0, 0, 1, 13, 32, }, ++ { 1, 0, 0, 1, 13, 32, }, ++ { 0, 0, 0, 1, 14, 63, }, ++ { 2, 0, 0, 1, 14, 63, }, ++ { 1, 0, 0, 1, 14, 63, }, ++ { 0, 0, 0, 2, 1, 34, }, ++ { 2, 0, 0, 2, 1, 32, }, ++ { 1, 0, 0, 2, 1, 32, }, ++ { 0, 0, 0, 2, 2, 36, }, ++ { 2, 0, 0, 2, 2, 32, }, ++ { 1, 0, 0, 2, 2, 32, }, ++ { 0, 0, 0, 2, 3, 36, }, ++ { 2, 0, 0, 2, 3, 32, }, ++ { 1, 0, 0, 2, 3, 32, }, ++ { 0, 0, 0, 2, 4, 36, }, ++ { 2, 0, 0, 2, 4, 32, }, ++ { 1, 0, 0, 2, 4, 32, }, ++ { 0, 0, 0, 2, 5, 36, }, ++ { 2, 0, 0, 2, 5, 32, }, ++ { 1, 0, 0, 2, 5, 32, }, ++ { 0, 0, 0, 2, 6, 36, }, ++ { 2, 0, 0, 2, 6, 32, }, ++ { 1, 0, 0, 2, 6, 32, }, ++ { 0, 0, 0, 2, 7, 36, }, ++ { 2, 0, 0, 2, 7, 32, }, ++ { 1, 0, 0, 2, 7, 32, }, ++ { 0, 0, 0, 2, 8, 36, }, ++ { 2, 0, 0, 2, 8, 32, }, ++ { 1, 0, 0, 2, 8, 32, }, ++ { 0, 0, 0, 2, 9, 36, }, ++ { 2, 0, 0, 2, 9, 32, }, ++ { 1, 0, 0, 2, 9, 32, }, ++ { 0, 0, 0, 2, 10, 36, }, ++ { 2, 0, 0, 2, 10, 32, }, ++ { 1, 0, 0, 2, 10, 32, }, ++ { 0, 0, 0, 2, 11, 32, }, ++ { 2, 0, 0, 2, 11, 32, }, ++ { 1, 0, 0, 2, 11, 32, }, ++ { 0, 0, 0, 2, 12, 63, }, ++ { 2, 0, 0, 2, 12, 32, }, ++ { 1, 0, 0, 2, 12, 32, }, ++ { 0, 0, 0, 2, 13, 63, }, ++ { 2, 0, 0, 2, 13, 32, }, ++ { 1, 0, 0, 2, 13, 32, }, ++ { 0, 0, 0, 2, 14, 63, }, ++ { 2, 0, 0, 2, 14, 63, }, ++ { 1, 0, 0, 2, 14, 63, }, ++ { 0, 0, 0, 3, 1, 32, }, ++ { 2, 0, 0, 3, 1, 32, }, ++ { 1, 0, 0, 3, 1, 32, }, ++ { 0, 0, 0, 3, 2, 34, }, ++ { 2, 0, 0, 3, 2, 32, }, ++ { 1, 0, 0, 3, 2, 32, }, ++ { 0, 0, 0, 3, 3, 34, }, ++ { 2, 0, 0, 3, 3, 32, }, ++ { 1, 0, 0, 3, 3, 32, }, ++ { 0, 0, 0, 3, 4, 34, }, ++ { 2, 0, 0, 3, 4, 32, }, ++ { 1, 0, 0, 3, 4, 32, }, ++ { 0, 0, 0, 3, 5, 34, }, ++ { 2, 0, 0, 3, 5, 32, }, ++ { 1, 0, 0, 3, 5, 32, }, ++ { 0, 0, 0, 3, 6, 34, }, ++ { 2, 0, 0, 3, 6, 32, }, ++ { 1, 0, 0, 3, 6, 32, }, ++ { 0, 0, 0, 3, 7, 34, }, ++ { 2, 0, 0, 3, 7, 32, }, ++ { 1, 0, 0, 3, 7, 32, }, ++ { 0, 0, 0, 3, 8, 34, }, ++ { 2, 0, 0, 3, 8, 32, }, ++ { 1, 0, 0, 3, 8, 32, }, ++ { 0, 0, 0, 3, 9, 34, }, ++ { 2, 0, 0, 3, 9, 32, }, ++ { 1, 0, 0, 3, 9, 32, }, ++ { 0, 0, 0, 3, 10, 34, }, ++ { 2, 0, 0, 3, 10, 32, }, ++ { 1, 0, 0, 3, 10, 32, }, ++ { 0, 0, 0, 3, 11, 30, }, ++ { 2, 0, 0, 3, 11, 32, }, ++ { 1, 0, 0, 3, 11, 32, }, ++ { 0, 0, 0, 3, 12, 63, }, ++ { 2, 0, 0, 3, 12, 32, }, ++ { 1, 0, 0, 3, 12, 32, }, ++ { 0, 0, 0, 3, 13, 63, }, ++ { 2, 0, 0, 3, 13, 32, }, ++ { 1, 0, 0, 3, 13, 32, }, ++ { 0, 0, 0, 3, 14, 63, }, ++ { 2, 0, 0, 3, 14, 63, }, ++ { 1, 0, 0, 3, 14, 63, }, ++ { 0, 0, 1, 2, 1, 63, }, ++ { 2, 0, 1, 2, 1, 63, }, ++ { 1, 0, 1, 2, 1, 63, }, ++ { 0, 0, 1, 2, 2, 63, }, ++ { 2, 0, 1, 2, 2, 63, }, ++ { 1, 0, 1, 2, 2, 63, }, ++ { 0, 0, 1, 2, 3, 32, }, ++ { 2, 0, 1, 2, 3, 32, }, ++ { 1, 0, 1, 2, 3, 32, }, ++ { 0, 0, 1, 2, 4, 36, }, ++ { 2, 0, 1, 2, 4, 32, }, ++ { 1, 0, 1, 2, 4, 32, }, ++ { 0, 0, 1, 2, 5, 36, }, ++ { 2, 0, 1, 2, 5, 32, }, ++ { 1, 0, 1, 2, 5, 32, }, ++ { 0, 0, 1, 2, 6, 36, }, ++ { 2, 0, 1, 2, 6, 32, }, ++ { 1, 0, 1, 2, 6, 32, }, ++ { 0, 0, 1, 2, 7, 36, }, ++ { 2, 0, 1, 2, 7, 32, }, ++ { 1, 0, 1, 2, 7, 32, }, ++ { 0, 0, 1, 2, 8, 36, }, ++ { 2, 0, 1, 2, 8, 32, }, ++ { 1, 0, 1, 2, 8, 32, }, ++ { 0, 0, 1, 2, 9, 36, }, ++ { 2, 0, 1, 2, 9, 32, }, ++ { 1, 0, 1, 2, 9, 32, }, ++ { 0, 0, 1, 2, 10, 36, }, ++ { 2, 0, 1, 2, 10, 32, }, ++ { 1, 0, 1, 2, 10, 32, }, ++ { 0, 0, 1, 2, 11, 32, }, ++ { 2, 0, 1, 2, 11, 32, }, ++ { 1, 0, 1, 2, 11, 32, }, ++ { 0, 0, 1, 2, 12, 63, }, ++ { 2, 0, 1, 2, 12, 32, }, ++ { 1, 0, 1, 2, 12, 32, }, ++ { 0, 0, 1, 2, 13, 63, }, ++ { 2, 0, 1, 2, 13, 32, }, ++ { 1, 0, 1, 2, 13, 32, }, ++ { 0, 0, 1, 2, 14, 63, }, ++ { 2, 0, 1, 2, 14, 63, }, ++ { 1, 0, 1, 2, 14, 63, }, ++ { 0, 0, 1, 3, 1, 63, }, ++ { 2, 0, 1, 3, 1, 63, }, ++ { 1, 0, 1, 3, 1, 63, }, ++ { 0, 0, 1, 3, 2, 63, }, ++ { 2, 0, 1, 3, 2, 63, }, ++ { 1, 0, 1, 3, 2, 63, }, ++ { 0, 0, 1, 3, 3, 30, }, ++ { 2, 0, 1, 3, 3, 30, }, ++ { 1, 0, 1, 3, 3, 30, }, ++ { 0, 0, 1, 3, 4, 34, }, ++ { 2, 0, 1, 3, 4, 30, }, ++ { 1, 0, 1, 3, 4, 30, }, ++ { 0, 0, 1, 3, 5, 34, }, ++ { 2, 0, 1, 3, 5, 30, }, ++ { 1, 0, 1, 3, 5, 30, }, ++ { 0, 0, 1, 3, 6, 34, }, ++ { 2, 0, 1, 3, 6, 30, }, ++ { 1, 0, 1, 3, 6, 30, }, ++ { 0, 0, 1, 3, 7, 34, }, ++ { 2, 0, 1, 3, 7, 30, }, ++ { 1, 0, 1, 3, 7, 30, }, ++ { 0, 0, 1, 3, 8, 34, }, ++ { 2, 0, 1, 3, 8, 30, }, ++ { 1, 0, 1, 3, 8, 30, }, ++ { 0, 0, 1, 3, 9, 34, }, ++ { 2, 0, 1, 3, 9, 30, }, ++ { 1, 0, 1, 3, 9, 30, }, ++ { 0, 0, 1, 3, 10, 34, }, ++ { 2, 0, 1, 3, 10, 30, }, ++ { 1, 0, 1, 3, 10, 30, }, ++ { 0, 0, 1, 3, 11, 30, }, ++ { 2, 0, 1, 3, 11, 30, }, ++ { 1, 0, 1, 3, 11, 30, }, ++ { 0, 0, 1, 3, 12, 63, }, ++ { 2, 0, 1, 3, 12, 32, }, ++ { 1, 0, 1, 3, 12, 32, }, ++ { 0, 0, 1, 3, 13, 63, }, ++ { 2, 0, 1, 3, 13, 32, }, ++ { 1, 0, 1, 3, 13, 32, }, ++ { 0, 0, 1, 3, 14, 63, }, ++ { 2, 0, 1, 3, 14, 63, }, ++ { 1, 0, 1, 3, 14, 63, }, ++ { 0, 1, 0, 1, 36, 30, }, ++ { 2, 1, 0, 1, 36, 32, }, ++ { 1, 1, 0, 1, 36, 32, }, ++ { 0, 1, 0, 1, 40, 30, }, ++ { 2, 1, 0, 1, 40, 32, }, ++ { 1, 1, 0, 1, 40, 32, }, ++ { 0, 1, 0, 1, 44, 30, }, ++ { 2, 1, 0, 1, 44, 32, }, ++ { 1, 1, 0, 1, 44, 32, }, ++ { 0, 1, 0, 1, 48, 30, }, ++ { 2, 1, 0, 1, 48, 32, }, ++ { 1, 1, 0, 1, 48, 32, }, ++ { 0, 1, 0, 1, 52, 36, }, ++ { 2, 1, 0, 1, 52, 32, }, ++ { 1, 1, 0, 1, 52, 32, }, ++ { 0, 1, 0, 1, 56, 34, }, ++ { 2, 1, 0, 1, 56, 32, }, ++ { 1, 1, 0, 1, 56, 32, }, ++ { 0, 1, 0, 1, 60, 32, }, ++ { 2, 1, 0, 1, 60, 32, }, ++ { 1, 1, 0, 1, 60, 32, }, ++ { 0, 1, 0, 1, 64, 28, }, ++ { 2, 1, 0, 1, 64, 32, }, ++ { 1, 1, 0, 1, 64, 32, }, ++ { 0, 1, 0, 1, 100, 30, }, ++ { 2, 1, 0, 1, 100, 32, }, ++ { 1, 1, 0, 1, 100, 32, }, ++ { 0, 1, 0, 1, 104, 30, }, ++ { 2, 1, 0, 1, 104, 32, }, ++ { 1, 1, 0, 1, 104, 32, }, ++ { 0, 1, 0, 1, 108, 32, }, ++ { 2, 1, 0, 1, 108, 32, }, ++ { 1, 1, 0, 1, 108, 32, }, ++ { 0, 1, 0, 1, 112, 34, }, ++ { 2, 1, 0, 1, 112, 32, }, ++ { 1, 1, 0, 1, 112, 32, }, ++ { 0, 1, 0, 1, 116, 34, }, ++ { 2, 1, 0, 1, 116, 32, }, ++ { 1, 1, 0, 1, 116, 32, }, ++ { 0, 1, 0, 1, 120, 36, }, ++ { 2, 1, 0, 1, 120, 32, }, ++ { 1, 1, 0, 1, 120, 32, }, ++ { 0, 1, 0, 1, 124, 34, }, ++ { 2, 1, 0, 1, 124, 32, }, ++ { 1, 1, 0, 1, 124, 32, }, ++ { 0, 1, 0, 1, 128, 32, }, ++ { 2, 1, 0, 1, 128, 32, }, ++ { 1, 1, 0, 1, 128, 32, }, ++ { 0, 1, 0, 1, 132, 30, }, ++ { 2, 1, 0, 1, 132, 32, }, ++ { 1, 1, 0, 1, 132, 32, }, ++ { 0, 1, 0, 1, 136, 30, }, ++ { 2, 1, 0, 1, 136, 32, }, ++ { 1, 1, 0, 1, 136, 32, }, ++ { 0, 1, 0, 1, 140, 28, }, ++ { 2, 1, 0, 1, 140, 32, }, ++ { 1, 1, 0, 1, 140, 32, }, ++ { 0, 1, 0, 1, 149, 36, }, ++ { 2, 1, 0, 1, 149, 32, }, ++ { 1, 1, 0, 1, 149, 63, }, ++ { 0, 1, 0, 1, 153, 36, }, ++ { 2, 1, 0, 1, 153, 32, }, ++ { 1, 1, 0, 1, 153, 63, }, ++ { 0, 1, 0, 1, 157, 36, }, ++ { 2, 1, 0, 1, 157, 32, }, ++ { 1, 1, 0, 1, 157, 63, }, ++ { 0, 1, 0, 1, 161, 36, }, ++ { 2, 1, 0, 1, 161, 32, }, ++ { 1, 1, 0, 1, 161, 63, }, ++ { 0, 1, 0, 1, 165, 36, }, ++ { 2, 1, 0, 1, 165, 32, }, ++ { 1, 1, 0, 1, 165, 63, }, ++ { 0, 1, 0, 2, 36, 30, }, ++ { 2, 1, 0, 2, 36, 32, }, ++ { 1, 1, 0, 2, 36, 32, }, ++ { 0, 1, 0, 2, 40, 30, }, ++ { 2, 1, 0, 2, 40, 32, }, ++ { 1, 1, 0, 2, 40, 32, }, ++ { 0, 1, 0, 2, 44, 30, }, ++ { 2, 1, 0, 2, 44, 32, }, ++ { 1, 1, 0, 2, 44, 32, }, ++ { 0, 1, 0, 2, 48, 30, }, ++ { 2, 1, 0, 2, 48, 32, }, ++ { 1, 1, 0, 2, 48, 32, }, ++ { 0, 1, 0, 2, 52, 36, }, ++ { 2, 1, 0, 2, 52, 32, }, ++ { 1, 1, 0, 2, 52, 32, }, ++ { 0, 1, 0, 2, 56, 34, }, ++ { 2, 1, 0, 2, 56, 32, }, ++ { 1, 1, 0, 2, 56, 32, }, ++ { 0, 1, 0, 2, 60, 32, }, ++ { 2, 1, 0, 2, 60, 32, }, ++ { 1, 1, 0, 2, 60, 32, }, ++ { 0, 1, 0, 2, 64, 28, }, ++ { 2, 1, 0, 2, 64, 32, }, ++ { 1, 1, 0, 2, 64, 32, }, ++ { 0, 1, 0, 2, 100, 30, }, ++ { 2, 1, 0, 2, 100, 32, }, ++ { 1, 1, 0, 2, 100, 32, }, ++ { 0, 1, 0, 2, 104, 30, }, ++ { 2, 1, 0, 2, 104, 32, }, ++ { 1, 1, 0, 2, 104, 32, }, ++ { 0, 1, 0, 2, 108, 32, }, ++ { 2, 1, 0, 2, 108, 32, }, ++ { 1, 1, 0, 2, 108, 32, }, ++ { 0, 1, 0, 2, 112, 34, }, ++ { 2, 1, 0, 2, 112, 32, }, ++ { 1, 1, 0, 2, 112, 32, }, ++ { 0, 1, 0, 2, 116, 34, }, ++ { 2, 1, 0, 2, 116, 32, }, ++ { 1, 1, 0, 2, 116, 32, }, ++ { 0, 1, 0, 2, 120, 36, }, ++ { 2, 1, 0, 2, 120, 32, }, ++ { 1, 1, 0, 2, 120, 32, }, ++ { 0, 1, 0, 2, 124, 34, }, ++ { 2, 1, 0, 2, 124, 32, }, ++ { 1, 1, 0, 2, 124, 32, }, ++ { 0, 1, 0, 2, 128, 32, }, ++ { 2, 1, 0, 2, 128, 32, }, ++ { 1, 1, 0, 2, 128, 32, }, ++ { 0, 1, 0, 2, 132, 30, }, ++ { 2, 1, 0, 2, 132, 32, }, ++ { 1, 1, 0, 2, 132, 32, }, ++ { 0, 1, 0, 2, 136, 30, }, ++ { 2, 1, 0, 2, 136, 32, }, ++ { 1, 1, 0, 2, 136, 32, }, ++ { 0, 1, 0, 2, 140, 28, }, ++ { 2, 1, 0, 2, 140, 32, }, ++ { 1, 1, 0, 2, 140, 32, }, ++ { 0, 1, 0, 2, 149, 36, }, ++ { 2, 1, 0, 2, 149, 32, }, ++ { 1, 1, 0, 2, 149, 63, }, ++ { 0, 1, 0, 2, 153, 36, }, ++ { 2, 1, 0, 2, 153, 32, }, ++ { 1, 1, 0, 2, 153, 63, }, ++ { 0, 1, 0, 2, 157, 36, }, ++ { 2, 1, 0, 2, 157, 32, }, ++ { 1, 1, 0, 2, 157, 63, }, ++ { 0, 1, 0, 2, 161, 36, }, ++ { 2, 1, 0, 2, 161, 32, }, ++ { 1, 1, 0, 2, 161, 63, }, ++ { 0, 1, 0, 2, 165, 36, }, ++ { 2, 1, 0, 2, 165, 32, }, ++ { 1, 1, 0, 2, 165, 63, }, ++ { 0, 1, 0, 3, 36, 28, }, ++ { 2, 1, 0, 3, 36, 30, }, ++ { 1, 1, 0, 3, 36, 30, }, ++ { 0, 1, 0, 3, 40, 28, }, ++ { 2, 1, 0, 3, 40, 30, }, ++ { 1, 1, 0, 3, 40, 30, }, ++ { 0, 1, 0, 3, 44, 28, }, ++ { 2, 1, 0, 3, 44, 30, }, ++ { 1, 1, 0, 3, 44, 30, }, ++ { 0, 1, 0, 3, 48, 28, }, ++ { 2, 1, 0, 3, 48, 30, }, ++ { 1, 1, 0, 3, 48, 30, }, ++ { 0, 1, 0, 3, 52, 34, }, ++ { 2, 1, 0, 3, 52, 30, }, ++ { 1, 1, 0, 3, 52, 30, }, ++ { 0, 1, 0, 3, 56, 32, }, ++ { 2, 1, 0, 3, 56, 30, }, ++ { 1, 1, 0, 3, 56, 30, }, ++ { 0, 1, 0, 3, 60, 30, }, ++ { 2, 1, 0, 3, 60, 30, }, ++ { 1, 1, 0, 3, 60, 30, }, ++ { 0, 1, 0, 3, 64, 26, }, ++ { 2, 1, 0, 3, 64, 30, }, ++ { 1, 1, 0, 3, 64, 30, }, ++ { 0, 1, 0, 3, 100, 28, }, ++ { 2, 1, 0, 3, 100, 30, }, ++ { 1, 1, 0, 3, 100, 30, }, ++ { 0, 1, 0, 3, 104, 28, }, ++ { 2, 1, 0, 3, 104, 30, }, ++ { 1, 1, 0, 3, 104, 30, }, ++ { 0, 1, 0, 3, 108, 30, }, ++ { 2, 1, 0, 3, 108, 30, }, ++ { 1, 1, 0, 3, 108, 30, }, ++ { 0, 1, 0, 3, 112, 32, }, ++ { 2, 1, 0, 3, 112, 30, }, ++ { 1, 1, 0, 3, 112, 30, }, ++ { 0, 1, 0, 3, 116, 32, }, ++ { 2, 1, 0, 3, 116, 30, }, ++ { 1, 1, 0, 3, 116, 30, }, ++ { 0, 1, 0, 3, 120, 34, }, ++ { 2, 1, 0, 3, 120, 30, }, ++ { 1, 1, 0, 3, 120, 30, }, ++ { 0, 1, 0, 3, 124, 32, }, ++ { 2, 1, 0, 3, 124, 30, }, ++ { 1, 1, 0, 3, 124, 30, }, ++ { 0, 1, 0, 3, 128, 30, }, ++ { 2, 1, 0, 3, 128, 30, }, ++ { 1, 1, 0, 3, 128, 30, }, ++ { 0, 1, 0, 3, 132, 28, }, ++ { 2, 1, 0, 3, 132, 30, }, ++ { 1, 1, 0, 3, 132, 30, }, ++ { 0, 1, 0, 3, 136, 28, }, ++ { 2, 1, 0, 3, 136, 30, }, ++ { 1, 1, 0, 3, 136, 30, }, ++ { 0, 1, 0, 3, 140, 26, }, ++ { 2, 1, 0, 3, 140, 30, }, ++ { 1, 1, 0, 3, 140, 30, }, ++ { 0, 1, 0, 3, 149, 34, }, ++ { 2, 1, 0, 3, 149, 30, }, ++ { 1, 1, 0, 3, 149, 63, }, ++ { 0, 1, 0, 3, 153, 34, }, ++ { 2, 1, 0, 3, 153, 30, }, ++ { 1, 1, 0, 3, 153, 63, }, ++ { 0, 1, 0, 3, 157, 34, }, ++ { 2, 1, 0, 3, 157, 30, }, ++ { 1, 1, 0, 3, 157, 63, }, ++ { 0, 1, 0, 3, 161, 34, }, ++ { 2, 1, 0, 3, 161, 30, }, ++ { 1, 1, 0, 3, 161, 63, }, ++ { 0, 1, 0, 3, 165, 34, }, ++ { 2, 1, 0, 3, 165, 30, }, ++ { 1, 1, 0, 3, 165, 63, }, ++ { 0, 1, 1, 2, 38, 30, }, ++ { 2, 1, 1, 2, 38, 32, }, ++ { 1, 1, 1, 2, 38, 32, }, ++ { 0, 1, 1, 2, 46, 30, }, ++ { 2, 1, 1, 2, 46, 32, }, ++ { 1, 1, 1, 2, 46, 32, }, ++ { 0, 1, 1, 2, 54, 32, }, ++ { 2, 1, 1, 2, 54, 32, }, ++ { 1, 1, 1, 2, 54, 32, }, ++ { 0, 1, 1, 2, 62, 32, }, ++ { 2, 1, 1, 2, 62, 32, }, ++ { 1, 1, 1, 2, 62, 32, }, ++ { 0, 1, 1, 2, 102, 28, }, ++ { 2, 1, 1, 2, 102, 32, }, ++ { 1, 1, 1, 2, 102, 32, }, ++ { 0, 1, 1, 2, 110, 32, }, ++ { 2, 1, 1, 2, 110, 32, }, ++ { 1, 1, 1, 2, 110, 32, }, ++ { 0, 1, 1, 2, 118, 36, }, ++ { 2, 1, 1, 2, 118, 32, }, ++ { 1, 1, 1, 2, 118, 32, }, ++ { 0, 1, 1, 2, 126, 34, }, ++ { 2, 1, 1, 2, 126, 32, }, ++ { 1, 1, 1, 2, 126, 32, }, ++ { 0, 1, 1, 2, 134, 32, }, ++ { 2, 1, 1, 2, 134, 32, }, ++ { 1, 1, 1, 2, 134, 32, }, ++ { 0, 1, 1, 2, 151, 36, }, ++ { 2, 1, 1, 2, 151, 32, }, ++ { 1, 1, 1, 2, 151, 63, }, ++ { 0, 1, 1, 2, 159, 36, }, ++ { 2, 1, 1, 2, 159, 32, }, ++ { 1, 1, 1, 2, 159, 63, }, ++ { 0, 1, 1, 3, 38, 28, }, ++ { 2, 1, 1, 3, 38, 30, }, ++ { 1, 1, 1, 3, 38, 30, }, ++ { 0, 1, 1, 3, 46, 28, }, ++ { 2, 1, 1, 3, 46, 30, }, ++ { 1, 1, 1, 3, 46, 30, }, ++ { 0, 1, 1, 3, 54, 30, }, ++ { 2, 1, 1, 3, 54, 30, }, ++ { 1, 1, 1, 3, 54, 30, }, ++ { 0, 1, 1, 3, 62, 30, }, ++ { 2, 1, 1, 3, 62, 30, }, ++ { 1, 1, 1, 3, 62, 30, }, ++ { 0, 1, 1, 3, 102, 26, }, ++ { 2, 1, 1, 3, 102, 30, }, ++ { 1, 1, 1, 3, 102, 30, }, ++ { 0, 1, 1, 3, 110, 30, }, ++ { 2, 1, 1, 3, 110, 30, }, ++ { 1, 1, 1, 3, 110, 30, }, ++ { 0, 1, 1, 3, 118, 34, }, ++ { 2, 1, 1, 3, 118, 30, }, ++ { 1, 1, 1, 3, 118, 30, }, ++ { 0, 1, 1, 3, 126, 32, }, ++ { 2, 1, 1, 3, 126, 30, }, ++ { 1, 1, 1, 3, 126, 30, }, ++ { 0, 1, 1, 3, 134, 30, }, ++ { 2, 1, 1, 3, 134, 30, }, ++ { 1, 1, 1, 3, 134, 30, }, ++ { 0, 1, 1, 3, 151, 34, }, ++ { 2, 1, 1, 3, 151, 30, }, ++ { 1, 1, 1, 3, 151, 63, }, ++ { 0, 1, 1, 3, 159, 34, }, ++ { 2, 1, 1, 3, 159, 30, }, ++ { 1, 1, 1, 3, 159, 63, }, ++ { 0, 1, 2, 4, 42, 30, }, ++ { 2, 1, 2, 4, 42, 32, }, ++ { 1, 1, 2, 4, 42, 32, }, ++ { 0, 1, 2, 4, 58, 28, }, ++ { 2, 1, 2, 4, 58, 32, }, ++ { 1, 1, 2, 4, 58, 32, }, ++ { 0, 1, 2, 4, 106, 30, }, ++ { 2, 1, 2, 4, 106, 32, }, ++ { 1, 1, 2, 4, 106, 32, }, ++ { 0, 1, 2, 4, 122, 34, }, ++ { 2, 1, 2, 4, 122, 32, }, ++ { 1, 1, 2, 4, 122, 32, }, ++ { 0, 1, 2, 4, 155, 36, }, ++ { 2, 1, 2, 4, 155, 32, }, ++ { 1, 1, 2, 4, 155, 63, }, ++ { 0, 1, 2, 5, 42, 28, }, ++ { 2, 1, 2, 5, 42, 30, }, ++ { 1, 1, 2, 5, 42, 30, }, ++ { 0, 1, 2, 5, 58, 26, }, ++ { 2, 1, 2, 5, 58, 30, }, ++ { 1, 1, 2, 5, 58, 30, }, ++ { 0, 1, 2, 5, 106, 28, }, ++ { 2, 1, 2, 5, 106, 30, }, ++ { 1, 1, 2, 5, 106, 30, }, ++ { 0, 1, 2, 5, 122, 32, }, ++ { 2, 1, 2, 5, 122, 30, }, ++ { 1, 1, 2, 5, 122, 30, }, ++ { 0, 1, 2, 5, 155, 34, }, ++ { 2, 1, 2, 5, 155, 30, }, ++ { 1, 1, 2, 5, 155, 63, }, ++}; ++ ++RTW_DECL_TABLE_TXPWR_LMT(rtw8812a_txpwr_lmt); ++ ++static const struct rtw_pwr_seq_cmd trans_carddis_to_cardemu_8812a[] = { ++ {0x0012, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(0), BIT(0)}, ++ {0x0014, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, 0x80, 0}, ++ {0x0015, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, 0x01, 0}, ++ {0x0023, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, 0x10, 0}, ++ {0x0046, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, 0xFF, 0x00}, ++ {0x0043, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, 0xFF, 0x00}, ++ {0x0005, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_PCI_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(2), 0}, ++ {0x0005, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(3), 0}, ++ {0x0003, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(2), BIT(2)}, ++ {0x0301, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_PCI_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, 0xFF, 0}, ++ {0x0024, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_USB_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(1), BIT(1)}, ++ {0x0028, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_USB_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(3), BIT(3)}, ++ {0xFFFF, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ 0, ++ RTW_PWR_CMD_END, 0, 0}, ++}; ++ ++static const struct rtw_pwr_seq_cmd trans_cardemu_to_act_8812a[] = { ++ {0x0005, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(2), 0}, ++ {0x0006, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_POLLING, BIT(1), BIT(1)}, ++ {0x0005, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_PCI_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(7), 0}, ++ {0x0005, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(3), 0}, ++ {0x0005, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(0), BIT(0)}, ++ {0x0005, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_POLLING, BIT(0), 0}, ++ {0x0024, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_USB_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(1), 0}, ++ {0x0028, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_USB_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(3), 0}, ++ {0xFFFF, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ 0, ++ RTW_PWR_CMD_END, 0, 0}, ++}; ++ ++static const struct rtw_pwr_seq_cmd trans_act_to_lps_8812a[] = { ++ {0x0301, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_PCI_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, 0xFF, 0xFF}, ++ {0x0522, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, 0xFF, 0x7F}, ++ {0x05F8, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_POLLING, 0xFF, 0}, ++ {0x05F9, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_POLLING, 0xFF, 0}, ++ {0x05FA, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_POLLING, 0xFF, 0}, ++ {0x05FB, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_POLLING, 0xFF, 0}, ++ {0x0c00, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, 0xFF, 0x04}, ++ {0x0e00, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, 0xFF, 0x04}, ++ {0x0002, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(0), 0}, ++ {0x0002, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_DELAY, 0, RTW_PWR_DELAY_US}, ++ {0x0002, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_USB_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(1), 0}, ++ {0x0100, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, 0xFF, 0x03}, ++ {0x0101, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(1), 0}, ++ {0x0553, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(5), BIT(5)}, ++ {0xFFFF, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ 0, ++ RTW_PWR_CMD_END, 0, 0}, ++}; ++ ++static const struct rtw_pwr_seq_cmd trans_act_to_cardemu_8812a[] = { ++ {0x0c00, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, 0xFF, 0x04}, ++ {0x0e00, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, 0xFF, 0x04}, ++ {0x0002, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(0), 0}, ++ {0x0002, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_DELAY, 0, RTW_PWR_DELAY_US}, ++ {0x0002, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_PCI_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(1), 0}, ++ {0x0007, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, 0xFF, 0x2A}, ++ {0x0008, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_USB_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, 0x02, 0}, ++ {0x0005, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(1), BIT(1)}, ++ {0x0005, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_POLLING, BIT(1), 0}, ++ {0xFFFF, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ 0, ++ RTW_PWR_CMD_END, 0, 0}, ++}; ++ ++static const struct rtw_pwr_seq_cmd trans_cardemu_to_carddis_8812a[] = { ++ {0x0003, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(2), 0}, ++ {0x0080, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, 0xFF, 0x05}, ++ {0x0042, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_USB_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, 0xF0, 0xcc}, ++ {0x0042, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_PCI_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, 0xF0, 0xEC}, ++ {0x0043, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, 0xFF, 0x07}, ++ {0x0045, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, 0xFF, 0x00}, ++ {0x0046, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, 0xFF, 0xff}, ++ {0x0047, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, 0xFF, 0}, ++ {0x0014, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, 0x80, BIT(7)}, ++ {0x0015, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, 0x01, BIT(0)}, ++ {0x0012, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, 0x01, 0}, ++ {0x0023, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, 0x10, BIT(4)}, ++ {0x0008, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_USB_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, 0x02, 0}, ++ {0x0007, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_USB_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, 0xFF, 0x20}, ++ {0x001f, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_USB_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(1), 0}, ++ {0x0076, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_USB_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(1), 0}, ++ {0x0005, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(3), BIT(3)}, ++ {0xFFFF, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ 0, ++ RTW_PWR_CMD_END, 0, 0}, ++}; ++ ++const struct rtw_pwr_seq_cmd * const card_enable_flow_8812a[] = { ++ trans_carddis_to_cardemu_8812a, ++ trans_cardemu_to_act_8812a, ++ NULL ++}; ++ ++const struct rtw_pwr_seq_cmd * const enter_lps_flow_8812a[] = { ++ trans_act_to_lps_8812a, ++ NULL ++}; ++ ++const struct rtw_pwr_seq_cmd * const card_disable_flow_8812a[] = { ++ trans_act_to_cardemu_8812a, ++ trans_cardemu_to_carddis_8812a, ++ NULL ++}; ++ ++static const u8 rtw8812a_pwrtrk_5gb_n[][RTW_PWR_TRK_TBL_SZ] = { ++ {0, 1, 1, 2, 2, 3, 4, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, ++ 12, 13, 13, 14, 14, 14, 14, 14, 14}, ++ {0, 1, 1, 2, 2, 3, 4, 4, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, ++ 12, 13, 13, 14, 14, 14, 14, 14, 14}, ++ {0, 1, 1, 2, 2, 3, 4, 5, 6, 6, 7, 8, 8, 9, 10, 10, 11, 11, 12, 12, 13, ++ 13, 14, 14, 15, 16, 16, 16, 16, 16}, ++}; ++ ++static const u8 rtw8812a_pwrtrk_5gb_p[][RTW_PWR_TRK_TBL_SZ] = { ++ {0, 1, 1, 2, 2, 3, 3, 4, 5, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 11, ++ 11, 11, 11, 11, 11, 11, 11, 11, 11}, ++ {0, 1, 1, 2, 3, 3, 4, 5, 5, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 11, ++ 11, 11, 11, 11, 11, 11, 11, 11, 11}, ++ {0, 1, 1, 2, 3, 3, 4, 5, 6, 7, 7, 8, 8, 9, 9, 10, 11, 11, 11, 11, 11, ++ 11, 11, 11, 11, 11, 11, 11, 11, 11}, ++}; ++ ++static const u8 rtw8812a_pwrtrk_5ga_n[][RTW_PWR_TRK_TBL_SZ] = { ++ {0, 1, 1, 2, 2, 3, 4, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, ++ 12, 13, 13, 14, 15, 15, 15, 15, 15}, ++ {0, 1, 1, 2, 2, 3, 4, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, ++ 12, 13, 13, 14, 15, 15, 15, 15, 15}, ++ {0, 1, 1, 2, 2, 3, 4, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, ++ 12, 13, 13, 14, 15, 15, 15, 15, 15}, ++}; ++ ++static const u8 rtw8812a_pwrtrk_5ga_p[][RTW_PWR_TRK_TBL_SZ] = { ++ {0, 1, 1, 2, 2, 3, 4, 5, 6, 7, 7, 8, 8, 9, 10, 11, 11, 11, 11, 11, 11, ++ 11, 11, 11, 11, 11, 11, 11, 11, 11}, ++ {0, 1, 1, 2, 3, 3, 4, 5, 6, 7, 7, 8, 8, 9, 10, 11, 11, 11, 11, 11, 11, ++ 11, 11, 11, 11, 11, 11, 11, 11, 11}, ++ {0, 1, 1, 2, 3, 3, 4, 5, 6, 7, 7, 8, 8, 9, 10, 11, 11, 12, 12, 11, 11, ++ 11, 11, 11, 11, 11, 11, 11, 11, 11}, ++}; ++ ++static const u8 rtw8812a_pwrtrk_2gb_n[] = { ++ 0, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6, 6, ++ 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 11, 11, 11, 11 ++}; ++ ++static const u8 rtw8812a_pwrtrk_2gb_p[] = { ++ 0, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, ++ 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7 ++}; ++ ++static const u8 rtw8812a_pwrtrk_2ga_n[] = { ++ 0, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, ++ 6, 6, 7, 7, 7, 8, 8, 9, 10, 10, 10, 10, 10, 10 ++}; ++ ++static const u8 rtw8812a_pwrtrk_2ga_p[] = { ++ 0, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, ++ 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7 ++}; ++ ++static const u8 rtw8812a_pwrtrk_2g_cck_b_n[] = { ++ 0, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6, 6, ++ 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 11, 11, 11, 11 ++}; ++ ++static const u8 rtw8812a_pwrtrk_2g_cck_b_p[] = { ++ 0, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, ++ 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7 ++}; ++ ++static const u8 rtw8812a_pwrtrk_2g_cck_a_n[] = { ++ 0, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, ++ 6, 6, 7, 7, 7, 8, 8, 9, 10, 10, 10, 10, 10, 10 ++}; ++ ++static const u8 rtw8812a_pwrtrk_2g_cck_a_p[] = { ++ 0, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, ++ 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7 ++}; ++ ++const struct rtw_pwr_track_tbl rtw8812a_rtw_pwr_track_tbl = { ++ .pwrtrk_5gb_n[0] = rtw8812a_pwrtrk_5gb_n[0], ++ .pwrtrk_5gb_n[1] = rtw8812a_pwrtrk_5gb_n[1], ++ .pwrtrk_5gb_n[2] = rtw8812a_pwrtrk_5gb_n[2], ++ .pwrtrk_5gb_p[0] = rtw8812a_pwrtrk_5gb_p[0], ++ .pwrtrk_5gb_p[1] = rtw8812a_pwrtrk_5gb_p[1], ++ .pwrtrk_5gb_p[2] = rtw8812a_pwrtrk_5gb_p[2], ++ .pwrtrk_5ga_n[0] = rtw8812a_pwrtrk_5ga_n[0], ++ .pwrtrk_5ga_n[1] = rtw8812a_pwrtrk_5ga_n[1], ++ .pwrtrk_5ga_n[2] = rtw8812a_pwrtrk_5ga_n[2], ++ .pwrtrk_5ga_p[0] = rtw8812a_pwrtrk_5ga_p[0], ++ .pwrtrk_5ga_p[1] = rtw8812a_pwrtrk_5ga_p[1], ++ .pwrtrk_5ga_p[2] = rtw8812a_pwrtrk_5ga_p[2], ++ .pwrtrk_2gb_n = rtw8812a_pwrtrk_2gb_n, ++ .pwrtrk_2gb_p = rtw8812a_pwrtrk_2gb_p, ++ .pwrtrk_2ga_n = rtw8812a_pwrtrk_2ga_n, ++ .pwrtrk_2ga_p = rtw8812a_pwrtrk_2ga_p, ++ .pwrtrk_2g_cckb_n = rtw8812a_pwrtrk_2g_cck_b_n, ++ .pwrtrk_2g_cckb_p = rtw8812a_pwrtrk_2g_cck_b_p, ++ .pwrtrk_2g_ccka_n = rtw8812a_pwrtrk_2g_cck_a_n, ++ .pwrtrk_2g_ccka_p = rtw8812a_pwrtrk_2g_cck_a_p, ++}; ++ ++static const u8 rtw8812a_pwrtrk_rfe3_5gb_n[][RTW_PWR_TRK_TBL_SZ] = { ++ {0, 1, 1, 2, 3, 3, 4, 5, 5, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 12, 13, ++ 13, 14, 15, 16, 16, 17, 17, 18, 18}, ++ {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10, 11, 11, 11, ++ 12, 14, 13, 13, 14, 14, 14, 15, 15}, ++ {0, 1, 1, 2, 2, 3, 4, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, ++ 12, 13, 13, 14, 14, 15, 15, 16, 16}, ++}; ++ ++static const u8 rtw8812a_pwrtrk_rfe3_5gb_p[][RTW_PWR_TRK_TBL_SZ] = { ++ {0, 1, 1, 2, 3, 3, 4, 5, 6, 7, 7, 8, 9, 9, 10, 10, 11, 11, 11, 11, 11, ++ 11, 11, 11, 11, 11, 11, 11, 11, 11}, ++ {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10, 11, 11, 11, ++ 11, 11, 11, 11, 11, 11, 11, 11, 11}, ++ {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 6, 6, 7, 7, 8, 9, 10, 10, 11, 11, 11, ++ 11, 11, 11, 11, 11, 11, 11, 11, 11}, ++}; ++ ++static const u8 rtw8812a_pwrtrk_rfe3_5ga_n[][RTW_PWR_TRK_TBL_SZ] = { ++ {0, 1, 1, 2, 3, 3, 4, 5, 5, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, ++ 13, 14, 15, 16, 16, 17, 17, 18, 18}, ++ {0, 1, 1, 2, 3, 3, 4, 4, 5, 6, 6, 7, 7, 8, 9, 9, 10, 10, 11, 11, 12, ++ 12, 13, 13, 14, 15, 16, 16, 17, 17}, ++ {0, 1, 1, 2, 3, 3, 4, 4, 5, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 12, 13, ++ 13, 14, 14, 15, 15, 16, 17, 18, 18}, ++}; ++ ++static const u8 rtw8812a_pwrtrk_rfe3_5ga_p[][RTW_PWR_TRK_TBL_SZ] = { ++ {0, 1, 1, 2, 2, 3, 4, 5, 6, 7, 7, 8, 9, 9, 10, 10, 11, 11, 11, 11, 11, ++ 11, 11, 11, 11, 11, 11, 11, 11, 11}, ++ {0, 1, 2, 3, 4, 4, 5, 5, 6, 7, 7, 8, 9, 9, 10, 11, 11, 11, 11, 11, 11, ++ 11, 11, 11, 11, 11, 11, 11, 11, 11}, ++ {0, 1, 2, 3, 4, 4, 5, 5, 6, 7, 7, 8, 9, 9, 10, 11, 11, 11, 11, 11, 11, ++ 11, 11, 11, 11, 11, 11, 11, 11, 11}, ++}; ++ ++static const u8 rtw8812a_pwrtrk_rfe3_2gb_n[] = { ++ 0, 1, 1, 2, 2, 3, 3, 4, 4, 4, 5, 5, 6, 6, 6, 7, ++ 7, 7, 8, 8, 9, 9, 10, 11, 12, 12, 13, 14, 15, 15 ++}; ++ ++static const u8 rtw8812a_pwrtrk_rfe3_2gb_p[] = { ++ 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6, ++ 6, 7, 7, 8, 9, 10, 10, 10, 10, 11, 11, 11, 11, 11 ++}; ++ ++static const u8 rtw8812a_pwrtrk_rfe3_2ga_n[] = { ++ 0, 1, 1, 2, 2, 3, 4, 5, 6, 6, 6, 7, 7, 8, 8, 9, ++ 10, 10, 11, 11, 12, 12, 13, 13, 13, 13, 14, 14, 15, 15 ++}; ++ ++static const u8 rtw8812a_pwrtrk_rfe3_2ga_p[] = { ++ 0, 0, 1, 1, 1, 2, 2, 3, 3, 4, 4, 4, 5, 5, 5, 6, ++ 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 11, 11, 11 ++}; ++ ++static const u8 rtw8812a_pwrtrk_rfe3_2g_cck_b_n[] = { ++ 0, 1, 1, 2, 2, 3, 3, 4, 4, 4, 5, 5, 6, 6, 6, 7, ++ 7, 7, 8, 8, 9, 9, 10, 11, 12, 12, 13, 14, 15, 15 ++}; ++ ++static const u8 rtw8812a_pwrtrk_rfe3_2g_cck_b_p[] = { ++ 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6, ++ 6, 7, 7, 8, 9, 10, 10, 10, 10, 11, 11, 11, 11, 11 ++}; ++ ++static const u8 rtw8812a_pwrtrk_rfe3_2g_cck_a_n[] = { ++ 0, 1, 1, 2, 2, 3, 4, 5, 6, 6, 6, 7, 7, 8, 8, 9, ++ 10, 10, 11, 11, 12, 12, 13, 13, 13, 13, 14, 14, 15, 15 ++}; ++ ++static const u8 rtw8812a_pwrtrk_rfe3_2g_cck_a_p[] = { ++ 0, 0, 1, 1, 1, 2, 2, 3, 3, 4, 4, 4, 5, 5, 5, 6, ++ 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 11, 11, 11 ++}; ++ ++const struct rtw_pwr_track_tbl rtw8812a_rtw_pwr_track_rfe3_tbl = { ++ .pwrtrk_5gb_n[0] = rtw8812a_pwrtrk_rfe3_5gb_n[0], ++ .pwrtrk_5gb_n[1] = rtw8812a_pwrtrk_rfe3_5gb_n[1], ++ .pwrtrk_5gb_n[2] = rtw8812a_pwrtrk_rfe3_5gb_n[2], ++ .pwrtrk_5gb_p[0] = rtw8812a_pwrtrk_rfe3_5gb_p[0], ++ .pwrtrk_5gb_p[1] = rtw8812a_pwrtrk_rfe3_5gb_p[1], ++ .pwrtrk_5gb_p[2] = rtw8812a_pwrtrk_rfe3_5gb_p[2], ++ .pwrtrk_5ga_n[0] = rtw8812a_pwrtrk_rfe3_5ga_n[0], ++ .pwrtrk_5ga_n[1] = rtw8812a_pwrtrk_rfe3_5ga_n[1], ++ .pwrtrk_5ga_n[2] = rtw8812a_pwrtrk_rfe3_5ga_n[2], ++ .pwrtrk_5ga_p[0] = rtw8812a_pwrtrk_rfe3_5ga_p[0], ++ .pwrtrk_5ga_p[1] = rtw8812a_pwrtrk_rfe3_5ga_p[1], ++ .pwrtrk_5ga_p[2] = rtw8812a_pwrtrk_rfe3_5ga_p[2], ++ .pwrtrk_2gb_n = rtw8812a_pwrtrk_rfe3_2gb_n, ++ .pwrtrk_2gb_p = rtw8812a_pwrtrk_rfe3_2gb_p, ++ .pwrtrk_2ga_n = rtw8812a_pwrtrk_rfe3_2ga_n, ++ .pwrtrk_2ga_p = rtw8812a_pwrtrk_rfe3_2ga_p, ++ .pwrtrk_2g_cckb_n = rtw8812a_pwrtrk_rfe3_2g_cck_b_n, ++ .pwrtrk_2g_cckb_p = rtw8812a_pwrtrk_rfe3_2g_cck_b_p, ++ .pwrtrk_2g_ccka_n = rtw8812a_pwrtrk_rfe3_2g_cck_a_n, ++ .pwrtrk_2g_ccka_p = rtw8812a_pwrtrk_rfe3_2g_cck_a_p, ++}; +--- /dev/null ++++ b/drivers/net/wireless/realtek/rtw88/rtw8812a_table.h +@@ -0,0 +1,26 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2024 Realtek Corporation ++ */ ++ ++#ifndef __RTW8812A_TABLE_H__ ++#define __RTW8812A_TABLE_H__ ++ ++extern const struct rtw_table rtw8812a_mac_tbl; ++extern const struct rtw_table rtw8812a_agc_tbl; ++extern const struct rtw_table rtw8812a_agc_diff_lb_tbl; ++extern const struct rtw_table rtw8812a_agc_diff_hb_tbl; ++extern const struct rtw_table rtw8812a_bb_tbl; ++extern const struct rtw_table rtw8812a_bb_pg_tbl; ++extern const struct rtw_table rtw8812a_bb_pg_rfe3_tbl; ++extern const struct rtw_table rtw8812a_rf_a_tbl; ++extern const struct rtw_table rtw8812a_rf_b_tbl; ++extern const struct rtw_table rtw8812a_txpwr_lmt_tbl; ++ ++extern const struct rtw_pwr_seq_cmd * const card_enable_flow_8812a[]; ++extern const struct rtw_pwr_seq_cmd * const enter_lps_flow_8812a[]; ++extern const struct rtw_pwr_seq_cmd * const card_disable_flow_8812a[]; ++ ++extern const struct rtw_pwr_track_tbl rtw8812a_rtw_pwr_track_tbl; ++extern const struct rtw_pwr_track_tbl rtw8812a_rtw_pwr_track_rfe3_tbl; ++ ++#endif diff --git a/package/kernel/mac80211/patches/rtl/040-v6.13-wifi-rtw88-Add-rtw8821a_table.-c-h.patch b/package/kernel/mac80211/patches/rtl/040-v6.13-wifi-rtw88-Add-rtw8821a_table.-c-h.patch new file mode 100644 index 00000000000000..e8ceaba61ea06e --- /dev/null +++ b/package/kernel/mac80211/patches/rtl/040-v6.13-wifi-rtw88-Add-rtw8821a_table.-c-h.patch @@ -0,0 +1,2395 @@ +From 4b81da5cd2b4c7231272216639bacecc818d8b51 Mon Sep 17 00:00:00 2001 +From: Bitterblue Smith +Date: Wed, 30 Oct 2024 20:25:16 +0200 +Subject: [PATCH] wifi: rtw88: Add rtw8821a_table.{c,h} + +These contain various arrays for initialising RTL8821AU. Also TX power +limits. + +Signed-off-by: Bitterblue Smith +Signed-off-by: Ping-Ke Shih +Link: https://patch.msgid.link/087c7260-fcc3-4e22-886b-ac477cad9198@gmail.com +--- + .../wireless/realtek/rtw88/rtw8821a_table.c | 2350 +++++++++++++++++ + .../wireless/realtek/rtw88/rtw8821a_table.h | 21 + + 2 files changed, 2371 insertions(+) + create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8821a_table.c + create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8821a_table.h + +--- /dev/null ++++ b/drivers/net/wireless/realtek/rtw88/rtw8821a_table.c +@@ -0,0 +1,2350 @@ ++// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause ++/* Copyright(c) 2024 Realtek Corporation ++ */ ++ ++#include "main.h" ++#include "phy.h" ++#include "rtw8821a_table.h" ++ ++static const u32 rtw8821a_mac[] = { ++ 0x421, 0x0000000F, ++ 0x428, 0x0000000A, ++ 0x429, 0x00000010, ++ 0x430, 0x00000000, ++ 0x431, 0x00000000, ++ 0x432, 0x00000000, ++ 0x433, 0x00000001, ++ 0x434, 0x00000004, ++ 0x435, 0x00000005, ++ 0x436, 0x00000007, ++ 0x437, 0x00000008, ++ 0x43C, 0x00000004, ++ 0x43D, 0x00000005, ++ 0x43E, 0x00000007, ++ 0x43F, 0x00000008, ++ 0x440, 0x0000005D, ++ 0x441, 0x00000001, ++ 0x442, 0x00000000, ++ 0x444, 0x00000010, ++ 0x445, 0x00000000, ++ 0x446, 0x00000000, ++ 0x447, 0x00000000, ++ 0x448, 0x00000000, ++ 0x449, 0x000000F0, ++ 0x44A, 0x0000000F, ++ 0x44B, 0x0000003E, ++ 0x44C, 0x00000010, ++ 0x44D, 0x00000000, ++ 0x44E, 0x00000000, ++ 0x44F, 0x00000000, ++ 0x450, 0x00000000, ++ 0x451, 0x000000F0, ++ 0x452, 0x0000000F, ++ 0x453, 0x00000000, ++ 0x456, 0x0000005E, ++ 0x460, 0x00000066, ++ 0x461, 0x00000066, ++ 0x4C8, 0x0000003F, ++ 0x4C9, 0x000000FF, ++ 0x4CC, 0x000000FF, ++ 0x4CD, 0x000000FF, ++ 0x4CE, 0x00000001, ++ 0x500, 0x00000026, ++ 0x501, 0x000000A2, ++ 0x502, 0x0000002F, ++ 0x503, 0x00000000, ++ 0x504, 0x00000028, ++ 0x505, 0x000000A3, ++ 0x506, 0x0000005E, ++ 0x507, 0x00000000, ++ 0x508, 0x0000002B, ++ 0x509, 0x000000A4, ++ 0x50A, 0x0000005E, ++ 0x50B, 0x00000000, ++ 0x50C, 0x0000004F, ++ 0x50D, 0x000000A4, ++ 0x50E, 0x00000000, ++ 0x50F, 0x00000000, ++ 0x512, 0x0000001C, ++ 0x514, 0x0000000A, ++ 0x516, 0x0000000A, ++ 0x525, 0x0000004F, ++ 0x550, 0x00000010, ++ 0x551, 0x00000010, ++ 0x559, 0x00000002, ++ 0x55C, 0x00000050, ++ 0x55D, 0x000000FF, ++ 0x605, 0x00000030, ++ 0x607, 0x00000007, ++ 0x608, 0x0000000E, ++ 0x609, 0x0000002A, ++ 0x620, 0x000000FF, ++ 0x621, 0x000000FF, ++ 0x622, 0x000000FF, ++ 0x623, 0x000000FF, ++ 0x624, 0x000000FF, ++ 0x625, 0x000000FF, ++ 0x626, 0x000000FF, ++ 0x627, 0x000000FF, ++ 0x638, 0x00000050, ++ 0x63C, 0x0000000A, ++ 0x63D, 0x0000000A, ++ 0x63E, 0x0000000E, ++ 0x63F, 0x0000000E, ++ 0x640, 0x00000040, ++ 0x642, 0x00000040, ++ 0x643, 0x00000000, ++ 0x652, 0x000000C8, ++ 0x66E, 0x00000005, ++ 0x700, 0x00000021, ++ 0x701, 0x00000043, ++ 0x702, 0x00000065, ++ 0x703, 0x00000087, ++ 0x708, 0x00000021, ++ 0x709, 0x00000043, ++ 0x70A, 0x00000065, ++ 0x70B, 0x00000087, ++ 0x718, 0x00000040, ++}; ++ ++RTW_DECL_TABLE_PHY_COND(rtw8821a_mac, rtw_phy_cfg_mac); ++ ++static const u32 rtw8821a_agc[] = { ++ 0x81C, 0xBF000001, ++ 0x81C, 0xBF020001, ++ 0x81C, 0xBF040001, ++ 0x81C, 0xBF060001, ++ 0x81C, 0xBE080001, ++ 0x81C, 0xBD0A0001, ++ 0x81C, 0xBC0C0001, ++ 0x81C, 0xBA0E0001, ++ 0x81C, 0xB9100001, ++ 0x81C, 0xB8120001, ++ 0x81C, 0xB7140001, ++ 0x81C, 0xB6160001, ++ 0x81C, 0xB5180001, ++ 0x81C, 0xB41A0001, ++ 0x81C, 0xB31C0001, ++ 0x81C, 0xB21E0001, ++ 0x81C, 0xB1200001, ++ 0x81C, 0xB0220001, ++ 0x81C, 0xAF240001, ++ 0x81C, 0xAE260001, ++ 0x81C, 0xAD280001, ++ 0x81C, 0xAC2A0001, ++ 0x81C, 0xAB2C0001, ++ 0x81C, 0xAA2E0001, ++ 0x81C, 0xA9300001, ++ 0x81C, 0xA8320001, ++ 0x81C, 0xA7340001, ++ 0x81C, 0xA6360001, ++ 0x81C, 0xA5380001, ++ 0x81C, 0xA43A0001, ++ 0x81C, 0x683C0001, ++ 0x81C, 0x673E0001, ++ 0x81C, 0x66400001, ++ 0x81C, 0x65420001, ++ 0x81C, 0x64440001, ++ 0x81C, 0x63460001, ++ 0x81C, 0x62480001, ++ 0x81C, 0x614A0001, ++ 0x81C, 0x474C0001, ++ 0x81C, 0x464E0001, ++ 0x81C, 0x45500001, ++ 0x81C, 0x44520001, ++ 0x81C, 0x43540001, ++ 0x81C, 0x42560001, ++ 0x81C, 0x41580001, ++ 0x81C, 0x285A0001, ++ 0x81C, 0x275C0001, ++ 0x81C, 0x265E0001, ++ 0x81C, 0x25600001, ++ 0x81C, 0x24620001, ++ 0x81C, 0x0A640001, ++ 0x81C, 0x09660001, ++ 0x81C, 0x08680001, ++ 0x81C, 0x076A0001, ++ 0x81C, 0x066C0001, ++ 0x81C, 0x056E0001, ++ 0x81C, 0x04700001, ++ 0x81C, 0x03720001, ++ 0x81C, 0x02740001, ++ 0x81C, 0x01760001, ++ 0x81C, 0x01780001, ++ 0x81C, 0x017A0001, ++ 0x81C, 0x017C0001, ++ 0x81C, 0x017E0001, ++ 0x8000020c, 0x00000000, 0x40000000, 0x00000000, ++ 0x81C, 0xFB000101, ++ 0x81C, 0xFA020101, ++ 0x81C, 0xF9040101, ++ 0x81C, 0xF8060101, ++ 0x81C, 0xF7080101, ++ 0x81C, 0xF60A0101, ++ 0x81C, 0xF50C0101, ++ 0x81C, 0xF40E0101, ++ 0x81C, 0xF3100101, ++ 0x81C, 0xF2120101, ++ 0x81C, 0xF1140101, ++ 0x81C, 0xF0160101, ++ 0x81C, 0xEF180101, ++ 0x81C, 0xEE1A0101, ++ 0x81C, 0xED1C0101, ++ 0x81C, 0xEC1E0101, ++ 0x81C, 0xEB200101, ++ 0x81C, 0xEA220101, ++ 0x81C, 0xE9240101, ++ 0x81C, 0xE8260101, ++ 0x81C, 0xE7280101, ++ 0x81C, 0xE62A0101, ++ 0x81C, 0xE52C0101, ++ 0x81C, 0xE42E0101, ++ 0x81C, 0xE3300101, ++ 0x81C, 0xA5320101, ++ 0x81C, 0xA4340101, ++ 0x81C, 0xA3360101, ++ 0x81C, 0x87380101, ++ 0x81C, 0x863A0101, ++ 0x81C, 0x853C0101, ++ 0x81C, 0x843E0101, ++ 0x81C, 0x69400101, ++ 0x81C, 0x68420101, ++ 0x81C, 0x67440101, ++ 0x81C, 0x66460101, ++ 0x81C, 0x49480101, ++ 0x81C, 0x484A0101, ++ 0x81C, 0x474C0101, ++ 0x81C, 0x2A4E0101, ++ 0x81C, 0x29500101, ++ 0x81C, 0x28520101, ++ 0x81C, 0x27540101, ++ 0x81C, 0x26560101, ++ 0x81C, 0x25580101, ++ 0x81C, 0x245A0101, ++ 0x81C, 0x235C0101, ++ 0x81C, 0x055E0101, ++ 0x81C, 0x04600101, ++ 0x81C, 0x03620101, ++ 0x81C, 0x02640101, ++ 0x81C, 0x01660101, ++ 0x81C, 0x01680101, ++ 0x81C, 0x016A0101, ++ 0x81C, 0x016C0101, ++ 0x81C, 0x016E0101, ++ 0x81C, 0x01700101, ++ 0x81C, 0x01720101, ++ 0x9000040c, 0x00000000, 0x40000000, 0x00000000, ++ 0x81C, 0xFB000101, ++ 0x81C, 0xFA020101, ++ 0x81C, 0xF9040101, ++ 0x81C, 0xF8060101, ++ 0x81C, 0xF7080101, ++ 0x81C, 0xF60A0101, ++ 0x81C, 0xF50C0101, ++ 0x81C, 0xF40E0101, ++ 0x81C, 0xF3100101, ++ 0x81C, 0xF2120101, ++ 0x81C, 0xF1140101, ++ 0x81C, 0xF0160101, ++ 0x81C, 0xEF180101, ++ 0x81C, 0xEE1A0101, ++ 0x81C, 0xED1C0101, ++ 0x81C, 0xEC1E0101, ++ 0x81C, 0xEB200101, ++ 0x81C, 0xEA220101, ++ 0x81C, 0xE9240101, ++ 0x81C, 0xE8260101, ++ 0x81C, 0xE7280101, ++ 0x81C, 0xE62A0101, ++ 0x81C, 0xE52C0101, ++ 0x81C, 0xE42E0101, ++ 0x81C, 0xE3300101, ++ 0x81C, 0xA5320101, ++ 0x81C, 0xA4340101, ++ 0x81C, 0xA3360101, ++ 0x81C, 0x87380101, ++ 0x81C, 0x863A0101, ++ 0x81C, 0x853C0101, ++ 0x81C, 0x843E0101, ++ 0x81C, 0x69400101, ++ 0x81C, 0x68420101, ++ 0x81C, 0x67440101, ++ 0x81C, 0x66460101, ++ 0x81C, 0x49480101, ++ 0x81C, 0x484A0101, ++ 0x81C, 0x474C0101, ++ 0x81C, 0x2A4E0101, ++ 0x81C, 0x29500101, ++ 0x81C, 0x28520101, ++ 0x81C, 0x27540101, ++ 0x81C, 0x26560101, ++ 0x81C, 0x25580101, ++ 0x81C, 0x245A0101, ++ 0x81C, 0x235C0101, ++ 0x81C, 0x055E0101, ++ 0x81C, 0x04600101, ++ 0x81C, 0x03620101, ++ 0x81C, 0x02640101, ++ 0x81C, 0x01660101, ++ 0x81C, 0x01680101, ++ 0x81C, 0x016A0101, ++ 0x81C, 0x016C0101, ++ 0x81C, 0x016E0101, ++ 0x81C, 0x01700101, ++ 0x81C, 0x01720101, ++ 0xA0000000, 0x00000000, ++ 0x81C, 0xFF000101, ++ 0x81C, 0xFF020101, ++ 0x81C, 0xFE040101, ++ 0x81C, 0xFD060101, ++ 0x81C, 0xFC080101, ++ 0x81C, 0xFD0A0101, ++ 0x81C, 0xFC0C0101, ++ 0x81C, 0xFB0E0101, ++ 0x81C, 0xFA100101, ++ 0x81C, 0xF9120101, ++ 0x81C, 0xF8140101, ++ 0x81C, 0xF7160101, ++ 0x81C, 0xF6180101, ++ 0x81C, 0xF51A0101, ++ 0x81C, 0xF41C0101, ++ 0x81C, 0xF31E0101, ++ 0x81C, 0xF2200101, ++ 0x81C, 0xF1220101, ++ 0x81C, 0xF0240101, ++ 0x81C, 0xEF260101, ++ 0x81C, 0xEE280101, ++ 0x81C, 0xED2A0101, ++ 0x81C, 0xEC2C0101, ++ 0x81C, 0xEB2E0101, ++ 0x81C, 0xEA300101, ++ 0x81C, 0xE9320101, ++ 0x81C, 0xE8340101, ++ 0x81C, 0xE7360101, ++ 0x81C, 0xE6380101, ++ 0x81C, 0xE53A0101, ++ 0x81C, 0xE43C0101, ++ 0x81C, 0xE33E0101, ++ 0x81C, 0xA5400101, ++ 0x81C, 0xA4420101, ++ 0x81C, 0xA3440101, ++ 0x81C, 0x87460101, ++ 0x81C, 0x86480101, ++ 0x81C, 0x854A0101, ++ 0x81C, 0x844C0101, ++ 0x81C, 0x694E0101, ++ 0x81C, 0x68500101, ++ 0x81C, 0x67520101, ++ 0x81C, 0x66540101, ++ 0x81C, 0x49560101, ++ 0x81C, 0x48580101, ++ 0x81C, 0x475A0101, ++ 0x81C, 0x2A5C0101, ++ 0x81C, 0x295E0101, ++ 0x81C, 0x28600101, ++ 0x81C, 0x27620101, ++ 0x81C, 0x26640101, ++ 0x81C, 0x25660101, ++ 0x81C, 0x24680101, ++ 0x81C, 0x236A0101, ++ 0x81C, 0x056C0101, ++ 0x81C, 0x046E0101, ++ 0x81C, 0x03700101, ++ 0x81C, 0x02720101, ++ 0xB0000000, 0x00000000, ++ 0x81C, 0x01740101, ++ 0x81C, 0x01760101, ++ 0x81C, 0x01780101, ++ 0x81C, 0x017A0101, ++ 0x81C, 0x017C0101, ++ 0x81C, 0x017E0101, ++ 0xC50, 0x00000022, ++ 0xC50, 0x00000020, ++}; ++ ++RTW_DECL_TABLE_PHY_COND(rtw8821a_agc, rtw_phy_cfg_agc); ++ ++static const u32 rtw8821a_bb[] = { ++ 0x800, 0x0020D090, ++ 0x804, 0x080112E0, ++ 0x808, 0x0E028211, ++ 0x80C, 0x92131111, ++ 0x810, 0x20101261, ++ 0x814, 0x020C3D10, ++ 0x818, 0x03A00385, ++ 0x820, 0x00000000, ++ 0x824, 0x00030FE0, ++ 0x828, 0x00000000, ++ 0x82C, 0x002081DD, ++ 0x830, 0x2AAAEEC8, ++ 0x834, 0x0037A706, ++ 0x838, 0x06489B44, ++ 0x83C, 0x0000095B, ++ 0x840, 0xC0000001, ++ 0x844, 0x40003CDE, ++ 0x848, 0x62103F8B, ++ 0x84C, 0x6CFDFFB8, ++ 0x850, 0x28874706, ++ 0x854, 0x0001520C, ++ 0x858, 0x8060E000, ++ 0x85C, 0x74210168, ++ 0x860, 0x6929C321, ++ 0x864, 0x79727432, ++ 0x868, 0x8CA7A314, ++ 0x86C, 0x888C2878, ++ 0x870, 0x08888888, ++ 0x874, 0x31612C2E, ++ 0x878, 0x00000152, ++ 0x87C, 0x000FD000, ++ 0x8A0, 0x00000013, ++ 0x8A4, 0x7F7F7F7F, ++ 0x8A8, 0xA2000338, ++ 0x8AC, 0x0FF0FA0A, ++ 0x8B4, 0x000FC080, ++ 0x8B8, 0x6C10D7FF, ++ 0x8BC, 0x0CA52090, ++ 0x8C0, 0x1BF00020, ++ 0x8C4, 0x00000000, ++ 0x8C8, 0x00013169, ++ 0x8CC, 0x08248492, ++ 0x8D4, 0x940008A0, ++ 0x8D8, 0x290B5612, ++ 0x8F8, 0x400002C0, ++ 0x8FC, 0x00000000, ++ 0x900, 0x00000700, ++ 0x90C, 0x00000000, ++ 0x910, 0x0000FC00, ++ 0x914, 0x00000404, ++ 0x918, 0x1C1028C0, ++ 0x91C, 0x64B11A1C, ++ 0x920, 0xE0767233, ++ 0x924, 0x055AA500, ++ 0x928, 0x00000004, ++ 0x92C, 0xFFFE0000, ++ 0x930, 0xFFFFFFFE, ++ 0x934, 0x001FFFFF, ++ 0x960, 0x00000000, ++ 0x964, 0x00000000, ++ 0x968, 0x00000000, ++ 0x96C, 0x00000000, ++ 0x970, 0x801FFFFF, ++ 0x974, 0x000003FF, ++ 0x978, 0x00000000, ++ 0x97C, 0x00000000, ++ 0x980, 0x00000000, ++ 0x984, 0x00000000, ++ 0x988, 0x00000000, ++ 0x990, 0x27100000, ++ 0x994, 0xFFFF0100, ++ 0x998, 0xFFFFFF5C, ++ 0x99C, 0xFFFFFFFF, ++ 0x9A0, 0x000000FF, ++ 0x9A4, 0x00480080, ++ 0x9A8, 0x00000000, ++ 0x9AC, 0x00000000, ++ 0x9B0, 0x81081008, ++ 0x9B4, 0x01081008, ++ 0x9B8, 0x01081008, ++ 0x9BC, 0x01081008, ++ 0x9D0, 0x00000000, ++ 0x9D4, 0x00000000, ++ 0x9D8, 0x00000000, ++ 0x9DC, 0x00000000, ++ 0x9E0, 0x00005D00, ++ 0x9E4, 0x00000003, ++ 0x9E8, 0x00000001, ++ 0xA00, 0x00D047C8, ++ 0xA04, 0x01FF800C, ++ 0xA08, 0x8C8A8300, ++ 0xA0C, 0x2E68000F, ++ 0xA10, 0x9500BB78, ++ 0xA14, 0x11144028, ++ 0xA18, 0x00881117, ++ 0xA1C, 0x89140F00, ++ 0xA20, 0x1A1B0000, ++ 0xA24, 0x090E1317, ++ 0xA28, 0x00000204, ++ 0xA2C, 0x00900000, ++ 0xA70, 0x101FFF00, ++ 0xA74, 0x00000008, ++ 0xA78, 0x00000900, ++ 0xA7C, 0x225B0606, ++ 0xA80, 0x21805490, ++ 0xA84, 0x001F0000, ++ 0XB00, 0x03100040, ++ 0XB04, 0x0000B000, ++ 0XB08, 0xAE0201EB, ++ 0XB0C, 0x01003207, ++ 0XB10, 0x00009807, ++ 0XB14, 0x01000000, ++ 0XB18, 0x00000002, ++ 0XB1C, 0x00000002, ++ 0XB20, 0x0000001F, ++ 0XB24, 0x03020100, ++ 0XB28, 0x07060504, ++ 0XB2C, 0x0B0A0908, ++ 0XB30, 0x0F0E0D0C, ++ 0XB34, 0x13121110, ++ 0XB38, 0x17161514, ++ 0XB3C, 0x0000003A, ++ 0XB40, 0x00000000, ++ 0XB44, 0x00000000, ++ 0XB48, 0x13000032, ++ 0XB4C, 0x48080000, ++ 0XB50, 0x00000000, ++ 0XB54, 0x00000000, ++ 0XB58, 0x00000000, ++ 0XB5C, 0x00000000, ++ 0xC00, 0x00000007, ++ 0xC04, 0x00042020, ++ 0xC08, 0x80410231, ++ 0xC0C, 0x00000000, ++ 0xC10, 0x00000100, ++ 0xC14, 0x01000000, ++ 0xC1C, 0x40000003, ++ 0xC20, 0x2C2C2C2C, ++ 0xC24, 0x30303030, ++ 0xC28, 0x30303030, ++ 0xC2C, 0x2C2C2C2C, ++ 0xC30, 0x2C2C2C2C, ++ 0xC34, 0x2C2C2C2C, ++ 0xC38, 0x2C2C2C2C, ++ 0xC3C, 0x2A2A2A2A, ++ 0xC40, 0x2A2A2A2A, ++ 0xC44, 0x2A2A2A2A, ++ 0xC48, 0x2A2A2A2A, ++ 0xC4C, 0x2A2A2A2A, ++ 0xC50, 0x00000020, ++ 0xC54, 0x001C1208, ++ 0xC58, 0x30000C1C, ++ 0xC5C, 0x00000058, ++ 0xC60, 0x34344443, ++ 0xC64, 0x07003333, ++ 0xC68, 0x19791979, ++ 0xC6C, 0x19791979, ++ 0xC70, 0x19791979, ++ 0xC74, 0x19791979, ++ 0xC78, 0x19791979, ++ 0xC7C, 0x19791979, ++ 0xC80, 0x19791979, ++ 0xC84, 0x19791979, ++ 0xC94, 0x0100005C, ++ 0xC98, 0x00000000, ++ 0xC9C, 0x00000000, ++ 0xCA0, 0x00000029, ++ 0xCA4, 0x08040201, ++ 0xCA8, 0x80402010, ++ 0xCB0, 0x77775747, ++ 0xCB4, 0x10000077, ++ 0xCB8, 0x00508240, ++}; ++ ++RTW_DECL_TABLE_PHY_COND(rtw8821a_bb, rtw_phy_cfg_bb); ++ ++static const struct rtw_phy_pg_cfg_pair rtw8821a_bb_pg[] = { ++ { 0, 0, 0, 0x00000c20, 0xffffffff, 0x32343638, }, ++ { 0, 0, 0, 0x00000c24, 0xffffffff, 0x36363838, }, ++ { 0, 0, 0, 0x00000c28, 0xffffffff, 0x28303234, }, ++ { 0, 0, 0, 0x00000c2c, 0xffffffff, 0x34363838, }, ++ { 0, 0, 0, 0x00000c30, 0xffffffff, 0x26283032, }, ++ { 0, 0, 0, 0x00000c3c, 0xffffffff, 0x32343636, }, ++ { 0, 0, 0, 0x00000c40, 0xffffffff, 0x24262830, }, ++ { 0, 0, 0, 0x00000c44, 0x0000ffff, 0x00002022, }, ++ { 1, 0, 0, 0x00000c24, 0xffffffff, 0x34343636, }, ++ { 1, 0, 0, 0x00000c28, 0xffffffff, 0x26283032, }, ++ { 1, 0, 0, 0x00000c2c, 0xffffffff, 0x32343636, }, ++ { 1, 0, 0, 0x00000c30, 0xffffffff, 0x24262830, }, ++ { 1, 0, 0, 0x00000c3c, 0xffffffff, 0x32343636, }, ++ { 1, 0, 0, 0x00000c40, 0xffffffff, 0x24262830, }, ++ { 1, 0, 0, 0x00000c44, 0x0000ffff, 0x00002022, }, ++}; ++ ++RTW_DECL_TABLE_BB_PG(rtw8821a_bb_pg); ++ ++static const u32 rtw8821a_rf_a[] = { ++ 0x018, 0x0001712A, ++ 0x056, 0x00051CF2, ++ 0x066, 0x00040000, ++ 0x000, 0x00010000, ++ 0x01E, 0x00080000, ++ 0x082, 0x00000830, ++ 0x083, 0x00021800, ++ 0x084, 0x00028000, ++ 0x085, 0x00048000, ++ 0x80000111, 0x00000000, 0x40000000, 0x00000000, ++ 0x086, 0x0009483A, ++ 0xA0000000, 0x00000000, ++ 0x086, 0x00094838, ++ 0xB0000000, 0x00000000, ++ 0x087, 0x00044980, ++ 0x088, 0x00048000, ++ 0x089, 0x0000D480, ++ 0x08A, 0x00042240, ++ 0x08B, 0x000F0380, ++ 0x08C, 0x00090000, ++ 0x08D, 0x00022852, ++ 0x08E, 0x00065540, ++ 0x08F, 0x00088001, ++ 0x0EF, 0x00020000, ++ 0x03E, 0x00000380, ++ 0x03F, 0x00090018, ++ 0x03E, 0x00020380, ++ 0x03F, 0x000A0018, ++ 0x03E, 0x00040308, ++ 0x03F, 0x000A0018, ++ 0x03E, 0x00060018, ++ 0x03F, 0x000A0018, ++ 0x0EF, 0x00000000, ++ 0x018, 0x0001712A, ++ 0x089, 0x00000080, ++ 0x08B, 0x00080180, ++ 0x0EF, 0x00001000, ++ 0x03A, 0x00000244, ++ 0x03B, 0x00038027, ++ 0x03C, 0x00082000, ++ 0x03A, 0x00000244, ++ 0x03B, 0x00030113, ++ 0x03C, 0x00082000, ++ 0x03A, 0x0000014C, ++ 0x03B, 0x00028027, ++ 0x03C, 0x00082000, ++ 0x03A, 0x000000CC, ++ 0x03B, 0x00027027, ++ 0x03C, 0x00042000, ++ 0x03A, 0x0000014C, ++ 0x03B, 0x0001F913, ++ 0x03C, 0x00042000, ++ 0x03A, 0x0000010C, ++ 0x03B, 0x00017F10, ++ 0x03C, 0x00012000, ++ 0x03A, 0x000000D0, ++ 0x03B, 0x00008027, ++ 0x03C, 0x000CA000, ++ 0x03A, 0x00000244, ++ 0x03B, 0x00078027, ++ 0x03C, 0x00082000, ++ 0x03A, 0x00000244, ++ 0x03B, 0x00070113, ++ 0x03C, 0x00082000, ++ 0x03A, 0x0000014C, ++ 0x03B, 0x00068027, ++ 0x03C, 0x00082000, ++ 0x03A, 0x000000CC, ++ 0x03B, 0x00067027, ++ 0x03C, 0x00042000, ++ 0x03A, 0x0000014C, ++ 0x03B, 0x0005F913, ++ 0x03C, 0x00042000, ++ 0x03A, 0x0000010C, ++ 0x03B, 0x00057F10, ++ 0x03C, 0x00012000, ++ 0x03A, 0x000000D0, ++ 0x03B, 0x00048027, ++ 0x03C, 0x000CA000, ++ 0x03A, 0x00000244, ++ 0x03B, 0x000B8027, ++ 0x03C, 0x00082000, ++ 0x03A, 0x00000244, ++ 0x03B, 0x000B0113, ++ 0x03C, 0x00082000, ++ 0x03A, 0x0000014C, ++ 0x03B, 0x000A8027, ++ 0x03C, 0x00082000, ++ 0x03A, 0x000000CC, ++ 0x03B, 0x000A7027, ++ 0x03C, 0x00042000, ++ 0x03A, 0x0000014C, ++ 0x03B, 0x0009F913, ++ 0x03C, 0x00042000, ++ 0x03A, 0x0000010C, ++ 0x03B, 0x00097F10, ++ 0x03C, 0x00012000, ++ 0x03A, 0x000000D0, ++ 0x03B, 0x00088027, ++ 0x03C, 0x000CA000, ++ 0x0EF, 0x00000000, ++ 0x0EF, 0x00001100, ++ 0x80000111, 0x00000000, 0x40000000, 0x00000000, ++ 0x034, 0x0004ADF3, ++ 0x034, 0x00049DF0, ++ 0x90000110, 0x00000000, 0x40000000, 0x00000000, ++ 0x034, 0x0004ADF3, ++ 0x034, 0x00049DF0, ++ 0x90000210, 0x00000000, 0x40000000, 0x00000000, ++ 0x034, 0x0004ADF5, ++ 0x034, 0x00049DF2, ++ 0x9000020c, 0x00000000, 0x40000000, 0x00000000, ++ 0x034, 0x0004A0F3, ++ 0x034, 0x000490B1, ++ 0x9000040c, 0x00000000, 0x40000000, 0x00000000, ++ 0x034, 0x0004A0F3, ++ 0x034, 0x000490B1, ++ 0x90000200, 0x00000000, 0x40000000, 0x00000000, ++ 0x034, 0x0004ADF5, ++ 0x034, 0x00049DF2, ++ 0x90000410, 0x00000000, 0x40000000, 0x00000000, ++ 0x034, 0x0004ADF3, ++ 0x034, 0x00049DF0, ++ 0xA0000000, 0x00000000, ++ 0x034, 0x0004ADF7, ++ 0x034, 0x00049DF3, ++ 0xB0000000, 0x00000000, ++ 0x80000111, 0x00000000, 0x40000000, 0x00000000, ++ 0x034, 0x00048DED, ++ 0x034, 0x00047DEA, ++ 0x034, 0x00046DE7, ++ 0x034, 0x00045CE9, ++ 0x034, 0x00044CE6, ++ 0x034, 0x000438C6, ++ 0x034, 0x00042886, ++ 0x034, 0x00041486, ++ 0x034, 0x00040447, ++ 0x90000110, 0x00000000, 0x40000000, 0x00000000, ++ 0x034, 0x00048DED, ++ 0x034, 0x00047DEA, ++ 0x034, 0x00046DE7, ++ 0x034, 0x00045CE9, ++ 0x034, 0x00044CE6, ++ 0x034, 0x000438C6, ++ 0x034, 0x00042886, ++ 0x034, 0x00041486, ++ 0x034, 0x00040447, ++ 0x9000020c, 0x00000000, 0x40000000, 0x00000000, ++ 0x034, 0x000480AE, ++ 0x034, 0x000470AB, ++ 0x034, 0x0004608B, ++ 0x034, 0x00045069, ++ 0x034, 0x00044048, ++ 0x034, 0x00043045, ++ 0x034, 0x00042026, ++ 0x034, 0x00041023, ++ 0x034, 0x00040002, ++ 0x9000040c, 0x00000000, 0x40000000, 0x00000000, ++ 0x034, 0x000480AE, ++ 0x034, 0x000470AB, ++ 0x034, 0x0004608B, ++ 0x034, 0x00045069, ++ 0x034, 0x00044048, ++ 0x034, 0x00043045, ++ 0x034, 0x00042026, ++ 0x034, 0x00041023, ++ 0x034, 0x00040002, ++ 0x90000410, 0x00000000, 0x40000000, 0x00000000, ++ 0x034, 0x00048DED, ++ 0x034, 0x00047DEA, ++ 0x034, 0x00046DE7, ++ 0x034, 0x00045CE9, ++ 0x034, 0x00044CE6, ++ 0x034, 0x000438C6, ++ 0x034, 0x00042886, ++ 0x034, 0x00041486, ++ 0x034, 0x00040447, ++ 0xA0000000, 0x00000000, ++ 0x034, 0x00048DEF, ++ 0x034, 0x00047DEC, ++ 0x034, 0x00046DE9, ++ 0x034, 0x00045CCB, ++ 0x034, 0x0004488D, ++ 0x034, 0x0004348D, ++ 0x034, 0x0004248A, ++ 0x034, 0x0004108D, ++ 0x034, 0x0004008A, ++ 0xB0000000, 0x00000000, ++ 0x80000210, 0x00000000, 0x40000000, 0x00000000, ++ 0x034, 0x0002ADF4, ++ 0x9000020c, 0x00000000, 0x40000000, 0x00000000, ++ 0x034, 0x0002A0F3, ++ 0x9000040c, 0x00000000, 0x40000000, 0x00000000, ++ 0x034, 0x0002A0F3, ++ 0x90000200, 0x00000000, 0x40000000, 0x00000000, ++ 0x034, 0x0002ADF4, ++ 0xA0000000, 0x00000000, ++ 0x034, 0x0002ADF7, ++ 0xB0000000, 0x00000000, ++ 0x80000111, 0x00000000, 0x40000000, 0x00000000, ++ 0x034, 0x00029DF4, ++ 0x90000110, 0x00000000, 0x40000000, 0x00000000, ++ 0x034, 0x00029DF4, ++ 0x90000210, 0x00000000, 0x40000000, 0x00000000, ++ 0x034, 0x00029DF1, ++ 0x9000020c, 0x00000000, 0x40000000, 0x00000000, ++ 0x034, 0x000290F0, ++ 0x9000040c, 0x00000000, 0x40000000, 0x00000000, ++ 0x034, 0x000290F0, ++ 0x90000200, 0x00000000, 0x40000000, 0x00000000, ++ 0x034, 0x00029DF1, ++ 0x90000410, 0x00000000, 0x40000000, 0x00000000, ++ 0x034, 0x00029DF4, ++ 0xA0000000, 0x00000000, ++ 0x034, 0x00029DF2, ++ 0xB0000000, 0x00000000, ++ 0x80000111, 0x00000000, 0x40000000, 0x00000000, ++ 0x034, 0x00028DF1, ++ 0x034, 0x00027DEE, ++ 0x034, 0x00026DEB, ++ 0x034, 0x00025CEC, ++ 0x034, 0x00024CE9, ++ 0x034, 0x000238CA, ++ 0x034, 0x00022889, ++ 0x034, 0x00021489, ++ 0x034, 0x0002044A, ++ 0x90000110, 0x00000000, 0x40000000, 0x00000000, ++ 0x034, 0x00028DF1, ++ 0x034, 0x00027DEE, ++ 0x034, 0x00026DEB, ++ 0x034, 0x00025CEC, ++ 0x034, 0x00024CE9, ++ 0x034, 0x000238CA, ++ 0x034, 0x00022889, ++ 0x034, 0x00021489, ++ 0x034, 0x0002044A, ++ 0x9000020c, 0x00000000, 0x40000000, 0x00000000, ++ 0x034, 0x000280AF, ++ 0x034, 0x000270AC, ++ 0x034, 0x0002608B, ++ 0x034, 0x00025069, ++ 0x034, 0x00024048, ++ 0x034, 0x00023045, ++ 0x034, 0x00022026, ++ 0x034, 0x00021023, ++ 0x034, 0x00020002, ++ 0x9000040c, 0x00000000, 0x40000000, 0x00000000, ++ 0x034, 0x000280AF, ++ 0x034, 0x000270AC, ++ 0x034, 0x0002608B, ++ 0x034, 0x00025069, ++ 0x034, 0x00024048, ++ 0x034, 0x00023045, ++ 0x034, 0x00022026, ++ 0x034, 0x00021023, ++ 0x034, 0x00020002, ++ 0x90000410, 0x00000000, 0x40000000, 0x00000000, ++ 0x034, 0x00028DF1, ++ 0x034, 0x00027DEE, ++ 0x034, 0x00026DEB, ++ 0x034, 0x00025CEC, ++ 0x034, 0x00024CE9, ++ 0x034, 0x000238CA, ++ 0x034, 0x00022889, ++ 0x034, 0x00021489, ++ 0x034, 0x0002044A, ++ 0xA0000000, 0x00000000, ++ 0x034, 0x00028DEE, ++ 0x034, 0x00027DEB, ++ 0x034, 0x00026CCD, ++ 0x034, 0x00025CCA, ++ 0x034, 0x0002488C, ++ 0x034, 0x0002384C, ++ 0x034, 0x00022849, ++ 0x034, 0x00021449, ++ 0x034, 0x0002004D, ++ 0xB0000000, 0x00000000, ++ 0x8000020c, 0x00000000, 0x40000000, 0x00000000, ++ 0x034, 0x0000A0D7, ++ 0x034, 0x000090D3, ++ 0x034, 0x000080B1, ++ 0x034, 0x000070AE, ++ 0x9000040c, 0x00000000, 0x40000000, 0x00000000, ++ 0x034, 0x0000A0D7, ++ 0x034, 0x000090D3, ++ 0x034, 0x000080B1, ++ 0x034, 0x000070AE, ++ 0xA0000000, 0x00000000, ++ 0x034, 0x0000ADF7, ++ 0x034, 0x00009DF4, ++ 0x034, 0x00008DF1, ++ 0x034, 0x00007DEE, ++ 0xB0000000, 0x00000000, ++ 0x80000111, 0x00000000, 0x40000000, 0x00000000, ++ 0x034, 0x00006DEB, ++ 0x034, 0x00005CEC, ++ 0x034, 0x00004CE9, ++ 0x034, 0x000038CA, ++ 0x034, 0x00002889, ++ 0x034, 0x00001489, ++ 0x034, 0x0000044A, ++ 0x90000110, 0x00000000, 0x40000000, 0x00000000, ++ 0x034, 0x00006DEB, ++ 0x034, 0x00005CEC, ++ 0x034, 0x00004CE9, ++ 0x034, 0x000038CA, ++ 0x034, 0x00002889, ++ 0x034, 0x00001489, ++ 0x034, 0x0000044A, ++ 0x9000020c, 0x00000000, 0x40000000, 0x00000000, ++ 0x034, 0x0000608D, ++ 0x034, 0x0000506B, ++ 0x034, 0x0000404A, ++ 0x034, 0x00003047, ++ 0x034, 0x00002044, ++ 0x034, 0x00001025, ++ 0x034, 0x00000004, ++ 0x9000040c, 0x00000000, 0x40000000, 0x00000000, ++ 0x034, 0x0000608D, ++ 0x034, 0x0000506B, ++ 0x034, 0x0000404A, ++ 0x034, 0x00003047, ++ 0x034, 0x00002044, ++ 0x034, 0x00001025, ++ 0x034, 0x00000004, ++ 0x90000410, 0x00000000, 0x40000000, 0x00000000, ++ 0x034, 0x00006DEB, ++ 0x034, 0x00005CEC, ++ 0x034, 0x00004CE9, ++ 0x034, 0x000038CA, ++ 0x034, 0x00002889, ++ 0x034, 0x00001489, ++ 0x034, 0x0000044A, ++ 0xA0000000, 0x00000000, ++ 0x034, 0x00006DCD, ++ 0x034, 0x00005CCD, ++ 0x034, 0x00004CCA, ++ 0x034, 0x0000388C, ++ 0x034, 0x00002888, ++ 0x034, 0x00001488, ++ 0x034, 0x00000486, ++ 0xB0000000, 0x00000000, ++ 0x0EF, 0x00000000, ++ 0x018, 0x0001712A, ++ 0x0EF, 0x00000040, ++ 0x80000111, 0x00000000, 0x40000000, 0x00000000, ++ 0x035, 0x00000187, ++ 0x035, 0x00008187, ++ 0x035, 0x00010187, ++ 0x035, 0x00020188, ++ 0x035, 0x00028188, ++ 0x035, 0x00030188, ++ 0x035, 0x00040188, ++ 0x035, 0x00048188, ++ 0x035, 0x00050188, ++ 0x90000110, 0x00000000, 0x40000000, 0x00000000, ++ 0x035, 0x00000187, ++ 0x035, 0x00008187, ++ 0x035, 0x00010187, ++ 0x035, 0x00020188, ++ 0x035, 0x00028188, ++ 0x035, 0x00030188, ++ 0x035, 0x00040188, ++ 0x035, 0x00048188, ++ 0x035, 0x00050188, ++ 0x90000210, 0x00000000, 0x40000000, 0x00000000, ++ 0x035, 0x00000128, ++ 0x035, 0x00008128, ++ 0x035, 0x00010128, ++ 0x035, 0x000201C8, ++ 0x035, 0x000281C8, ++ 0x035, 0x000301C8, ++ 0x035, 0x000401C8, ++ 0x035, 0x000481C8, ++ 0x035, 0x000501C8, ++ 0x9000040c, 0x00000000, 0x40000000, 0x00000000, ++ 0x035, 0x00000145, ++ 0x035, 0x00008145, ++ 0x035, 0x00010145, ++ 0x035, 0x00020196, ++ 0x035, 0x00028196, ++ 0x035, 0x00030196, ++ 0x035, 0x000401C7, ++ 0x035, 0x000481C7, ++ 0x035, 0x000501C7, ++ 0x90000200, 0x00000000, 0x40000000, 0x00000000, ++ 0x035, 0x00000128, ++ 0x035, 0x00008128, ++ 0x035, 0x00010128, ++ 0x035, 0x000201C8, ++ 0x035, 0x000281C8, ++ 0x035, 0x000301C8, ++ 0x035, 0x000401C8, ++ 0x035, 0x000481C8, ++ 0x035, 0x000501C8, ++ 0x90000410, 0x00000000, 0x40000000, 0x00000000, ++ 0x035, 0x00000187, ++ 0x035, 0x00008187, ++ 0x035, 0x00010187, ++ 0x035, 0x00020188, ++ 0x035, 0x00028188, ++ 0x035, 0x00030188, ++ 0x035, 0x00040188, ++ 0x035, 0x00048188, ++ 0x035, 0x00050188, ++ 0xA0000000, 0x00000000, ++ 0x035, 0x00000145, ++ 0x035, 0x00008145, ++ 0x035, 0x00010145, ++ 0x035, 0x00020196, ++ 0x035, 0x00028196, ++ 0x035, 0x00030196, ++ 0x035, 0x000401C7, ++ 0x035, 0x000481C7, ++ 0x035, 0x000501C7, ++ 0xB0000000, 0x00000000, ++ 0x0EF, 0x00000000, ++ 0x018, 0x0001712A, ++ 0x0EF, 0x00000010, ++ 0x80000111, 0x00000000, 0x40000000, 0x00000000, ++ 0x036, 0x00085733, ++ 0x036, 0x0008D733, ++ 0x036, 0x00095733, ++ 0x036, 0x0009D733, ++ 0x036, 0x000A64B4, ++ 0x036, 0x000AE4B4, ++ 0x036, 0x000B64B4, ++ 0x036, 0x000BE4B4, ++ 0x036, 0x000C64B4, ++ 0x036, 0x000CE4B4, ++ 0x036, 0x000D64B4, ++ 0x036, 0x000DE4B4, ++ 0x90000110, 0x00000000, 0x40000000, 0x00000000, ++ 0x036, 0x00085733, ++ 0x036, 0x0008D733, ++ 0x036, 0x00095733, ++ 0x036, 0x0009D733, ++ 0x036, 0x000A64B4, ++ 0x036, 0x000AE4B4, ++ 0x036, 0x000B64B4, ++ 0x036, 0x000BE4B4, ++ 0x036, 0x000C64B4, ++ 0x036, 0x000CE4B4, ++ 0x036, 0x000D64B4, ++ 0x036, 0x000DE4B4, ++ 0x90000210, 0x00000000, 0x40000000, 0x00000000, ++ 0x036, 0x000063B5, ++ 0x036, 0x0000E3B5, ++ 0x036, 0x000163B5, ++ 0x036, 0x0001E3B5, ++ 0x036, 0x000263B5, ++ 0x036, 0x0002E3B5, ++ 0x036, 0x000363B5, ++ 0x036, 0x0003E3B5, ++ 0x036, 0x000463B5, ++ 0x036, 0x0004E3B5, ++ 0x036, 0x000563B5, ++ 0x036, 0x0005E3B5, ++ 0x9000040c, 0x00000000, 0x40000000, 0x00000000, ++ 0x036, 0x000056B3, ++ 0x036, 0x0000D6B3, ++ 0x036, 0x000156B3, ++ 0x036, 0x0001D6B3, ++ 0x036, 0x00026634, ++ 0x036, 0x0002E634, ++ 0x036, 0x00036634, ++ 0x036, 0x0003E634, ++ 0x036, 0x000467B4, ++ 0x036, 0x0004E7B4, ++ 0x036, 0x000567B4, ++ 0x036, 0x0005E7B4, ++ 0x90000200, 0x00000000, 0x40000000, 0x00000000, ++ 0x036, 0x000063B5, ++ 0x036, 0x0000E3B5, ++ 0x036, 0x000163B5, ++ 0x036, 0x0001E3B5, ++ 0x036, 0x000263B5, ++ 0x036, 0x0002E3B5, ++ 0x036, 0x000363B5, ++ 0x036, 0x0003E3B5, ++ 0x036, 0x000463B5, ++ 0x036, 0x0004E3B5, ++ 0x036, 0x000563B5, ++ 0x036, 0x0005E3B5, ++ 0x90000410, 0x00000000, 0x40000000, 0x00000000, ++ 0x036, 0x00085733, ++ 0x036, 0x0008D733, ++ 0x036, 0x00095733, ++ 0x036, 0x0009D733, ++ 0x036, 0x000A64B4, ++ 0x036, 0x000AE4B4, ++ 0x036, 0x000B64B4, ++ 0x036, 0x000BE4B4, ++ 0x036, 0x000C64B4, ++ 0x036, 0x000CE4B4, ++ 0x036, 0x000D64B4, ++ 0x036, 0x000DE4B4, ++ 0xA0000000, 0x00000000, ++ 0x036, 0x000056B3, ++ 0x036, 0x0000D6B3, ++ 0x036, 0x000156B3, ++ 0x036, 0x0001D6B3, ++ 0x036, 0x00026634, ++ 0x036, 0x0002E634, ++ 0x036, 0x00036634, ++ 0x036, 0x0003E634, ++ 0x036, 0x000467B4, ++ 0x036, 0x0004E7B4, ++ 0x036, 0x000567B4, ++ 0x036, 0x0005E7B4, ++ 0xB0000000, 0x00000000, ++ 0x0EF, 0x00000000, ++ 0x0EF, 0x00000008, ++ 0x80000111, 0x00000000, 0x40000000, 0x00000000, ++ 0x03C, 0x000001C8, ++ 0x03C, 0x00000492, ++ 0x90000110, 0x00000000, 0x40000000, 0x00000000, ++ 0x03C, 0x000001C8, ++ 0x03C, 0x00000492, ++ 0x90000210, 0x00000000, 0x40000000, 0x00000000, ++ 0x03C, 0x000001B6, ++ 0x03C, 0x00000492, ++ 0x9000040c, 0x00000000, 0x40000000, 0x00000000, ++ 0x03C, 0x0000022A, ++ 0x03C, 0x00000594, ++ 0x90000200, 0x00000000, 0x40000000, 0x00000000, ++ 0x03C, 0x000001B6, ++ 0x03C, 0x00000492, ++ 0x90000410, 0x00000000, 0x40000000, 0x00000000, ++ 0x03C, 0x000001C8, ++ 0x03C, 0x00000492, ++ 0xA0000000, 0x00000000, ++ 0x03C, 0x0000022A, ++ 0x03C, 0x00000594, ++ 0xB0000000, 0x00000000, ++ 0x80000111, 0x00000000, 0x40000000, 0x00000000, ++ 0x03C, 0x00000800, ++ 0x90000110, 0x00000000, 0x40000000, 0x00000000, ++ 0x03C, 0x00000800, ++ 0x90000210, 0x00000000, 0x40000000, 0x00000000, ++ 0x03C, 0x00000800, ++ 0x9000020c, 0x00000000, 0x40000000, 0x00000000, ++ 0x03C, 0x00000820, ++ 0x9000040c, 0x00000000, 0x40000000, 0x00000000, ++ 0x03C, 0x00000820, ++ 0x90000200, 0x00000000, 0x40000000, 0x00000000, ++ 0x03C, 0x00000800, ++ 0x90000410, 0x00000000, 0x40000000, 0x00000000, ++ 0x03C, 0x00000800, ++ 0xA0000000, 0x00000000, ++ 0x03C, 0x00000900, ++ 0xB0000000, 0x00000000, ++ 0x0EF, 0x00000000, ++ 0x018, 0x0001712A, ++ 0x0EF, 0x00000002, ++ 0x80000111, 0x00000000, 0x40000000, 0x00000000, ++ 0x008, 0x0004E400, ++ 0x90000110, 0x00000000, 0x40000000, 0x00000000, ++ 0x008, 0x0004E400, ++ 0x90000210, 0x00000000, 0x40000000, 0x00000000, ++ 0x008, 0x00002000, ++ 0x9000020c, 0x00000000, 0x40000000, 0x00000000, ++ 0x008, 0x00002000, ++ 0x9000040c, 0x00000000, 0x40000000, 0x00000000, ++ 0x008, 0x00002000, ++ 0x90000200, 0x00000000, 0x40000000, 0x00000000, ++ 0x008, 0x00002000, ++ 0x90000410, 0x00000000, 0x40000000, 0x00000000, ++ 0x008, 0x0004E400, ++ 0xA0000000, 0x00000000, ++ 0x008, 0x00002000, ++ 0xB0000000, 0x00000000, ++ 0x0EF, 0x00000000, ++ 0x0DF, 0x000000C0, ++ 0x01F, 0x00000064, ++ 0x80000111, 0x00000000, 0x40000000, 0x00000000, ++ 0x058, 0x000A7284, ++ 0x059, 0x000600EC, ++ 0x90000110, 0x00000000, 0x40000000, 0x00000000, ++ 0x058, 0x000A7284, ++ 0x059, 0x000600EC, ++ 0x9000020c, 0x00000000, 0x40000000, 0x00000000, ++ 0x058, 0x00081184, ++ 0x059, 0x0006016C, ++ 0x9000040c, 0x00000000, 0x40000000, 0x00000000, ++ 0x058, 0x00081184, ++ 0x059, 0x0006016C, ++ 0x90000200, 0x00000000, 0x40000000, 0x00000000, ++ 0x058, 0x00081184, ++ 0x059, 0x0006016C, ++ 0x90000410, 0x00000000, 0x40000000, 0x00000000, ++ 0x058, 0x000A7284, ++ 0x059, 0x000600EC, ++ 0xA0000000, 0x00000000, ++ 0x058, 0x00081184, ++ 0x059, 0x0006016C, ++ 0xB0000000, 0x00000000, ++ 0x80000111, 0x00000000, 0x40000000, 0x00000000, ++ 0x061, 0x000E8D73, ++ 0x062, 0x00093FC5, ++ 0x90000110, 0x00000000, 0x40000000, 0x00000000, ++ 0x061, 0x000E8D73, ++ 0x062, 0x00093FC5, ++ 0x90000210, 0x00000000, 0x40000000, 0x00000000, ++ 0x061, 0x000EFD83, ++ 0x062, 0x00093FCC, ++ 0x9000040c, 0x00000000, 0x40000000, 0x00000000, ++ 0x061, 0x000EAD53, ++ 0x062, 0x00093BC4, ++ 0x90000200, 0x00000000, 0x40000000, 0x00000000, ++ 0x061, 0x000EFD83, ++ 0x062, 0x00093FCC, ++ 0x90000410, 0x00000000, 0x40000000, 0x00000000, ++ 0x061, 0x000E8D73, ++ 0x062, 0x00093FC5, ++ 0xA0000000, 0x00000000, ++ 0x061, 0x000EAD53, ++ 0x062, 0x00093BC4, ++ 0xB0000000, 0x00000000, ++ 0x80000111, 0x00000000, 0x40000000, 0x00000000, ++ 0x063, 0x000110E9, ++ 0x90000110, 0x00000000, 0x40000000, 0x00000000, ++ 0x063, 0x000110E9, ++ 0x90000210, 0x00000000, 0x40000000, 0x00000000, ++ 0x063, 0x000110EB, ++ 0x9000020c, 0x00000000, 0x40000000, 0x00000000, ++ 0x063, 0x000110E9, ++ 0x9000040c, 0x00000000, 0x40000000, 0x00000000, ++ 0x063, 0x000110E9, ++ 0x90000200, 0x00000000, 0x40000000, 0x00000000, ++ 0x063, 0x000110EB, ++ 0x90000410, 0x00000000, 0x40000000, 0x00000000, ++ 0x063, 0x000110E9, ++ 0xA0000000, 0x00000000, ++ 0x063, 0x000714E9, ++ 0xB0000000, 0x00000000, ++ 0x80000111, 0x00000000, 0x40000000, 0x00000000, ++ 0x064, 0x0001C27C, ++ 0x90000110, 0x00000000, 0x40000000, 0x00000000, ++ 0x064, 0x0001C27C, ++ 0x90000210, 0x00000000, 0x40000000, 0x00000000, ++ 0x064, 0x0001C27C, ++ 0x9000040c, 0x00000000, 0x40000000, 0x00000000, ++ 0x064, 0x0001C67C, ++ 0x90000200, 0x00000000, 0x40000000, 0x00000000, ++ 0x064, 0x0001C27C, ++ 0x90000410, 0x00000000, 0x40000000, 0x00000000, ++ 0x064, 0x0001C27C, ++ 0xA0000000, 0x00000000, ++ 0x064, 0x0001C67C, ++ 0xB0000000, 0x00000000, ++ 0x80000111, 0x00000000, 0x40000000, 0x00000000, ++ 0x065, 0x00091016, ++ 0x90000110, 0x00000000, 0x40000000, 0x00000000, ++ 0x065, 0x00091016, ++ 0x90000210, 0x00000000, 0x40000000, 0x00000000, ++ 0x065, 0x00093016, ++ 0x9000020c, 0x00000000, 0x40000000, 0x00000000, ++ 0x065, 0x00093015, ++ 0x9000040c, 0x00000000, 0x40000000, 0x00000000, ++ 0x065, 0x00093015, ++ 0x90000200, 0x00000000, 0x40000000, 0x00000000, ++ 0x065, 0x00093016, ++ 0xA0000000, 0x00000000, ++ 0x065, 0x00091016, ++ 0xB0000000, 0x00000000, ++ 0x018, 0x00000006, ++ 0x0EF, 0x00002000, ++ 0x03B, 0x0003824B, ++ 0x03B, 0x0003024B, ++ 0x03B, 0x0002844B, ++ 0x03B, 0x00020F4B, ++ 0x03B, 0x00018F4B, ++ 0x03B, 0x000104B2, ++ 0x03B, 0x00008049, ++ 0x03B, 0x00000148, ++ 0x03B, 0x0007824B, ++ 0x03B, 0x0007024B, ++ 0x03B, 0x0006824B, ++ 0x03B, 0x00060F4B, ++ 0x03B, 0x00058F4B, ++ 0x03B, 0x000504B2, ++ 0x03B, 0x00048049, ++ 0x03B, 0x00040148, ++ 0x0EF, 0x00000000, ++ 0x0EF, 0x00000100, ++ 0x034, 0x0000ADF3, ++ 0x034, 0x00009DF0, ++ 0x034, 0x00008D70, ++ 0x034, 0x00007D6D, ++ 0x034, 0x00006CEE, ++ 0x034, 0x00005CCC, ++ 0x034, 0x000044EC, ++ 0x034, 0x000034AC, ++ 0x034, 0x0000246D, ++ 0x034, 0x0000106F, ++ 0x034, 0x0000006C, ++ 0x0EF, 0x00000000, ++ 0x0ED, 0x00000010, ++ 0x044, 0x0000ADF2, ++ 0x044, 0x00009DEF, ++ 0x044, 0x00008DEC, ++ 0x044, 0x00007DE9, ++ 0x044, 0x00006CEC, ++ 0x044, 0x00005CE9, ++ 0x044, 0x000044EC, ++ 0x044, 0x000034E9, ++ 0x044, 0x0000246C, ++ 0x044, 0x00001469, ++ 0x044, 0x0000006C, ++ 0x0ED, 0x00000000, ++ 0x0ED, 0x00000001, ++ 0x040, 0x00038DA7, ++ 0x040, 0x000300C2, ++ 0x040, 0x000288E2, ++ 0x040, 0x000200B8, ++ 0x040, 0x000188A5, ++ 0x040, 0x00010FBC, ++ 0x040, 0x00008F71, ++ 0x040, 0x00000240, ++ 0x0ED, 0x00000000, ++ 0x0EF, 0x000020A2, ++ 0x0DF, 0x00000080, ++ 0x035, 0x00000120, ++ 0x035, 0x00008120, ++ 0x035, 0x00010120, ++ 0x036, 0x00000085, ++ 0x036, 0x00008085, ++ 0x036, 0x00010085, ++ 0x036, 0x00018085, ++ 0x0EF, 0x00000000, ++ 0x051, 0x00000C31, ++ 0x052, 0x00000622, ++ 0x053, 0x000FC70B, ++ 0x054, 0x0000017E, ++ 0x056, 0x00051DF3, ++ 0x051, 0x00000C01, ++ 0x052, 0x000006D6, ++ 0x053, 0x000FC649, ++ 0x070, 0x00049661, ++ 0x071, 0x0007843E, ++ 0x072, 0x00000382, ++ 0x074, 0x00051400, ++ 0x035, 0x00000160, ++ 0x035, 0x00008160, ++ 0x035, 0x00010160, ++ 0x036, 0x00000124, ++ 0x036, 0x00008124, ++ 0x036, 0x00010124, ++ 0x036, 0x00018124, ++ 0x0ED, 0x0000000C, ++ 0x045, 0x00000140, ++ 0x045, 0x00008140, ++ 0x045, 0x00010140, ++ 0x046, 0x00000124, ++ 0x046, 0x00008124, ++ 0x046, 0x00010124, ++ 0x046, 0x00018124, ++ 0x0DF, 0x00000088, ++ 0x0B3, 0x000F0E18, ++ 0x0B4, 0x0001214C, ++ 0x0B7, 0x0003000C, ++ 0x01C, 0x000539D2, ++ 0x0C4, 0x000AFE00, ++ 0x018, 0x0001F12A, ++ 0xFFE, 0x00000000, ++ 0xFFE, 0x00000000, ++ 0x018, 0x0001712A, ++}; ++ ++RTW_DECL_TABLE_RF_RADIO(rtw8821a_rf_a, A); ++ ++static const struct rtw_txpwr_lmt_cfg_pair rtw8821a_txpwr_lmt[] = { ++ { 0, 0, 0, 0, 1, 32, }, ++ { 2, 0, 0, 0, 1, 28, }, ++ { 1, 0, 0, 0, 1, 32, }, ++ { 0, 0, 0, 0, 2, 32, }, ++ { 2, 0, 0, 0, 2, 28, }, ++ { 1, 0, 0, 0, 2, 32, }, ++ { 0, 0, 0, 0, 3, 36, }, ++ { 2, 0, 0, 0, 3, 28, }, ++ { 1, 0, 0, 0, 3, 32, }, ++ { 0, 0, 0, 0, 4, 36, }, ++ { 2, 0, 0, 0, 4, 28, }, ++ { 1, 0, 0, 0, 4, 32, }, ++ { 0, 0, 0, 0, 5, 36, }, ++ { 2, 0, 0, 0, 5, 28, }, ++ { 1, 0, 0, 0, 5, 32, }, ++ { 0, 0, 0, 0, 6, 36, }, ++ { 2, 0, 0, 0, 6, 28, }, ++ { 1, 0, 0, 0, 6, 32, }, ++ { 0, 0, 0, 0, 7, 36, }, ++ { 2, 0, 0, 0, 7, 28, }, ++ { 1, 0, 0, 0, 7, 32, }, ++ { 0, 0, 0, 0, 8, 36, }, ++ { 2, 0, 0, 0, 8, 28, }, ++ { 1, 0, 0, 0, 8, 32, }, ++ { 0, 0, 0, 0, 9, 32, }, ++ { 2, 0, 0, 0, 9, 28, }, ++ { 1, 0, 0, 0, 9, 32, }, ++ { 0, 0, 0, 0, 10, 32, }, ++ { 2, 0, 0, 0, 10, 28, }, ++ { 1, 0, 0, 0, 10, 32, }, ++ { 0, 0, 0, 0, 11, 32, }, ++ { 2, 0, 0, 0, 11, 28, }, ++ { 1, 0, 0, 0, 11, 32, }, ++ { 0, 0, 0, 0, 12, 28, }, ++ { 2, 0, 0, 0, 12, 28, }, ++ { 1, 0, 0, 0, 12, 32, }, ++ { 0, 0, 0, 0, 13, 26, }, ++ { 2, 0, 0, 0, 13, 28, }, ++ { 1, 0, 0, 0, 13, 32, }, ++ { 0, 0, 0, 0, 14, 63, }, ++ { 2, 0, 0, 0, 14, 63, }, ++ { 1, 0, 0, 0, 14, 32, }, ++ { 0, 0, 0, 1, 1, 30, }, ++ { 2, 0, 0, 1, 1, 30, }, ++ { 1, 0, 0, 1, 1, 32, }, ++ { 0, 0, 0, 1, 2, 30, }, ++ { 2, 0, 0, 1, 2, 32, }, ++ { 1, 0, 0, 1, 2, 32, }, ++ { 0, 0, 0, 1, 3, 32, }, ++ { 2, 0, 0, 1, 3, 32, }, ++ { 1, 0, 0, 1, 3, 32, }, ++ { 0, 0, 0, 1, 4, 32, }, ++ { 2, 0, 0, 1, 4, 32, }, ++ { 1, 0, 0, 1, 4, 32, }, ++ { 0, 0, 0, 1, 5, 32, }, ++ { 2, 0, 0, 1, 5, 32, }, ++ { 1, 0, 0, 1, 5, 32, }, ++ { 0, 0, 0, 1, 6, 32, }, ++ { 2, 0, 0, 1, 6, 32, }, ++ { 1, 0, 0, 1, 6, 32, }, ++ { 0, 0, 0, 1, 7, 32, }, ++ { 2, 0, 0, 1, 7, 32, }, ++ { 1, 0, 0, 1, 7, 32, }, ++ { 0, 0, 0, 1, 8, 32, }, ++ { 2, 0, 0, 1, 8, 32, }, ++ { 1, 0, 0, 1, 8, 32, }, ++ { 0, 0, 0, 1, 9, 30, }, ++ { 2, 0, 0, 1, 9, 32, }, ++ { 1, 0, 0, 1, 9, 32, }, ++ { 0, 0, 0, 1, 10, 30, }, ++ { 2, 0, 0, 1, 10, 32, }, ++ { 1, 0, 0, 1, 10, 32, }, ++ { 0, 0, 0, 1, 11, 30, }, ++ { 2, 0, 0, 1, 11, 32, }, ++ { 1, 0, 0, 1, 11, 32, }, ++ { 0, 0, 0, 1, 12, 26, }, ++ { 2, 0, 0, 1, 12, 32, }, ++ { 1, 0, 0, 1, 12, 32, }, ++ { 0, 0, 0, 1, 13, 24, }, ++ { 2, 0, 0, 1, 13, 30, }, ++ { 1, 0, 0, 1, 13, 32, }, ++ { 0, 0, 0, 1, 14, 63, }, ++ { 2, 0, 0, 1, 14, 63, }, ++ { 1, 0, 0, 1, 14, 63, }, ++ { 0, 0, 0, 2, 1, 26, }, ++ { 2, 0, 0, 2, 1, 26, }, ++ { 1, 0, 0, 2, 1, 32, }, ++ { 0, 0, 0, 2, 2, 26, }, ++ { 2, 0, 0, 2, 2, 32, }, ++ { 1, 0, 0, 2, 2, 32, }, ++ { 0, 0, 0, 2, 3, 32, }, ++ { 2, 0, 0, 2, 3, 32, }, ++ { 1, 0, 0, 2, 3, 32, }, ++ { 0, 0, 0, 2, 4, 32, }, ++ { 2, 0, 0, 2, 4, 32, }, ++ { 1, 0, 0, 2, 4, 32, }, ++ { 0, 0, 0, 2, 5, 32, }, ++ { 2, 0, 0, 2, 5, 32, }, ++ { 1, 0, 0, 2, 5, 32, }, ++ { 0, 0, 0, 2, 6, 32, }, ++ { 2, 0, 0, 2, 6, 32, }, ++ { 1, 0, 0, 2, 6, 32, }, ++ { 0, 0, 0, 2, 7, 32, }, ++ { 2, 0, 0, 2, 7, 32, }, ++ { 1, 0, 0, 2, 7, 32, }, ++ { 0, 0, 0, 2, 8, 32, }, ++ { 2, 0, 0, 2, 8, 32, }, ++ { 1, 0, 0, 2, 8, 32, }, ++ { 0, 0, 0, 2, 9, 26, }, ++ { 2, 0, 0, 2, 9, 32, }, ++ { 1, 0, 0, 2, 9, 32, }, ++ { 0, 0, 0, 2, 10, 26, }, ++ { 2, 0, 0, 2, 10, 32, }, ++ { 1, 0, 0, 2, 10, 32, }, ++ { 0, 0, 0, 2, 11, 26, }, ++ { 2, 0, 0, 2, 11, 32, }, ++ { 1, 0, 0, 2, 11, 32, }, ++ { 0, 0, 0, 2, 12, 26, }, ++ { 2, 0, 0, 2, 12, 32, }, ++ { 1, 0, 0, 2, 12, 32, }, ++ { 0, 0, 0, 2, 13, 24, }, ++ { 2, 0, 0, 2, 13, 26, }, ++ { 1, 0, 0, 2, 13, 32, }, ++ { 0, 0, 0, 2, 14, 63, }, ++ { 2, 0, 0, 2, 14, 63, }, ++ { 1, 0, 0, 2, 14, 63, }, ++ { 0, 0, 0, 3, 1, 30, }, ++ { 2, 0, 0, 3, 1, 32, }, ++ { 1, 0, 0, 3, 1, 32, }, ++ { 0, 0, 0, 3, 2, 32, }, ++ { 2, 0, 0, 3, 2, 32, }, ++ { 1, 0, 0, 3, 2, 32, }, ++ { 0, 0, 0, 3, 3, 32, }, ++ { 2, 0, 0, 3, 3, 32, }, ++ { 1, 0, 0, 3, 3, 32, }, ++ { 0, 0, 0, 3, 4, 32, }, ++ { 2, 0, 0, 3, 4, 32, }, ++ { 1, 0, 0, 3, 4, 32, }, ++ { 0, 0, 0, 3, 5, 32, }, ++ { 2, 0, 0, 3, 5, 32, }, ++ { 1, 0, 0, 3, 5, 32, }, ++ { 0, 0, 0, 3, 6, 32, }, ++ { 2, 0, 0, 3, 6, 32, }, ++ { 1, 0, 0, 3, 6, 32, }, ++ { 0, 0, 0, 3, 7, 32, }, ++ { 2, 0, 0, 3, 7, 32, }, ++ { 1, 0, 0, 3, 7, 32, }, ++ { 0, 0, 0, 3, 8, 32, }, ++ { 2, 0, 0, 3, 8, 32, }, ++ { 1, 0, 0, 3, 8, 32, }, ++ { 0, 0, 0, 3, 9, 32, }, ++ { 2, 0, 0, 3, 9, 32, }, ++ { 1, 0, 0, 3, 9, 32, }, ++ { 0, 0, 0, 3, 10, 32, }, ++ { 2, 0, 0, 3, 10, 32, }, ++ { 1, 0, 0, 3, 10, 32, }, ++ { 0, 0, 0, 3, 11, 30, }, ++ { 2, 0, 0, 3, 11, 32, }, ++ { 1, 0, 0, 3, 11, 32, }, ++ { 0, 0, 0, 3, 12, 63, }, ++ { 2, 0, 0, 3, 12, 32, }, ++ { 1, 0, 0, 3, 12, 32, }, ++ { 0, 0, 0, 3, 13, 63, }, ++ { 2, 0, 0, 3, 13, 32, }, ++ { 1, 0, 0, 3, 13, 32, }, ++ { 0, 0, 0, 3, 14, 63, }, ++ { 2, 0, 0, 3, 14, 63, }, ++ { 1, 0, 0, 3, 14, 63, }, ++ { 0, 0, 1, 2, 1, 63, }, ++ { 2, 0, 1, 2, 1, 63, }, ++ { 1, 0, 1, 2, 1, 63, }, ++ { 0, 0, 1, 2, 2, 63, }, ++ { 2, 0, 1, 2, 2, 63, }, ++ { 1, 0, 1, 2, 2, 63, }, ++ { 0, 0, 1, 2, 3, 26, }, ++ { 2, 0, 1, 2, 3, 26, }, ++ { 1, 0, 1, 2, 3, 32, }, ++ { 0, 0, 1, 2, 4, 26, }, ++ { 2, 0, 1, 2, 4, 32, }, ++ { 1, 0, 1, 2, 4, 32, }, ++ { 0, 0, 1, 2, 5, 26, }, ++ { 2, 0, 1, 2, 5, 32, }, ++ { 1, 0, 1, 2, 5, 32, }, ++ { 0, 0, 1, 2, 6, 32, }, ++ { 2, 0, 1, 2, 6, 32, }, ++ { 1, 0, 1, 2, 6, 32, }, ++ { 0, 0, 1, 2, 7, 32, }, ++ { 2, 0, 1, 2, 7, 32, }, ++ { 1, 0, 1, 2, 7, 32, }, ++ { 0, 0, 1, 2, 8, 32, }, ++ { 2, 0, 1, 2, 8, 32, }, ++ { 1, 0, 1, 2, 8, 32, }, ++ { 0, 0, 1, 2, 9, 26, }, ++ { 2, 0, 1, 2, 9, 32, }, ++ { 1, 0, 1, 2, 9, 32, }, ++ { 0, 0, 1, 2, 10, 24, }, ++ { 2, 0, 1, 2, 10, 32, }, ++ { 1, 0, 1, 2, 10, 32, }, ++ { 0, 0, 1, 2, 11, 22, }, ++ { 2, 0, 1, 2, 11, 26, }, ++ { 1, 0, 1, 2, 11, 32, }, ++ { 0, 0, 1, 2, 12, 63, }, ++ { 2, 0, 1, 2, 12, 63, }, ++ { 1, 0, 1, 2, 12, 63, }, ++ { 0, 0, 1, 2, 13, 63, }, ++ { 2, 0, 1, 2, 13, 63, }, ++ { 1, 0, 1, 2, 13, 63, }, ++ { 0, 0, 1, 2, 14, 63, }, ++ { 2, 0, 1, 2, 14, 63, }, ++ { 1, 0, 1, 2, 14, 63, }, ++ { 0, 0, 1, 3, 1, 63, }, ++ { 2, 0, 1, 3, 1, 63, }, ++ { 1, 0, 1, 3, 1, 63, }, ++ { 0, 0, 1, 3, 2, 63, }, ++ { 2, 0, 1, 3, 2, 63, }, ++ { 1, 0, 1, 3, 2, 63, }, ++ { 0, 0, 1, 3, 3, 30, }, ++ { 2, 0, 1, 3, 3, 30, }, ++ { 1, 0, 1, 3, 3, 30, }, ++ { 0, 0, 1, 3, 4, 32, }, ++ { 2, 0, 1, 3, 4, 30, }, ++ { 1, 0, 1, 3, 4, 30, }, ++ { 0, 0, 1, 3, 5, 32, }, ++ { 2, 0, 1, 3, 5, 30, }, ++ { 1, 0, 1, 3, 5, 30, }, ++ { 0, 0, 1, 3, 6, 32, }, ++ { 2, 0, 1, 3, 6, 30, }, ++ { 1, 0, 1, 3, 6, 30, }, ++ { 0, 0, 1, 3, 7, 32, }, ++ { 2, 0, 1, 3, 7, 30, }, ++ { 1, 0, 1, 3, 7, 30, }, ++ { 0, 0, 1, 3, 8, 32, }, ++ { 2, 0, 1, 3, 8, 30, }, ++ { 1, 0, 1, 3, 8, 30, }, ++ { 0, 0, 1, 3, 9, 32, }, ++ { 2, 0, 1, 3, 9, 30, }, ++ { 1, 0, 1, 3, 9, 30, }, ++ { 0, 0, 1, 3, 10, 32, }, ++ { 2, 0, 1, 3, 10, 30, }, ++ { 1, 0, 1, 3, 10, 30, }, ++ { 0, 0, 1, 3, 11, 30, }, ++ { 2, 0, 1, 3, 11, 30, }, ++ { 1, 0, 1, 3, 11, 30, }, ++ { 0, 0, 1, 3, 12, 63, }, ++ { 2, 0, 1, 3, 12, 32, }, ++ { 1, 0, 1, 3, 12, 32, }, ++ { 0, 0, 1, 3, 13, 63, }, ++ { 2, 0, 1, 3, 13, 32, }, ++ { 1, 0, 1, 3, 13, 32, }, ++ { 0, 0, 1, 3, 14, 63, }, ++ { 2, 0, 1, 3, 14, 63, }, ++ { 1, 0, 1, 3, 14, 63, }, ++ { 0, 1, 0, 1, 36, 32, }, ++ { 2, 1, 0, 1, 36, 30, }, ++ { 1, 1, 0, 1, 36, 30, }, ++ { 0, 1, 0, 1, 40, 32, }, ++ { 2, 1, 0, 1, 40, 30, }, ++ { 1, 1, 0, 1, 40, 30, }, ++ { 0, 1, 0, 1, 44, 32, }, ++ { 2, 1, 0, 1, 44, 30, }, ++ { 1, 1, 0, 1, 44, 30, }, ++ { 0, 1, 0, 1, 48, 32, }, ++ { 2, 1, 0, 1, 48, 30, }, ++ { 1, 1, 0, 1, 48, 30, }, ++ { 0, 1, 0, 1, 52, 32, }, ++ { 2, 1, 0, 1, 52, 30, }, ++ { 1, 1, 0, 1, 52, 30, }, ++ { 0, 1, 0, 1, 56, 32, }, ++ { 2, 1, 0, 1, 56, 30, }, ++ { 1, 1, 0, 1, 56, 30, }, ++ { 0, 1, 0, 1, 60, 32, }, ++ { 2, 1, 0, 1, 60, 30, }, ++ { 1, 1, 0, 1, 60, 30, }, ++ { 0, 1, 0, 1, 64, 32, }, ++ { 2, 1, 0, 1, 64, 30, }, ++ { 1, 1, 0, 1, 64, 30, }, ++ { 0, 1, 0, 1, 100, 32, }, ++ { 2, 1, 0, 1, 100, 30, }, ++ { 1, 1, 0, 1, 100, 30, }, ++ { 0, 1, 0, 1, 104, 32, }, ++ { 2, 1, 0, 1, 104, 30, }, ++ { 1, 1, 0, 1, 104, 30, }, ++ { 0, 1, 0, 1, 108, 32, }, ++ { 2, 1, 0, 1, 108, 30, }, ++ { 1, 1, 0, 1, 108, 30, }, ++ { 0, 1, 0, 1, 112, 32, }, ++ { 2, 1, 0, 1, 112, 30, }, ++ { 1, 1, 0, 1, 112, 30, }, ++ { 0, 1, 0, 1, 116, 32, }, ++ { 2, 1, 0, 1, 116, 30, }, ++ { 1, 1, 0, 1, 116, 30, }, ++ { 0, 1, 0, 1, 120, 32, }, ++ { 2, 1, 0, 1, 120, 30, }, ++ { 1, 1, 0, 1, 120, 30, }, ++ { 0, 1, 0, 1, 124, 32, }, ++ { 2, 1, 0, 1, 124, 30, }, ++ { 1, 1, 0, 1, 124, 30, }, ++ { 0, 1, 0, 1, 128, 32, }, ++ { 2, 1, 0, 1, 128, 30, }, ++ { 1, 1, 0, 1, 128, 30, }, ++ { 0, 1, 0, 1, 132, 32, }, ++ { 2, 1, 0, 1, 132, 30, }, ++ { 1, 1, 0, 1, 132, 30, }, ++ { 0, 1, 0, 1, 136, 32, }, ++ { 2, 1, 0, 1, 136, 30, }, ++ { 1, 1, 0, 1, 136, 30, }, ++ { 0, 1, 0, 1, 140, 32, }, ++ { 2, 1, 0, 1, 140, 30, }, ++ { 1, 1, 0, 1, 140, 30, }, ++ { 0, 1, 0, 1, 149, 32, }, ++ { 2, 1, 0, 1, 149, 30, }, ++ { 1, 1, 0, 1, 149, 63, }, ++ { 0, 1, 0, 1, 153, 32, }, ++ { 2, 1, 0, 1, 153, 30, }, ++ { 1, 1, 0, 1, 153, 63, }, ++ { 0, 1, 0, 1, 157, 32, }, ++ { 2, 1, 0, 1, 157, 30, }, ++ { 1, 1, 0, 1, 157, 63, }, ++ { 0, 1, 0, 1, 161, 32, }, ++ { 2, 1, 0, 1, 161, 30, }, ++ { 1, 1, 0, 1, 161, 63, }, ++ { 0, 1, 0, 1, 165, 32, }, ++ { 2, 1, 0, 1, 165, 30, }, ++ { 1, 1, 0, 1, 165, 63, }, ++ { 0, 1, 0, 2, 36, 32, }, ++ { 2, 1, 0, 2, 36, 30, }, ++ { 1, 1, 0, 2, 36, 30, }, ++ { 0, 1, 0, 2, 40, 32, }, ++ { 2, 1, 0, 2, 40, 30, }, ++ { 1, 1, 0, 2, 40, 30, }, ++ { 0, 1, 0, 2, 44, 32, }, ++ { 2, 1, 0, 2, 44, 30, }, ++ { 1, 1, 0, 2, 44, 30, }, ++ { 0, 1, 0, 2, 48, 32, }, ++ { 2, 1, 0, 2, 48, 30, }, ++ { 1, 1, 0, 2, 48, 30, }, ++ { 0, 1, 0, 2, 52, 32, }, ++ { 2, 1, 0, 2, 52, 30, }, ++ { 1, 1, 0, 2, 52, 30, }, ++ { 0, 1, 0, 2, 56, 32, }, ++ { 2, 1, 0, 2, 56, 30, }, ++ { 1, 1, 0, 2, 56, 30, }, ++ { 0, 1, 0, 2, 60, 32, }, ++ { 2, 1, 0, 2, 60, 30, }, ++ { 1, 1, 0, 2, 60, 30, }, ++ { 0, 1, 0, 2, 64, 32, }, ++ { 2, 1, 0, 2, 64, 30, }, ++ { 1, 1, 0, 2, 64, 30, }, ++ { 0, 1, 0, 2, 100, 32, }, ++ { 2, 1, 0, 2, 100, 30, }, ++ { 1, 1, 0, 2, 100, 30, }, ++ { 0, 1, 0, 2, 104, 32, }, ++ { 2, 1, 0, 2, 104, 30, }, ++ { 1, 1, 0, 2, 104, 30, }, ++ { 0, 1, 0, 2, 108, 32, }, ++ { 2, 1, 0, 2, 108, 30, }, ++ { 1, 1, 0, 2, 108, 30, }, ++ { 0, 1, 0, 2, 112, 32, }, ++ { 2, 1, 0, 2, 112, 30, }, ++ { 1, 1, 0, 2, 112, 30, }, ++ { 0, 1, 0, 2, 116, 32, }, ++ { 2, 1, 0, 2, 116, 30, }, ++ { 1, 1, 0, 2, 116, 30, }, ++ { 0, 1, 0, 2, 120, 32, }, ++ { 2, 1, 0, 2, 120, 30, }, ++ { 1, 1, 0, 2, 120, 30, }, ++ { 0, 1, 0, 2, 124, 32, }, ++ { 2, 1, 0, 2, 124, 30, }, ++ { 1, 1, 0, 2, 124, 30, }, ++ { 0, 1, 0, 2, 128, 32, }, ++ { 2, 1, 0, 2, 128, 30, }, ++ { 1, 1, 0, 2, 128, 30, }, ++ { 0, 1, 0, 2, 132, 32, }, ++ { 2, 1, 0, 2, 132, 30, }, ++ { 1, 1, 0, 2, 132, 30, }, ++ { 0, 1, 0, 2, 136, 32, }, ++ { 2, 1, 0, 2, 136, 30, }, ++ { 1, 1, 0, 2, 136, 30, }, ++ { 0, 1, 0, 2, 140, 32, }, ++ { 2, 1, 0, 2, 140, 30, }, ++ { 1, 1, 0, 2, 140, 30, }, ++ { 0, 1, 0, 2, 149, 32, }, ++ { 2, 1, 0, 2, 149, 30, }, ++ { 1, 1, 0, 2, 149, 63, }, ++ { 0, 1, 0, 2, 153, 32, }, ++ { 2, 1, 0, 2, 153, 30, }, ++ { 1, 1, 0, 2, 153, 63, }, ++ { 0, 1, 0, 2, 157, 32, }, ++ { 2, 1, 0, 2, 157, 30, }, ++ { 1, 1, 0, 2, 157, 63, }, ++ { 0, 1, 0, 2, 161, 32, }, ++ { 2, 1, 0, 2, 161, 30, }, ++ { 1, 1, 0, 2, 161, 63, }, ++ { 0, 1, 0, 2, 165, 32, }, ++ { 2, 1, 0, 2, 165, 30, }, ++ { 1, 1, 0, 2, 165, 63, }, ++ { 0, 1, 0, 3, 36, 28, }, ++ { 2, 1, 0, 3, 36, 30, }, ++ { 1, 1, 0, 3, 36, 30, }, ++ { 0, 1, 0, 3, 40, 28, }, ++ { 2, 1, 0, 3, 40, 30, }, ++ { 1, 1, 0, 3, 40, 30, }, ++ { 0, 1, 0, 3, 44, 28, }, ++ { 2, 1, 0, 3, 44, 30, }, ++ { 1, 1, 0, 3, 44, 30, }, ++ { 0, 1, 0, 3, 48, 28, }, ++ { 2, 1, 0, 3, 48, 30, }, ++ { 1, 1, 0, 3, 48, 30, }, ++ { 0, 1, 0, 3, 52, 34, }, ++ { 2, 1, 0, 3, 52, 30, }, ++ { 1, 1, 0, 3, 52, 30, }, ++ { 0, 1, 0, 3, 56, 32, }, ++ { 2, 1, 0, 3, 56, 30, }, ++ { 1, 1, 0, 3, 56, 30, }, ++ { 0, 1, 0, 3, 60, 30, }, ++ { 2, 1, 0, 3, 60, 30, }, ++ { 1, 1, 0, 3, 60, 30, }, ++ { 0, 1, 0, 3, 64, 26, }, ++ { 2, 1, 0, 3, 64, 30, }, ++ { 1, 1, 0, 3, 64, 30, }, ++ { 0, 1, 0, 3, 100, 28, }, ++ { 2, 1, 0, 3, 100, 30, }, ++ { 1, 1, 0, 3, 100, 30, }, ++ { 0, 1, 0, 3, 104, 28, }, ++ { 2, 1, 0, 3, 104, 30, }, ++ { 1, 1, 0, 3, 104, 30, }, ++ { 0, 1, 0, 3, 108, 30, }, ++ { 2, 1, 0, 3, 108, 30, }, ++ { 1, 1, 0, 3, 108, 30, }, ++ { 0, 1, 0, 3, 112, 32, }, ++ { 2, 1, 0, 3, 112, 30, }, ++ { 1, 1, 0, 3, 112, 30, }, ++ { 0, 1, 0, 3, 116, 32, }, ++ { 2, 1, 0, 3, 116, 30, }, ++ { 1, 1, 0, 3, 116, 30, }, ++ { 0, 1, 0, 3, 120, 34, }, ++ { 2, 1, 0, 3, 120, 30, }, ++ { 1, 1, 0, 3, 120, 30, }, ++ { 0, 1, 0, 3, 124, 32, }, ++ { 2, 1, 0, 3, 124, 30, }, ++ { 1, 1, 0, 3, 124, 30, }, ++ { 0, 1, 0, 3, 128, 30, }, ++ { 2, 1, 0, 3, 128, 30, }, ++ { 1, 1, 0, 3, 128, 30, }, ++ { 0, 1, 0, 3, 132, 28, }, ++ { 2, 1, 0, 3, 132, 30, }, ++ { 1, 1, 0, 3, 132, 30, }, ++ { 0, 1, 0, 3, 136, 28, }, ++ { 2, 1, 0, 3, 136, 30, }, ++ { 1, 1, 0, 3, 136, 30, }, ++ { 0, 1, 0, 3, 140, 26, }, ++ { 2, 1, 0, 3, 140, 30, }, ++ { 1, 1, 0, 3, 140, 30, }, ++ { 0, 1, 0, 3, 149, 34, }, ++ { 2, 1, 0, 3, 149, 30, }, ++ { 1, 1, 0, 3, 149, 63, }, ++ { 0, 1, 0, 3, 153, 34, }, ++ { 2, 1, 0, 3, 153, 30, }, ++ { 1, 1, 0, 3, 153, 63, }, ++ { 0, 1, 0, 3, 157, 34, }, ++ { 2, 1, 0, 3, 157, 30, }, ++ { 1, 1, 0, 3, 157, 63, }, ++ { 0, 1, 0, 3, 161, 34, }, ++ { 2, 1, 0, 3, 161, 30, }, ++ { 1, 1, 0, 3, 161, 63, }, ++ { 0, 1, 0, 3, 165, 34, }, ++ { 2, 1, 0, 3, 165, 30, }, ++ { 1, 1, 0, 3, 165, 63, }, ++ { 0, 1, 1, 2, 38, 26, }, ++ { 2, 1, 1, 2, 38, 30, }, ++ { 1, 1, 1, 2, 38, 30, }, ++ { 0, 1, 1, 2, 46, 32, }, ++ { 2, 1, 1, 2, 46, 30, }, ++ { 1, 1, 1, 2, 46, 30, }, ++ { 0, 1, 1, 2, 54, 32, }, ++ { 2, 1, 1, 2, 54, 30, }, ++ { 1, 1, 1, 2, 54, 30, }, ++ { 0, 1, 1, 2, 62, 24, }, ++ { 2, 1, 1, 2, 62, 30, }, ++ { 1, 1, 1, 2, 62, 30, }, ++ { 0, 1, 1, 2, 102, 24, }, ++ { 2, 1, 1, 2, 102, 30, }, ++ { 1, 1, 1, 2, 102, 30, }, ++ { 0, 1, 1, 2, 110, 32, }, ++ { 2, 1, 1, 2, 110, 30, }, ++ { 1, 1, 1, 2, 110, 30, }, ++ { 0, 1, 1, 2, 118, 32, }, ++ { 2, 1, 1, 2, 118, 30, }, ++ { 1, 1, 1, 2, 118, 30, }, ++ { 0, 1, 1, 2, 126, 32, }, ++ { 2, 1, 1, 2, 126, 30, }, ++ { 1, 1, 1, 2, 126, 30, }, ++ { 0, 1, 1, 2, 134, 32, }, ++ { 2, 1, 1, 2, 134, 30, }, ++ { 1, 1, 1, 2, 134, 30, }, ++ { 0, 1, 1, 2, 151, 30, }, ++ { 2, 1, 1, 2, 151, 30, }, ++ { 1, 1, 1, 2, 151, 63, }, ++ { 0, 1, 1, 2, 159, 32, }, ++ { 2, 1, 1, 2, 159, 30, }, ++ { 1, 1, 1, 2, 159, 63, }, ++ { 0, 1, 1, 3, 38, 28, }, ++ { 2, 1, 1, 3, 38, 30, }, ++ { 1, 1, 1, 3, 38, 30, }, ++ { 0, 1, 1, 3, 46, 28, }, ++ { 2, 1, 1, 3, 46, 30, }, ++ { 1, 1, 1, 3, 46, 30, }, ++ { 0, 1, 1, 3, 54, 30, }, ++ { 2, 1, 1, 3, 54, 30, }, ++ { 1, 1, 1, 3, 54, 30, }, ++ { 0, 1, 1, 3, 62, 30, }, ++ { 2, 1, 1, 3, 62, 30, }, ++ { 1, 1, 1, 3, 62, 30, }, ++ { 0, 1, 1, 3, 102, 26, }, ++ { 2, 1, 1, 3, 102, 30, }, ++ { 1, 1, 1, 3, 102, 30, }, ++ { 0, 1, 1, 3, 110, 30, }, ++ { 2, 1, 1, 3, 110, 30, }, ++ { 1, 1, 1, 3, 110, 30, }, ++ { 0, 1, 1, 3, 118, 34, }, ++ { 2, 1, 1, 3, 118, 30, }, ++ { 1, 1, 1, 3, 118, 30, }, ++ { 0, 1, 1, 3, 126, 32, }, ++ { 2, 1, 1, 3, 126, 30, }, ++ { 1, 1, 1, 3, 126, 30, }, ++ { 0, 1, 1, 3, 134, 30, }, ++ { 2, 1, 1, 3, 134, 30, }, ++ { 1, 1, 1, 3, 134, 30, }, ++ { 0, 1, 1, 3, 151, 34, }, ++ { 2, 1, 1, 3, 151, 30, }, ++ { 1, 1, 1, 3, 151, 63, }, ++ { 0, 1, 1, 3, 159, 34, }, ++ { 2, 1, 1, 3, 159, 30, }, ++ { 1, 1, 1, 3, 159, 63, }, ++ { 0, 1, 2, 4, 42, 22, }, ++ { 2, 1, 2, 4, 42, 30, }, ++ { 1, 1, 2, 4, 42, 30, }, ++ { 0, 1, 2, 4, 58, 20, }, ++ { 2, 1, 2, 4, 58, 30, }, ++ { 1, 1, 2, 4, 58, 30, }, ++ { 0, 1, 2, 4, 106, 20, }, ++ { 2, 1, 2, 4, 106, 30, }, ++ { 1, 1, 2, 4, 106, 30, }, ++ { 0, 1, 2, 4, 122, 20, }, ++ { 2, 1, 2, 4, 122, 30, }, ++ { 1, 1, 2, 4, 122, 30, }, ++ { 0, 1, 2, 4, 155, 28, }, ++ { 2, 1, 2, 4, 155, 30, }, ++ { 1, 1, 2, 4, 155, 63, }, ++ { 0, 1, 2, 5, 42, 28, }, ++ { 2, 1, 2, 5, 42, 30, }, ++ { 1, 1, 2, 5, 42, 30, }, ++ { 0, 1, 2, 5, 58, 26, }, ++ { 2, 1, 2, 5, 58, 30, }, ++ { 1, 1, 2, 5, 58, 30, }, ++ { 0, 1, 2, 5, 106, 28, }, ++ { 2, 1, 2, 5, 106, 30, }, ++ { 1, 1, 2, 5, 106, 30, }, ++ { 0, 1, 2, 5, 122, 32, }, ++ { 2, 1, 2, 5, 122, 30, }, ++ { 1, 1, 2, 5, 122, 30, }, ++ { 0, 1, 2, 5, 155, 34, }, ++ { 2, 1, 2, 5, 155, 30, }, ++ { 1, 1, 2, 5, 155, 63, }, ++}; ++ ++RTW_DECL_TABLE_TXPWR_LMT(rtw8821a_txpwr_lmt); ++ ++static const struct rtw_pwr_seq_cmd trans_carddis_to_cardemu_8821a[] = { ++ {0x0005, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(3) | BIT(7), 0}, ++ {0x0086, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_SDIO_MSK, ++ RTW_PWR_ADDR_SDIO, ++ RTW_PWR_CMD_WRITE, BIT(0), 0}, ++ {0x0086, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_SDIO_MSK, ++ RTW_PWR_ADDR_SDIO, ++ RTW_PWR_CMD_POLLING, BIT(1), BIT(1)}, ++ {0x004A, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_USB_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(0), 0}, ++ {0x0005, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(3) | BIT(4), 0}, ++ {0x0023, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_SDIO_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(4), 0}, ++ {0x0301, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_PCI_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, 0xFF, 0}, ++ {0xFFFF, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ 0, ++ RTW_PWR_CMD_END, 0, 0}, ++}; ++ ++static const struct rtw_pwr_seq_cmd trans_cardemu_to_act_8821a[] = { ++ {0x0020, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(0), BIT(0)}, ++ {0x0067, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(4), 0}, ++ {0x0001, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_DELAY, 1, RTW_PWR_DELAY_MS}, ++ {0x0000, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(5), 0}, ++ {0x0005, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(4) | BIT(3) | BIT(2), 0}, ++ {0x0075, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_PCI_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(0), BIT(0)}, ++ {0x0006, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_POLLING, BIT(1), BIT(1)}, ++ {0x0075, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_PCI_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(0), 0}, ++ {0x0006, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(0), BIT(0)}, ++ {0x0005, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(7), 0}, ++ {0x0005, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(4) | BIT(3), 0}, ++ {0x0005, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(0), BIT(0)}, ++ {0x0005, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_POLLING, BIT(0), 0}, ++ {0x004F, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(0), BIT(0)}, ++ {0x0067, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(5) | BIT(4), BIT(5) | BIT(4)}, ++ {0x0025, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(6), 0}, ++ {0x0049, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(1), BIT(1)}, ++ {0x0063, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(1), BIT(1)}, ++ {0x0062, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(1), 0}, ++ {0x0058, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(0), BIT(0)}, ++ {0x005A, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(1), BIT(1)}, ++ {0x002E, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, 0xFF, 0x82}, ++ {0x0010, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(6), BIT(6)}, ++ {0xFFFF, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ 0, ++ RTW_PWR_CMD_END, 0, 0}, ++}; ++ ++static const struct rtw_pwr_seq_cmd trans_act_to_lps_8821a[] = { ++ {0x0301, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_PCI_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, 0xFF, 0xFF}, ++ {0x0522, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, 0xFF, 0xFF}, ++ {0x05F8, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_POLLING, 0xFF, 0}, ++ {0x05F9, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_POLLING, 0xFF, 0}, ++ {0x05FA, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_POLLING, 0xFF, 0}, ++ {0x05FB, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_POLLING, 0xFF, 0}, ++ {0x0002, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(0), 0}, ++ {0x0002, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_DELAY, 0, RTW_PWR_DELAY_US}, ++ {0x0002, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(1), 0}, ++ {0x0100, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, 0xFF, 0x03}, ++ {0x0101, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(1), 0}, ++ {0x0093, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_SDIO_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, 0xFF, 0x00}, ++ {0x0553, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(5), BIT(5)}, ++ {0xFFFF, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ 0, ++ RTW_PWR_CMD_END, 0, 0}, ++}; ++ ++static const struct rtw_pwr_seq_cmd trans_act_to_cardemu_8821a[] = { ++ {0x001F, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, 0xFF, 0}, ++ {0x004F, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(0), 0}, ++ {0x0049, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(1), 0}, ++ {0x0006, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_USB_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(0), BIT(0)}, ++ {0x0005, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(1), BIT(1)}, ++ {0x0005, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_POLLING, BIT(1), 0}, ++ {0x0000, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(5), BIT(5)}, ++ {0x0020, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(0), 0}, ++ {0xFFFF, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ 0, ++ RTW_PWR_CMD_END, 0, 0}, ++}; ++ ++static const struct rtw_pwr_seq_cmd trans_cardemu_to_carddis_8821a[] = { ++ {0x0007, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_SDIO_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, 0xFF, 0x20}, ++ {0x0005, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(3) | BIT(4), BIT(3)}, ++ {0x0005, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_PCI_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(2), BIT(2)}, ++ {0x004A, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_USB_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(0), 1}, ++ {0x0023, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_SDIO_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(4), BIT(4)}, ++ {0x0086, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_SDIO_MSK, ++ RTW_PWR_ADDR_SDIO, ++ RTW_PWR_CMD_WRITE, BIT(0), BIT(0)}, ++ {0x0086, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_SDIO_MSK, ++ RTW_PWR_ADDR_SDIO, ++ RTW_PWR_CMD_POLLING, BIT(1), 0}, ++ {0xFFFF, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ 0, ++ RTW_PWR_CMD_END, 0, 0}, ++}; ++ ++const struct rtw_pwr_seq_cmd * const card_enable_flow_8821a[] = { ++ trans_carddis_to_cardemu_8821a, ++ trans_cardemu_to_act_8821a, ++ NULL ++}; ++ ++const struct rtw_pwr_seq_cmd * const enter_lps_flow_8821a[] = { ++ trans_act_to_lps_8821a, ++ NULL ++}; ++ ++const struct rtw_pwr_seq_cmd * const card_disable_flow_8821a[] = { ++ trans_act_to_cardemu_8821a, ++ trans_cardemu_to_carddis_8821a, ++ NULL ++}; ++ ++static const u8 rtw8821a_pwrtrk_5gb_n[][RTW_PWR_TRK_TBL_SZ] = { ++ {0, 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11, 12, 12, 13, 14, 15, ++ 15, 16, 16, 16, 16, 16, 16, 16, 16}, ++ {0, 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11, 12, 12, 13, 14, 15, ++ 15, 16, 16, 16, 16, 16, 16, 16, 16}, ++ {0, 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11, 12, 12, 13, 14, 15, ++ 15, 16, 16, 16, 16, 16, 16, 16, 16}, ++}; ++ ++static const u8 rtw8821a_pwrtrk_5gb_p[][RTW_PWR_TRK_TBL_SZ] = { ++ {0, 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11, 12, 12, 13, 14, 15, ++ 15, 16, 16, 16, 16, 16, 16, 16, 16}, ++ {0, 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11, 12, 12, 13, 14, 15, ++ 15, 16, 16, 16, 16, 16, 16, 16, 16}, ++ {0, 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11, 12, 12, 13, 14, 15, ++ 15, 16, 16, 16, 16, 16, 16, 16, 16}, ++}; ++ ++static const u8 rtw8821a_pwrtrk_5ga_n[][RTW_PWR_TRK_TBL_SZ] = { ++ {0, 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11, 12, 12, 13, 14, 15, ++ 15, 16, 16, 16, 16, 16, 16, 16, 16}, ++ {0, 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11, 12, 12, 13, 14, 15, ++ 15, 16, 16, 16, 16, 16, 16, 16, 16}, ++ {0, 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11, 12, 12, 13, 14, 15, ++ 15, 16, 16, 16, 16, 16, 16, 16, 16}, ++}; ++ ++static const u8 rtw8821a_pwrtrk_5ga_p[][RTW_PWR_TRK_TBL_SZ] = { ++ {0, 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11, 12, 12, 13, 14, 15, ++ 15, 16, 16, 16, 16, 16, 16, 16, 16}, ++ {0, 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11, 12, 12, 13, 14, 15, ++ 15, 16, 16, 16, 16, 16, 16, 16, 16}, ++ {0, 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11, 12, 12, 13, 14, 15, ++ 15, 16, 16, 16, 16, 16, 16, 16, 16}, ++}; ++ ++static const u8 rtw8821a_pwrtrk_2gb_n[] = { ++ 0, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, ++ 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10 ++}; ++ ++static const u8 rtw8821a_pwrtrk_2gb_p[] = { ++ 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, ++ 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12, 12, 12 ++}; ++ ++static const u8 rtw8821a_pwrtrk_2ga_n[] = { ++ 0, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, ++ 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10 ++}; ++ ++static const u8 rtw8821a_pwrtrk_2ga_p[] = { ++ 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, ++ 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12, 12, 12 ++}; ++ ++static const u8 rtw8821a_pwrtrk_2g_cck_b_n[] = { ++ 0, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, ++ 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10 ++}; ++ ++static const u8 rtw8821a_pwrtrk_2g_cck_b_p[] = { ++ 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, ++ 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12, 12, 12 ++}; ++ ++static const u8 rtw8821a_pwrtrk_2g_cck_a_n[] = { ++ 0, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, ++ 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10 ++}; ++ ++static const u8 rtw8821a_pwrtrk_2g_cck_a_p[] = { ++ 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, ++ 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12, 12, 12 ++}; ++ ++const struct rtw_pwr_track_tbl rtw8821a_rtw_pwr_track_tbl = { ++ .pwrtrk_5gb_n[0] = rtw8821a_pwrtrk_5gb_n[0], ++ .pwrtrk_5gb_n[1] = rtw8821a_pwrtrk_5gb_n[1], ++ .pwrtrk_5gb_n[2] = rtw8821a_pwrtrk_5gb_n[2], ++ .pwrtrk_5gb_p[0] = rtw8821a_pwrtrk_5gb_p[0], ++ .pwrtrk_5gb_p[1] = rtw8821a_pwrtrk_5gb_p[1], ++ .pwrtrk_5gb_p[2] = rtw8821a_pwrtrk_5gb_p[2], ++ .pwrtrk_5ga_n[0] = rtw8821a_pwrtrk_5ga_n[0], ++ .pwrtrk_5ga_n[1] = rtw8821a_pwrtrk_5ga_n[1], ++ .pwrtrk_5ga_n[2] = rtw8821a_pwrtrk_5ga_n[2], ++ .pwrtrk_5ga_p[0] = rtw8821a_pwrtrk_5ga_p[0], ++ .pwrtrk_5ga_p[1] = rtw8821a_pwrtrk_5ga_p[1], ++ .pwrtrk_5ga_p[2] = rtw8821a_pwrtrk_5ga_p[2], ++ .pwrtrk_2gb_n = rtw8821a_pwrtrk_2gb_n, ++ .pwrtrk_2gb_p = rtw8821a_pwrtrk_2gb_p, ++ .pwrtrk_2ga_n = rtw8821a_pwrtrk_2ga_n, ++ .pwrtrk_2ga_p = rtw8821a_pwrtrk_2ga_p, ++ .pwrtrk_2g_cckb_n = rtw8821a_pwrtrk_2g_cck_b_n, ++ .pwrtrk_2g_cckb_p = rtw8821a_pwrtrk_2g_cck_b_p, ++ .pwrtrk_2g_ccka_n = rtw8821a_pwrtrk_2g_cck_a_n, ++ .pwrtrk_2g_ccka_p = rtw8821a_pwrtrk_2g_cck_a_p, ++}; +--- /dev/null ++++ b/drivers/net/wireless/realtek/rtw88/rtw8821a_table.h +@@ -0,0 +1,21 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2024 Realtek Corporation ++ */ ++ ++#ifndef __RTW8821A_TABLE_H__ ++#define __RTW8821A_TABLE_H__ ++ ++extern const struct rtw_table rtw8821a_mac_tbl; ++extern const struct rtw_table rtw8821a_agc_tbl; ++extern const struct rtw_table rtw8821a_bb_tbl; ++extern const struct rtw_table rtw8821a_bb_pg_tbl; ++extern const struct rtw_table rtw8821a_rf_a_tbl; ++extern const struct rtw_table rtw8821a_txpwr_lmt_tbl; ++ ++extern const struct rtw_pwr_seq_cmd * const card_enable_flow_8821a[]; ++extern const struct rtw_pwr_seq_cmd * const enter_lps_flow_8821a[]; ++extern const struct rtw_pwr_seq_cmd * const card_disable_flow_8821a[]; ++ ++extern const struct rtw_pwr_track_tbl rtw8821a_rtw_pwr_track_tbl; ++ ++#endif diff --git a/package/kernel/mac80211/patches/rtl/041-v6.13-wifi-rtw88-Add-rtw88xxa.-c-h.patch b/package/kernel/mac80211/patches/rtl/041-v6.13-wifi-rtw88-Add-rtw88xxa.-c-h.patch new file mode 100644 index 00000000000000..79e1deebf795ac --- /dev/null +++ b/package/kernel/mac80211/patches/rtl/041-v6.13-wifi-rtw88-Add-rtw88xxa.-c-h.patch @@ -0,0 +1,2187 @@ +From b870b9d31c9e4e6b20c410e1e017f8c87d4c2ae0 Mon Sep 17 00:00:00 2001 +From: Bitterblue Smith +Date: Wed, 30 Oct 2024 20:27:39 +0200 +Subject: [PATCH] wifi: rtw88: Add rtw88xxa.{c,h} + +These contain code shared by both RTL8821AU and RTL8812AU chips. + +Signed-off-by: Bitterblue Smith +Signed-off-by: Ping-Ke Shih +Link: https://patch.msgid.link/b8590382-a954-412d-a96b-63e360b97acc@gmail.com +--- + drivers/net/wireless/realtek/rtw88/rtw88xxa.c | 1989 +++++++++++++++++ + drivers/net/wireless/realtek/rtw88/rtw88xxa.h | 175 ++ + 2 files changed, 2164 insertions(+) + create mode 100644 drivers/net/wireless/realtek/rtw88/rtw88xxa.c + create mode 100644 drivers/net/wireless/realtek/rtw88/rtw88xxa.h + +--- /dev/null ++++ b/drivers/net/wireless/realtek/rtw88/rtw88xxa.c +@@ -0,0 +1,1989 @@ ++// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause ++/* Copyright(c) 2024 Realtek Corporation ++ */ ++ ++#include ++#include "main.h" ++#include "coex.h" ++#include "phy.h" ++#include "rtw88xxa.h" ++#include "mac.h" ++#include "reg.h" ++#include "sec.h" ++#include "debug.h" ++#include "bf.h" ++#include "efuse.h" ++#include "usb.h" ++ ++void rtw88xxa_efuse_grant(struct rtw_dev *rtwdev, bool on) ++{ ++ if (on) { ++ rtw_write8(rtwdev, REG_EFUSE_ACCESS, EFUSE_ACCESS_ON); ++ ++ rtw_write16_set(rtwdev, REG_SYS_FUNC_EN, BIT_FEN_ELDR); ++ rtw_write16_set(rtwdev, REG_SYS_CLKR, ++ BIT_LOADER_CLK_EN | BIT_ANA8M); ++ } else { ++ rtw_write8(rtwdev, REG_EFUSE_ACCESS, EFUSE_ACCESS_OFF); ++ } ++} ++EXPORT_SYMBOL(rtw88xxa_efuse_grant); ++ ++static void rtw8812a_read_amplifier_type(struct rtw_dev *rtwdev) ++{ ++ struct rtw_efuse *efuse = &rtwdev->efuse; ++ ++ efuse->ext_pa_2g = (efuse->pa_type_2g & BIT(5)) && ++ (efuse->pa_type_2g & BIT(4)); ++ efuse->ext_lna_2g = (efuse->lna_type_2g & BIT(7)) && ++ (efuse->lna_type_2g & BIT(3)); ++ ++ efuse->ext_pa_5g = (efuse->pa_type_5g & BIT(1)) && ++ (efuse->pa_type_5g & BIT(0)); ++ efuse->ext_lna_5g = (efuse->lna_type_5g & BIT(7)) && ++ (efuse->lna_type_5g & BIT(3)); ++ ++ /* For rtw_phy_cond2: */ ++ if (efuse->ext_pa_2g) { ++ u8 ext_type_pa_2g_a = u8_get_bits(efuse->lna_type_2g, BIT(2)); ++ u8 ext_type_pa_2g_b = u8_get_bits(efuse->lna_type_2g, BIT(6)); ++ ++ efuse->gpa_type = (ext_type_pa_2g_b << 2) | ext_type_pa_2g_a; ++ } ++ ++ if (efuse->ext_pa_5g) { ++ u8 ext_type_pa_5g_a = u8_get_bits(efuse->lna_type_5g, BIT(2)); ++ u8 ext_type_pa_5g_b = u8_get_bits(efuse->lna_type_5g, BIT(6)); ++ ++ efuse->apa_type = (ext_type_pa_5g_b << 2) | ext_type_pa_5g_a; ++ } ++ ++ if (efuse->ext_lna_2g) { ++ u8 ext_type_lna_2g_a = u8_get_bits(efuse->lna_type_2g, ++ BIT(1) | BIT(0)); ++ u8 ext_type_lna_2g_b = u8_get_bits(efuse->lna_type_2g, ++ BIT(5) | BIT(4)); ++ ++ efuse->glna_type = (ext_type_lna_2g_b << 2) | ext_type_lna_2g_a; ++ } ++ ++ if (efuse->ext_lna_5g) { ++ u8 ext_type_lna_5g_a = u8_get_bits(efuse->lna_type_5g, ++ BIT(1) | BIT(0)); ++ u8 ext_type_lna_5g_b = u8_get_bits(efuse->lna_type_5g, ++ BIT(5) | BIT(4)); ++ ++ efuse->alna_type = (ext_type_lna_5g_b << 2) | ext_type_lna_5g_a; ++ } ++} ++ ++static void rtw8812a_read_rfe_type(struct rtw_dev *rtwdev, ++ struct rtw88xxa_efuse *map) ++{ ++ struct rtw_efuse *efuse = &rtwdev->efuse; ++ ++ if (map->rfe_option == 0xff) { ++ if (rtwdev->hci.type == RTW_HCI_TYPE_USB) ++ efuse->rfe_option = 0; ++ else if (rtwdev->hci.type == RTW_HCI_TYPE_PCIE) ++ efuse->rfe_option = 2; ++ else ++ efuse->rfe_option = 4; ++ } else if (map->rfe_option & BIT(7)) { ++ if (efuse->ext_lna_5g) { ++ if (efuse->ext_pa_5g) { ++ if (efuse->ext_lna_2g && efuse->ext_pa_2g) ++ efuse->rfe_option = 3; ++ else ++ efuse->rfe_option = 0; ++ } else { ++ efuse->rfe_option = 2; ++ } ++ } else { ++ efuse->rfe_option = 4; ++ } ++ } else { ++ efuse->rfe_option = map->rfe_option & 0x3f; ++ ++ /* Due to other customer already use incorrect EFUSE map for ++ * their product. We need to add workaround to prevent to ++ * modify spec and notify all customer to revise the IC 0xca ++ * content. ++ */ ++ if (efuse->rfe_option == 4 && ++ (efuse->ext_pa_5g || efuse->ext_pa_2g || ++ efuse->ext_lna_5g || efuse->ext_lna_2g)) { ++ if (rtwdev->hci.type == RTW_HCI_TYPE_USB) ++ efuse->rfe_option = 0; ++ else if (rtwdev->hci.type == RTW_HCI_TYPE_PCIE) ++ efuse->rfe_option = 2; ++ } ++ } ++} ++ ++static void rtw88xxa_read_usb_type(struct rtw_dev *rtwdev) ++{ ++ struct rtw_efuse *efuse = &rtwdev->efuse; ++ struct rtw_hal *hal = &rtwdev->hal; ++ u8 antenna = 0; ++ u8 wmode = 0; ++ u8 val8, i; ++ ++ efuse->hw_cap.bw = BIT(RTW_CHANNEL_WIDTH_20) | ++ BIT(RTW_CHANNEL_WIDTH_40) | ++ BIT(RTW_CHANNEL_WIDTH_80); ++ efuse->hw_cap.ptcl = EFUSE_HW_CAP_PTCL_VHT; ++ ++ if (rtwdev->chip->id == RTW_CHIP_TYPE_8821A) ++ efuse->hw_cap.nss = 1; ++ else ++ efuse->hw_cap.nss = 2; ++ ++ if (rtwdev->chip->id == RTW_CHIP_TYPE_8821A) ++ goto print_hw_cap; ++ ++ for (i = 0; i < 2; i++) { ++ rtw_read8_physical_efuse(rtwdev, 1019 - i, &val8); ++ ++ antenna = u8_get_bits(val8, GENMASK(7, 5)); ++ if (antenna) ++ break; ++ antenna = u8_get_bits(val8, GENMASK(3, 1)); ++ if (antenna) ++ break; ++ } ++ ++ for (i = 0; i < 2; i++) { ++ rtw_read8_physical_efuse(rtwdev, 1021 - i, &val8); ++ ++ wmode = u8_get_bits(val8, GENMASK(3, 2)); ++ if (wmode) ++ break; ++ } ++ ++ if (antenna == 1) { ++ rtw_info(rtwdev, "This RTL8812AU says it is 1T1R.\n"); ++ ++ efuse->hw_cap.nss = 1; ++ hal->rf_type = RF_1T1R; ++ hal->rf_path_num = 1; ++ hal->rf_phy_num = 1; ++ hal->antenna_tx = BB_PATH_A; ++ hal->antenna_rx = BB_PATH_A; ++ } else { ++ /* Override rtw_chip_parameter_setup(). It detects 8812au as 1T1R. */ ++ efuse->hw_cap.nss = 2; ++ hal->rf_type = RF_2T2R; ++ hal->rf_path_num = 2; ++ hal->rf_phy_num = 2; ++ hal->antenna_tx = BB_PATH_AB; ++ hal->antenna_rx = BB_PATH_AB; ++ ++ if (antenna == 2 && wmode == 2) { ++ rtw_info(rtwdev, "This RTL8812AU says it can't do VHT.\n"); ++ ++ /* Can't be EFUSE_HW_CAP_IGNORE and can't be ++ * EFUSE_HW_CAP_PTCL_VHT, so make it 1. ++ */ ++ efuse->hw_cap.ptcl = 1; ++ efuse->hw_cap.bw &= ~BIT(RTW_CHANNEL_WIDTH_80); ++ } ++ } ++ ++print_hw_cap: ++ rtw_dbg(rtwdev, RTW_DBG_EFUSE, ++ "hw cap: hci=0x%02x, bw=0x%02x, ptcl=0x%02x, ant_num=%d, nss=%d\n", ++ efuse->hw_cap.hci, efuse->hw_cap.bw, efuse->hw_cap.ptcl, ++ efuse->hw_cap.ant_num, efuse->hw_cap.nss); ++} ++ ++int rtw88xxa_read_efuse(struct rtw_dev *rtwdev, u8 *log_map) ++{ ++ const struct rtw_chip_info *chip = rtwdev->chip; ++ struct rtw_efuse *efuse = &rtwdev->efuse; ++ struct rtw88xxa_efuse *map; ++ int i; ++ ++ if (chip->id == RTW_CHIP_TYPE_8812A) ++ rtwdev->hal.cut_version += 1; ++ ++ if (rtw_dbg_is_enabled(rtwdev, RTW_DBG_EFUSE)) ++ print_hex_dump(KERN_INFO, "", DUMP_PREFIX_OFFSET, 16, 1, ++ log_map, chip->log_efuse_size, true); ++ ++ map = (struct rtw88xxa_efuse *)log_map; ++ ++ efuse->rf_board_option = map->rf_board_option; ++ efuse->crystal_cap = map->xtal_k; ++ if (efuse->crystal_cap == 0xff) ++ efuse->crystal_cap = 0x20; ++ efuse->pa_type_2g = map->pa_type; ++ efuse->pa_type_5g = map->pa_type; ++ efuse->lna_type_2g = map->lna_type_2g; ++ efuse->lna_type_5g = map->lna_type_5g; ++ if (chip->id == RTW_CHIP_TYPE_8812A) { ++ rtw8812a_read_amplifier_type(rtwdev); ++ rtw8812a_read_rfe_type(rtwdev, map); ++ ++ efuse->usb_mode_switch = u8_get_bits(map->usb_mode, BIT(1)); ++ } ++ efuse->channel_plan = map->channel_plan; ++ efuse->country_code[0] = map->country_code[0]; ++ efuse->country_code[1] = map->country_code[1]; ++ efuse->bt_setting = map->rf_bt_setting; ++ efuse->regd = map->rf_board_option & 0x7; ++ efuse->thermal_meter[0] = map->thermal_meter; ++ efuse->thermal_meter[1] = map->thermal_meter; ++ efuse->thermal_meter_k = map->thermal_meter; ++ efuse->tx_bb_swing_setting_2g = map->tx_bb_swing_setting_2g; ++ efuse->tx_bb_swing_setting_5g = map->tx_bb_swing_setting_5g; ++ ++ rtw88xxa_read_usb_type(rtwdev); ++ ++ if (chip->id == RTW_CHIP_TYPE_8821A) ++ efuse->btcoex = rtw_read32_mask(rtwdev, REG_WL_BT_PWR_CTRL, ++ BIT_BT_FUNC_EN); ++ else ++ efuse->btcoex = (map->rf_board_option & 0xe0) == 0x20; ++ efuse->share_ant = !!(efuse->bt_setting & BIT(0)); ++ ++ /* No antenna diversity because it's disabled in the vendor driver */ ++ efuse->ant_div_cfg = 0; ++ ++ efuse->ant_div_type = map->rf_antenna_option; ++ if (efuse->ant_div_type == 0xff) ++ efuse->ant_div_type = 0x3; ++ ++ for (i = 0; i < 4; i++) ++ efuse->txpwr_idx_table[i] = map->txpwr_idx_table[i]; ++ ++ switch (rtw_hci_type(rtwdev)) { ++ case RTW_HCI_TYPE_USB: ++ if (chip->id == RTW_CHIP_TYPE_8821A) ++ ether_addr_copy(efuse->addr, map->rtw8821au.mac_addr); ++ else ++ ether_addr_copy(efuse->addr, map->rtw8812au.mac_addr); ++ break; ++ case RTW_HCI_TYPE_PCIE: ++ case RTW_HCI_TYPE_SDIO: ++ default: ++ /* unsupported now */ ++ return -EOPNOTSUPP; ++ } ++ ++ return 0; ++} ++EXPORT_SYMBOL(rtw88xxa_read_efuse); ++ ++static void rtw88xxa_reset_8051(struct rtw_dev *rtwdev) ++{ ++ const struct rtw_chip_info *chip = rtwdev->chip; ++ u8 val8; ++ ++ /* Reset MCU IO Wrapper */ ++ rtw_write8_clr(rtwdev, REG_RSV_CTRL, BIT(1)); ++ if (chip->id == RTW_CHIP_TYPE_8812A) ++ rtw_write8_clr(rtwdev, REG_RSV_CTRL + 1, BIT(3)); ++ else ++ rtw_write8_clr(rtwdev, REG_RSV_CTRL + 1, BIT(0)); ++ ++ val8 = rtw_read8(rtwdev, REG_SYS_FUNC_EN + 1); ++ rtw_write8(rtwdev, REG_SYS_FUNC_EN + 1, val8 & ~BIT(2)); ++ ++ /* Enable MCU IO Wrapper */ ++ rtw_write8_clr(rtwdev, REG_RSV_CTRL, BIT(1)); ++ if (chip->id == RTW_CHIP_TYPE_8812A) ++ rtw_write8_set(rtwdev, REG_RSV_CTRL + 1, BIT(3)); ++ else ++ rtw_write8_set(rtwdev, REG_RSV_CTRL + 1, BIT(0)); ++ ++ rtw_write8(rtwdev, REG_SYS_FUNC_EN + 1, val8 | BIT(2)); ++} ++ ++/* A lightweight deinit function */ ++static void rtw88xxau_hw_reset(struct rtw_dev *rtwdev) ++{ ++ u8 val8; ++ ++ if (!(rtw_read8(rtwdev, REG_MCUFW_CTRL) & BIT_RAM_DL_SEL)) ++ return; ++ ++ rtw88xxa_reset_8051(rtwdev); ++ rtw_write8(rtwdev, REG_MCUFW_CTRL, 0x00); ++ ++ /* before BB reset should do clock gated */ ++ rtw_write32_set(rtwdev, REG_FPGA0_XCD_RF_PARA, BIT(6)); ++ ++ /* reset BB */ ++ rtw_write8_clr(rtwdev, REG_SYS_FUNC_EN, BIT(0) | BIT(1)); ++ ++ /* reset RF */ ++ rtw_write8(rtwdev, REG_RF_CTRL, 0); ++ ++ /* reset TRX path */ ++ rtw_write16(rtwdev, REG_CR, 0); ++ ++ /* reset MAC, reg0x5[1], auto FSM off */ ++ rtw_write8_set(rtwdev, REG_APS_FSMCO + 1, APS_FSMCO_MAC_OFF >> 8); ++ ++ /* check if reg0x5[1] auto cleared */ ++ if (read_poll_timeout_atomic(rtw_read8, val8, ++ !(val8 & (APS_FSMCO_MAC_OFF >> 8)), ++ 1, 5000, false, ++ rtwdev, REG_APS_FSMCO + 1)) ++ rtw_err(rtwdev, "%s: timed out waiting for 0x5[1]\n", __func__); ++ ++ /* reg0x5[0], auto FSM on */ ++ val8 |= APS_FSMCO_MAC_ENABLE >> 8; ++ rtw_write8(rtwdev, REG_APS_FSMCO + 1, val8); ++ ++ rtw_write8_clr(rtwdev, REG_SYS_FUNC_EN + 1, BIT(4) | BIT(7)); ++ rtw_write8_set(rtwdev, REG_SYS_FUNC_EN + 1, BIT(4) | BIT(7)); ++} ++ ++static int rtw88xxau_init_power_on(struct rtw_dev *rtwdev) ++{ ++ const struct rtw_chip_info *chip = rtwdev->chip; ++ u16 val16; ++ int ret; ++ ++ ret = rtw_pwr_seq_parser(rtwdev, chip->pwr_on_seq); ++ if (ret) { ++ rtw_err(rtwdev, "power on flow failed\n"); ++ return ret; ++ } ++ ++ rtw_write16(rtwdev, REG_CR, 0); ++ val16 = BIT_HCI_TXDMA_EN | BIT_HCI_RXDMA_EN | BIT_TXDMA_EN | ++ BIT_RXDMA_EN | BIT_PROTOCOL_EN | BIT_SCHEDULE_EN | ++ BIT_MAC_SEC_EN | BIT_32K_CAL_TMR_EN; ++ rtw_write16_set(rtwdev, REG_CR, val16); ++ ++ if (chip->id == RTW_CHIP_TYPE_8821A) { ++ if (rtw_read8(rtwdev, REG_SYS_CFG1 + 3) & BIT(0)) ++ rtw_write8_set(rtwdev, REG_LDO_SWR_CTRL, BIT(6)); ++ } ++ ++ return ret; ++} ++ ++static int rtw88xxa_llt_write(struct rtw_dev *rtwdev, u32 address, u32 data) ++{ ++ u32 value = BIT_LLT_WRITE_ACCESS | (address << 8) | data; ++ int count = 0; ++ ++ rtw_write32(rtwdev, REG_LLT_INIT, value); ++ ++ do { ++ if (!rtw_read32_mask(rtwdev, REG_LLT_INIT, BIT(31) | BIT(30))) ++ break; ++ ++ if (count > 20) { ++ rtw_err(rtwdev, "Failed to poll write LLT done at %d!\n", ++ address); ++ return -EBUSY; ++ } ++ } while (++count); ++ ++ return 0; ++} ++ ++static int rtw88xxa_llt_init(struct rtw_dev *rtwdev, u32 boundary) ++{ ++ u32 last_entry = 255; ++ int status = 0; ++ u32 i; ++ ++ for (i = 0; i < boundary - 1; i++) { ++ status = rtw88xxa_llt_write(rtwdev, i, i + 1); ++ if (status) ++ return status; ++ } ++ ++ status = rtw88xxa_llt_write(rtwdev, boundary - 1, 0xFF); ++ if (status) ++ return status; ++ ++ for (i = boundary; i < last_entry; i++) { ++ status = rtw88xxa_llt_write(rtwdev, i, i + 1); ++ if (status) ++ return status; ++ } ++ ++ status = rtw88xxa_llt_write(rtwdev, last_entry, boundary); ++ ++ return status; ++} ++ ++static void rtw88xxau_init_queue_reserved_page(struct rtw_dev *rtwdev) ++{ ++ const struct rtw_chip_info *chip = rtwdev->chip; ++ struct rtw_fifo_conf *fifo = &rtwdev->fifo; ++ const struct rtw_page_table *pg_tbl = NULL; ++ u16 pubq_num; ++ u32 val32; ++ ++ switch (rtw_hci_type(rtwdev)) { ++ case RTW_HCI_TYPE_PCIE: ++ pg_tbl = &chip->page_table[1]; ++ break; ++ case RTW_HCI_TYPE_USB: ++ if (rtwdev->hci.bulkout_num == 2) ++ pg_tbl = &chip->page_table[2]; ++ else if (rtwdev->hci.bulkout_num == 3) ++ pg_tbl = &chip->page_table[3]; ++ else if (rtwdev->hci.bulkout_num == 4) ++ pg_tbl = &chip->page_table[4]; ++ break; ++ case RTW_HCI_TYPE_SDIO: ++ pg_tbl = &chip->page_table[0]; ++ break; ++ default: ++ break; ++ } ++ ++ pubq_num = fifo->acq_pg_num - pg_tbl->hq_num - pg_tbl->lq_num - ++ pg_tbl->nq_num - pg_tbl->exq_num - pg_tbl->gapq_num; ++ ++ val32 = BIT_RQPN_NE(pg_tbl->nq_num, pg_tbl->exq_num); ++ rtw_write32(rtwdev, REG_RQPN_NPQ, val32); ++ ++ val32 = BIT_RQPN_HLP(pg_tbl->hq_num, pg_tbl->lq_num, pubq_num); ++ rtw_write32(rtwdev, REG_RQPN, val32); ++} ++ ++static void rtw88xxau_init_tx_buffer_boundary(struct rtw_dev *rtwdev) ++{ ++ struct rtw_fifo_conf *fifo = &rtwdev->fifo; ++ ++ rtw_write8(rtwdev, REG_BCNQ_BDNY, fifo->rsvd_boundary); ++ rtw_write8(rtwdev, REG_MGQ_BDNY, fifo->rsvd_boundary); ++ rtw_write8(rtwdev, REG_WMAC_LBK_BF_HD, fifo->rsvd_boundary); ++ rtw_write8(rtwdev, REG_TRXFF_BNDY, fifo->rsvd_boundary); ++ rtw_write8(rtwdev, REG_DWBCN0_CTRL + 1, fifo->rsvd_boundary); ++} ++ ++static int rtw88xxau_init_queue_priority(struct rtw_dev *rtwdev) ++{ ++ const struct rtw_chip_info *chip = rtwdev->chip; ++ u8 bulkout_num = rtwdev->hci.bulkout_num; ++ const struct rtw_rqpn *rqpn = NULL; ++ u16 txdma_pq_map; ++ ++ switch (rtw_hci_type(rtwdev)) { ++ case RTW_HCI_TYPE_PCIE: ++ rqpn = &chip->rqpn_table[1]; ++ break; ++ case RTW_HCI_TYPE_USB: ++ if (bulkout_num == 2) ++ rqpn = &chip->rqpn_table[2]; ++ else if (bulkout_num == 3) ++ rqpn = &chip->rqpn_table[3]; ++ else if (bulkout_num == 4) ++ rqpn = &chip->rqpn_table[4]; ++ else ++ return -EINVAL; ++ break; ++ case RTW_HCI_TYPE_SDIO: ++ rqpn = &chip->rqpn_table[0]; ++ break; ++ default: ++ return -EINVAL; ++ } ++ ++ rtwdev->fifo.rqpn = rqpn; ++ ++ txdma_pq_map = rtw_read16(rtwdev, REG_TXDMA_PQ_MAP) & 0x7; ++ txdma_pq_map |= BIT_TXDMA_HIQ_MAP(rqpn->dma_map_hi); ++ txdma_pq_map |= BIT_TXDMA_MGQ_MAP(rqpn->dma_map_mg); ++ txdma_pq_map |= BIT_TXDMA_BKQ_MAP(rqpn->dma_map_bk); ++ txdma_pq_map |= BIT_TXDMA_BEQ_MAP(rqpn->dma_map_be); ++ txdma_pq_map |= BIT_TXDMA_VIQ_MAP(rqpn->dma_map_vi); ++ txdma_pq_map |= BIT_TXDMA_VOQ_MAP(rqpn->dma_map_vo); ++ rtw_write16(rtwdev, REG_TXDMA_PQ_MAP, txdma_pq_map); ++ ++ /* Packet in Hi Queue Tx immediately (No constraint for ATIM Period). */ ++ if (rtw_hci_type(rtwdev) == RTW_HCI_TYPE_USB && bulkout_num == 4) ++ rtw_write8(rtwdev, REG_HIQ_NO_LMT_EN, 0xff); ++ ++ return 0; ++} ++ ++static void rtw88xxa_init_wmac_setting(struct rtw_dev *rtwdev) ++{ ++ rtw_write16(rtwdev, REG_RXFLTMAP0, 0xffff); ++ rtw_write16(rtwdev, REG_RXFLTMAP1, 0x0400); ++ rtw_write16(rtwdev, REG_RXFLTMAP2, 0xffff); ++ ++ rtw_write32(rtwdev, REG_MAR, 0xffffffff); ++ rtw_write32(rtwdev, REG_MAR + 4, 0xffffffff); ++} ++ ++static void rtw88xxa_init_adaptive_ctrl(struct rtw_dev *rtwdev) ++{ ++ rtw_write32_mask(rtwdev, REG_RRSR, 0xfffff, 0xffff1); ++ rtw_write16(rtwdev, REG_RETRY_LIMIT, 0x3030); ++} ++ ++static void rtw88xxa_init_edca(struct rtw_dev *rtwdev) ++{ ++ rtw_write16(rtwdev, REG_SPEC_SIFS, 0x100a); ++ rtw_write16(rtwdev, REG_MAC_SPEC_SIFS, 0x100a); ++ ++ rtw_write16(rtwdev, REG_SIFS, 0x100a); ++ rtw_write16(rtwdev, REG_SIFS + 2, 0x100a); ++ ++ rtw_write32(rtwdev, REG_EDCA_BE_PARAM, 0x005EA42B); ++ rtw_write32(rtwdev, REG_EDCA_BK_PARAM, 0x0000A44F); ++ rtw_write32(rtwdev, REG_EDCA_VI_PARAM, 0x005EA324); ++ rtw_write32(rtwdev, REG_EDCA_VO_PARAM, 0x002FA226); ++ ++ rtw_write8(rtwdev, REG_USTIME_TSF, 0x50); ++ rtw_write8(rtwdev, REG_USTIME_EDCA, 0x50); ++} ++ ++static void rtw88xxau_tx_aggregation(struct rtw_dev *rtwdev) ++{ ++ const struct rtw_chip_info *chip = rtwdev->chip; ++ ++ rtw_write32_mask(rtwdev, REG_DWBCN0_CTRL, 0xf0, ++ chip->usb_tx_agg_desc_num); ++ ++ if (chip->id == RTW_CHIP_TYPE_8821A) ++ rtw_write8(rtwdev, REG_DWBCN1_CTRL, ++ chip->usb_tx_agg_desc_num << 1); ++} ++ ++static void rtw88xxa_init_beacon_parameters(struct rtw_dev *rtwdev) ++{ ++ u16 val16; ++ ++ val16 = (BIT_DIS_TSF_UDT << 8) | BIT_DIS_TSF_UDT; ++ if (rtwdev->efuse.btcoex) ++ val16 |= BIT_EN_BCN_FUNCTION; ++ rtw_write16(rtwdev, REG_BCN_CTRL, val16); ++ ++ rtw_write32_mask(rtwdev, REG_TBTT_PROHIBIT, 0xfffff, WLAN_TBTT_TIME); ++ rtw_write8(rtwdev, REG_DRVERLYINT, 0x05); ++ rtw_write8(rtwdev, REG_BCNDMATIM, WLAN_BCN_DMA_TIME); ++ rtw_write16(rtwdev, REG_BCNTCFG, 0x4413); ++} ++ ++static void rtw88xxa_phy_bb_config(struct rtw_dev *rtwdev) ++{ ++ u8 val8, crystal_cap; ++ ++ /* power on BB/RF domain */ ++ val8 = rtw_read8(rtwdev, REG_SYS_FUNC_EN); ++ val8 |= BIT_FEN_USBA; ++ rtw_write8(rtwdev, REG_SYS_FUNC_EN, val8); ++ ++ /* toggle BB reset */ ++ val8 |= BIT_FEN_BB_RSTB | BIT_FEN_BB_GLB_RST; ++ rtw_write8(rtwdev, REG_SYS_FUNC_EN, val8); ++ ++ rtw_write8(rtwdev, REG_RF_CTRL, ++ BIT_RF_EN | BIT_RF_RSTB | BIT_RF_SDM_RSTB); ++ rtw_write8(rtwdev, REG_RF_B_CTRL, ++ BIT_RF_EN | BIT_RF_RSTB | BIT_RF_SDM_RSTB); ++ ++ rtw_load_table(rtwdev, rtwdev->chip->bb_tbl); ++ rtw_load_table(rtwdev, rtwdev->chip->agc_tbl); ++ ++ crystal_cap = rtwdev->efuse.crystal_cap & 0x3F; ++ if (rtwdev->chip->id == RTW_CHIP_TYPE_8812A) ++ rtw_write32_mask(rtwdev, REG_AFE_CTRL3, 0x7FF80000, ++ crystal_cap | (crystal_cap << 6)); ++ else ++ rtw_write32_mask(rtwdev, REG_AFE_CTRL3, 0x00FFF000, ++ crystal_cap | (crystal_cap << 6)); ++} ++ ++static void rtw88xxa_phy_rf_config(struct rtw_dev *rtwdev) ++{ ++ u8 rf_path; ++ ++ for (rf_path = 0; rf_path < rtwdev->hal.rf_path_num; rf_path++) ++ rtw_load_table(rtwdev, rtwdev->chip->rf_tbl[rf_path]); ++} ++ ++static void rtw8812a_config_1t(struct rtw_dev *rtwdev) ++{ ++ /* BB OFDM RX Path_A */ ++ rtw_write32_mask(rtwdev, REG_RXPSEL, 0xff, 0x11); ++ ++ /* BB OFDM TX Path_A */ ++ rtw_write32_mask(rtwdev, REG_TXPSEL, MASKLWORD, 0x1111); ++ ++ /* BB CCK R/Rx Path_A */ ++ rtw_write32_mask(rtwdev, REG_CCK_RX, 0x0c000000, 0x0); ++ ++ /* MCS support */ ++ rtw_write32_mask(rtwdev, REG_RX_MCS_LIMIT, 0xc0000060, 0x4); ++ ++ /* RF Path_B HSSI OFF */ ++ rtw_write32_mask(rtwdev, REG_3WIRE_SWB, 0xf, 0x4); ++ ++ /* RF Path_B Power Down */ ++ rtw_write32_mask(rtwdev, REG_LSSI_WRITE_B, MASKDWORD, 0); ++ ++ /* ADDA Path_B OFF */ ++ rtw_write32_mask(rtwdev, REG_AFE_PWR1_B, MASKDWORD, 0); ++ rtw_write32_mask(rtwdev, REG_AFE_PWR2_B, MASKDWORD, 0); ++} ++ ++static const u32 rtw88xxa_txscale_tbl[] = { ++ 0x081, 0x088, 0x090, 0x099, 0x0a2, 0x0ac, 0x0b6, 0x0c0, 0x0cc, 0x0d8, ++ 0x0e5, 0x0f2, 0x101, 0x110, 0x120, 0x131, 0x143, 0x156, 0x16a, 0x180, ++ 0x197, 0x1af, 0x1c8, 0x1e3, 0x200, 0x21e, 0x23e, 0x261, 0x285, 0x2ab, ++ 0x2d3, 0x2fe, 0x32b, 0x35c, 0x38e, 0x3c4, 0x3fe ++}; ++ ++static u32 rtw88xxa_get_bb_swing(struct rtw_dev *rtwdev, u8 band, u8 path) ++{ ++ static const u32 swing2setting[4] = {0x200, 0x16a, 0x101, 0x0b6}; ++ struct rtw_efuse *efuse = &rtwdev->efuse; ++ u8 tx_bb_swing; ++ ++ if (band == RTW_BAND_2G) ++ tx_bb_swing = efuse->tx_bb_swing_setting_2g; ++ else ++ tx_bb_swing = efuse->tx_bb_swing_setting_5g; ++ ++ if (path == RF_PATH_B) ++ tx_bb_swing >>= 2; ++ tx_bb_swing &= 0x3; ++ ++ return swing2setting[tx_bb_swing]; ++} ++ ++static u8 rtw88xxa_get_swing_index(struct rtw_dev *rtwdev) ++{ ++ u32 swing, table_value; ++ u8 i; ++ ++ swing = rtw88xxa_get_bb_swing(rtwdev, rtwdev->hal.current_band_type, ++ RF_PATH_A); ++ ++ for (i = 0; i < ARRAY_SIZE(rtw88xxa_txscale_tbl); i++) { ++ table_value = rtw88xxa_txscale_tbl[i]; ++ if (swing == table_value) ++ return i; ++ } ++ ++ return 24; ++} ++ ++static void rtw88xxa_pwrtrack_init(struct rtw_dev *rtwdev) ++{ ++ struct rtw_dm_info *dm_info = &rtwdev->dm_info; ++ u8 path; ++ ++ dm_info->default_ofdm_index = rtw88xxa_get_swing_index(rtwdev); ++ ++ if (rtwdev->chip->id == RTW_CHIP_TYPE_8821A) ++ dm_info->default_cck_index = 0; ++ else ++ dm_info->default_cck_index = 24; ++ ++ for (path = RF_PATH_A; path < rtwdev->hal.rf_path_num; path++) { ++ ewma_thermal_init(&dm_info->avg_thermal[path]); ++ dm_info->delta_power_index[path] = 0; ++ dm_info->delta_power_index_last[path] = 0; ++ } ++ ++ dm_info->pwr_trk_triggered = false; ++ dm_info->pwr_trk_init_trigger = true; ++ dm_info->thermal_meter_k = rtwdev->efuse.thermal_meter_k; ++} ++ ++void rtw88xxa_power_off(struct rtw_dev *rtwdev, ++ const struct rtw_pwr_seq_cmd *const *enter_lps_flow) ++{ ++ struct rtw_usb *rtwusb = rtw_get_usb_priv(rtwdev); ++ enum usb_device_speed speed = rtwusb->udev->speed; ++ u16 ori_fsmc0; ++ u8 reg_cr; ++ ++ reg_cr = rtw_read8(rtwdev, REG_CR); ++ ++ /* Already powered off */ ++ if (reg_cr == 0 || reg_cr == 0xEA) ++ return; ++ ++ rtw_hci_stop(rtwdev); ++ ++ if (!rtwdev->efuse.btcoex) ++ rtw_write16_clr(rtwdev, REG_GPIO_MUXCFG, BIT_EN_SIC); ++ ++ /* set Reg 0xf008[3:4] to 2'11 to enable U1/U2 Mode in USB3.0. */ ++ if (speed == USB_SPEED_SUPER) ++ rtw_write8_set(rtwdev, REG_USB_MOD, 0x18); ++ ++ rtw_write32(rtwdev, REG_HISR0, 0xffffffff); ++ rtw_write32(rtwdev, REG_HISR1, 0xffffffff); ++ rtw_write32(rtwdev, REG_HIMR0, 0); ++ rtw_write32(rtwdev, REG_HIMR1, 0); ++ ++ if (rtwdev->efuse.btcoex) ++ rtw_coex_power_off_setting(rtwdev); ++ ++ ori_fsmc0 = rtw_read16(rtwdev, REG_APS_FSMCO); ++ rtw_write16(rtwdev, REG_APS_FSMCO, ori_fsmc0 & ~APS_FSMCO_HW_POWERDOWN); ++ ++ /* Stop Tx Report Timer. */ ++ rtw_write8_clr(rtwdev, REG_TX_RPT_CTRL, BIT(1)); ++ ++ /* Stop Rx */ ++ rtw_write8(rtwdev, REG_CR, 0); ++ ++ rtw_pwr_seq_parser(rtwdev, enter_lps_flow); ++ ++ if (rtw_read8(rtwdev, REG_MCUFW_CTRL) & BIT_RAM_DL_SEL) ++ rtw88xxa_reset_8051(rtwdev); ++ ++ rtw_write8_clr(rtwdev, REG_SYS_FUNC_EN + 1, BIT(2)); ++ rtw_write8(rtwdev, REG_MCUFW_CTRL, 0); ++ ++ rtw_pwr_seq_parser(rtwdev, rtwdev->chip->pwr_off_seq); ++ ++ if (ori_fsmc0 & APS_FSMCO_HW_POWERDOWN) ++ rtw_write16_set(rtwdev, REG_APS_FSMCO, APS_FSMCO_HW_POWERDOWN); ++ ++ clear_bit(RTW_FLAG_POWERON, rtwdev->flags); ++} ++EXPORT_SYMBOL(rtw88xxa_power_off); ++ ++static void rtw88xxa_set_channel_bb_swing(struct rtw_dev *rtwdev, u8 band) ++{ ++ rtw_write32_mask(rtwdev, REG_TXSCALE_A, BB_SWING_MASK, ++ rtw88xxa_get_bb_swing(rtwdev, band, RF_PATH_A)); ++ rtw_write32_mask(rtwdev, REG_TXSCALE_B, BB_SWING_MASK, ++ rtw88xxa_get_bb_swing(rtwdev, band, RF_PATH_B)); ++ rtw88xxa_pwrtrack_init(rtwdev); ++} ++ ++static void rtw8821a_set_ext_band_switch(struct rtw_dev *rtwdev, u8 band) ++{ ++ rtw_write32_mask(rtwdev, REG_LED_CFG, BIT_DPDT_SEL_EN, 0); ++ rtw_write32_mask(rtwdev, REG_LED_CFG, BIT_DPDT_WL_SEL, 1); ++ rtw_write32_mask(rtwdev, REG_RFE_INV_A, 0xf, 7); ++ rtw_write32_mask(rtwdev, REG_RFE_INV_A, 0xf0, 7); ++ ++ if (band == RTW_BAND_2G) ++ rtw_write32_mask(rtwdev, REG_RFE_INV_A, BIT(29) | BIT(28), 1); ++ else ++ rtw_write32_mask(rtwdev, REG_RFE_INV_A, BIT(29) | BIT(28), 2); ++} ++ ++static void rtw8821a_phy_set_rfe_reg_24g(struct rtw_dev *rtwdev) ++{ ++ struct rtw_efuse *efuse = &rtwdev->efuse; ++ ++ /* Turn off RF PA and LNA */ ++ ++ /* 0xCB0[15:12] = 0x7 (LNA_On)*/ ++ rtw_write32_mask(rtwdev, REG_RFE_PINMUX_A, 0xF000, 0x7); ++ /* 0xCB0[7:4] = 0x7 (PAPE_A)*/ ++ rtw_write32_mask(rtwdev, REG_RFE_PINMUX_A, 0xF0, 0x7); ++ ++ if (efuse->ext_lna_2g) { ++ /* Turn on 2.4G External LNA */ ++ rtw_write32_mask(rtwdev, REG_RFE_INV_A, BIT(20), 1); ++ rtw_write32_mask(rtwdev, REG_RFE_INV_A, BIT(22), 0); ++ rtw_write32_mask(rtwdev, REG_RFE_PINMUX_A, GENMASK(2, 0), 0x2); ++ rtw_write32_mask(rtwdev, REG_RFE_PINMUX_A, GENMASK(10, 8), 0x2); ++ } else { ++ /* Bypass 2.4G External LNA */ ++ rtw_write32_mask(rtwdev, REG_RFE_INV_A, BIT(20), 0); ++ rtw_write32_mask(rtwdev, REG_RFE_INV_A, BIT(22), 0); ++ rtw_write32_mask(rtwdev, REG_RFE_PINMUX_A, GENMASK(2, 0), 0x7); ++ rtw_write32_mask(rtwdev, REG_RFE_PINMUX_A, GENMASK(10, 8), 0x7); ++ } ++} ++ ++static void rtw8821a_phy_set_rfe_reg_5g(struct rtw_dev *rtwdev) ++{ ++ /* Turn ON RF PA and LNA */ ++ ++ /* 0xCB0[15:12] = 0x7 (LNA_On)*/ ++ rtw_write32_mask(rtwdev, REG_RFE_PINMUX_A, 0xF000, 0x5); ++ /* 0xCB0[7:4] = 0x7 (PAPE_A)*/ ++ rtw_write32_mask(rtwdev, REG_RFE_PINMUX_A, 0xF0, 0x4); ++ ++ /* Bypass 2.4G External LNA */ ++ rtw_write32_mask(rtwdev, REG_RFE_INV_A, BIT(20), 0); ++ rtw_write32_mask(rtwdev, REG_RFE_INV_A, BIT(22), 0); ++ rtw_write32_mask(rtwdev, REG_RFE_PINMUX_A, GENMASK(2, 0), 0x7); ++ rtw_write32_mask(rtwdev, REG_RFE_PINMUX_A, GENMASK(10, 8), 0x7); ++} ++ ++static void rtw8812a_phy_set_rfe_reg_24g(struct rtw_dev *rtwdev) ++{ ++ switch (rtwdev->efuse.rfe_option) { ++ case 0: ++ case 2: ++ rtw_write32(rtwdev, REG_RFE_PINMUX_A, 0x77777777); ++ rtw_write32(rtwdev, REG_RFE_PINMUX_B, 0x77777777); ++ rtw_write32_mask(rtwdev, REG_RFE_INV_A, RFE_INV_MASK, 0x000); ++ rtw_write32_mask(rtwdev, REG_RFE_INV_B, RFE_INV_MASK, 0x000); ++ break; ++ case 1: ++ if (rtwdev->efuse.btcoex) { ++ rtw_write32_mask(rtwdev, REG_RFE_PINMUX_A, 0xffffff, 0x777777); ++ rtw_write32(rtwdev, REG_RFE_PINMUX_B, 0x77777777); ++ rtw_write32_mask(rtwdev, REG_RFE_INV_A, 0x33f00000, 0x000); ++ rtw_write32_mask(rtwdev, REG_RFE_INV_B, RFE_INV_MASK, 0x000); ++ } else { ++ rtw_write32(rtwdev, REG_RFE_PINMUX_A, 0x77777777); ++ rtw_write32(rtwdev, REG_RFE_PINMUX_B, 0x77777777); ++ rtw_write32_mask(rtwdev, REG_RFE_INV_A, RFE_INV_MASK, 0x000); ++ rtw_write32_mask(rtwdev, REG_RFE_INV_B, RFE_INV_MASK, 0x000); ++ } ++ break; ++ case 3: ++ rtw_write32(rtwdev, REG_RFE_PINMUX_A, 0x54337770); ++ rtw_write32(rtwdev, REG_RFE_PINMUX_B, 0x54337770); ++ rtw_write32_mask(rtwdev, REG_RFE_INV_A, RFE_INV_MASK, 0x010); ++ rtw_write32_mask(rtwdev, REG_RFE_INV_B, RFE_INV_MASK, 0x010); ++ rtw_write32_mask(rtwdev, REG_ANTSEL_SW, 0x00000303, 0x1); ++ break; ++ case 4: ++ rtw_write32(rtwdev, REG_RFE_PINMUX_A, 0x77777777); ++ rtw_write32(rtwdev, REG_RFE_PINMUX_B, 0x77777777); ++ rtw_write32_mask(rtwdev, REG_RFE_INV_A, RFE_INV_MASK, 0x001); ++ rtw_write32_mask(rtwdev, REG_RFE_INV_B, RFE_INV_MASK, 0x001); ++ break; ++ case 5: ++ rtw_write8(rtwdev, REG_RFE_PINMUX_A + 2, 0x77); ++ rtw_write32(rtwdev, REG_RFE_PINMUX_B, 0x77777777); ++ rtw_write8_clr(rtwdev, REG_RFE_INV_A + 3, BIT(0)); ++ rtw_write32_mask(rtwdev, REG_RFE_INV_B, RFE_INV_MASK, 0x000); ++ break; ++ case 6: ++ rtw_write32(rtwdev, REG_RFE_PINMUX_A, 0x07772770); ++ rtw_write32(rtwdev, REG_RFE_PINMUX_B, 0x07772770); ++ rtw_write32(rtwdev, REG_RFE_INV_A, 0x00000077); ++ rtw_write32(rtwdev, REG_RFE_INV_B, 0x00000077); ++ break; ++ default: ++ break; ++ } ++} ++ ++static void rtw8812a_phy_set_rfe_reg_5g(struct rtw_dev *rtwdev) ++{ ++ switch (rtwdev->efuse.rfe_option) { ++ case 0: ++ rtw_write32(rtwdev, REG_RFE_PINMUX_A, 0x77337717); ++ rtw_write32(rtwdev, REG_RFE_PINMUX_B, 0x77337717); ++ rtw_write32_mask(rtwdev, REG_RFE_INV_A, RFE_INV_MASK, 0x010); ++ rtw_write32_mask(rtwdev, REG_RFE_INV_B, RFE_INV_MASK, 0x010); ++ break; ++ case 1: ++ if (rtwdev->efuse.btcoex) { ++ rtw_write32_mask(rtwdev, REG_RFE_PINMUX_A, 0xffffff, 0x337717); ++ rtw_write32(rtwdev, REG_RFE_PINMUX_B, 0x77337717); ++ rtw_write32_mask(rtwdev, REG_RFE_INV_A, 0x33f00000, 0x000); ++ rtw_write32_mask(rtwdev, REG_RFE_INV_B, RFE_INV_MASK, 0x000); ++ } else { ++ rtw_write32(rtwdev, REG_RFE_PINMUX_A, 0x77337717); ++ rtw_write32(rtwdev, REG_RFE_PINMUX_B, 0x77337717); ++ rtw_write32_mask(rtwdev, REG_RFE_INV_A, RFE_INV_MASK, 0x000); ++ rtw_write32_mask(rtwdev, REG_RFE_INV_B, RFE_INV_MASK, 0x000); ++ } ++ break; ++ case 2: ++ case 4: ++ rtw_write32(rtwdev, REG_RFE_PINMUX_A, 0x77337777); ++ rtw_write32(rtwdev, REG_RFE_PINMUX_B, 0x77337777); ++ rtw_write32_mask(rtwdev, REG_RFE_INV_A, RFE_INV_MASK, 0x010); ++ rtw_write32_mask(rtwdev, REG_RFE_INV_B, RFE_INV_MASK, 0x010); ++ break; ++ case 3: ++ rtw_write32(rtwdev, REG_RFE_PINMUX_A, 0x54337717); ++ rtw_write32(rtwdev, REG_RFE_PINMUX_B, 0x54337717); ++ rtw_write32_mask(rtwdev, REG_RFE_INV_A, RFE_INV_MASK, 0x010); ++ rtw_write32_mask(rtwdev, REG_RFE_INV_B, RFE_INV_MASK, 0x010); ++ rtw_write32_mask(rtwdev, REG_ANTSEL_SW, 0x00000303, 0x1); ++ break; ++ case 5: ++ rtw_write8(rtwdev, REG_RFE_PINMUX_A + 2, 0x33); ++ rtw_write32(rtwdev, REG_RFE_PINMUX_B, 0x77337777); ++ rtw_write8_set(rtwdev, REG_RFE_INV_A + 3, BIT(0)); ++ rtw_write32_mask(rtwdev, REG_RFE_INV_B, RFE_INV_MASK, 0x010); ++ break; ++ case 6: ++ rtw_write32(rtwdev, REG_RFE_PINMUX_A, 0x07737717); ++ rtw_write32(rtwdev, REG_RFE_PINMUX_B, 0x07737717); ++ rtw_write32(rtwdev, REG_RFE_INV_A, 0x00000077); ++ rtw_write32(rtwdev, REG_RFE_INV_B, 0x00000077); ++ break; ++ default: ++ break; ++ } ++} ++ ++static void rtw88xxa_switch_band(struct rtw_dev *rtwdev, u8 new_band, u8 bw) ++{ ++ const struct rtw_chip_info *chip = rtwdev->chip; ++ u16 basic_rates, reg_41a; ++ ++ /* 8811au one antenna module doesn't support antenna div, so driver must ++ * control antenna band, otherwise one of the band will have issue ++ */ ++ if (chip->id == RTW_CHIP_TYPE_8821A && !rtwdev->efuse.btcoex && ++ rtwdev->efuse.ant_div_cfg == 0) ++ rtw8821a_set_ext_band_switch(rtwdev, new_band); ++ ++ if (new_band == RTW_BAND_2G) { ++ rtw_write32_set(rtwdev, REG_RXPSEL, BIT_RX_PSEL_RST); ++ ++ if (chip->id == RTW_CHIP_TYPE_8821A) { ++ rtw8821a_phy_set_rfe_reg_24g(rtwdev); ++ ++ rtw_write32_mask(rtwdev, REG_TXSCALE_A, 0xf00, 0); ++ } else { ++ rtw_write32_mask(rtwdev, REG_BWINDICATION, 0x3, 0x1); ++ rtw_write32_mask(rtwdev, REG_PDMFTH, GENMASK(17, 13), 0x17); ++ ++ if (bw == RTW_CHANNEL_WIDTH_20 && ++ rtwdev->hal.rf_type == RF_1T1R && ++ !rtwdev->efuse.ext_lna_2g) ++ rtw_write32_mask(rtwdev, REG_PDMFTH, GENMASK(3, 1), 0x02); ++ else ++ rtw_write32_mask(rtwdev, REG_PDMFTH, GENMASK(3, 1), 0x04); ++ ++ rtw_write32_mask(rtwdev, REG_CCASEL, 0x3, 0); ++ ++ rtw8812a_phy_set_rfe_reg_24g(rtwdev); ++ } ++ ++ rtw_write32_mask(rtwdev, REG_TXPSEL, 0xf0, 0x1); ++ rtw_write32_mask(rtwdev, REG_CCK_RX, 0x0f000000, 0x1); ++ ++ basic_rates = BIT(DESC_RATE1M) | BIT(DESC_RATE2M) | ++ BIT(DESC_RATE5_5M) | BIT(DESC_RATE11M) | ++ BIT(DESC_RATE6M) | BIT(DESC_RATE12M) | ++ BIT(DESC_RATE24M); ++ rtw_write32_mask(rtwdev, REG_RRSR, 0xfffff, basic_rates); ++ ++ rtw_write8_clr(rtwdev, REG_CCK_CHECK, BIT_CHECK_CCK_EN); ++ } else { /* RTW_BAND_5G */ ++ if (chip->id == RTW_CHIP_TYPE_8821A) ++ rtw8821a_phy_set_rfe_reg_5g(rtwdev); ++ ++ rtw_write8_set(rtwdev, REG_CCK_CHECK, BIT_CHECK_CCK_EN); ++ ++ read_poll_timeout_atomic(rtw_read16, reg_41a, (reg_41a & 0x30) == 0x30, ++ 50, 2500, false, rtwdev, REG_TXPKT_EMPTY); ++ ++ rtw_write32_set(rtwdev, REG_RXPSEL, BIT_RX_PSEL_RST); ++ ++ if (chip->id == RTW_CHIP_TYPE_8821A) { ++ rtw_write32_mask(rtwdev, REG_TXSCALE_A, 0xf00, 1); ++ } else { ++ rtw_write32_mask(rtwdev, REG_BWINDICATION, 0x3, 0x2); ++ rtw_write32_mask(rtwdev, REG_PDMFTH, GENMASK(17, 13), 0x15); ++ rtw_write32_mask(rtwdev, REG_PDMFTH, GENMASK(3, 1), 0x04); ++ ++ rtw_write32_mask(rtwdev, REG_CCASEL, 0x3, 1); ++ ++ rtw8812a_phy_set_rfe_reg_5g(rtwdev); ++ } ++ ++ rtw_write32_mask(rtwdev, REG_TXPSEL, 0xf0, 0); ++ rtw_write32_mask(rtwdev, REG_CCK_RX, 0x0f000000, 0xf); ++ ++ basic_rates = BIT(DESC_RATE6M) | BIT(DESC_RATE12M) | ++ BIT(DESC_RATE24M); ++ rtw_write32_mask(rtwdev, REG_RRSR, 0xfffff, basic_rates); ++ } ++ ++ rtw88xxa_set_channel_bb_swing(rtwdev, new_band); ++} ++ ++int rtw88xxa_power_on(struct rtw_dev *rtwdev) ++{ ++ struct rtw_usb *rtwusb = rtw_get_usb_priv(rtwdev); ++ const struct rtw_chip_info *chip = rtwdev->chip; ++ struct rtw_efuse *efuse = &rtwdev->efuse; ++ struct rtw_hal *hal = &rtwdev->hal; ++ int ret; ++ ++ if (test_bit(RTW_FLAG_POWERON, rtwdev->flags)) ++ return 0; ++ ++ /* Override rtw_chip_efuse_info_setup() */ ++ if (chip->id == RTW_CHIP_TYPE_8821A) ++ efuse->btcoex = rtw_read32_mask(rtwdev, REG_WL_BT_PWR_CTRL, ++ BIT_BT_FUNC_EN); ++ ++ /* Override rtw_chip_efuse_info_setup() */ ++ if (chip->id == RTW_CHIP_TYPE_8812A) ++ rtw8812a_read_amplifier_type(rtwdev); ++ ++ ret = rtw_hci_setup(rtwdev); ++ if (ret) { ++ rtw_err(rtwdev, "failed to setup hci\n"); ++ goto err; ++ } ++ ++ /* Revise for U2/U3 switch we can not update RF-A/B reset. ++ * Reset after MAC power on to prevent RF R/W error. ++ * Is it a right method? ++ */ ++ if (chip->id == RTW_CHIP_TYPE_8812A) { ++ rtw_write8(rtwdev, REG_RF_CTRL, 5); ++ rtw_write8(rtwdev, REG_RF_CTRL, 7); ++ rtw_write8(rtwdev, REG_RF_B_CTRL, 5); ++ rtw_write8(rtwdev, REG_RF_B_CTRL, 7); ++ } ++ ++ /* If HW didn't go through a complete de-initial procedure, ++ * it probably occurs some problem for double initial ++ * procedure. ++ */ ++ rtw88xxau_hw_reset(rtwdev); ++ ++ ret = rtw88xxau_init_power_on(rtwdev); ++ if (ret) { ++ rtw_err(rtwdev, "failed to power on\n"); ++ goto err; ++ } ++ ++ ret = rtw_set_trx_fifo_info(rtwdev); ++ if (ret) { ++ rtw_err(rtwdev, "failed to set trx fifo info\n"); ++ goto err; ++ } ++ ++ ret = rtw88xxa_llt_init(rtwdev, rtwdev->fifo.rsvd_boundary); ++ if (ret) { ++ rtw_err(rtwdev, "failed to init llt\n"); ++ goto err; ++ } ++ ++ rtw_write32_set(rtwdev, REG_TXDMA_OFFSET_CHK, BIT_DROP_DATA_EN); ++ ++ ret = rtw_wait_firmware_completion(rtwdev); ++ if (ret) { ++ rtw_err(rtwdev, "failed to wait firmware completion\n"); ++ goto err_off; ++ } ++ ++ ret = rtw_download_firmware(rtwdev, &rtwdev->fw); ++ if (ret) { ++ rtw_err(rtwdev, "failed to download firmware\n"); ++ goto err_off; ++ } ++ ++ rtw_write8(rtwdev, REG_HMETFR, 0xf); ++ ++ rtw_load_table(rtwdev, chip->mac_tbl); ++ ++ rtw88xxau_init_queue_reserved_page(rtwdev); ++ rtw88xxau_init_tx_buffer_boundary(rtwdev); ++ rtw88xxau_init_queue_priority(rtwdev); ++ ++ rtw_write16(rtwdev, REG_TRXFF_BNDY + 2, ++ chip->rxff_size - REPORT_BUF - 1); ++ ++ if (chip->id == RTW_CHIP_TYPE_8812A) ++ rtw_write8(rtwdev, REG_PBP, ++ u8_encode_bits(PBP_512, PBP_TX_MASK) | ++ u8_encode_bits(PBP_64, PBP_RX_MASK)); ++ ++ rtw_write8(rtwdev, REG_RX_DRVINFO_SZ, PHY_STATUS_SIZE); ++ ++ rtw_write32(rtwdev, REG_HIMR0, 0); ++ rtw_write32(rtwdev, REG_HIMR1, 0); ++ ++ rtw_write32_mask(rtwdev, REG_CR, 0x30000, 0x2); ++ ++ rtw88xxa_init_wmac_setting(rtwdev); ++ rtw88xxa_init_adaptive_ctrl(rtwdev); ++ rtw88xxa_init_edca(rtwdev); ++ ++ rtw_write8_set(rtwdev, REG_FWHW_TXQ_CTRL, BIT(7)); ++ rtw_write8(rtwdev, REG_ACKTO, 0x80); ++ ++ rtw88xxau_tx_aggregation(rtwdev); ++ ++ rtw88xxa_init_beacon_parameters(rtwdev); ++ rtw_write8(rtwdev, REG_BCN_MAX_ERR, 0xff); ++ ++ rtw_hci_interface_cfg(rtwdev); ++ ++ /* usb3 rx interval */ ++ rtw_write8(rtwdev, REG_USB3_RXITV, 0x01); ++ ++ /* burst length=4, set 0x3400 for burst length=2 */ ++ rtw_write16(rtwdev, REG_RXDMA_STATUS, 0x7400); ++ rtw_write8(rtwdev, REG_RXDMA_STATUS + 1, 0xf5); ++ ++ /* 0x456 = 0x70, sugguested by Zhilin */ ++ if (chip->id == RTW_CHIP_TYPE_8821A) ++ rtw_write8(rtwdev, REG_AMPDU_MAX_TIME, 0x5e); ++ else ++ rtw_write8(rtwdev, REG_AMPDU_MAX_TIME, 0x70); ++ ++ rtw_write32(rtwdev, REG_AMPDU_MAX_LENGTH, 0xffffffff); ++ rtw_write8(rtwdev, REG_USTIME_TSF, 0x50); ++ rtw_write8(rtwdev, REG_USTIME_EDCA, 0x50); ++ ++ if (rtwusb->udev->speed == USB_SPEED_SUPER) ++ /* Disable U1/U2 Mode to avoid 2.5G spur in USB3.0. */ ++ rtw_write8_clr(rtwdev, REG_USB_MOD, BIT(4) | BIT(3)); ++ ++ rtw_write8_set(rtwdev, REG_SINGLE_AMPDU_CTRL, BIT_EN_SINGLE_APMDU); ++ ++ /* for VHT packet length 11K */ ++ rtw_write8(rtwdev, REG_RX_PKT_LIMIT, 0x18); ++ ++ rtw_write8(rtwdev, REG_PIFS, 0x00); ++ ++ if (chip->id == RTW_CHIP_TYPE_8821A) { ++ /* 0x0a0a too small, it can't pass AC logo. change to 0x1f1f */ ++ rtw_write16(rtwdev, REG_MAX_AGGR_NUM, 0x1f1f); ++ rtw_write8(rtwdev, REG_FWHW_TXQ_CTRL, 0x80); ++ rtw_write32(rtwdev, REG_FAST_EDCA_CTRL, 0x03087777); ++ } else { ++ rtw_write16(rtwdev, REG_MAX_AGGR_NUM, 0x1f1f); ++ rtw_write8_clr(rtwdev, REG_FWHW_TXQ_CTRL, BIT(7)); ++ } ++ ++ /* to prevent mac is reseted by bus. */ ++ rtw_write8_set(rtwdev, REG_RSV_CTRL, BIT(5) | BIT(6)); ++ ++ /* ARFB table 9 for 11ac 5G 2SS */ ++ rtw_write32(rtwdev, REG_ARFR0, 0x00000010); ++ rtw_write32(rtwdev, REG_ARFRH0, 0xfffff000); ++ ++ /* ARFB table 10 for 11ac 5G 1SS */ ++ rtw_write32(rtwdev, REG_ARFR1_V1, 0x00000010); ++ rtw_write32(rtwdev, REG_ARFRH1_V1, 0x003ff000); ++ ++ /* ARFB table 11 for 11ac 24G 1SS */ ++ rtw_write32(rtwdev, REG_ARFR2_V1, 0x00000015); ++ rtw_write32(rtwdev, REG_ARFRH2_V1, 0x003ff000); ++ ++ /* ARFB table 12 for 11ac 24G 2SS */ ++ rtw_write32(rtwdev, REG_ARFR3_V1, 0x00000015); ++ rtw_write32(rtwdev, REG_ARFRH3_V1, 0xffcff000); ++ ++ rtw_write8_set(rtwdev, REG_CR, BIT_MACTXEN | BIT_MACRXEN); ++ ++ rtw88xxa_phy_bb_config(rtwdev); ++ rtw88xxa_phy_rf_config(rtwdev); ++ ++ if (chip->id == RTW_CHIP_TYPE_8812A && hal->rf_path_num == 1) ++ rtw8812a_config_1t(rtwdev); ++ ++ rtw88xxa_switch_band(rtwdev, RTW_BAND_2G, RTW_CHANNEL_WIDTH_20); ++ ++ rtw_write32(rtwdev, RTW_SEC_CMD_REG, BIT(31) | BIT(30)); ++ ++ rtw_write8(rtwdev, REG_HWSEQ_CTRL, 0xff); ++ rtw_write32(rtwdev, REG_BAR_MODE_CTRL, 0x0201ffff); ++ rtw_write8(rtwdev, REG_NAV_CTRL + 2, 0); ++ ++ rtw_write8_clr(rtwdev, REG_GPIO_MUXCFG, BIT(5)); ++ ++ rtw_phy_init(rtwdev); ++ ++ rtw88xxa_pwrtrack_init(rtwdev); ++ ++ /* 0x4c6[3] 1: RTS BW = Data BW ++ * 0: RTS BW depends on CCA / secondary CCA result. ++ */ ++ rtw_write8_clr(rtwdev, REG_QUEUE_CTRL, BIT(3)); ++ ++ /* enable Tx report. */ ++ rtw_write8(rtwdev, REG_FWHW_TXQ_CTRL + 1, 0x0f); ++ ++ /* Pretx_en, for WEP/TKIP SEC */ ++ rtw_write8(rtwdev, REG_EARLY_MODE_CONTROL + 3, 0x01); ++ ++ rtw_write16(rtwdev, REG_TX_RPT_TIME, 0x3df0); ++ ++ /* Reset USB mode switch setting */ ++ rtw_write8(rtwdev, REG_SYS_SDIO_CTRL, 0x0); ++ rtw_write8(rtwdev, REG_ACLK_MON, 0x0); ++ ++ rtw_write8(rtwdev, REG_USB_HRPWM, 0); ++ ++ /* ack for xmit mgmt frames. */ ++ rtw_write32_set(rtwdev, REG_FWHW_TXQ_CTRL, BIT(12)); ++ ++ hal->cck_high_power = rtw_read32_mask(rtwdev, REG_CCK_RPT_FORMAT, ++ BIT_CCK_RPT_FORMAT); ++ ++ ret = rtw_hci_start(rtwdev); ++ if (ret) { ++ rtw_err(rtwdev, "failed to start hci\n"); ++ goto err_off; ++ } ++ ++ if (efuse->btcoex) { ++ rtw_coex_power_on_setting(rtwdev); ++ rtw_coex_init_hw_config(rtwdev, false); ++ } ++ ++ set_bit(RTW_FLAG_POWERON, rtwdev->flags); ++ ++ return 0; ++ ++err_off: ++ chip->ops->power_off(rtwdev); ++ ++err: ++ return ret; ++} ++EXPORT_SYMBOL(rtw88xxa_power_on); ++ ++u32 rtw88xxa_phy_read_rf(struct rtw_dev *rtwdev, ++ enum rtw_rf_path rf_path, u32 addr, u32 mask) ++{ ++ static const u32 pi_addr[2] = { REG_3WIRE_SWA, REG_3WIRE_SWB }; ++ static const u32 read_addr[2][2] = { ++ { REG_SI_READ_A, REG_SI_READ_B }, ++ { REG_PI_READ_A, REG_PI_READ_B } ++ }; ++ const struct rtw_chip_info *chip = rtwdev->chip; ++ const struct rtw_hal *hal = &rtwdev->hal; ++ bool set_cca, pi_mode; ++ u32 val; ++ ++ if (rf_path >= hal->rf_phy_num) { ++ rtw_err(rtwdev, "unsupported rf path (%d)\n", rf_path); ++ return INV_RF_DATA; ++ } ++ ++ /* CCA off to avoid reading the wrong value. ++ * Toggling CCA would affect RF 0x0, skip it. ++ */ ++ set_cca = addr != 0x0 && chip->id == RTW_CHIP_TYPE_8812A && ++ hal->cut_version != RTW_CHIP_VER_CUT_C; ++ ++ if (set_cca) ++ rtw_write32_set(rtwdev, REG_CCA2ND, BIT(3)); ++ ++ addr &= 0xff; ++ ++ pi_mode = rtw_read32_mask(rtwdev, pi_addr[rf_path], 0x4); ++ ++ rtw_write32_mask(rtwdev, REG_HSSI_READ, MASKBYTE0, addr); ++ ++ if (chip->id == RTW_CHIP_TYPE_8821A || ++ hal->cut_version == RTW_CHIP_VER_CUT_C) ++ udelay(20); ++ ++ val = rtw_read32_mask(rtwdev, read_addr[pi_mode][rf_path], mask); ++ ++ /* CCA on */ ++ if (set_cca) ++ rtw_write32_clr(rtwdev, REG_CCA2ND, BIT(3)); ++ ++ return val; ++} ++EXPORT_SYMBOL(rtw88xxa_phy_read_rf); ++ ++static void rtw8812a_phy_fix_spur(struct rtw_dev *rtwdev, u8 channel, u8 bw) ++{ ++ /* C cut Item12 ADC FIFO CLOCK */ ++ if (rtwdev->hal.cut_version == RTW_CHIP_VER_CUT_C) { ++ if (bw == RTW_CHANNEL_WIDTH_40 && channel == 11) ++ rtw_write32_mask(rtwdev, REG_ADCCLK, 0xC00, 0x3); ++ else ++ rtw_write32_mask(rtwdev, REG_ADCCLK, 0xC00, 0x2); ++ ++ /* A workaround to resolve 2480Mhz spur by setting ADC clock ++ * as 160M. ++ */ ++ if (bw == RTW_CHANNEL_WIDTH_20 && (channel == 13 || channel == 14)) { ++ rtw_write32_mask(rtwdev, REG_ADCCLK, 0x300, 0x3); ++ rtw_write32_mask(rtwdev, REG_ADC160, BIT(30), 1); ++ } else if (bw == RTW_CHANNEL_WIDTH_40 && channel == 11) { ++ rtw_write32_mask(rtwdev, REG_ADC160, BIT(30), 1); ++ } else if (bw != RTW_CHANNEL_WIDTH_80) { ++ rtw_write32_mask(rtwdev, REG_ADCCLK, 0x300, 0x2); ++ rtw_write32_mask(rtwdev, REG_ADC160, BIT(30), 0); ++ } ++ } else { ++ /* A workaround to resolve 2480Mhz spur by setting ADC clock ++ * as 160M. ++ */ ++ if (bw == RTW_CHANNEL_WIDTH_20 && (channel == 13 || channel == 14)) ++ rtw_write32_mask(rtwdev, REG_ADCCLK, 0x300, 0x3); ++ else if (channel <= 14) /* 2.4G only */ ++ rtw_write32_mask(rtwdev, REG_ADCCLK, 0x300, 0x2); ++ } ++} ++ ++static void rtw88xxa_switch_channel(struct rtw_dev *rtwdev, u8 channel, u8 bw) ++{ ++ struct rtw_hal *hal = &rtwdev->hal; ++ u32 fc_area, rf_mod_ag; ++ u8 path; ++ ++ switch (channel) { ++ case 36 ... 48: ++ fc_area = 0x494; ++ break; ++ case 50 ... 64: ++ fc_area = 0x453; ++ break; ++ case 100 ... 116: ++ fc_area = 0x452; ++ break; ++ default: ++ if (channel >= 118) ++ fc_area = 0x412; ++ else ++ fc_area = 0x96a; ++ break; ++ } ++ ++ rtw_write32_mask(rtwdev, REG_CLKTRK, 0x1ffe0000, fc_area); ++ ++ for (path = 0; path < hal->rf_path_num; path++) { ++ switch (channel) { ++ case 36 ... 64: ++ rf_mod_ag = 0x101; ++ break; ++ case 100 ... 140: ++ rf_mod_ag = 0x301; ++ break; ++ default: ++ if (channel > 140) ++ rf_mod_ag = 0x501; ++ else ++ rf_mod_ag = 0x000; ++ break; ++ } ++ ++ rtw_write_rf(rtwdev, path, RF_CFGCH, ++ RF18_RFSI_MASK | RF18_BAND_MASK, rf_mod_ag); ++ ++ if (rtwdev->chip->id == RTW_CHIP_TYPE_8812A) ++ rtw8812a_phy_fix_spur(rtwdev, channel, bw); ++ ++ rtw_write_rf(rtwdev, path, RF_CFGCH, RF18_CHANNEL_MASK, channel); ++ } ++} ++ ++static void rtw88xxa_set_reg_bw(struct rtw_dev *rtwdev, u8 bw) ++{ ++ u16 val16 = rtw_read16(rtwdev, REG_WMAC_TRXPTCL_CTL); ++ ++ val16 &= ~BIT_RFMOD; ++ if (bw == RTW_CHANNEL_WIDTH_80) ++ val16 |= BIT_RFMOD_80M; ++ else if (bw == RTW_CHANNEL_WIDTH_40) ++ val16 |= BIT_RFMOD_40M; ++ ++ rtw_write16(rtwdev, REG_WMAC_TRXPTCL_CTL, val16); ++} ++ ++static void rtw88xxa_post_set_bw_mode(struct rtw_dev *rtwdev, u8 channel, ++ u8 bw, u8 primary_chan_idx) ++{ ++ struct rtw_hal *hal = &rtwdev->hal; ++ u8 txsc40 = 0, txsc20, txsc; ++ u8 reg_837, l1pkval; ++ ++ rtw88xxa_set_reg_bw(rtwdev, bw); ++ ++ txsc20 = primary_chan_idx; ++ if (bw == RTW_CHANNEL_WIDTH_80) { ++ if (txsc20 == RTW_SC_20_UPPER || txsc20 == RTW_SC_20_UPMOST) ++ txsc40 = RTW_SC_40_UPPER; ++ else ++ txsc40 = RTW_SC_40_LOWER; ++ } ++ ++ txsc = BIT_TXSC_20M(txsc20) | BIT_TXSC_40M(txsc40); ++ rtw_write8(rtwdev, REG_DATA_SC, txsc); ++ ++ reg_837 = rtw_read8(rtwdev, REG_BWINDICATION + 3); ++ ++ switch (bw) { ++ default: ++ case RTW_CHANNEL_WIDTH_20: ++ rtw_write32_mask(rtwdev, REG_ADCCLK, 0x003003C3, 0x00300200); ++ rtw_write32_mask(rtwdev, REG_ADC160, BIT(30), 0); ++ ++ if (hal->rf_type == RF_2T2R) ++ rtw_write32_mask(rtwdev, REG_L1PKTH, 0x03C00000, 7); ++ else ++ rtw_write32_mask(rtwdev, REG_L1PKTH, 0x03C00000, 8); ++ ++ break; ++ case RTW_CHANNEL_WIDTH_40: ++ rtw_write32_mask(rtwdev, REG_ADCCLK, 0x003003C3, 0x00300201); ++ rtw_write32_mask(rtwdev, REG_ADC160, BIT(30), 0); ++ rtw_write32_mask(rtwdev, REG_ADCCLK, 0x3C, txsc); ++ rtw_write32_mask(rtwdev, REG_CCA2ND, 0xf0000000, txsc); ++ ++ if (reg_837 & BIT(2)) { ++ l1pkval = 6; ++ } else { ++ if (hal->rf_type == RF_2T2R) ++ l1pkval = 7; ++ else ++ l1pkval = 8; ++ } ++ ++ rtw_write32_mask(rtwdev, REG_L1PKTH, 0x03C00000, l1pkval); ++ ++ if (txsc == RTW_SC_20_UPPER) ++ rtw_write32_set(rtwdev, REG_RXSB, BIT(4)); ++ else ++ rtw_write32_clr(rtwdev, REG_RXSB, BIT(4)); ++ ++ break; ++ case RTW_CHANNEL_WIDTH_80: ++ rtw_write32_mask(rtwdev, REG_ADCCLK, 0x003003C3, 0x00300202); ++ rtw_write32_mask(rtwdev, REG_ADC160, BIT(30), 1); ++ rtw_write32_mask(rtwdev, REG_ADCCLK, 0x3C, txsc); ++ rtw_write32_mask(rtwdev, REG_CCA2ND, 0xf0000000, txsc); ++ ++ if (reg_837 & BIT(2)) { ++ l1pkval = 5; ++ } else { ++ if (hal->rf_type == RF_2T2R) ++ l1pkval = 6; ++ else ++ l1pkval = 7; ++ } ++ ++ rtw_write32_mask(rtwdev, REG_L1PKTH, 0x03C00000, l1pkval); ++ ++ break; ++ } ++} ++ ++static void rtw88xxa_set_channel_rf(struct rtw_dev *rtwdev, u8 channel, u8 bw) ++{ ++ u8 path; ++ ++ for (path = RF_PATH_A; path < rtwdev->hal.rf_path_num; path++) { ++ switch (bw) { ++ case RTW_CHANNEL_WIDTH_5: ++ case RTW_CHANNEL_WIDTH_10: ++ case RTW_CHANNEL_WIDTH_20: ++ default: ++ rtw_write_rf(rtwdev, path, RF_CFGCH, RF18_BW_MASK, 3); ++ break; ++ case RTW_CHANNEL_WIDTH_40: ++ rtw_write_rf(rtwdev, path, RF_CFGCH, RF18_BW_MASK, 1); ++ break; ++ case RTW_CHANNEL_WIDTH_80: ++ rtw_write_rf(rtwdev, path, RF_CFGCH, RF18_BW_MASK, 0); ++ break; ++ } ++ } ++} ++ ++void rtw88xxa_set_channel(struct rtw_dev *rtwdev, u8 channel, u8 bw, ++ u8 primary_chan_idx) ++{ ++ u8 old_band, new_band; ++ ++ if (rtw_read8(rtwdev, REG_CCK_CHECK) & BIT_CHECK_CCK_EN) ++ old_band = RTW_BAND_5G; ++ else ++ old_band = RTW_BAND_2G; ++ ++ if (channel > 14) ++ new_band = RTW_BAND_5G; ++ else ++ new_band = RTW_BAND_2G; ++ ++ if (new_band != old_band) ++ rtw88xxa_switch_band(rtwdev, new_band, bw); ++ ++ rtw88xxa_switch_channel(rtwdev, channel, bw); ++ ++ rtw88xxa_post_set_bw_mode(rtwdev, channel, bw, primary_chan_idx); ++ ++ if (rtwdev->chip->id == RTW_CHIP_TYPE_8812A) ++ rtw8812a_phy_fix_spur(rtwdev, channel, bw); ++ ++ rtw88xxa_set_channel_rf(rtwdev, channel, bw); ++} ++EXPORT_SYMBOL(rtw88xxa_set_channel); ++ ++void rtw88xxa_query_phy_status(struct rtw_dev *rtwdev, u8 *phy_status, ++ struct rtw_rx_pkt_stat *pkt_stat, ++ s8 (*cck_rx_pwr)(u8 lna_idx, u8 vga_idx)) ++{ ++ struct rtw_dm_info *dm_info = &rtwdev->dm_info; ++ struct rtw_jaguar_phy_status_rpt *rpt; ++ u8 gain[RTW_RF_PATH_MAX], rssi, i; ++ s8 rx_pwr_db, power_a, power_b; ++ const s8 min_rx_power = -120; ++ u8 lna_idx, vga_idx; ++ ++ rpt = (struct rtw_jaguar_phy_status_rpt *)phy_status; ++ ++ if (pkt_stat->rate <= DESC_RATE11M) { ++ lna_idx = le32_get_bits(rpt->w1, RTW_JGRPHY_W1_AGC_RPT_LNA_IDX); ++ vga_idx = le32_get_bits(rpt->w1, RTW_JGRPHY_W1_AGC_RPT_VGA_IDX); ++ ++ rx_pwr_db = cck_rx_pwr(lna_idx, vga_idx); ++ ++ pkt_stat->rx_power[RF_PATH_A] = rx_pwr_db; ++ pkt_stat->rssi = rtw_phy_rf_power_2_rssi(pkt_stat->rx_power, 1); ++ dm_info->rssi[RF_PATH_A] = pkt_stat->rssi; ++ pkt_stat->bw = RTW_CHANNEL_WIDTH_20; ++ pkt_stat->signal_power = rx_pwr_db; ++ } else { /* OFDM rate */ ++ gain[RF_PATH_A] = le32_get_bits(rpt->w0, RTW_JGRPHY_W0_GAIN_A); ++ gain[RF_PATH_B] = le32_get_bits(rpt->w0, RTW_JGRPHY_W0_GAIN_B); ++ ++ for (i = RF_PATH_A; i < rtwdev->hal.rf_path_num; i++) { ++ pkt_stat->rx_power[i] = gain[i] - 110; ++ rssi = rtw_phy_rf_power_2_rssi(&pkt_stat->rx_power[i], 1); ++ dm_info->rssi[i] = rssi; ++ } ++ ++ pkt_stat->rssi = rtw_phy_rf_power_2_rssi(pkt_stat->rx_power, ++ rtwdev->hal.rf_path_num); ++ ++ power_a = pkt_stat->rx_power[RF_PATH_A]; ++ power_b = pkt_stat->rx_power[RF_PATH_B]; ++ if (rtwdev->hal.rf_path_num == 1) ++ power_b = power_a; ++ ++ pkt_stat->signal_power = max3(power_a, power_b, min_rx_power); ++ } ++} ++EXPORT_SYMBOL(rtw88xxa_query_phy_status); ++ ++static void ++rtw88xxa_set_tx_power_index_by_rate(struct rtw_dev *rtwdev, u8 path, ++ u8 rs, u32 *phy_pwr_idx) ++{ ++ static const u32 offset_txagc[2] = { ++ REG_TX_AGC_A_CCK_11_CCK_1, REG_TX_AGC_B_CCK_11_CCK_1 ++ }; ++ u8 rate, rate_idx, pwr_index, shift; ++ struct rtw_hal *hal = &rtwdev->hal; ++ bool write_1ss_mcs9; ++ u32 mask; ++ int j; ++ ++ for (j = 0; j < rtw_rate_size[rs]; j++) { ++ rate = rtw_rate_section[rs][j]; ++ ++ pwr_index = hal->tx_pwr_tbl[path][rate]; ++ ++ shift = rate & 0x3; ++ *phy_pwr_idx |= ((u32)pwr_index << (shift * 8)); ++ ++ write_1ss_mcs9 = rate == DESC_RATEVHT1SS_MCS9 && ++ hal->rf_path_num == 1; ++ ++ if (write_1ss_mcs9) ++ mask = MASKLWORD; ++ else ++ mask = MASKDWORD; ++ ++ if (shift == 0x3 || write_1ss_mcs9) { ++ rate_idx = rate & 0xfc; ++ if (rate >= DESC_RATEVHT1SS_MCS0) ++ rate_idx -= 0x10; ++ ++ rtw_write32_mask(rtwdev, offset_txagc[path] + rate_idx, ++ mask, *phy_pwr_idx); ++ ++ *phy_pwr_idx = 0; ++ } ++ } ++} ++ ++static void rtw88xxa_tx_power_training(struct rtw_dev *rtwdev, u8 bw, ++ u8 channel, u8 path) ++{ ++ static const u32 write_offset[] = { ++ REG_TX_PWR_TRAINING_A, REG_TX_PWR_TRAINING_B, ++ }; ++ u32 power_level, write_data; ++ u8 i; ++ ++ power_level = rtwdev->hal.tx_pwr_tbl[path][DESC_RATEMCS7]; ++ write_data = 0; ++ ++ for (i = 0; i < 3; i++) { ++ if (i == 0) ++ power_level -= 10; ++ else if (i == 1) ++ power_level -= 8; ++ else ++ power_level -= 6; ++ ++ write_data |= max_t(u32, power_level, 2) << (i * 8); ++ } ++ ++ rtw_write32_mask(rtwdev, write_offset[path], 0xffffff, write_data); ++} ++ ++void rtw88xxa_set_tx_power_index(struct rtw_dev *rtwdev) ++{ ++ struct rtw_hal *hal = &rtwdev->hal; ++ u32 phy_pwr_idx = 0; ++ int rs, path; ++ ++ for (path = 0; path < hal->rf_path_num; path++) { ++ for (rs = 0; rs < RTW_RATE_SECTION_MAX; rs++) { ++ if (hal->rf_path_num == 1 && ++ (rs == RTW_RATE_SECTION_HT_2S || ++ rs == RTW_RATE_SECTION_VHT_2S)) ++ continue; ++ ++ if (test_bit(RTW_FLAG_SCANNING, rtwdev->flags) && ++ rs > RTW_RATE_SECTION_OFDM) ++ continue; ++ ++ if (hal->current_band_type == RTW_BAND_5G && ++ rs == RTW_RATE_SECTION_CCK) ++ continue; ++ ++ rtw88xxa_set_tx_power_index_by_rate(rtwdev, path, rs, ++ &phy_pwr_idx); ++ } ++ ++ rtw88xxa_tx_power_training(rtwdev, hal->current_band_width, ++ hal->current_channel, path); ++ } ++} ++EXPORT_SYMBOL(rtw88xxa_set_tx_power_index); ++ ++void rtw88xxa_false_alarm_statistics(struct rtw_dev *rtwdev) ++{ ++ struct rtw_dm_info *dm_info = &rtwdev->dm_info; ++ u32 cck_fa_cnt, ofdm_fa_cnt; ++ u32 crc32_cnt, cca32_cnt; ++ u32 cck_enable; ++ ++ cck_enable = rtw_read32(rtwdev, REG_RXPSEL) & BIT(28); ++ cck_fa_cnt = rtw_read16(rtwdev, REG_FA_CCK); ++ ofdm_fa_cnt = rtw_read16(rtwdev, REG_FA_OFDM); ++ ++ dm_info->cck_fa_cnt = cck_fa_cnt; ++ dm_info->ofdm_fa_cnt = ofdm_fa_cnt; ++ dm_info->total_fa_cnt = ofdm_fa_cnt; ++ if (cck_enable) ++ dm_info->total_fa_cnt += cck_fa_cnt; ++ ++ crc32_cnt = rtw_read32(rtwdev, REG_CRC_CCK); ++ dm_info->cck_ok_cnt = u32_get_bits(crc32_cnt, MASKLWORD); ++ dm_info->cck_err_cnt = u32_get_bits(crc32_cnt, MASKHWORD); ++ ++ crc32_cnt = rtw_read32(rtwdev, REG_CRC_OFDM); ++ dm_info->ofdm_ok_cnt = u32_get_bits(crc32_cnt, MASKLWORD); ++ dm_info->ofdm_err_cnt = u32_get_bits(crc32_cnt, MASKHWORD); ++ ++ crc32_cnt = rtw_read32(rtwdev, REG_CRC_HT); ++ dm_info->ht_ok_cnt = u32_get_bits(crc32_cnt, MASKLWORD); ++ dm_info->ht_err_cnt = u32_get_bits(crc32_cnt, MASKHWORD); ++ ++ crc32_cnt = rtw_read32(rtwdev, REG_CRC_VHT); ++ dm_info->vht_ok_cnt = u32_get_bits(crc32_cnt, MASKLWORD); ++ dm_info->vht_err_cnt = u32_get_bits(crc32_cnt, MASKHWORD); ++ ++ cca32_cnt = rtw_read32(rtwdev, REG_CCA_OFDM); ++ dm_info->ofdm_cca_cnt = u32_get_bits(cca32_cnt, MASKHWORD); ++ dm_info->total_cca_cnt = dm_info->ofdm_cca_cnt; ++ if (cck_enable) { ++ cca32_cnt = rtw_read32(rtwdev, REG_CCA_CCK); ++ dm_info->cck_cca_cnt = u32_get_bits(cca32_cnt, MASKLWORD); ++ dm_info->total_cca_cnt += dm_info->cck_cca_cnt; ++ } ++ ++ rtw_write32_set(rtwdev, REG_FAS, BIT(17)); ++ rtw_write32_clr(rtwdev, REG_FAS, BIT(17)); ++ rtw_write32_clr(rtwdev, REG_CCK0_FAREPORT, BIT(15)); ++ rtw_write32_set(rtwdev, REG_CCK0_FAREPORT, BIT(15)); ++ rtw_write32_set(rtwdev, REG_CNTRST, BIT(0)); ++ rtw_write32_clr(rtwdev, REG_CNTRST, BIT(0)); ++} ++EXPORT_SYMBOL(rtw88xxa_false_alarm_statistics); ++ ++void rtw88xxa_iqk_backup_mac_bb(struct rtw_dev *rtwdev, ++ u32 *macbb_backup, ++ const u32 *backup_macbb_reg, ++ u32 macbb_num) ++{ ++ u32 i; ++ ++ /* [31] = 0 --> Page C */ ++ rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0); ++ ++ /* save MACBB default value */ ++ for (i = 0; i < macbb_num; i++) ++ macbb_backup[i] = rtw_read32(rtwdev, backup_macbb_reg[i]); ++} ++EXPORT_SYMBOL(rtw88xxa_iqk_backup_mac_bb); ++ ++void rtw88xxa_iqk_backup_afe(struct rtw_dev *rtwdev, u32 *afe_backup, ++ const u32 *backup_afe_reg, u32 afe_num) ++{ ++ u32 i; ++ ++ /* [31] = 0 --> Page C */ ++ rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0); ++ ++ /* Save AFE Parameters */ ++ for (i = 0; i < afe_num; i++) ++ afe_backup[i] = rtw_read32(rtwdev, backup_afe_reg[i]); ++} ++EXPORT_SYMBOL(rtw88xxa_iqk_backup_afe); ++ ++void rtw88xxa_iqk_restore_mac_bb(struct rtw_dev *rtwdev, ++ u32 *macbb_backup, ++ const u32 *backup_macbb_reg, ++ u32 macbb_num) ++{ ++ u32 i; ++ ++ /* [31] = 0 --> Page C */ ++ rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0); ++ ++ /* Reload MacBB Parameters */ ++ for (i = 0; i < macbb_num; i++) ++ rtw_write32(rtwdev, backup_macbb_reg[i], macbb_backup[i]); ++} ++EXPORT_SYMBOL(rtw88xxa_iqk_restore_mac_bb); ++ ++void rtw88xxa_iqk_configure_mac(struct rtw_dev *rtwdev) ++{ ++ /* [31] = 0 --> Page C */ ++ rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0); ++ ++ rtw_write8(rtwdev, REG_TXPAUSE, 0x3f); ++ rtw_write32_mask(rtwdev, REG_BCN_CTRL, ++ (BIT_EN_BCN_FUNCTION << 8) | BIT_EN_BCN_FUNCTION, 0x0); ++ ++ /* RX ante off */ ++ rtw_write8(rtwdev, REG_RXPSEL, 0x00); ++ ++ /* CCA off */ ++ rtw_write32_mask(rtwdev, REG_CCA2ND, 0xf, 0xc); ++ ++ /* CCK RX path off */ ++ rtw_write8(rtwdev, REG_CCK_RX + 3, 0xf); ++} ++EXPORT_SYMBOL(rtw88xxa_iqk_configure_mac); ++ ++bool rtw88xxa_iqk_finish(int average, int threshold, ++ int *x_temp, int *y_temp, int *x, int *y, ++ bool break_inner, bool break_outer) ++{ ++ bool finish = false; ++ int i, ii, dx, dy; ++ ++ for (i = 0; i < average; i++) { ++ for (ii = i + 1; ii < average; ii++) { ++ dx = abs_diff(x_temp[i] >> 21, x_temp[ii] >> 21); ++ dy = abs_diff(y_temp[i] >> 21, y_temp[ii] >> 21); ++ ++ if (dx < threshold && dy < threshold) { ++ *x = ((x_temp[i] >> 21) + (x_temp[ii] >> 21)); ++ *y = ((y_temp[i] >> 21) + (y_temp[ii] >> 21)); ++ ++ *x /= 2; ++ *y /= 2; ++ ++ finish = true; ++ ++ if (break_inner) ++ break; ++ } ++ } ++ ++ if (finish && break_outer) ++ break; ++ } ++ ++ return finish; ++} ++EXPORT_SYMBOL(rtw88xxa_iqk_finish); ++ ++static void rtw88xxa_pwrtrack_set(struct rtw_dev *rtwdev, u8 tx_rate, u8 path) ++{ ++ static const u32 reg_txscale[2] = { REG_TXSCALE_A, REG_TXSCALE_B }; ++ struct rtw_dm_info *dm_info = &rtwdev->dm_info; ++ u8 cck_swing_idx, ofdm_swing_idx; ++ u8 pwr_tracking_limit; ++ ++ switch (tx_rate) { ++ case DESC_RATE1M ... DESC_RATE11M: ++ pwr_tracking_limit = 32; ++ break; ++ case DESC_RATE6M ... DESC_RATE48M: ++ case DESC_RATEMCS3 ... DESC_RATEMCS4: ++ case DESC_RATEMCS11 ... DESC_RATEMCS12: ++ case DESC_RATEVHT1SS_MCS3 ... DESC_RATEVHT1SS_MCS4: ++ case DESC_RATEVHT2SS_MCS3 ... DESC_RATEVHT2SS_MCS4: ++ pwr_tracking_limit = 30; ++ break; ++ case DESC_RATE54M: ++ case DESC_RATEMCS5 ... DESC_RATEMCS7: ++ case DESC_RATEMCS13 ... DESC_RATEMCS15: ++ case DESC_RATEVHT1SS_MCS5 ... DESC_RATEVHT1SS_MCS6: ++ case DESC_RATEVHT2SS_MCS5 ... DESC_RATEVHT2SS_MCS6: ++ pwr_tracking_limit = 28; ++ break; ++ case DESC_RATEMCS0 ... DESC_RATEMCS2: ++ case DESC_RATEMCS8 ... DESC_RATEMCS10: ++ case DESC_RATEVHT1SS_MCS0 ... DESC_RATEVHT1SS_MCS2: ++ case DESC_RATEVHT2SS_MCS0 ... DESC_RATEVHT2SS_MCS2: ++ pwr_tracking_limit = 34; ++ break; ++ case DESC_RATEVHT1SS_MCS7: ++ case DESC_RATEVHT2SS_MCS7: ++ pwr_tracking_limit = 26; ++ break; ++ default: ++ case DESC_RATEVHT1SS_MCS8: ++ case DESC_RATEVHT2SS_MCS8: ++ pwr_tracking_limit = 24; ++ break; ++ case DESC_RATEVHT1SS_MCS9: ++ case DESC_RATEVHT2SS_MCS9: ++ pwr_tracking_limit = 22; ++ break; ++ } ++ ++ cck_swing_idx = dm_info->delta_power_index[path] + dm_info->default_cck_index; ++ ofdm_swing_idx = dm_info->delta_power_index[path] + dm_info->default_ofdm_index; ++ ++ if (ofdm_swing_idx > pwr_tracking_limit) { ++ if (path == RF_PATH_A) ++ dm_info->txagc_remnant_cck = cck_swing_idx - pwr_tracking_limit; ++ dm_info->txagc_remnant_ofdm[path] = ofdm_swing_idx - pwr_tracking_limit; ++ ++ ofdm_swing_idx = pwr_tracking_limit; ++ } else if (ofdm_swing_idx == 0) { ++ if (path == RF_PATH_A) ++ dm_info->txagc_remnant_cck = cck_swing_idx; ++ dm_info->txagc_remnant_ofdm[path] = ofdm_swing_idx; ++ } else { ++ if (path == RF_PATH_A) ++ dm_info->txagc_remnant_cck = 0; ++ dm_info->txagc_remnant_ofdm[path] = 0; ++ } ++ ++ rtw_write32_mask(rtwdev, reg_txscale[path], GENMASK(31, 21), ++ rtw88xxa_txscale_tbl[ofdm_swing_idx]); ++} ++ ++void rtw88xxa_phy_pwrtrack(struct rtw_dev *rtwdev, ++ void (*do_lck)(struct rtw_dev *rtwdev), ++ void (*do_iqk)(struct rtw_dev *rtwdev)) ++{ ++ struct rtw_dm_info *dm_info = &rtwdev->dm_info; ++ struct rtw_hal *hal = &rtwdev->hal; ++ struct rtw_swing_table swing_table; ++ s8 remnant_pre[RTW_RF_PATH_MAX]; ++ u8 thermal_value, delta, path; ++ bool need_iqk; ++ ++ rtw_phy_config_swing_table(rtwdev, &swing_table); ++ ++ if (rtwdev->efuse.thermal_meter[0] == 0xff) { ++ pr_err_once("efuse thermal meter is 0xff\n"); ++ return; ++ } ++ ++ thermal_value = rtw_read_rf(rtwdev, RF_PATH_A, RF_T_METER, 0xfc00); ++ ++ rtw_phy_pwrtrack_avg(rtwdev, thermal_value, RF_PATH_A); ++ ++ need_iqk = rtw_phy_pwrtrack_need_iqk(rtwdev); ++ ++ if (need_iqk && do_lck) ++ do_lck(rtwdev); ++ ++ if (dm_info->pwr_trk_init_trigger) ++ dm_info->pwr_trk_init_trigger = false; ++ else if (!rtw_phy_pwrtrack_thermal_changed(rtwdev, thermal_value, ++ RF_PATH_A)) ++ goto iqk; ++ ++ delta = rtw_phy_pwrtrack_get_delta(rtwdev, RF_PATH_A); ++ ++ for (path = RF_PATH_A; path < hal->rf_path_num; path++) { ++ remnant_pre[path] = dm_info->txagc_remnant_ofdm[path]; ++ ++ dm_info->delta_power_index[path] = ++ rtw_phy_pwrtrack_get_pwridx(rtwdev, &swing_table, path, ++ RF_PATH_A, delta); ++ ++ if (dm_info->delta_power_index[path] != ++ dm_info->delta_power_index_last[path]) { ++ dm_info->delta_power_index_last[path] = ++ dm_info->delta_power_index[path]; ++ ++ rtw88xxa_pwrtrack_set(rtwdev, dm_info->tx_rate, path); ++ } ++ } ++ ++ for (path = RF_PATH_A; path < hal->rf_path_num; path++) { ++ if (remnant_pre[path] != dm_info->txagc_remnant_ofdm[path]) { ++ rtw_phy_set_tx_power_level(rtwdev, ++ hal->current_channel); ++ break; ++ } ++ } ++ ++iqk: ++ if (need_iqk) ++ do_iqk(rtwdev); ++} ++EXPORT_SYMBOL(rtw88xxa_phy_pwrtrack); ++ ++void rtw88xxa_phy_cck_pd_set(struct rtw_dev *rtwdev, u8 new_lvl) ++{ ++ static const u8 pd[CCK_PD_LV_MAX] = {0x40, 0x83, 0xcd, 0xdd, 0xed}; ++ struct rtw_dm_info *dm_info = &rtwdev->dm_info; ++ ++ /* Override rtw_phy_cck_pd_lv_link(). It implements something ++ * like type 2/3/4. We need type 1 here. ++ */ ++ if (rtw_is_assoc(rtwdev)) { ++ if (dm_info->min_rssi > 60) { ++ new_lvl = CCK_PD_LV3; ++ } else if (dm_info->min_rssi > 35) { ++ new_lvl = CCK_PD_LV2; ++ } else if (dm_info->min_rssi > 20) { ++ if (dm_info->cck_fa_avg > 500) ++ new_lvl = CCK_PD_LV2; ++ else if (dm_info->cck_fa_avg < 250) ++ new_lvl = CCK_PD_LV1; ++ else ++ return; ++ } else { ++ new_lvl = CCK_PD_LV1; ++ } ++ } ++ ++ rtw_dbg(rtwdev, RTW_DBG_PHY, "lv: (%d) -> (%d)\n", ++ dm_info->cck_pd_lv[RTW_CHANNEL_WIDTH_20][RF_PATH_A], new_lvl); ++ ++ if (dm_info->cck_pd_lv[RTW_CHANNEL_WIDTH_20][RF_PATH_A] == new_lvl) ++ return; ++ ++ dm_info->cck_fa_avg = CCK_FA_AVG_RESET; ++ dm_info->cck_pd_lv[RTW_CHANNEL_WIDTH_20][RF_PATH_A] = new_lvl; ++ ++ rtw_write8(rtwdev, REG_CCK_PD_TH, pd[new_lvl]); ++} ++EXPORT_SYMBOL(rtw88xxa_phy_cck_pd_set); ++ ++MODULE_AUTHOR("Realtek Corporation"); ++MODULE_DESCRIPTION("Realtek 802.11ac wireless 8821a/8811a/8812a common code"); ++MODULE_LICENSE("Dual BSD/GPL"); +--- /dev/null ++++ b/drivers/net/wireless/realtek/rtw88/rtw88xxa.h +@@ -0,0 +1,175 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2024 Realtek Corporation ++ */ ++ ++#ifndef __RTW88XXA_H__ ++#define __RTW88XXA_H__ ++ ++#include ++#include "reg.h" ++ ++struct rtw8821au_efuse { ++ u8 res4[48]; /* 0xd0 */ ++ u8 vid[2]; /* 0x100 */ ++ u8 pid[2]; ++ u8 res8[3]; ++ u8 mac_addr[ETH_ALEN]; /* 0x107 */ ++ u8 res9[243]; ++} __packed; ++ ++struct rtw8812au_efuse { ++ u8 vid[2]; /* 0xd0 */ ++ u8 pid[2]; /* 0xd2 */ ++ u8 res0[3]; ++ u8 mac_addr[ETH_ALEN]; /* 0xd7 */ ++ u8 res1[291]; ++} __packed; ++ ++struct rtw88xxa_efuse { ++ __le16 rtl_id; ++ u8 res0[6]; /* 0x02 */ ++ u8 usb_mode; /* 0x08 */ ++ u8 res1[7]; /* 0x09 */ ++ ++ /* power index for four RF paths */ ++ struct rtw_txpwr_idx txpwr_idx_table[4]; ++ ++ u8 channel_plan; /* 0xb8 */ ++ u8 xtal_k; ++ u8 thermal_meter; ++ u8 iqk_lck; ++ u8 pa_type; /* 0xbc */ ++ u8 lna_type_2g; /* 0xbd */ ++ u8 res2; ++ u8 lna_type_5g; /* 0xbf */ ++ u8 res3; ++ u8 rf_board_option; /* 0xc1 */ ++ u8 rf_feature_option; ++ u8 rf_bt_setting; ++ u8 eeprom_version; ++ u8 eeprom_customer_id; /* 0xc5 */ ++ u8 tx_bb_swing_setting_2g; ++ u8 tx_bb_swing_setting_5g; ++ u8 tx_pwr_calibrate_rate; ++ u8 rf_antenna_option; /* 0xc9 */ ++ u8 rfe_option; ++ u8 country_code[2]; ++ u8 res4[3]; ++ union { ++ struct rtw8821au_efuse rtw8821au; ++ struct rtw8812au_efuse rtw8812au; ++ }; ++} __packed; ++ ++static_assert(sizeof(struct rtw88xxa_efuse) == 512); ++ ++#define WLAN_BCN_DMA_TIME 0x02 ++#define WLAN_TBTT_PROHIBIT 0x04 ++#define WLAN_TBTT_HOLD_TIME 0x064 ++#define WLAN_TBTT_TIME (WLAN_TBTT_PROHIBIT |\ ++ (WLAN_TBTT_HOLD_TIME << BIT_SHIFT_TBTT_HOLD_TIME_AP)) ++ ++struct rtw_jaguar_phy_status_rpt { ++ __le32 w0; ++ __le32 w1; ++ __le32 w2; ++ __le32 w3; ++ __le32 w4; ++ __le32 w5; ++ __le32 w6; ++} __packed; ++ ++#define RTW_JGRPHY_W0_GAIN_A GENMASK(6, 0) ++#define RTW_JGRPHY_W0_TRSW_A BIT(7) ++#define RTW_JGRPHY_W0_GAIN_B GENMASK(14, 8) ++#define RTW_JGRPHY_W0_TRSW_B BIT(15) ++#define RTW_JGRPHY_W0_CHL_NUM GENMASK(25, 16) ++#define RTW_JGRPHY_W0_SUB_CHNL GENMASK(29, 26) ++#define RTW_JGRPHY_W0_R_RFMOD GENMASK(31, 30) ++ ++/* CCK: */ ++#define RTW_JGRPHY_W1_SIG_QUAL GENMASK(7, 0) ++#define RTW_JGRPHY_W1_AGC_RPT_VGA_IDX GENMASK(12, 8) ++#define RTW_JGRPHY_W1_AGC_RPT_LNA_IDX GENMASK(15, 13) ++#define RTW_JGRPHY_W1_BB_POWER GENMASK(23, 16) ++/* OFDM: */ ++#define RTW_JGRPHY_W1_PWDB_ALL GENMASK(7, 0) ++#define RTW_JGRPHY_W1_CFO_SHORT_A GENMASK(15, 8) /* s8 */ ++#define RTW_JGRPHY_W1_CFO_SHORT_B GENMASK(23, 16) /* s8 */ ++#define RTW_JGRPHY_W1_BT_RF_CH_MSB GENMASK(31, 30) ++ ++#define RTW_JGRPHY_W2_ANT_DIV_SW_A BIT(0) ++#define RTW_JGRPHY_W2_ANT_DIV_SW_B BIT(1) ++#define RTW_JGRPHY_W2_BT_RF_CH_LSB GENMASK(7, 2) ++#define RTW_JGRPHY_W2_CFO_TAIL_A GENMASK(15, 8) /* s8 */ ++#define RTW_JGRPHY_W2_CFO_TAIL_B GENMASK(23, 16) /* s8 */ ++#define RTW_JGRPHY_W2_PCTS_MSK_RPT_0 GENMASK(31, 24) ++ ++#define RTW_JGRPHY_W3_PCTS_MSK_RPT_1 GENMASK(7, 0) ++/* Stream 1 and 2 RX EVM: */ ++#define RTW_JGRPHY_W3_RXEVM_1 GENMASK(15, 8) /* s8 */ ++#define RTW_JGRPHY_W3_RXEVM_2 GENMASK(23, 16) /* s8 */ ++#define RTW_JGRPHY_W3_RXSNR_A GENMASK(31, 24) /* s8 */ ++ ++#define RTW_JGRPHY_W4_RXSNR_B GENMASK(7, 0) /* s8 */ ++#define RTW_JGRPHY_W4_PCTS_MSK_RPT_2 GENMASK(21, 8) ++#define RTW_JGRPHY_W4_PCTS_RPT_VALID BIT(22) ++#define RTW_JGRPHY_W4_RXEVM_3 GENMASK(31, 24) /* s8 */ ++ ++#define RTW_JGRPHY_W5_RXEVM_4 GENMASK(7, 0) /* s8 */ ++/* 8812a, stream 1 and 2 CSI: */ ++#define RTW_JGRPHY_W5_CSI_CURRENT_1 GENMASK(15, 8) ++#define RTW_JGRPHY_W5_CSI_CURRENT_2 GENMASK(23, 16) ++/* 8814a: */ ++#define RTW_JGRPHY_W5_RXSNR_C GENMASK(15, 8) /* s8 */ ++#define RTW_JGRPHY_W5_RXSNR_D GENMASK(23, 16) /* s8 */ ++#define RTW_JGRPHY_W5_GAIN_C GENMASK(30, 24) ++#define RTW_JGRPHY_W5_TRSW_C BIT(31) ++ ++#define RTW_JGRPHY_W6_GAIN_D GENMASK(6, 0) ++#define RTW_JGRPHY_W6_TRSW_D BIT(7) ++#define RTW_JGRPHY_W6_SIGEVM GENMASK(15, 8) /* s8 */ ++#define RTW_JGRPHY_W6_ANTIDX_ANTC GENMASK(18, 16) ++#define RTW_JGRPHY_W6_ANTIDX_ANTD GENMASK(21, 19) ++#define RTW_JGRPHY_W6_DPDT_CTRL_KEEP BIT(22) ++#define RTW_JGRPHY_W6_GNT_BT_KEEP BIT(23) ++#define RTW_JGRPHY_W6_ANTIDX_ANTA GENMASK(26, 24) ++#define RTW_JGRPHY_W6_ANTIDX_ANTB GENMASK(29, 27) ++#define RTW_JGRPHY_W6_HW_ANTSW_OCCUR GENMASK(31, 30) ++ ++#define RF18_BW_MASK (BIT(11) | BIT(10)) ++ ++void rtw88xxa_efuse_grant(struct rtw_dev *rtwdev, bool on); ++int rtw88xxa_read_efuse(struct rtw_dev *rtwdev, u8 *log_map); ++void rtw88xxa_power_off(struct rtw_dev *rtwdev, ++ const struct rtw_pwr_seq_cmd *const *enter_lps_flow); ++int rtw88xxa_power_on(struct rtw_dev *rtwdev); ++u32 rtw88xxa_phy_read_rf(struct rtw_dev *rtwdev, ++ enum rtw_rf_path rf_path, u32 addr, u32 mask); ++void rtw88xxa_set_channel(struct rtw_dev *rtwdev, u8 channel, u8 bw, ++ u8 primary_chan_idx); ++void rtw88xxa_query_phy_status(struct rtw_dev *rtwdev, u8 *phy_status, ++ struct rtw_rx_pkt_stat *pkt_stat, ++ s8 (*cck_rx_pwr)(u8 lna_idx, u8 vga_idx)); ++void rtw88xxa_set_tx_power_index(struct rtw_dev *rtwdev); ++void rtw88xxa_false_alarm_statistics(struct rtw_dev *rtwdev); ++void rtw88xxa_iqk_backup_mac_bb(struct rtw_dev *rtwdev, ++ u32 *macbb_backup, ++ const u32 *backup_macbb_reg, ++ u32 macbb_num); ++void rtw88xxa_iqk_backup_afe(struct rtw_dev *rtwdev, u32 *afe_backup, ++ const u32 *backup_afe_reg, u32 afe_num); ++void rtw88xxa_iqk_restore_mac_bb(struct rtw_dev *rtwdev, ++ u32 *macbb_backup, ++ const u32 *backup_macbb_reg, ++ u32 macbb_num); ++void rtw88xxa_iqk_configure_mac(struct rtw_dev *rtwdev); ++bool rtw88xxa_iqk_finish(int average, int threshold, ++ int *x_temp, int *y_temp, int *x, int *y, ++ bool break_inner, bool break_outer); ++void rtw88xxa_phy_pwrtrack(struct rtw_dev *rtwdev, ++ void (*do_lck)(struct rtw_dev *rtwdev), ++ void (*do_iqk)(struct rtw_dev *rtwdev)); ++void rtw88xxa_phy_cck_pd_set(struct rtw_dev *rtwdev, u8 new_lvl); ++ ++#endif diff --git a/package/kernel/mac80211/patches/rtl/042-v6.13-wifi-rtw88-Add-rtw8821a.-c-h.patch b/package/kernel/mac80211/patches/rtl/042-v6.13-wifi-rtw88-Add-rtw8821a.-c-h.patch new file mode 100644 index 00000000000000..dca3f7b275aab6 --- /dev/null +++ b/package/kernel/mac80211/patches/rtl/042-v6.13-wifi-rtw88-Add-rtw8821a.-c-h.patch @@ -0,0 +1,1230 @@ +From 32e284a238806d1984ea68cda25f6b09a4053b94 Mon Sep 17 00:00:00 2001 +From: Bitterblue Smith +Date: Wed, 30 Oct 2024 20:28:15 +0200 +Subject: [PATCH] wifi: rtw88: Add rtw8821a.{c,h} + +These contain code specific to RTL8821AU. + +Signed-off-by: Bitterblue Smith +Signed-off-by: Ping-Ke Shih +Link: https://patch.msgid.link/37218648-ada7-4fad-b7bd-d2aee28cefb9@gmail.com +--- + drivers/net/wireless/realtek/rtw88/rtw8821a.c | 1197 +++++++++++++++++ + drivers/net/wireless/realtek/rtw88/rtw8821a.h | 10 + + 2 files changed, 1207 insertions(+) + create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8821a.c + create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8821a.h + +--- /dev/null ++++ b/drivers/net/wireless/realtek/rtw88/rtw8821a.c +@@ -0,0 +1,1197 @@ ++// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause ++/* Copyright(c) 2024 Realtek Corporation ++ */ ++ ++#include "main.h" ++#include "coex.h" ++#include "phy.h" ++#include "reg.h" ++#include "rtw88xxa.h" ++#include "rtw8821a.h" ++#include "rtw8821a_table.h" ++#include "tx.h" ++ ++static void rtw8821a_power_off(struct rtw_dev *rtwdev) ++{ ++ rtw88xxa_power_off(rtwdev, enter_lps_flow_8821a); ++} ++ ++static s8 rtw8821a_cck_rx_pwr(u8 lna_idx, u8 vga_idx) ++{ ++ static const s8 lna_gain_table[] = {15, -1, -17, 0, -30, -38}; ++ s8 rx_pwr_all = 0; ++ s8 lna_gain; ++ ++ switch (lna_idx) { ++ case 5: ++ case 4: ++ case 2: ++ case 1: ++ case 0: ++ lna_gain = lna_gain_table[lna_idx]; ++ rx_pwr_all = lna_gain - 2 * vga_idx; ++ break; ++ default: ++ break; ++ } ++ ++ return rx_pwr_all; ++} ++ ++static void rtw8821a_query_phy_status(struct rtw_dev *rtwdev, u8 *phy_status, ++ struct rtw_rx_pkt_stat *pkt_stat) ++{ ++ rtw88xxa_query_phy_status(rtwdev, phy_status, pkt_stat, ++ rtw8821a_cck_rx_pwr); ++} ++ ++static void rtw8821a_cfg_ldo25(struct rtw_dev *rtwdev, bool enable) ++{ ++} ++ ++#define CAL_NUM_8821A 3 ++#define MACBB_REG_NUM_8821A 8 ++#define AFE_REG_NUM_8821A 4 ++#define RF_REG_NUM_8821A 3 ++ ++static void rtw8821a_iqk_backup_rf(struct rtw_dev *rtwdev, u32 *rfa_backup, ++ const u32 *backup_rf_reg, u32 rf_num) ++{ ++ u32 i; ++ ++ /* [31] = 0 --> Page C */ ++ rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0); ++ ++ /* Save RF Parameters */ ++ for (i = 0; i < rf_num; i++) ++ rfa_backup[i] = rtw_read_rf(rtwdev, RF_PATH_A, ++ backup_rf_reg[i], MASKDWORD); ++} ++ ++static void rtw8821a_iqk_restore_rf(struct rtw_dev *rtwdev, ++ const u32 *backup_rf_reg, ++ u32 *RF_backup, u32 rf_reg_num) ++{ ++ u32 i; ++ ++ /* [31] = 0 --> Page C */ ++ rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0); ++ ++ for (i = 0; i < rf_reg_num; i++) ++ rtw_write_rf(rtwdev, RF_PATH_A, backup_rf_reg[i], ++ RFREG_MASK, RF_backup[i]); ++} ++ ++static void rtw8821a_iqk_restore_afe(struct rtw_dev *rtwdev, u32 *afe_backup, ++ const u32 *backup_afe_reg, u32 afe_num) ++{ ++ u32 i; ++ ++ /* [31] = 0 --> Page C */ ++ rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0); ++ ++ /* Reload AFE Parameters */ ++ for (i = 0; i < afe_num; i++) ++ rtw_write32(rtwdev, backup_afe_reg[i], afe_backup[i]); ++ ++ /* [31] = 1 --> Page C1 */ ++ rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x1); ++ ++ rtw_write32(rtwdev, REG_OFDM0_XA_TX_IQ_IMBALANCE, 0x0); ++ rtw_write32(rtwdev, REG_OFDM0_A_TX_AFE, 0x0); ++ rtw_write32(rtwdev, REG_OFDM0_XB_TX_IQ_IMBALANCE, 0x0); ++ rtw_write32(rtwdev, REG_TSSI_TRK_SW, 0x3c000000); ++ rtw_write32(rtwdev, REG_LSSI_WRITE_A, 0x00000080); ++ rtw_write32(rtwdev, REG_TXAGCIDX, 0x00000000); ++ rtw_write32(rtwdev, REG_IQK_DPD_CFG, 0x20040000); ++ rtw_write32(rtwdev, REG_CFG_PMPD, 0x20000000); ++ rtw_write32(rtwdev, REG_RFECTL_A, 0x0); ++} ++ ++static void rtw8821a_iqk_rx_fill(struct rtw_dev *rtwdev, ++ unsigned int rx_x, unsigned int rx_y) ++{ ++ /* [31] = 0 --> Page C */ ++ rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0); ++ ++ rtw_write32_mask(rtwdev, REG_RX_IQC_AB_A, ++ 0x000003ff, rx_x >> 1); ++ rtw_write32_mask(rtwdev, REG_RX_IQC_AB_A, ++ 0x03ff0000, (rx_y >> 1) & 0x3ff); ++} ++ ++static void rtw8821a_iqk_tx_fill(struct rtw_dev *rtwdev, ++ unsigned int tx_x, unsigned int tx_y) ++{ ++ /* [31] = 1 --> Page C1 */ ++ rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x1); ++ ++ rtw_write32(rtwdev, REG_LSSI_WRITE_A, 0x00000080); ++ rtw_write32(rtwdev, REG_IQK_DPD_CFG, 0x20040000); ++ rtw_write32(rtwdev, REG_CFG_PMPD, 0x20000000); ++ rtw_write32_mask(rtwdev, REG_IQC_Y, 0x000007ff, tx_y); ++ rtw_write32_mask(rtwdev, REG_IQC_X, 0x000007ff, tx_x); ++} ++ ++static void rtw8821a_iqk_tx_vdf_true(struct rtw_dev *rtwdev, u32 cal, ++ bool *tx0iqkok, ++ int tx_x0[CAL_NUM_8821A], ++ int tx_y0[CAL_NUM_8821A]) ++{ ++ u32 cal_retry, delay_count, iqk_ready, tx_fail; ++ int tx_dt[3], vdf_y[3], vdf_x[3]; ++ int k; ++ ++ for (k = 0; k < 3; k++) { ++ switch (k) { ++ case 0: ++ /* TX_Tone_idx[9:0], TxK_Mask[29] TX_Tone = 16 */ ++ rtw_write32(rtwdev, REG_OFDM0_XA_TX_IQ_IMBALANCE, ++ 0x18008c38); ++ /* RX_Tone_idx[9:0], RxK_Mask[29] */ ++ rtw_write32(rtwdev, REG_OFDM0_A_TX_AFE, 0x38008c38); ++ rtw_write32_mask(rtwdev, REG_INTPO_SETA, BIT(31), 0x0); ++ break; ++ case 1: ++ rtw_write32_mask(rtwdev, REG_OFDM0_XA_TX_IQ_IMBALANCE, ++ BIT(28), 0x0); ++ rtw_write32_mask(rtwdev, REG_OFDM0_A_TX_AFE, ++ BIT(28), 0x0); ++ rtw_write32_mask(rtwdev, REG_INTPO_SETA, BIT(31), 0x0); ++ break; ++ case 2: ++ rtw_dbg(rtwdev, RTW_DBG_RFK, ++ "vdf_y[1] = %x vdf_y[0] = %x\n", ++ vdf_y[1] >> 21 & 0x00007ff, ++ vdf_y[0] >> 21 & 0x00007ff); ++ ++ rtw_dbg(rtwdev, RTW_DBG_RFK, ++ "vdf_x[1] = %x vdf_x[0] = %x\n", ++ vdf_x[1] >> 21 & 0x00007ff, ++ vdf_x[0] >> 21 & 0x00007ff); ++ ++ tx_dt[cal] = (vdf_y[1] >> 20) - (vdf_y[0] >> 20); ++ tx_dt[cal] = (16 * tx_dt[cal]) * 10000 / 15708; ++ tx_dt[cal] = (tx_dt[cal] >> 1) + (tx_dt[cal] & BIT(0)); ++ ++ /* TX_Tone_idx[9:0], TxK_Mask[29] TX_Tone = 16 */ ++ rtw_write32(rtwdev, REG_OFDM0_XA_TX_IQ_IMBALANCE, ++ 0x18008c20); ++ /* RX_Tone_idx[9:0], RxK_Mask[29] */ ++ rtw_write32(rtwdev, REG_OFDM0_A_TX_AFE, 0x38008c20); ++ rtw_write32_mask(rtwdev, REG_INTPO_SETA, BIT(31), 0x1); ++ rtw_write32_mask(rtwdev, REG_INTPO_SETA, 0x3fff0000, ++ tx_dt[cal] & 0x00003fff); ++ break; ++ } ++ ++ rtw_write32(rtwdev, REG_RFECTL_A, 0x00100000); ++ ++ for (cal_retry = 0; cal_retry < 10; cal_retry++) { ++ /* one shot */ ++ rtw_write32(rtwdev, REG_IQK_COM64, 0xfa000000); ++ rtw_write32(rtwdev, REG_IQK_COM64, 0xf8000000); ++ ++ mdelay(10); ++ ++ rtw_write32(rtwdev, REG_RFECTL_A, 0x00000000); ++ ++ for (delay_count = 0; delay_count < 20; delay_count++) { ++ iqk_ready = rtw_read32_mask(rtwdev, ++ REG_IQKA_END, ++ BIT(10)); ++ ++ /* Originally: if (~iqk_ready || delay_count > 20) ++ * that looks like a typo so make it more explicit ++ */ ++ iqk_ready = true; ++ ++ if (iqk_ready) ++ break; ++ ++ mdelay(1); ++ } ++ ++ if (delay_count < 20) { ++ /* ============TXIQK Check============== */ ++ tx_fail = rtw_read32_mask(rtwdev, ++ REG_IQKA_END, ++ BIT(12)); ++ ++ /* Originally: if (~tx_fail) { ++ * It looks like a typo, so make it more explicit. ++ */ ++ tx_fail = false; ++ ++ if (!tx_fail) { ++ rtw_write32(rtwdev, REG_RFECTL_A, ++ 0x02000000); ++ vdf_x[k] = rtw_read32_mask(rtwdev, ++ REG_IQKA_END, ++ 0x07ff0000); ++ vdf_x[k] <<= 21; ++ ++ rtw_write32(rtwdev, REG_RFECTL_A, ++ 0x04000000); ++ vdf_y[k] = rtw_read32_mask(rtwdev, ++ REG_IQKA_END, ++ 0x07ff0000); ++ vdf_y[k] <<= 21; ++ ++ *tx0iqkok = true; ++ break; ++ } ++ ++ rtw_write32_mask(rtwdev, REG_IQC_Y, ++ 0x000007ff, 0x0); ++ rtw_write32_mask(rtwdev, REG_IQC_X, ++ 0x000007ff, 0x200); ++ } ++ ++ *tx0iqkok = false; ++ } ++ } ++ ++ if (k == 3) { ++ tx_x0[cal] = vdf_x[k - 1]; ++ tx_y0[cal] = vdf_y[k - 1]; ++ } ++} ++ ++static void rtw8821a_iqk_tx_vdf_false(struct rtw_dev *rtwdev, u32 cal, ++ bool *tx0iqkok, ++ int tx_x0[CAL_NUM_8821A], ++ int tx_y0[CAL_NUM_8821A]) ++{ ++ u32 cal_retry, delay_count, iqk_ready, tx_fail; ++ ++ /* TX_Tone_idx[9:0], TxK_Mask[29] TX_Tone = 16 */ ++ rtw_write32(rtwdev, REG_OFDM0_XA_TX_IQ_IMBALANCE, 0x18008c10); ++ /* RX_Tone_idx[9:0], RxK_Mask[29] */ ++ rtw_write32(rtwdev, REG_OFDM0_A_TX_AFE, 0x38008c10); ++ rtw_write32(rtwdev, REG_RFECTL_A, 0x00100000); ++ ++ for (cal_retry = 0; cal_retry < 10; cal_retry++) { ++ /* one shot */ ++ rtw_write32(rtwdev, REG_IQK_COM64, 0xfa000000); ++ rtw_write32(rtwdev, REG_IQK_COM64, 0xf8000000); ++ ++ mdelay(10); ++ rtw_write32(rtwdev, REG_RFECTL_A, 0x00000000); ++ ++ for (delay_count = 0; delay_count < 20; delay_count++) { ++ iqk_ready = rtw_read32_mask(rtwdev, REG_IQKA_END, BIT(10)); ++ ++ /* Originally: if (~iqk_ready || delay_count > 20) ++ * that looks like a typo so make it more explicit ++ */ ++ iqk_ready = true; ++ ++ if (iqk_ready) ++ break; ++ ++ mdelay(1); ++ } ++ ++ if (delay_count < 20) { ++ /* ============TXIQK Check============== */ ++ tx_fail = rtw_read32_mask(rtwdev, REG_IQKA_END, BIT(12)); ++ ++ /* Originally: if (~tx_fail) { ++ * It looks like a typo, so make it more explicit. ++ */ ++ tx_fail = false; ++ ++ if (!tx_fail) { ++ rtw_write32(rtwdev, REG_RFECTL_A, 0x02000000); ++ tx_x0[cal] = rtw_read32_mask(rtwdev, REG_IQKA_END, ++ 0x07ff0000); ++ tx_x0[cal] <<= 21; ++ ++ rtw_write32(rtwdev, REG_RFECTL_A, 0x04000000); ++ tx_y0[cal] = rtw_read32_mask(rtwdev, REG_IQKA_END, ++ 0x07ff0000); ++ tx_y0[cal] <<= 21; ++ ++ *tx0iqkok = true; ++ break; ++ } ++ ++ rtw_write32_mask(rtwdev, REG_IQC_Y, 0x000007ff, 0x0); ++ rtw_write32_mask(rtwdev, REG_IQC_X, 0x000007ff, 0x200); ++ } ++ ++ *tx0iqkok = false; ++ } ++} ++ ++static void rtw8821a_iqk_rx(struct rtw_dev *rtwdev, u32 cal, bool *rx0iqkok, ++ int rx_x0[CAL_NUM_8821A], ++ int rx_y0[CAL_NUM_8821A]) ++{ ++ u32 cal_retry, delay_count, iqk_ready, rx_fail; ++ ++ rtw_write32(rtwdev, REG_RFECTL_A, 0x00100000); ++ ++ for (cal_retry = 0; cal_retry < 10; cal_retry++) { ++ /* one shot */ ++ rtw_write32(rtwdev, REG_IQK_COM64, 0xfa000000); ++ rtw_write32(rtwdev, REG_IQK_COM64, 0xf8000000); ++ ++ mdelay(10); ++ ++ rtw_write32(rtwdev, REG_RFECTL_A, 0x00000000); ++ ++ for (delay_count = 0; delay_count < 20; delay_count++) { ++ iqk_ready = rtw_read32_mask(rtwdev, REG_IQKA_END, BIT(10)); ++ ++ /* Originally: if (~iqk_ready || delay_count > 20) ++ * that looks like a typo so make it more explicit ++ */ ++ iqk_ready = true; ++ ++ if (iqk_ready) ++ break; ++ ++ mdelay(1); ++ } ++ ++ if (delay_count < 20) { ++ /* ============RXIQK Check============== */ ++ rx_fail = rtw_read32_mask(rtwdev, REG_IQKA_END, BIT(11)); ++ if (!rx_fail) { ++ rtw_write32(rtwdev, REG_RFECTL_A, 0x06000000); ++ rx_x0[cal] = rtw_read32_mask(rtwdev, REG_IQKA_END, ++ 0x07ff0000); ++ rx_x0[cal] <<= 21; ++ ++ rtw_write32(rtwdev, REG_RFECTL_A, 0x08000000); ++ rx_y0[cal] = rtw_read32_mask(rtwdev, REG_IQKA_END, ++ 0x07ff0000); ++ rx_y0[cal] <<= 21; ++ ++ *rx0iqkok = true; ++ break; ++ } ++ ++ rtw_write32_mask(rtwdev, REG_RX_IQC_AB_A, ++ 0x000003ff, 0x200 >> 1); ++ rtw_write32_mask(rtwdev, REG_RX_IQC_AB_A, ++ 0x03ff0000, 0x0 >> 1); ++ } ++ ++ *rx0iqkok = false; ++ } ++} ++ ++static void rtw8821a_iqk(struct rtw_dev *rtwdev) ++{ ++ int tx_average = 0, rx_average = 0, rx_iqk_loop = 0; ++ const struct rtw_efuse *efuse = &rtwdev->efuse; ++ int tx_x = 0, tx_y = 0, rx_x = 0, rx_y = 0; ++ const struct rtw_hal *hal = &rtwdev->hal; ++ bool tx0iqkok = false, rx0iqkok = false; ++ int rx_x_temp = 0, rx_y_temp = 0; ++ int rx_x0[2][CAL_NUM_8821A]; ++ int rx_y0[2][CAL_NUM_8821A]; ++ int tx_x0[CAL_NUM_8821A]; ++ int tx_y0[CAL_NUM_8821A]; ++ bool rx_finish1 = false; ++ bool rx_finish2 = false; ++ bool vdf_enable; ++ u32 cal; ++ int i; ++ ++ rtw_dbg(rtwdev, RTW_DBG_RFK, ++ "band_width = %d, ext_pa = %d, ext_pa_5g = %d\n", ++ hal->current_band_width, efuse->ext_pa_2g, efuse->ext_pa_5g); ++ ++ vdf_enable = hal->current_band_width == RTW_CHANNEL_WIDTH_80; ++ ++ for (cal = 0; cal < CAL_NUM_8821A; cal++) { ++ /* path-A LOK */ ++ ++ /* [31] = 0 --> Page C */ ++ rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0); ++ ++ /* ========path-A AFE all on======== */ ++ /* Port 0 DAC/ADC on */ ++ rtw_write32(rtwdev, REG_AFE_PWR1_A, 0x77777777); ++ rtw_write32(rtwdev, REG_AFE_PWR2_A, 0x77777777); ++ ++ rtw_write32(rtwdev, REG_RX_WAIT_CCA_TX_CCK_RFON_A, 0x19791979); ++ ++ /* hardware 3-wire off */ ++ rtw_write32_mask(rtwdev, REG_3WIRE_SWA, 0xf, 0x4); ++ ++ /* LOK setting */ ++ ++ /* 1. DAC/ADC sampling rate (160 MHz) */ ++ rtw_write32_mask(rtwdev, REG_CK_MONHA, GENMASK(26, 24), 0x7); ++ ++ /* 2. LoK RF setting (at BW = 20M) */ ++ rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWE, RFREG_MASK, 0x80002); ++ rtw_write_rf(rtwdev, RF_PATH_A, RF_CFGCH, 0x00c00, 0x3); ++ rtw_write_rf(rtwdev, RF_PATH_A, RF_MODE_TABLE_ADDR, RFREG_MASK, ++ 0x20000); ++ rtw_write_rf(rtwdev, RF_PATH_A, RF_MODE_TABLE_DATA0, RFREG_MASK, ++ 0x0003f); ++ rtw_write_rf(rtwdev, RF_PATH_A, RF_MODE_TABLE_DATA1, RFREG_MASK, ++ 0xf3fc3); ++ ++ rtw_write_rf(rtwdev, RF_PATH_A, RF_TXA_PREPAD, RFREG_MASK, ++ 0x931d5); ++ rtw_write_rf(rtwdev, RF_PATH_A, RF_RXBB2, RFREG_MASK, 0x8a001); ++ rtw_write32(rtwdev, REG_DAC_RSTB, 0x00008000); ++ rtw_write32_mask(rtwdev, REG_TXAGCIDX, BIT(0), 0x1); ++ /* TX (X,Y) */ ++ rtw_write32(rtwdev, REG_IQK_COM00, 0x29002000); ++ /* RX (X,Y) */ ++ rtw_write32(rtwdev, REG_IQK_COM32, 0xa9002000); ++ /* [0]:AGC_en, [15]:idac_K_Mask */ ++ rtw_write32(rtwdev, REG_IQK_COM96, 0x00462910); ++ ++ /* [31] = 1 --> Page C1 */ ++ rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x1); ++ ++ if (efuse->ext_pa_5g) ++ rtw_write32(rtwdev, REG_OFDM0_XB_TX_IQ_IMBALANCE, ++ 0x821403f7); ++ else ++ rtw_write32(rtwdev, REG_OFDM0_XB_TX_IQ_IMBALANCE, ++ 0x821403f4); ++ ++ if (hal->current_band_type == RTW_BAND_5G) ++ rtw_write32(rtwdev, REG_TSSI_TRK_SW, 0x68163e96); ++ else ++ rtw_write32(rtwdev, REG_TSSI_TRK_SW, 0x28163e96); ++ ++ /* TX_Tone_idx[9:0], TxK_Mask[29] TX_Tone = 16 */ ++ rtw_write32(rtwdev, REG_OFDM0_XA_TX_IQ_IMBALANCE, 0x18008c10); ++ /* RX_Tone_idx[9:0], RxK_Mask[29] */ ++ rtw_write32(rtwdev, REG_OFDM0_A_TX_AFE, 0x38008c10); ++ rtw_write32(rtwdev, REG_RFECTL_A, 0x00100000); ++ rtw_write32(rtwdev, REG_IQK_COM64, 0xfa000000); ++ rtw_write32(rtwdev, REG_IQK_COM64, 0xf8000000); ++ ++ mdelay(10); ++ rtw_write32(rtwdev, REG_RFECTL_A, 0x00000000); ++ ++ /* [31] = 0 --> Page C */ ++ rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0); ++ rtw_write_rf(rtwdev, RF_PATH_A, RF_TXMOD, 0x7fe00, ++ rtw_read_rf(rtwdev, RF_PATH_A, RF_DTXLOK, 0xffc00)); ++ ++ if (hal->current_band_width == RTW_CHANNEL_WIDTH_40) ++ rtw_write_rf(rtwdev, RF_PATH_A, RF_CFGCH, ++ RF18_BW_MASK, 0x1); ++ else if (hal->current_band_width == RTW_CHANNEL_WIDTH_80) ++ rtw_write_rf(rtwdev, RF_PATH_A, RF_CFGCH, ++ RF18_BW_MASK, 0x0); ++ ++ /* [31] = 1 --> Page C1 */ ++ rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x1); ++ ++ /* 3. TX RF setting */ ++ /* [31] = 0 --> Page C */ ++ rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0); ++ rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWE, RFREG_MASK, 0x80000); ++ rtw_write_rf(rtwdev, RF_PATH_A, RF_MODE_TABLE_ADDR, RFREG_MASK, ++ 0x20000); ++ rtw_write_rf(rtwdev, RF_PATH_A, RF_MODE_TABLE_DATA0, RFREG_MASK, ++ 0x0003f); ++ rtw_write_rf(rtwdev, RF_PATH_A, RF_MODE_TABLE_DATA1, RFREG_MASK, ++ 0xf3fc3); ++ ++ rtw_write_rf(rtwdev, RF_PATH_A, RF_TXA_PREPAD, RFREG_MASK, 0x931d5); ++ rtw_write_rf(rtwdev, RF_PATH_A, RF_RXBB2, RFREG_MASK, 0x8a001); ++ rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWE, RFREG_MASK, 0x00000); ++ rtw_write32(rtwdev, REG_DAC_RSTB, 0x00008000); ++ rtw_write32_mask(rtwdev, REG_TXAGCIDX, BIT(0), 0x1); ++ /* TX (X,Y) */ ++ rtw_write32(rtwdev, REG_IQK_COM00, 0x29002000); ++ /* RX (X,Y) */ ++ rtw_write32(rtwdev, REG_IQK_COM32, 0xa9002000); ++ /* [0]:AGC_en, [15]:idac_K_Mask */ ++ rtw_write32(rtwdev, REG_IQK_COM96, 0x0046a910); ++ ++ /* [31] = 1 --> Page C1 */ ++ rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x1); ++ ++ if (efuse->ext_pa_5g) ++ rtw_write32(rtwdev, REG_OFDM0_XB_TX_IQ_IMBALANCE, ++ 0x821403f7); ++ else ++ rtw_write32(rtwdev, REG_OFDM0_XB_TX_IQ_IMBALANCE, ++ 0x821403e3); ++ ++ if (hal->current_band_type == RTW_BAND_5G) ++ rtw_write32(rtwdev, REG_TSSI_TRK_SW, 0x40163e96); ++ else ++ rtw_write32(rtwdev, REG_TSSI_TRK_SW, 0x00163e96); ++ ++ if (vdf_enable) ++ rtw8821a_iqk_tx_vdf_true(rtwdev, cal, &tx0iqkok, ++ tx_x0, tx_y0); ++ else ++ rtw8821a_iqk_tx_vdf_false(rtwdev, cal, &tx0iqkok, ++ tx_x0, tx_y0); ++ ++ if (!tx0iqkok) ++ break; /* TXK fail, Don't do RXK */ ++ ++ /* ====== RX IQK ====== */ ++ /* [31] = 0 --> Page C */ ++ rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0); ++ /* 1. RX RF setting */ ++ rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWE, RFREG_MASK, 0x80000); ++ rtw_write_rf(rtwdev, RF_PATH_A, RF_MODE_TABLE_ADDR, RFREG_MASK, ++ 0x30000); ++ rtw_write_rf(rtwdev, RF_PATH_A, RF_MODE_TABLE_DATA0, RFREG_MASK, ++ 0x0002f); ++ rtw_write_rf(rtwdev, RF_PATH_A, RF_MODE_TABLE_DATA1, RFREG_MASK, ++ 0xfffbb); ++ rtw_write_rf(rtwdev, RF_PATH_A, RF_RXBB2, RFREG_MASK, 0x88001); ++ rtw_write_rf(rtwdev, RF_PATH_A, RF_TXA_PREPAD, RFREG_MASK, 0x931d8); ++ rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWE, RFREG_MASK, 0x00000); ++ ++ rtw_write32_mask(rtwdev, REG_IQK_COM00, 0x03FF8000, ++ (tx_x0[cal] >> 21) & 0x000007ff); ++ rtw_write32_mask(rtwdev, REG_IQK_COM00, 0x000007FF, ++ (tx_y0[cal] >> 21) & 0x000007ff); ++ rtw_write32_mask(rtwdev, REG_IQK_COM00, BIT(31), 0x1); ++ rtw_write32_mask(rtwdev, REG_IQK_COM00, BIT(31), 0x0); ++ rtw_write32(rtwdev, REG_DAC_RSTB, 0x00008000); ++ rtw_write32(rtwdev, REG_IQK_COM96, 0x0046a911); ++ ++ /* [31] = 1 --> Page C1 */ ++ rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x1); ++ ++ /* TX_Tone_idx[9:0], TxK_Mask[29] TX_Tone = 16 */ ++ rtw_write32(rtwdev, REG_OFDM0_XA_TX_IQ_IMBALANCE, 0x38008c10); ++ /* RX_Tone_idx[9:0], RxK_Mask[29] */ ++ rtw_write32(rtwdev, REG_OFDM0_A_TX_AFE, 0x18008c10); ++ rtw_write32(rtwdev, REG_OFDM0_XB_TX_IQ_IMBALANCE, 0x02140119); ++ ++ if (rtw_hci_type(rtwdev) == RTW_HCI_TYPE_PCIE) ++ rx_iqk_loop = 2; /* for 2% fail; */ ++ else ++ rx_iqk_loop = 1; ++ ++ for (i = 0; i < rx_iqk_loop; i++) { ++ if (rtw_hci_type(rtwdev) == RTW_HCI_TYPE_PCIE && i == 0) ++ rtw_write32(rtwdev, REG_TSSI_TRK_SW, 0x28161100); /* Good */ ++ else ++ rtw_write32(rtwdev, REG_TSSI_TRK_SW, 0x28160d00); ++ ++ rtw8821a_iqk_rx(rtwdev, cal, &rx0iqkok, ++ rx_x0[i], rx_y0[i]); ++ } ++ ++ if (tx0iqkok) ++ tx_average++; ++ if (rx0iqkok) ++ rx_average++; ++ } ++ ++ /* FillIQK Result */ ++ ++ if (tx_average == 0) ++ return; ++ ++ for (i = 0; i < tx_average; i++) ++ rtw_dbg(rtwdev, RTW_DBG_RFK, ++ "tx_x0[%d] = %x ;; tx_y0[%d] = %x\n", ++ i, (tx_x0[i] >> 21) & 0x000007ff, ++ i, (tx_y0[i] >> 21) & 0x000007ff); ++ ++ if (rtw88xxa_iqk_finish(tx_average, 3, tx_x0, tx_y0, ++ &tx_x, &tx_y, true, true)) ++ rtw8821a_iqk_tx_fill(rtwdev, tx_x, tx_y); ++ else ++ rtw8821a_iqk_tx_fill(rtwdev, 0x200, 0x0); ++ ++ if (rx_average == 0) ++ return; ++ ++ for (i = 0; i < rx_average; i++) { ++ rtw_dbg(rtwdev, RTW_DBG_RFK, ++ "rx_x0[0][%d] = %x ;; rx_y0[0][%d] = %x\n", ++ i, (rx_x0[0][i] >> 21) & 0x000007ff, ++ i, (rx_y0[0][i] >> 21) & 0x000007ff); ++ ++ if (rx_iqk_loop == 2) ++ rtw_dbg(rtwdev, RTW_DBG_RFK, ++ "rx_x0[1][%d] = %x ;; rx_y0[1][%d] = %x\n", ++ i, (rx_x0[1][i] >> 21) & 0x000007ff, ++ i, (rx_y0[1][i] >> 21) & 0x000007ff); ++ } ++ ++ rx_finish1 = rtw88xxa_iqk_finish(rx_average, 4, rx_x0[0], rx_y0[0], ++ &rx_x_temp, &rx_y_temp, true, true); ++ ++ if (rx_finish1) { ++ rx_x = rx_x_temp; ++ rx_y = rx_y_temp; ++ } ++ ++ if (rx_iqk_loop == 2) { ++ rx_finish2 = rtw88xxa_iqk_finish(rx_average, 4, ++ rx_x0[1], rx_y0[1], ++ &rx_x, &rx_y, true, true); ++ ++ if (rx_finish1 && rx_finish2) { ++ rx_x = (rx_x + rx_x_temp) / 2; ++ rx_y = (rx_y + rx_y_temp) / 2; ++ } ++ } ++ ++ if (rx_finish1 || rx_finish2) ++ rtw8821a_iqk_rx_fill(rtwdev, rx_x, rx_y); ++ else ++ rtw8821a_iqk_rx_fill(rtwdev, 0x200, 0x0); ++} ++ ++static void rtw8821a_do_iqk(struct rtw_dev *rtwdev) ++{ ++ static const u32 backup_macbb_reg[MACBB_REG_NUM_8821A] = { ++ 0x520, 0x550, 0x808, 0xa04, 0x90c, 0xc00, 0x838, 0x82c ++ }; ++ static const u32 backup_afe_reg[AFE_REG_NUM_8821A] = { ++ 0xc5c, 0xc60, 0xc64, 0xc68 ++ }; ++ static const u32 backup_rf_reg[RF_REG_NUM_8821A] = { ++ 0x65, 0x8f, 0x0 ++ }; ++ u32 macbb_backup[MACBB_REG_NUM_8821A]; ++ u32 afe_backup[AFE_REG_NUM_8821A]; ++ u32 rfa_backup[RF_REG_NUM_8821A]; ++ ++ rtw88xxa_iqk_backup_mac_bb(rtwdev, macbb_backup, ++ backup_macbb_reg, MACBB_REG_NUM_8821A); ++ rtw88xxa_iqk_backup_afe(rtwdev, afe_backup, ++ backup_afe_reg, AFE_REG_NUM_8821A); ++ rtw8821a_iqk_backup_rf(rtwdev, rfa_backup, ++ backup_rf_reg, RF_REG_NUM_8821A); ++ ++ rtw88xxa_iqk_configure_mac(rtwdev); ++ ++ rtw8821a_iqk(rtwdev); ++ ++ rtw8821a_iqk_restore_rf(rtwdev, backup_rf_reg, ++ rfa_backup, RF_REG_NUM_8821A); ++ rtw8821a_iqk_restore_afe(rtwdev, afe_backup, ++ backup_afe_reg, AFE_REG_NUM_8821A); ++ rtw88xxa_iqk_restore_mac_bb(rtwdev, macbb_backup, ++ backup_macbb_reg, MACBB_REG_NUM_8821A); ++} ++ ++static void rtw8821a_phy_calibration(struct rtw_dev *rtwdev) ++{ ++ rtw8821a_do_iqk(rtwdev); ++} ++ ++static void rtw8821a_pwr_track(struct rtw_dev *rtwdev) ++{ ++ struct rtw_dm_info *dm_info = &rtwdev->dm_info; ++ ++ if (!dm_info->pwr_trk_triggered) { ++ rtw_write_rf(rtwdev, RF_PATH_A, RF_T_METER, ++ GENMASK(17, 16), 0x03); ++ dm_info->pwr_trk_triggered = true; ++ return; ++ } ++ ++ rtw88xxa_phy_pwrtrack(rtwdev, NULL, rtw8821a_do_iqk); ++ dm_info->pwr_trk_triggered = false; ++} ++ ++static void rtw8821a_fill_txdesc_checksum(struct rtw_dev *rtwdev, ++ struct rtw_tx_pkt_info *pkt_info, ++ u8 *txdesc) ++{ ++ fill_txdesc_checksum_common(txdesc, 16); ++} ++ ++static void rtw8821a_coex_cfg_init(struct rtw_dev *rtwdev) ++{ ++ u8 val8; ++ ++ /* BT report packet sample rate */ ++ rtw_write8_mask(rtwdev, REG_BT_TDMA_TIME, BIT_MASK_SAMPLE_RATE, 0x5); ++ ++ val8 = BIT_STATIS_BT_EN; ++ if (rtwdev->efuse.share_ant) ++ val8 |= BIT_R_GRANTALL_WLMASK; ++ rtw_write8(rtwdev, REG_BT_COEX_ENH_INTR_CTRL, val8); ++ ++ /* enable BT counter statistics */ ++ rtw_write8(rtwdev, REG_BT_STAT_CTRL, 0x3); ++ ++ /* enable PTA */ ++ rtw_write32_set(rtwdev, REG_GPIO_MUXCFG, BIT_BT_PTA_EN); ++} ++ ++static void rtw8821a_coex_cfg_ant_switch(struct rtw_dev *rtwdev, u8 ctrl_type, ++ u8 pos_type) ++{ ++ bool share_ant = rtwdev->efuse.share_ant; ++ struct rtw_coex *coex = &rtwdev->coex; ++ struct rtw_coex_dm *coex_dm = &coex->dm; ++ u32 phase = coex_dm->cur_ant_pos_type; ++ ++ if (!rtwdev->efuse.btcoex) ++ return; ++ ++ switch (phase) { ++ case COEX_SET_ANT_POWERON: ++ case COEX_SET_ANT_INIT: ++ rtw_write32_clr(rtwdev, REG_LED_CFG, BIT_DPDT_SEL_EN); ++ rtw_write32_set(rtwdev, REG_LED_CFG, BIT_DPDT_WL_SEL); ++ rtw_write8_set(rtwdev, REG_GNT_BT, BIT_PTA_SW_CTL); ++ ++ rtw_write8(rtwdev, REG_RFE_CTRL8, ++ share_ant ? PTA_CTRL_PIN : DPDT_CTRL_PIN); ++ rtw_write32_mask(rtwdev, REG_RFE_CTRL8, 0x30000000, 0x1); ++ break; ++ case COEX_SET_ANT_WONLY: ++ rtw_write32_clr(rtwdev, REG_LED_CFG, BIT_DPDT_SEL_EN); ++ rtw_write32_set(rtwdev, REG_LED_CFG, BIT_DPDT_WL_SEL); ++ rtw_write8_clr(rtwdev, REG_GNT_BT, BIT_PTA_SW_CTL); ++ ++ rtw_write8(rtwdev, REG_RFE_CTRL8, DPDT_CTRL_PIN); ++ rtw_write32_mask(rtwdev, REG_RFE_CTRL8, 0x30000000, 0x1); ++ break; ++ case COEX_SET_ANT_2G: ++ rtw_write32_clr(rtwdev, REG_LED_CFG, BIT_DPDT_SEL_EN); ++ rtw_write32_set(rtwdev, REG_LED_CFG, BIT_DPDT_WL_SEL); ++ rtw_write8_clr(rtwdev, REG_GNT_BT, BIT_PTA_SW_CTL); ++ ++ rtw_write8(rtwdev, REG_RFE_CTRL8, ++ share_ant ? PTA_CTRL_PIN : DPDT_CTRL_PIN); ++ rtw_write32_mask(rtwdev, REG_RFE_CTRL8, 0x30000000, 0x1); ++ break; ++ case COEX_SET_ANT_5G: ++ rtw_write32_clr(rtwdev, REG_LED_CFG, BIT_DPDT_SEL_EN); ++ rtw_write32_set(rtwdev, REG_LED_CFG, BIT_DPDT_WL_SEL); ++ rtw_write8_set(rtwdev, REG_GNT_BT, BIT_PTA_SW_CTL); ++ ++ rtw_write8(rtwdev, REG_RFE_CTRL8, DPDT_CTRL_PIN); ++ rtw_write32_mask(rtwdev, REG_RFE_CTRL8, 0x30000000, ++ share_ant ? 0x2 : 0x1); ++ break; ++ case COEX_SET_ANT_WOFF: ++ rtw_write32_clr(rtwdev, REG_LED_CFG, BIT_DPDT_SEL_EN); ++ rtw_write32_clr(rtwdev, REG_LED_CFG, BIT_DPDT_WL_SEL); ++ rtw_write8_set(rtwdev, REG_GNT_BT, BIT_PTA_SW_CTL); ++ ++ rtw_write8(rtwdev, REG_RFE_CTRL8, DPDT_CTRL_PIN); ++ rtw_write32_mask(rtwdev, REG_RFE_CTRL8, 0x30000000, ++ share_ant ? 0x2 : 0x1); ++ break; ++ default: ++ rtw_warn(rtwdev, "%s: not handling phase %d\n", ++ __func__, phase); ++ break; ++ } ++} ++ ++static void rtw8821a_coex_cfg_gnt_fix(struct rtw_dev *rtwdev) ++{ ++} ++ ++static void rtw8821a_coex_cfg_gnt_debug(struct rtw_dev *rtwdev) ++{ ++} ++ ++static void rtw8821a_coex_cfg_rfe_type(struct rtw_dev *rtwdev) ++{ ++ struct rtw_coex *coex = &rtwdev->coex; ++ struct rtw_coex_rfe *coex_rfe = &coex->rfe; ++ ++ coex_rfe->ant_switch_exist = true; ++} ++ ++static void rtw8821a_coex_cfg_wl_tx_power(struct rtw_dev *rtwdev, u8 wl_pwr) ++{ ++ struct rtw_coex *coex = &rtwdev->coex; ++ struct rtw_coex_dm *coex_dm = &coex->dm; ++ struct rtw_efuse *efuse = &rtwdev->efuse; ++ bool share_ant = efuse->share_ant; ++ ++ if (share_ant) ++ return; ++ ++ if (wl_pwr == coex_dm->cur_wl_pwr_lvl) ++ return; ++ ++ coex_dm->cur_wl_pwr_lvl = wl_pwr; ++} ++ ++static void rtw8821a_coex_cfg_wl_rx_gain(struct rtw_dev *rtwdev, bool low_gain) ++{ ++} ++ ++static const struct rtw_chip_ops rtw8821a_ops = { ++ .power_on = rtw88xxa_power_on, ++ .power_off = rtw8821a_power_off, ++ .phy_set_param = NULL, ++ .read_efuse = rtw88xxa_read_efuse, ++ .query_phy_status = rtw8821a_query_phy_status, ++ .set_channel = rtw88xxa_set_channel, ++ .mac_init = NULL, ++ .read_rf = rtw88xxa_phy_read_rf, ++ .write_rf = rtw_phy_write_rf_reg_sipi, ++ .set_antenna = NULL, ++ .set_tx_power_index = rtw88xxa_set_tx_power_index, ++ .cfg_ldo25 = rtw8821a_cfg_ldo25, ++ .efuse_grant = rtw88xxa_efuse_grant, ++ .false_alarm_statistics = rtw88xxa_false_alarm_statistics, ++ .phy_calibration = rtw8821a_phy_calibration, ++ .cck_pd_set = rtw88xxa_phy_cck_pd_set, ++ .pwr_track = rtw8821a_pwr_track, ++ .config_bfee = NULL, ++ .set_gid_table = NULL, ++ .cfg_csi_rate = NULL, ++ .fill_txdesc_checksum = rtw8821a_fill_txdesc_checksum, ++ .coex_set_init = rtw8821a_coex_cfg_init, ++ .coex_set_ant_switch = rtw8821a_coex_cfg_ant_switch, ++ .coex_set_gnt_fix = rtw8821a_coex_cfg_gnt_fix, ++ .coex_set_gnt_debug = rtw8821a_coex_cfg_gnt_debug, ++ .coex_set_rfe_type = rtw8821a_coex_cfg_rfe_type, ++ .coex_set_wl_tx_power = rtw8821a_coex_cfg_wl_tx_power, ++ .coex_set_wl_rx_gain = rtw8821a_coex_cfg_wl_rx_gain, ++}; ++ ++static const struct rtw_page_table page_table_8821a[] = { ++ /* hq_num, nq_num, lq_num, exq_num, gapq_num */ ++ {0, 0, 0, 0, 0}, /* SDIO */ ++ {0, 0, 0, 0, 0}, /* PCI */ ++ {8, 0, 0, 0, 1}, /* 2 bulk out endpoints */ ++ {8, 0, 8, 0, 1}, /* 3 bulk out endpoints */ ++ {8, 0, 8, 4, 1}, /* 4 bulk out endpoints */ ++}; ++ ++static const struct rtw_rqpn rqpn_table_8821a[] = { ++ {RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL, ++ RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW, ++ RTW_DMA_MAPPING_EXTRA, RTW_DMA_MAPPING_HIGH}, ++ ++ {RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL, ++ RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW, ++ RTW_DMA_MAPPING_EXTRA, RTW_DMA_MAPPING_HIGH}, ++ ++ {RTW_DMA_MAPPING_HIGH, RTW_DMA_MAPPING_HIGH, ++ RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL, ++ RTW_DMA_MAPPING_HIGH, RTW_DMA_MAPPING_HIGH}, ++ ++ {RTW_DMA_MAPPING_HIGH, RTW_DMA_MAPPING_NORMAL, ++ RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW, ++ RTW_DMA_MAPPING_HIGH, RTW_DMA_MAPPING_HIGH}, ++ ++ {RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL, ++ RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW, ++ RTW_DMA_MAPPING_EXTRA, RTW_DMA_MAPPING_HIGH}, ++}; ++ ++static const struct rtw_prioq_addrs prioq_addrs_8821a = { ++ .prio[RTW_DMA_MAPPING_EXTRA] = { ++ .rsvd = REG_RQPN_NPQ + 2, .avail = REG_RQPN_NPQ + 3, ++ }, ++ .prio[RTW_DMA_MAPPING_LOW] = { ++ .rsvd = REG_RQPN + 1, .avail = REG_FIFOPAGE_CTRL_2 + 1, ++ }, ++ .prio[RTW_DMA_MAPPING_NORMAL] = { ++ .rsvd = REG_RQPN_NPQ, .avail = REG_RQPN_NPQ + 1, ++ }, ++ .prio[RTW_DMA_MAPPING_HIGH] = { ++ .rsvd = REG_RQPN, .avail = REG_FIFOPAGE_CTRL_2, ++ }, ++ .wsize = false, ++}; ++ ++static const struct rtw_hw_reg rtw8821a_dig[] = { ++ [0] = { .addr = REG_RXIGI_A, .mask = 0x7f }, ++}; ++ ++static const struct rtw_rfe_def rtw8821a_rfe_defs[] = { ++ [0] = { .phy_pg_tbl = &rtw8821a_bb_pg_tbl, ++ .txpwr_lmt_tbl = &rtw8821a_txpwr_lmt_tbl, ++ .pwr_track_tbl = &rtw8821a_rtw_pwr_track_tbl, }, ++}; ++ ++/* TODO */ ++/* rssi in percentage % (dbm = % - 100) */ ++static const u8 wl_rssi_step_8821a[] = {101, 45, 101, 40}; ++static const u8 bt_rssi_step_8821a[] = {101, 101, 101, 101}; ++ ++/* table_sant_8821a, table_nsant_8821a, tdma_sant_8821a, and tdma_nsant_8821a ++ * are copied from rtw8821c.c because the 8821au driver's tables are not ++ * compatible with the coex code in rtw88. ++ * ++ * tdma case 112 (A2DP) byte 0 had to be modified from 0x61 to 0x51, ++ * otherwise the firmware gets confused after pausing the music: ++ * rtw_8821au 1-2:1.2: [BTCoex], Bt_info[1], len=7, data=[81 00 0a 01 00 00] ++ * - 81 means PAN (personal area network) when it should be 4x (A2DP) ++ * The music is not smooth with the PAN algorithm. ++ */ ++ ++/* Shared-Antenna Coex Table */ ++static const struct coex_table_para table_sant_8821a[] = { ++ {0x55555555, 0x55555555}, /* case-0 */ ++ {0x55555555, 0x55555555}, ++ {0x66555555, 0x66555555}, ++ {0xaaaaaaaa, 0xaaaaaaaa}, ++ {0x5a5a5a5a, 0x5a5a5a5a}, ++ {0xfafafafa, 0xfafafafa}, /* case-5 */ ++ {0x6a5a5555, 0xaaaaaaaa}, ++ {0x6a5a56aa, 0x6a5a56aa}, ++ {0x6a5a5a5a, 0x6a5a5a5a}, ++ {0x66555555, 0x5a5a5a5a}, ++ {0x66555555, 0x6a5a5a5a}, /* case-10 */ ++ {0x66555555, 0xaaaaaaaa}, ++ {0x66555555, 0x6a5a5aaa}, ++ {0x66555555, 0x6aaa6aaa}, ++ {0x66555555, 0x6a5a5aaa}, ++ {0x66555555, 0xaaaaaaaa}, /* case-15 */ ++ {0xffff55ff, 0xfafafafa}, ++ {0xffff55ff, 0x6afa5afa}, ++ {0xaaffffaa, 0xfafafafa}, ++ {0xaa5555aa, 0x5a5a5a5a}, ++ {0xaa5555aa, 0x6a5a5a5a}, /* case-20 */ ++ {0xaa5555aa, 0xaaaaaaaa}, ++ {0xffffffff, 0x55555555}, ++ {0xffffffff, 0x5a5a5a5a}, ++ {0xffffffff, 0x5a5a5a5a}, ++ {0xffffffff, 0x5a5a5aaa}, /* case-25 */ ++ {0x55555555, 0x5a5a5a5a}, ++ {0x55555555, 0xaaaaaaaa}, ++ {0x66555555, 0x6a5a6a5a}, ++ {0x66556655, 0x66556655}, ++ {0x66556aaa, 0x6a5a6aaa}, /* case-30 */ ++ {0xffffffff, 0x5aaa5aaa}, ++ {0x56555555, 0x5a5a5aaa} ++}; ++ ++/* Non-Shared-Antenna Coex Table */ ++static const struct coex_table_para table_nsant_8821a[] = { ++ {0xffffffff, 0xffffffff}, /* case-100 */ ++ {0xffff55ff, 0xfafafafa}, ++ {0x66555555, 0x66555555}, ++ {0xaaaaaaaa, 0xaaaaaaaa}, ++ {0x5a5a5a5a, 0x5a5a5a5a}, ++ {0xffffffff, 0xffffffff}, /* case-105 */ ++ {0x5afa5afa, 0x5afa5afa}, ++ {0x55555555, 0xfafafafa}, ++ {0x66555555, 0xfafafafa}, ++ {0x66555555, 0x5a5a5a5a}, ++ {0x66555555, 0x6a5a5a5a}, /* case-110 */ ++ {0x66555555, 0xaaaaaaaa}, ++ {0xffff55ff, 0xfafafafa}, ++ {0xffff55ff, 0x5afa5afa}, ++ {0xffff55ff, 0xaaaaaaaa}, ++ {0xffff55ff, 0xffff55ff}, /* case-115 */ ++ {0xaaffffaa, 0x5afa5afa}, ++ {0xaaffffaa, 0xaaaaaaaa}, ++ {0xffffffff, 0xfafafafa}, ++ {0xffff55ff, 0xfafafafa}, ++ {0xffffffff, 0xaaaaaaaa}, /* case-120 */ ++ {0xffff55ff, 0x5afa5afa}, ++ {0xffff55ff, 0x5afa5afa}, ++ {0x55ff55ff, 0x55ff55ff} ++}; ++ ++/* Shared-Antenna TDMA */ ++static const struct coex_tdma_para tdma_sant_8821a[] = { ++ { {0x00, 0x00, 0x00, 0x00, 0x00} }, /* case-0 */ ++ { {0x61, 0x45, 0x03, 0x11, 0x11} }, /* case-1 */ ++ { {0x61, 0x3a, 0x03, 0x11, 0x11} }, ++ { {0x61, 0x35, 0x03, 0x11, 0x11} }, ++ { {0x61, 0x20, 0x03, 0x11, 0x11} }, ++ { {0x61, 0x3a, 0x03, 0x11, 0x11} }, /* case-5 */ ++ { {0x61, 0x45, 0x03, 0x11, 0x10} }, ++ { {0x61, 0x35, 0x03, 0x11, 0x10} }, ++ { {0x61, 0x30, 0x03, 0x11, 0x10} }, ++ { {0x61, 0x20, 0x03, 0x11, 0x10} }, ++ { {0x61, 0x10, 0x03, 0x11, 0x10} }, /* case-10 */ ++ { {0x61, 0x08, 0x03, 0x11, 0x15} }, ++ { {0x61, 0x08, 0x03, 0x10, 0x14} }, ++ { {0x51, 0x08, 0x03, 0x10, 0x54} }, ++ { {0x51, 0x08, 0x03, 0x10, 0x55} }, ++ { {0x51, 0x08, 0x07, 0x10, 0x54} }, /* case-15 */ ++ { {0x51, 0x45, 0x03, 0x10, 0x50} }, ++ { {0x51, 0x3a, 0x03, 0x11, 0x50} }, ++ { {0x51, 0x30, 0x03, 0x10, 0x50} }, ++ { {0x51, 0x21, 0x03, 0x10, 0x50} }, ++ { {0x51, 0x10, 0x03, 0x10, 0x50} }, /* case-20 */ ++ { {0x51, 0x4a, 0x03, 0x10, 0x50} }, ++ { {0x51, 0x08, 0x03, 0x30, 0x54} }, ++ { {0x55, 0x08, 0x03, 0x10, 0x54} }, ++ { {0x65, 0x10, 0x03, 0x11, 0x10} }, ++ { {0x51, 0x10, 0x03, 0x10, 0x51} }, /* case-25 */ ++ { {0x51, 0x21, 0x03, 0x10, 0x50} }, ++ { {0x61, 0x08, 0x03, 0x11, 0x11} } ++}; ++ ++/* Non-Shared-Antenna TDMA */ ++static const struct coex_tdma_para tdma_nsant_8821a[] = { ++ { {0x00, 0x00, 0x00, 0x40, 0x00} }, /* case-100 */ ++ { {0x61, 0x45, 0x03, 0x11, 0x11} }, ++ { {0x61, 0x25, 0x03, 0x11, 0x11} }, ++ { {0x61, 0x35, 0x03, 0x11, 0x11} }, ++ { {0x61, 0x20, 0x03, 0x11, 0x11} }, ++ { {0x61, 0x10, 0x03, 0x11, 0x11} }, /* case-105 */ ++ { {0x61, 0x45, 0x03, 0x11, 0x10} }, ++ { {0x61, 0x30, 0x03, 0x11, 0x10} }, ++ { {0x61, 0x30, 0x03, 0x11, 0x10} }, ++ { {0x61, 0x20, 0x03, 0x11, 0x10} }, ++ { {0x61, 0x10, 0x03, 0x11, 0x10} }, /* case-110 */ ++ { {0x61, 0x10, 0x03, 0x11, 0x11} }, ++ { {0x51, 0x08, 0x03, 0x10, 0x14} }, /* a2dp high rssi */ ++ { {0x51, 0x08, 0x03, 0x10, 0x54} }, /* a2dp not high rssi */ ++ { {0x51, 0x08, 0x03, 0x10, 0x55} }, ++ { {0x51, 0x08, 0x07, 0x10, 0x54} }, /* case-115 */ ++ { {0x51, 0x45, 0x03, 0x10, 0x50} }, ++ { {0x51, 0x3a, 0x03, 0x10, 0x50} }, ++ { {0x51, 0x30, 0x03, 0x10, 0x50} }, ++ { {0x51, 0x21, 0x03, 0x10, 0x50} }, ++ { {0x51, 0x21, 0x03, 0x10, 0x50} }, /* case-120 */ ++ { {0x51, 0x10, 0x03, 0x10, 0x50} } ++}; ++ ++/* TODO */ ++static const struct coex_rf_para rf_para_tx_8821a[] = { ++ {0, 0, false, 7}, /* for normal */ ++ {0, 20, false, 7}, /* for WL-CPT */ ++ {8, 17, true, 4}, ++ {7, 18, true, 4}, ++ {6, 19, true, 4}, ++ {5, 20, true, 4} ++}; ++ ++static const struct coex_rf_para rf_para_rx_8821a[] = { ++ {0, 0, false, 7}, /* for normal */ ++ {0, 20, false, 7}, /* for WL-CPT */ ++ {3, 24, true, 5}, ++ {2, 26, true, 5}, ++ {1, 27, true, 5}, ++ {0, 28, true, 5} ++}; ++ ++static_assert(ARRAY_SIZE(rf_para_tx_8821a) == ARRAY_SIZE(rf_para_rx_8821a)); ++ ++static const struct coex_5g_afh_map afh_5g_8821a[] = { {0, 0, 0} }; ++ ++static const struct rtw_reg_domain coex_info_hw_regs_8821a[] = { ++ {0xCB0, MASKDWORD, RTW_REG_DOMAIN_MAC32}, ++ {0xCB4, MASKDWORD, RTW_REG_DOMAIN_MAC32}, ++ {0xCBA, MASKBYTE0, RTW_REG_DOMAIN_MAC8}, ++ {0, 0, RTW_REG_DOMAIN_NL}, ++ {0x430, MASKDWORD, RTW_REG_DOMAIN_MAC32}, ++ {0x434, MASKDWORD, RTW_REG_DOMAIN_MAC32}, ++ {0x42a, MASKLWORD, RTW_REG_DOMAIN_MAC16}, ++ {0x426, MASKBYTE0, RTW_REG_DOMAIN_MAC8}, ++ {0x45e, BIT(3), RTW_REG_DOMAIN_MAC8}, ++ {0x454, MASKLWORD, RTW_REG_DOMAIN_MAC16}, ++ {0, 0, RTW_REG_DOMAIN_NL}, ++ {0x4c, BIT(24) | BIT(23), RTW_REG_DOMAIN_MAC32}, ++ {0x64, BIT(0), RTW_REG_DOMAIN_MAC8}, ++ {0x4c6, BIT(4), RTW_REG_DOMAIN_MAC8}, ++ {0x40, BIT(5), RTW_REG_DOMAIN_MAC8}, ++ {0x1, RFREG_MASK, RTW_REG_DOMAIN_RF_A}, ++ {0, 0, RTW_REG_DOMAIN_NL}, ++ {0x550, MASKDWORD, RTW_REG_DOMAIN_MAC32}, ++ {0x522, MASKBYTE0, RTW_REG_DOMAIN_MAC8}, ++ {0x953, BIT(1), RTW_REG_DOMAIN_MAC8}, ++ {0xc50, MASKBYTE0, RTW_REG_DOMAIN_MAC8}, ++ {0x60A, MASKBYTE0, RTW_REG_DOMAIN_MAC8}, ++}; ++ ++const struct rtw_chip_info rtw8821a_hw_spec = { ++ .ops = &rtw8821a_ops, ++ .id = RTW_CHIP_TYPE_8821A, ++ .fw_name = "rtw88/rtw8821a_fw.bin", ++ .wlan_cpu = RTW_WCPU_11N, ++ .tx_pkt_desc_sz = 40, ++ .tx_buf_desc_sz = 16, ++ .rx_pkt_desc_sz = 24, ++ .rx_buf_desc_sz = 8, ++ .phy_efuse_size = 512, ++ .log_efuse_size = 512, ++ .ptct_efuse_size = 96 + 1, /* TODO or just 18? */ ++ .txff_size = 65536, ++ .rxff_size = 16128, ++ .rsvd_drv_pg_num = 8, ++ .txgi_factor = 1, ++ .is_pwr_by_rate_dec = true, ++ .max_power_index = 0x3f, ++ .csi_buf_pg_num = 0, ++ .band = RTW_BAND_2G | RTW_BAND_5G, ++ .page_size = 256, ++ .dig_min = 0x20, ++ .ht_supported = true, ++ .vht_supported = true, ++ .lps_deep_mode_supported = 0, ++ .sys_func_en = 0xFD, ++ .pwr_on_seq = card_enable_flow_8821a, ++ .pwr_off_seq = card_disable_flow_8821a, ++ .page_table = page_table_8821a, ++ .rqpn_table = rqpn_table_8821a, ++ .prioq_addrs = &prioq_addrs_8821a, ++ .intf_table = NULL, ++ .dig = rtw8821a_dig, ++ .rf_sipi_addr = {REG_LSSI_WRITE_A, REG_LSSI_WRITE_B}, ++ .ltecoex_addr = NULL, ++ .mac_tbl = &rtw8821a_mac_tbl, ++ .agc_tbl = &rtw8821a_agc_tbl, ++ .bb_tbl = &rtw8821a_bb_tbl, ++ .rf_tbl = {&rtw8821a_rf_a_tbl}, ++ .rfe_defs = rtw8821a_rfe_defs, ++ .rfe_defs_size = ARRAY_SIZE(rtw8821a_rfe_defs), ++ .rx_ldpc = false, ++ .hw_feature_report = false, ++ .c2h_ra_report_size = 4, ++ .old_datarate_fb_limit = true, ++ .usb_tx_agg_desc_num = 6, ++ .iqk_threshold = 8, ++ .ampdu_density = IEEE80211_HT_MPDU_DENSITY_16, ++ .max_scan_ie_len = IEEE80211_MAX_DATA_LEN, ++ ++ .coex_para_ver = 20190509, /* glcoex_ver_date_8821a_1ant */ ++ .bt_desired_ver = 0x62, /* But for 2 ant it's 0x5c */ ++ .scbd_support = false, ++ .new_scbd10_def = false, ++ .ble_hid_profile_support = false, ++ .wl_mimo_ps_support = false, ++ .pstdma_type = COEX_PSTDMA_FORCE_LPSOFF, ++ .bt_rssi_type = COEX_BTRSSI_RATIO, ++ .ant_isolation = 10, ++ .rssi_tolerance = 2, ++ .wl_rssi_step = wl_rssi_step_8821a, ++ .bt_rssi_step = bt_rssi_step_8821a, ++ .table_sant_num = ARRAY_SIZE(table_sant_8821a), ++ .table_sant = table_sant_8821a, ++ .table_nsant_num = ARRAY_SIZE(table_nsant_8821a), ++ .table_nsant = table_nsant_8821a, ++ .tdma_sant_num = ARRAY_SIZE(tdma_sant_8821a), ++ .tdma_sant = tdma_sant_8821a, ++ .tdma_nsant_num = ARRAY_SIZE(tdma_nsant_8821a), ++ .tdma_nsant = tdma_nsant_8821a, ++ .wl_rf_para_num = ARRAY_SIZE(rf_para_tx_8821a), ++ .wl_rf_para_tx = rf_para_tx_8821a, ++ .wl_rf_para_rx = rf_para_rx_8821a, ++ .bt_afh_span_bw20 = 0x20, ++ .bt_afh_span_bw40 = 0x30, ++ .afh_5g_num = ARRAY_SIZE(afh_5g_8821a), ++ .afh_5g = afh_5g_8821a, ++ ++ .coex_info_hw_regs_num = ARRAY_SIZE(coex_info_hw_regs_8821a), ++ .coex_info_hw_regs = coex_info_hw_regs_8821a, ++}; ++EXPORT_SYMBOL(rtw8821a_hw_spec); ++ ++MODULE_FIRMWARE("rtw88/rtw8821a_fw.bin"); ++ ++MODULE_AUTHOR("Realtek Corporation"); ++MODULE_DESCRIPTION("Realtek 802.11ac wireless 8821a/8811a driver"); ++MODULE_LICENSE("Dual BSD/GPL"); +--- /dev/null ++++ b/drivers/net/wireless/realtek/rtw88/rtw8821a.h +@@ -0,0 +1,10 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2024 Realtek Corporation ++ */ ++ ++#ifndef __RTW8821A_H__ ++#define __RTW8821A_H__ ++ ++extern const struct rtw_chip_info rtw8821a_hw_spec; ++ ++#endif diff --git a/package/kernel/mac80211/patches/rtl/043-v6.13-wifi-rtw88-Add-rtw8812a.-c-h.patch b/package/kernel/mac80211/patches/rtl/043-v6.13-wifi-rtw88-Add-rtw8812a.-c-h.patch new file mode 100644 index 00000000000000..610dca037a2367 --- /dev/null +++ b/package/kernel/mac80211/patches/rtl/043-v6.13-wifi-rtw88-Add-rtw8812a.-c-h.patch @@ -0,0 +1,1135 @@ +From 4f8ec8927bc292b2a71cd5a253c96ce3c6b2927f Mon Sep 17 00:00:00 2001 +From: Bitterblue Smith +Date: Wed, 30 Oct 2024 20:28:49 +0200 +Subject: [PATCH] wifi: rtw88: Add rtw8812a.{c,h} + +These contain code specific to RTL8812AU. + +Signed-off-by: Bitterblue Smith +Signed-off-by: Ping-Ke Shih +Link: https://patch.msgid.link/a0057683-79eb-4ab2-8f74-11a3bc58adfb@gmail.com +--- + drivers/net/wireless/realtek/rtw88/rtw8812a.c | 1102 +++++++++++++++++ + drivers/net/wireless/realtek/rtw88/rtw8812a.h | 10 + + 2 files changed, 1112 insertions(+) + create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8812a.c + create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8812a.h + +--- /dev/null ++++ b/drivers/net/wireless/realtek/rtw88/rtw8812a.c +@@ -0,0 +1,1102 @@ ++// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause ++/* Copyright(c) 2024 Realtek Corporation ++ */ ++ ++#include "main.h" ++#include "coex.h" ++#include "phy.h" ++#include "reg.h" ++#include "rtw88xxa.h" ++#include "rtw8812a.h" ++#include "rtw8812a_table.h" ++#include "tx.h" ++ ++static void rtw8812a_power_off(struct rtw_dev *rtwdev) ++{ ++ rtw88xxa_power_off(rtwdev, enter_lps_flow_8812a); ++} ++ ++static s8 rtw8812a_cck_rx_pwr(u8 lna_idx, u8 vga_idx) ++{ ++ s8 rx_pwr_all = 0; ++ ++ switch (lna_idx) { ++ case 7: ++ if (vga_idx <= 27) ++ rx_pwr_all = -94 + 2 * (27 - vga_idx); ++ else ++ rx_pwr_all = -94; ++ break; ++ case 6: ++ rx_pwr_all = -42 + 2 * (2 - vga_idx); ++ break; ++ case 5: ++ rx_pwr_all = -36 + 2 * (7 - vga_idx); ++ break; ++ case 4: ++ rx_pwr_all = -30 + 2 * (7 - vga_idx); ++ break; ++ case 3: ++ rx_pwr_all = -18 + 2 * (7 - vga_idx); ++ break; ++ case 2: ++ rx_pwr_all = 2 * (5 - vga_idx); ++ break; ++ case 1: ++ rx_pwr_all = 14 - 2 * vga_idx; ++ break; ++ case 0: ++ rx_pwr_all = 20 - 2 * vga_idx; ++ break; ++ default: ++ break; ++ } ++ ++ return rx_pwr_all; ++} ++ ++static void rtw8812a_query_phy_status(struct rtw_dev *rtwdev, u8 *phy_status, ++ struct rtw_rx_pkt_stat *pkt_stat) ++{ ++ rtw88xxa_query_phy_status(rtwdev, phy_status, pkt_stat, ++ rtw8812a_cck_rx_pwr); ++ ++ if (pkt_stat->rate >= DESC_RATE6M) ++ return; ++ ++ if (rtwdev->hal.cck_high_power) ++ return; ++ ++ if (pkt_stat->rssi >= 80) ++ pkt_stat->rssi = ((pkt_stat->rssi - 80) << 1) + ++ ((pkt_stat->rssi - 80) >> 1) + 80; ++ else if (pkt_stat->rssi <= 78 && pkt_stat->rssi >= 20) ++ pkt_stat->rssi += 3; ++} ++ ++static void rtw8812a_cfg_ldo25(struct rtw_dev *rtwdev, bool enable) ++{ ++} ++ ++static void rtw8812a_do_lck(struct rtw_dev *rtwdev) ++{ ++ u32 cont_tx, lc_cal, i; ++ ++ cont_tx = rtw_read32_mask(rtwdev, REG_SINGLE_TONE_CONT_TX, 0x70000); ++ ++ lc_cal = rtw_read_rf(rtwdev, RF_PATH_A, RF_CFGCH, RFREG_MASK); ++ ++ if (!cont_tx) ++ rtw_write8(rtwdev, REG_TXPAUSE, 0xff); ++ ++ rtw_write_rf(rtwdev, RF_PATH_A, RF_LCK, BIT(14), 1); ++ ++ rtw_write_rf(rtwdev, RF_PATH_A, RF_CFGCH, 0x08000, 1); ++ ++ mdelay(150); ++ ++ for (i = 0; i < 5; i++) { ++ if (rtw_read_rf(rtwdev, RF_PATH_A, RF_CFGCH, 0x08000) != 1) ++ break; ++ ++ mdelay(10); ++ } ++ ++ if (i == 5) ++ rtw_dbg(rtwdev, RTW_DBG_RFK, "LCK timed out\n"); ++ ++ rtw_write_rf(rtwdev, RF_PATH_A, RF_CFGCH, RFREG_MASK, lc_cal); ++ ++ rtw_write_rf(rtwdev, RF_PATH_A, RF_LCK, BIT(14), 0); ++ ++ if (!cont_tx) ++ rtw_write8(rtwdev, REG_TXPAUSE, 0); ++ ++ rtw_write_rf(rtwdev, RF_PATH_A, RF_CFGCH, RFREG_MASK, lc_cal); ++} ++ ++static void rtw8812a_iqk_backup_rf(struct rtw_dev *rtwdev, u32 *rfa_backup, ++ u32 *rfb_backup, const u32 *backup_rf_reg, ++ u32 rf_num) ++{ ++ u32 i; ++ ++ /* [31] = 0 --> Page C */ ++ rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0); ++ ++ /* Save RF Parameters */ ++ for (i = 0; i < rf_num; i++) { ++ rfa_backup[i] = rtw_read_rf(rtwdev, RF_PATH_A, ++ backup_rf_reg[i], MASKDWORD); ++ rfb_backup[i] = rtw_read_rf(rtwdev, RF_PATH_B, ++ backup_rf_reg[i], MASKDWORD); ++ } ++} ++ ++static void rtw8812a_iqk_restore_rf(struct rtw_dev *rtwdev, ++ enum rtw_rf_path path, ++ const u32 *backup_rf_reg, ++ u32 *RF_backup, u32 rf_reg_num) ++{ ++ u32 i; ++ ++ /* [31] = 0 --> Page C */ ++ rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0); ++ ++ for (i = 0; i < rf_reg_num; i++) ++ rtw_write_rf(rtwdev, path, backup_rf_reg[i], ++ RFREG_MASK, RF_backup[i]); ++ ++ rtw_write_rf(rtwdev, path, RF_LUTWE, RFREG_MASK, 0); ++} ++ ++static void rtw8812a_iqk_restore_afe(struct rtw_dev *rtwdev, u32 *afe_backup, ++ const u32 *backup_afe_reg, u32 afe_num) ++{ ++ u32 i; ++ ++ /* [31] = 0 --> Page C */ ++ rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0); ++ ++ /* Reload AFE Parameters */ ++ for (i = 0; i < afe_num; i++) ++ rtw_write32(rtwdev, backup_afe_reg[i], afe_backup[i]); ++ ++ /* [31] = 1 --> Page C1 */ ++ rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x1); ++ ++ rtw_write32(rtwdev, REG_OFDM0_XA_TX_IQ_IMBALANCE, 0x0); ++ rtw_write32(rtwdev, REG_OFDM0_A_TX_AFE, 0x0); ++ rtw_write32(rtwdev, REG_OFDM0_XB_TX_IQ_IMBALANCE, 0x0); ++ rtw_write32(rtwdev, REG_TSSI_TRK_SW, 0x3c000000); ++ rtw_write32_mask(rtwdev, REG_LSSI_WRITE_A, BIT(7), 1); ++ rtw_write32_mask(rtwdev, REG_IQK_DPD_CFG, BIT(18), 1); ++ rtw_write32_mask(rtwdev, REG_IQK_DPD_CFG, BIT(29), 1); ++ rtw_write32_mask(rtwdev, REG_CFG_PMPD, BIT(29), 1); ++ ++ rtw_write32(rtwdev, REG_TXTONEB, 0x0); ++ rtw_write32(rtwdev, REG_RXTONEB, 0x0); ++ rtw_write32(rtwdev, REG_TXPITMB, 0x0); ++ rtw_write32(rtwdev, REG_RXPITMB, 0x3c000000); ++ rtw_write32_mask(rtwdev, REG_LSSI_WRITE_B, BIT(7), 1); ++ rtw_write32_mask(rtwdev, REG_BPBDB, BIT(18), 1); ++ rtw_write32_mask(rtwdev, REG_BPBDB, BIT(29), 1); ++ rtw_write32_mask(rtwdev, REG_PHYTXONB, BIT(29), 1); ++} ++ ++static void rtw8812a_iqk_rx_fill(struct rtw_dev *rtwdev, enum rtw_rf_path path, ++ unsigned int rx_x, unsigned int rx_y) ++{ ++ switch (path) { ++ case RF_PATH_A: ++ /* [31] = 0 --> Page C */ ++ rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0); ++ if (rx_x >> 1 >= 0x112 || ++ (rx_y >> 1 >= 0x12 && rx_y >> 1 <= 0x3ee)) { ++ rtw_write32_mask(rtwdev, REG_RX_IQC_AB_A, ++ 0x000003ff, 0x100); ++ rtw_write32_mask(rtwdev, REG_RX_IQC_AB_A, ++ 0x03ff0000, 0); ++ } else { ++ rtw_write32_mask(rtwdev, REG_RX_IQC_AB_A, ++ 0x000003ff, rx_x >> 1); ++ rtw_write32_mask(rtwdev, REG_RX_IQC_AB_A, ++ 0x03ff0000, rx_y >> 1); ++ } ++ rtw_dbg(rtwdev, RTW_DBG_RFK, ++ "rx_x = %x;;rx_y = %x ====>fill to IQC\n", ++ rx_x >> 1 & 0x000003ff, rx_y >> 1 & 0x000003ff); ++ rtw_dbg(rtwdev, RTW_DBG_RFK, "0xc10 = %x ====>fill to IQC\n", ++ rtw_read32(rtwdev, REG_RX_IQC_AB_A)); ++ break; ++ case RF_PATH_B: ++ /* [31] = 0 --> Page C */ ++ rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0); ++ if (rx_x >> 1 >= 0x112 || ++ (rx_y >> 1 >= 0x12 && rx_y >> 1 <= 0x3ee)) { ++ rtw_write32_mask(rtwdev, REG_RX_IQC_AB_B, ++ 0x000003ff, 0x100); ++ rtw_write32_mask(rtwdev, REG_RX_IQC_AB_B, ++ 0x03ff0000, 0); ++ } else { ++ rtw_write32_mask(rtwdev, REG_RX_IQC_AB_B, ++ 0x000003ff, rx_x >> 1); ++ rtw_write32_mask(rtwdev, REG_RX_IQC_AB_B, ++ 0x03ff0000, rx_y >> 1); ++ } ++ rtw_dbg(rtwdev, RTW_DBG_RFK, ++ "rx_x = %x;;rx_y = %x ====>fill to IQC\n", ++ rx_x >> 1 & 0x000003ff, rx_y >> 1 & 0x000003ff); ++ rtw_dbg(rtwdev, RTW_DBG_RFK, "0xe10 = %x====>fill to IQC\n", ++ rtw_read32(rtwdev, REG_RX_IQC_AB_B)); ++ break; ++ default: ++ break; ++ } ++} ++ ++static void rtw8812a_iqk_tx_fill(struct rtw_dev *rtwdev, enum rtw_rf_path path, ++ unsigned int tx_x, unsigned int tx_y) ++{ ++ switch (path) { ++ case RF_PATH_A: ++ /* [31] = 1 --> Page C1 */ ++ rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x1); ++ rtw_write32_mask(rtwdev, REG_PREDISTA, BIT(7), 0x1); ++ rtw_write32_mask(rtwdev, REG_IQK_DPD_CFG, BIT(18), 0x1); ++ rtw_write32_mask(rtwdev, REG_IQK_DPD_CFG, BIT(29), 0x1); ++ rtw_write32_mask(rtwdev, REG_CFG_PMPD, BIT(29), 0x1); ++ rtw_write32_mask(rtwdev, REG_IQC_Y, 0x000007ff, tx_y); ++ rtw_write32_mask(rtwdev, REG_IQC_X, 0x000007ff, tx_x); ++ rtw_dbg(rtwdev, RTW_DBG_RFK, ++ "tx_x = %x;;tx_y = %x =====> fill to IQC\n", ++ tx_x & 0x000007ff, tx_y & 0x000007ff); ++ rtw_dbg(rtwdev, RTW_DBG_RFK, ++ "0xcd4 = %x;;0xccc = %x ====>fill to IQC\n", ++ rtw_read32_mask(rtwdev, REG_IQC_X, 0x000007ff), ++ rtw_read32_mask(rtwdev, REG_IQC_Y, 0x000007ff)); ++ break; ++ case RF_PATH_B: ++ /* [31] = 1 --> Page C1 */ ++ rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x1); ++ rtw_write32_mask(rtwdev, REG_PREDISTB, BIT(7), 0x1); ++ rtw_write32_mask(rtwdev, REG_BPBDB, BIT(18), 0x1); ++ rtw_write32_mask(rtwdev, REG_BPBDB, BIT(29), 0x1); ++ rtw_write32_mask(rtwdev, REG_PHYTXONB, BIT(29), 0x1); ++ rtw_write32_mask(rtwdev, REG_IQKYB, 0x000007ff, tx_y); ++ rtw_write32_mask(rtwdev, REG_IQKXB, 0x000007ff, tx_x); ++ rtw_dbg(rtwdev, RTW_DBG_RFK, ++ "tx_x = %x;;tx_y = %x =====> fill to IQC\n", ++ tx_x & 0x000007ff, tx_y & 0x000007ff); ++ rtw_dbg(rtwdev, RTW_DBG_RFK, ++ "0xed4 = %x;;0xecc = %x ====>fill to IQC\n", ++ rtw_read32_mask(rtwdev, REG_IQKXB, 0x000007ff), ++ rtw_read32_mask(rtwdev, REG_IQKYB, 0x000007ff)); ++ break; ++ default: ++ break; ++ } ++} ++ ++static void rtw8812a_iqk(struct rtw_dev *rtwdev) ++{ ++ int tx_x0_temp[10], tx_y0_temp[10], tx_x1_temp[10], tx_y1_temp[10]; ++ int rx_x0_temp[10], rx_y0_temp[10], rx_x1_temp[10], rx_y1_temp[10]; ++ bool iqk0_ready = false, tx0_finish = false, rx0_finish = false; ++ bool iqk1_ready = false, tx1_finish = false, rx1_finish = false; ++ u8 tx0_avg = 0, tx1_avg = 0, rx0_avg = 0, rx1_avg = 0; ++ int tx_x0 = 0, tx_y0 = 0, tx_x1 = 0, tx_y1 = 0; ++ int rx_x0 = 0, rx_y0 = 0, rx_x1 = 0, rx_y1 = 0; ++ struct rtw_efuse *efuse = &rtwdev->efuse; ++ bool tx0_fail = true, rx0_fail = true; ++ bool tx1_fail = true, rx1_fail = true; ++ u8 cal0_retry, cal1_retry; ++ u8 delay_count; ++ ++ /* [31] = 0 --> Page C */ ++ rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0); ++ ++ /* ========path-A AFE all on======== */ ++ /* Port 0 DAC/ADC on */ ++ rtw_write32(rtwdev, REG_AFE_PWR1_A, 0x77777777); ++ rtw_write32(rtwdev, REG_AFE_PWR2_A, 0x77777777); ++ ++ /* Port 1 DAC/ADC on */ ++ rtw_write32(rtwdev, REG_AFE_PWR1_B, 0x77777777); ++ rtw_write32(rtwdev, REG_AFE_PWR2_B, 0x77777777); ++ ++ rtw_write32(rtwdev, REG_RX_WAIT_CCA_TX_CCK_RFON_A, 0x19791979); ++ rtw_write32(rtwdev, REG_RX_WAIT_CCA_TX_CCK_RFON_B, 0x19791979); ++ ++ /* hardware 3-wire off */ ++ rtw_write32_mask(rtwdev, REG_3WIRE_SWA, 0xf, 0x4); ++ rtw_write32_mask(rtwdev, REG_3WIRE_SWB, 0xf, 0x4); ++ ++ /* DAC/ADC sampling rate (160 MHz) */ ++ rtw_write32_mask(rtwdev, REG_CK_MONHA, GENMASK(26, 24), 0x7); ++ rtw_write32_mask(rtwdev, REG_CK_MONHB, GENMASK(26, 24), 0x7); ++ ++ /* [31] = 0 --> Page C */ ++ rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0); ++ /* ====== path A TX IQK RF setting ====== */ ++ rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWE, RFREG_MASK, 0x80002); ++ rtw_write_rf(rtwdev, RF_PATH_A, RF_MODE_TABLE_ADDR, RFREG_MASK, 0x20000); ++ rtw_write_rf(rtwdev, RF_PATH_A, RF_MODE_TABLE_DATA0, RFREG_MASK, 0x3fffd); ++ rtw_write_rf(rtwdev, RF_PATH_A, RF_MODE_TABLE_DATA1, RFREG_MASK, 0xfe83f); ++ rtw_write_rf(rtwdev, RF_PATH_A, RF_TXA_PREPAD, RFREG_MASK, 0x931d5); ++ rtw_write_rf(rtwdev, RF_PATH_A, RF_RXBB2, RFREG_MASK, 0x8a001); ++ ++ /* ====== path B TX IQK RF setting ====== */ ++ rtw_write_rf(rtwdev, RF_PATH_B, RF_LUTWE, RFREG_MASK, 0x80002); ++ rtw_write_rf(rtwdev, RF_PATH_B, RF_MODE_TABLE_ADDR, RFREG_MASK, 0x20000); ++ rtw_write_rf(rtwdev, RF_PATH_B, RF_MODE_TABLE_DATA0, RFREG_MASK, 0x3fffd); ++ rtw_write_rf(rtwdev, RF_PATH_B, RF_MODE_TABLE_DATA1, RFREG_MASK, 0xfe83f); ++ rtw_write_rf(rtwdev, RF_PATH_B, RF_TXA_PREPAD, RFREG_MASK, 0x931d5); ++ rtw_write_rf(rtwdev, RF_PATH_B, RF_RXBB2, RFREG_MASK, 0x8a001); ++ ++ rtw_write32(rtwdev, REG_DAC_RSTB, 0x00008000); ++ rtw_write32_mask(rtwdev, REG_TXAGCIDX, BIT(0), 0x1); ++ rtw_write32_mask(rtwdev, REG_INIDLYB, BIT(0), 0x1); ++ rtw_write32(rtwdev, REG_IQK_COM00, 0x29002000); /* TX (X,Y) */ ++ rtw_write32(rtwdev, REG_IQK_COM32, 0xa9002000); /* RX (X,Y) */ ++ rtw_write32(rtwdev, REG_IQK_COM96, 0x00462910); /* [0]:AGC_en, [15]:idac_K_Mask */ ++ /* [31] = 1 --> Page C1 */ ++ rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x1); ++ ++ if (efuse->ext_pa_5g) { ++ if (efuse->rfe_option == 1) { ++ rtw_write32(rtwdev, REG_OFDM0_XB_TX_IQ_IMBALANCE, 0x821403e3); ++ rtw_write32(rtwdev, REG_TXPITMB, 0x821403e3); ++ } else { ++ rtw_write32(rtwdev, REG_OFDM0_XB_TX_IQ_IMBALANCE, 0x821403f7); ++ rtw_write32(rtwdev, REG_TXPITMB, 0x821403f7); ++ } ++ } else { ++ rtw_write32(rtwdev, REG_OFDM0_XB_TX_IQ_IMBALANCE, 0x821403f1); ++ rtw_write32(rtwdev, REG_TXPITMB, 0x821403f1); ++ } ++ ++ if (rtwdev->hal.current_band_type == RTW_BAND_5G) { ++ rtw_write32(rtwdev, REG_TSSI_TRK_SW, 0x68163e96); ++ rtw_write32(rtwdev, REG_RXPITMB, 0x68163e96); ++ } else { ++ rtw_write32(rtwdev, REG_TSSI_TRK_SW, 0x28163e96); ++ rtw_write32(rtwdev, REG_RXPITMB, 0x28163e96); ++ ++ if (efuse->rfe_option == 3) { ++ if (efuse->ext_pa_2g) ++ rtw_write32(rtwdev, REG_OFDM0_XB_TX_IQ_IMBALANCE, ++ 0x821403e3); ++ else ++ rtw_write32(rtwdev, REG_OFDM0_XB_TX_IQ_IMBALANCE, ++ 0x821403f7); ++ } ++ } ++ ++ /* TX_Tone_idx[9:0], TxK_Mask[29] TX_Tone = 16 */ ++ rtw_write32(rtwdev, REG_OFDM0_XA_TX_IQ_IMBALANCE, 0x18008c10); ++ /* RX_Tone_idx[9:0], RxK_Mask[29] */ ++ rtw_write32(rtwdev, REG_OFDM0_A_TX_AFE, 0x38008c10); ++ rtw_write32(rtwdev, REG_INTPO_SETA, 0x00000000); ++ /* TX_Tone_idx[9:0], TxK_Mask[29] TX_Tone = 16 */ ++ rtw_write32(rtwdev, REG_TXTONEB, 0x18008c10); ++ /* RX_Tone_idx[9:0], RxK_Mask[29] */ ++ rtw_write32(rtwdev, REG_RXTONEB, 0x38008c10); ++ rtw_write32(rtwdev, REG_INTPO_SETB, 0x00000000); ++ ++ cal0_retry = 0; ++ cal1_retry = 0; ++ while (1) { ++ /* one shot */ ++ rtw_write32(rtwdev, REG_RFECTL_A, 0x00100000); ++ rtw_write32(rtwdev, REG_RFECTL_B, 0x00100000); ++ rtw_write32(rtwdev, REG_IQK_COM64, 0xfa000000); ++ rtw_write32(rtwdev, REG_IQK_COM64, 0xf8000000); ++ ++ mdelay(10); ++ ++ rtw_write32(rtwdev, REG_RFECTL_A, 0x00000000); ++ rtw_write32(rtwdev, REG_RFECTL_B, 0x00000000); ++ ++ for (delay_count = 0; delay_count < 20; delay_count++) { ++ if (!tx0_finish) ++ iqk0_ready = rtw_read32_mask(rtwdev, ++ REG_IQKA_END, ++ BIT(10)); ++ if (!tx1_finish) ++ iqk1_ready = rtw_read32_mask(rtwdev, ++ REG_IQKB_END, ++ BIT(10)); ++ if (iqk0_ready && iqk1_ready) ++ break; ++ ++ mdelay(1); ++ } ++ ++ rtw_dbg(rtwdev, RTW_DBG_RFK, "TX delay_count = %d\n", ++ delay_count); ++ ++ if (delay_count < 20) { /* If 20ms No Result, then cal_retry++ */ ++ /* ============TXIQK Check============== */ ++ tx0_fail = rtw_read32_mask(rtwdev, REG_IQKA_END, BIT(12)); ++ tx1_fail = rtw_read32_mask(rtwdev, REG_IQKB_END, BIT(12)); ++ ++ if (!(tx0_fail || tx0_finish)) { ++ rtw_write32(rtwdev, REG_RFECTL_A, 0x02000000); ++ tx_x0_temp[tx0_avg] = rtw_read32_mask(rtwdev, ++ REG_IQKA_END, ++ 0x07ff0000); ++ rtw_write32(rtwdev, REG_RFECTL_A, 0x04000000); ++ tx_y0_temp[tx0_avg] = rtw_read32_mask(rtwdev, ++ REG_IQKA_END, ++ 0x07ff0000); ++ ++ rtw_dbg(rtwdev, RTW_DBG_RFK, ++ "tx_x0[%d] = %x ;; tx_y0[%d] = %x\n", ++ tx0_avg, tx_x0_temp[tx0_avg], ++ tx0_avg, tx_y0_temp[tx0_avg]); ++ ++ tx_x0_temp[tx0_avg] <<= 21; ++ tx_y0_temp[tx0_avg] <<= 21; ++ ++ tx0_avg++; ++ } else { ++ cal0_retry++; ++ if (cal0_retry == 10) ++ break; ++ } ++ ++ if (!(tx1_fail || tx1_finish)) { ++ rtw_write32(rtwdev, REG_RFECTL_B, 0x02000000); ++ tx_x1_temp[tx1_avg] = rtw_read32_mask(rtwdev, ++ REG_IQKB_END, ++ 0x07ff0000); ++ rtw_write32(rtwdev, REG_RFECTL_B, 0x04000000); ++ tx_y1_temp[tx1_avg] = rtw_read32_mask(rtwdev, ++ REG_IQKB_END, ++ 0x07ff0000); ++ ++ rtw_dbg(rtwdev, RTW_DBG_RFK, ++ "tx_x1[%d] = %x ;; tx_y1[%d] = %x\n", ++ tx1_avg, tx_x1_temp[tx1_avg], ++ tx1_avg, tx_y1_temp[tx1_avg]); ++ ++ tx_x1_temp[tx1_avg] <<= 21; ++ tx_y1_temp[tx1_avg] <<= 21; ++ ++ tx1_avg++; ++ } else { ++ cal1_retry++; ++ if (cal1_retry == 10) ++ break; ++ } ++ } else { ++ cal0_retry++; ++ cal1_retry++; ++ ++ rtw_dbg(rtwdev, RTW_DBG_RFK, ++ "delay 20ms TX IQK Not Ready!!!!!\n"); ++ ++ if (cal0_retry == 10) ++ break; ++ } ++ ++ if (tx0_avg >= 2) ++ tx0_finish = rtw88xxa_iqk_finish(tx0_avg, 4, ++ tx_x0_temp, tx_y0_temp, &tx_x0, &tx_y0, ++ false, false); ++ ++ if (tx1_avg >= 2) ++ tx1_finish = rtw88xxa_iqk_finish(tx1_avg, 4, ++ tx_x1_temp, tx_y1_temp, &tx_x1, &tx_y1, ++ false, false); ++ ++ rtw_dbg(rtwdev, RTW_DBG_RFK, ++ "tx0_average = %d, tx1_average = %d\n", ++ tx0_avg, tx1_avg); ++ rtw_dbg(rtwdev, RTW_DBG_RFK, ++ "tx0_finish = %d, tx1_finish = %d\n", ++ tx0_finish, tx1_finish); ++ ++ if (tx0_finish && tx1_finish) ++ break; ++ ++ if ((cal0_retry + tx0_avg) >= 10 || ++ (cal1_retry + tx1_avg) >= 10) ++ break; ++ } ++ ++ rtw_dbg(rtwdev, RTW_DBG_RFK, "TXA_cal_retry = %d\n", cal0_retry); ++ rtw_dbg(rtwdev, RTW_DBG_RFK, "TXB_cal_retry = %d\n", cal1_retry); ++ ++ /* [31] = 0 --> Page C */ ++ rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0); ++ /* Load LOK */ ++ rtw_write_rf(rtwdev, RF_PATH_A, RF_TXMOD, 0x7fe00, ++ rtw_read_rf(rtwdev, RF_PATH_A, RF_DTXLOK, 0xffc00)); ++ rtw_write_rf(rtwdev, RF_PATH_B, RF_TXMOD, 0x7fe00, ++ rtw_read_rf(rtwdev, RF_PATH_B, RF_DTXLOK, 0xffc00)); ++ /* [31] = 1 --> Page C1 */ ++ rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x1); ++ ++ /* [31] = 0 --> Page C */ ++ rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0); ++ if (tx0_finish) { ++ /* ====== path A RX IQK RF setting====== */ ++ rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWE, RFREG_MASK, 0x80000); ++ rtw_write_rf(rtwdev, RF_PATH_A, RF_MODE_TABLE_ADDR, RFREG_MASK, ++ 0x30000); ++ rtw_write_rf(rtwdev, RF_PATH_A, RF_MODE_TABLE_DATA0, RFREG_MASK, ++ 0x3f7ff); ++ rtw_write_rf(rtwdev, RF_PATH_A, RF_MODE_TABLE_DATA1, RFREG_MASK, ++ 0xfe7bf); ++ rtw_write_rf(rtwdev, RF_PATH_A, RF_RXBB2, RFREG_MASK, 0x88001); ++ rtw_write_rf(rtwdev, RF_PATH_A, RF_TXA_PREPAD, RFREG_MASK, 0x931d1); ++ rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWE, RFREG_MASK, 0x00000); ++ } ++ if (tx1_finish) { ++ /* ====== path B RX IQK RF setting====== */ ++ rtw_write_rf(rtwdev, RF_PATH_B, RF_LUTWE, RFREG_MASK, 0x80000); ++ rtw_write_rf(rtwdev, RF_PATH_B, RF_MODE_TABLE_ADDR, RFREG_MASK, ++ 0x30000); ++ rtw_write_rf(rtwdev, RF_PATH_B, RF_MODE_TABLE_DATA0, RFREG_MASK, ++ 0x3f7ff); ++ rtw_write_rf(rtwdev, RF_PATH_B, RF_MODE_TABLE_DATA1, RFREG_MASK, ++ 0xfe7bf); ++ rtw_write_rf(rtwdev, RF_PATH_B, RF_RXBB2, RFREG_MASK, 0x88001); ++ rtw_write_rf(rtwdev, RF_PATH_B, RF_TXA_PREPAD, RFREG_MASK, 0x931d1); ++ rtw_write_rf(rtwdev, RF_PATH_B, RF_LUTWE, RFREG_MASK, 0x00000); ++ } ++ ++ rtw_write32_mask(rtwdev, REG_IQK_COM00, BIT(31), 0x1); ++ rtw_write32_mask(rtwdev, REG_IQK_COM00, BIT(31), 0x0); ++ rtw_write32(rtwdev, REG_DAC_RSTB, 0x00008000); ++ ++ if (rtwdev->hci.type == RTW_HCI_TYPE_PCIE) ++ rtw_write32(rtwdev, REG_IQK_COM96, 0x0046a911); ++ else ++ rtw_write32(rtwdev, REG_IQK_COM96, 0x0046a890); ++ ++ if (efuse->rfe_option == 1) { ++ rtw_write32(rtwdev, REG_RFE_PINMUX_A, 0x77777717); ++ rtw_write32(rtwdev, REG_RFE_INV_A, 0x00000077); ++ rtw_write32(rtwdev, REG_RFE_PINMUX_B, 0x77777717); ++ rtw_write32(rtwdev, REG_RFE_INV_B, 0x00000077); ++ } else { ++ rtw_write32(rtwdev, REG_RFE_PINMUX_A, 0x77777717); ++ rtw_write32(rtwdev, REG_RFE_INV_A, 0x02000077); ++ rtw_write32(rtwdev, REG_RFE_PINMUX_B, 0x77777717); ++ rtw_write32(rtwdev, REG_RFE_INV_B, 0x02000077); ++ } ++ ++ /* [31] = 1 --> Page C1 */ ++ rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x1); ++ ++ if (tx0_finish) { ++ /* TX_Tone_idx[9:0], TxK_Mask[29] TX_Tone = 16 */ ++ rtw_write32(rtwdev, REG_OFDM0_XA_TX_IQ_IMBALANCE, 0x38008c10); ++ /* RX_Tone_idx[9:0], RxK_Mask[29] */ ++ rtw_write32(rtwdev, REG_OFDM0_A_TX_AFE, 0x18008c10); ++ rtw_write32(rtwdev, REG_OFDM0_XB_TX_IQ_IMBALANCE, 0x82140119); ++ } ++ if (tx1_finish) { ++ /* TX_Tone_idx[9:0], TxK_Mask[29] TX_Tone = 16 */ ++ rtw_write32(rtwdev, REG_TXTONEB, 0x38008c10); ++ /* RX_Tone_idx[9:0], RxK_Mask[29] */ ++ rtw_write32(rtwdev, REG_RXTONEB, 0x18008c10); ++ rtw_write32(rtwdev, REG_TXPITMB, 0x82140119); ++ } ++ ++ cal0_retry = 0; ++ cal1_retry = 0; ++ while (1) { ++ /* one shot */ ++ /* [31] = 0 --> Page C */ ++ rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0); ++ ++ if (tx0_finish) { ++ rtw_write32_mask(rtwdev, REG_IQK_COM00, 0x03FF8000, ++ tx_x0 & 0x000007ff); ++ rtw_write32_mask(rtwdev, REG_IQK_COM00, 0x000007FF, ++ tx_y0 & 0x000007ff); ++ /* [31] = 1 --> Page C1 */ ++ rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x1); ++ if (efuse->rfe_option == 1) ++ rtw_write32(rtwdev, REG_TSSI_TRK_SW, 0x28161500); ++ else ++ rtw_write32(rtwdev, REG_TSSI_TRK_SW, 0x28160cc0); ++ rtw_write32(rtwdev, REG_RFECTL_A, 0x00300000); ++ rtw_write32(rtwdev, REG_RFECTL_A, 0x00100000); ++ mdelay(5); ++ rtw_write32(rtwdev, REG_TSSI_TRK_SW, 0x3c000000); ++ rtw_write32(rtwdev, REG_RFECTL_A, 0x00000000); ++ } ++ ++ if (tx1_finish) { ++ /* [31] = 0 --> Page C */ ++ rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0); ++ rtw_write32_mask(rtwdev, REG_IQK_COM00, 0x03FF8000, ++ tx_x1 & 0x000007ff); ++ rtw_write32_mask(rtwdev, REG_IQK_COM00, 0x000007FF, ++ tx_y1 & 0x000007ff); ++ /* [31] = 1 --> Page C1 */ ++ rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x1); ++ if (efuse->rfe_option == 1) ++ rtw_write32(rtwdev, REG_RXPITMB, 0x28161500); ++ else ++ rtw_write32(rtwdev, REG_RXPITMB, 0x28160ca0); ++ rtw_write32(rtwdev, REG_RFECTL_B, 0x00300000); ++ rtw_write32(rtwdev, REG_RFECTL_B, 0x00100000); ++ mdelay(5); ++ rtw_write32(rtwdev, REG_RXPITMB, 0x3c000000); ++ rtw_write32(rtwdev, REG_RFECTL_B, 0x00000000); ++ } ++ ++ for (delay_count = 0; delay_count < 20; delay_count++) { ++ if (!rx0_finish && tx0_finish) ++ iqk0_ready = rtw_read32_mask(rtwdev, ++ REG_IQKA_END, ++ BIT(10)); ++ if (!rx1_finish && tx1_finish) ++ iqk1_ready = rtw_read32_mask(rtwdev, ++ REG_IQKB_END, ++ BIT(10)); ++ if (iqk0_ready && iqk1_ready) ++ break; ++ ++ mdelay(1); ++ } ++ ++ rtw_dbg(rtwdev, RTW_DBG_RFK, "RX delay_count = %d\n", ++ delay_count); ++ ++ if (delay_count < 20) { /* If 20ms No Result, then cal_retry++ */ ++ /* ============RXIQK Check============== */ ++ rx0_fail = rtw_read32_mask(rtwdev, REG_IQKA_END, BIT(11)); ++ rx1_fail = rtw_read32_mask(rtwdev, REG_IQKB_END, BIT(11)); ++ ++ if (!(rx0_fail || rx0_finish) && tx0_finish) { ++ rtw_write32(rtwdev, REG_RFECTL_A, 0x06000000); ++ rx_x0_temp[rx0_avg] = rtw_read32_mask(rtwdev, ++ REG_IQKA_END, ++ 0x07ff0000); ++ rtw_write32(rtwdev, REG_RFECTL_A, 0x08000000); ++ rx_y0_temp[rx0_avg] = rtw_read32_mask(rtwdev, ++ REG_IQKA_END, ++ 0x07ff0000); ++ ++ rtw_dbg(rtwdev, RTW_DBG_RFK, ++ "rx_x0[%d] = %x ;; rx_y0[%d] = %x\n", ++ rx0_avg, rx_x0_temp[rx0_avg], ++ rx0_avg, rx_y0_temp[rx0_avg]); ++ ++ rx_x0_temp[rx0_avg] <<= 21; ++ rx_y0_temp[rx0_avg] <<= 21; ++ ++ rx0_avg++; ++ } else { ++ rtw_dbg(rtwdev, RTW_DBG_RFK, ++ "1. RXA_cal_retry = %d\n", cal0_retry); ++ ++ cal0_retry++; ++ if (cal0_retry == 10) ++ break; ++ } ++ ++ if (!(rx1_fail || rx1_finish) && tx1_finish) { ++ rtw_write32(rtwdev, REG_RFECTL_B, 0x06000000); ++ rx_x1_temp[rx1_avg] = rtw_read32_mask(rtwdev, ++ REG_IQKB_END, ++ 0x07ff0000); ++ rtw_write32(rtwdev, REG_RFECTL_B, 0x08000000); ++ rx_y1_temp[rx1_avg] = rtw_read32_mask(rtwdev, ++ REG_IQKB_END, ++ 0x07ff0000); ++ ++ rtw_dbg(rtwdev, RTW_DBG_RFK, ++ "rx_x1[%d] = %x ;; rx_y1[%d] = %x\n", ++ rx1_avg, rx_x1_temp[rx1_avg], ++ rx1_avg, rx_y1_temp[rx1_avg]); ++ ++ rx_x1_temp[rx1_avg] <<= 21; ++ rx_y1_temp[rx1_avg] <<= 21; ++ ++ rx1_avg++; ++ } else { ++ cal1_retry++; ++ if (cal1_retry == 10) ++ break; ++ } ++ } else { ++ rtw_dbg(rtwdev, RTW_DBG_RFK, ++ "2. RXA_cal_retry = %d\n", cal0_retry); ++ ++ cal0_retry++; ++ cal1_retry++; ++ ++ rtw_dbg(rtwdev, RTW_DBG_RFK, ++ "delay 20ms RX IQK Not Ready!!!!!\n"); ++ ++ if (cal0_retry == 10) ++ break; ++ } ++ ++ rtw_dbg(rtwdev, RTW_DBG_RFK, "3. RXA_cal_retry = %d\n", ++ cal0_retry); ++ ++ if (rx0_avg >= 2) ++ rx0_finish = rtw88xxa_iqk_finish(rx0_avg, 4, ++ rx_x0_temp, rx_y0_temp, ++ &rx_x0, &rx_y0, ++ true, false); ++ ++ if (rx1_avg >= 2) ++ rx1_finish = rtw88xxa_iqk_finish(rx1_avg, 4, ++ rx_x1_temp, rx_y1_temp, ++ &rx_x1, &rx_y1, ++ true, false); ++ ++ rtw_dbg(rtwdev, RTW_DBG_RFK, ++ "rx0_average = %d, rx1_average = %d\n", ++ rx0_avg, rx1_avg); ++ rtw_dbg(rtwdev, RTW_DBG_RFK, ++ "rx0_finish = %d, rx1_finish = %d\n", ++ rx0_finish, rx1_finish); ++ ++ if ((rx0_finish || !tx0_finish) && (rx1_finish || !tx1_finish)) ++ break; ++ ++ if ((cal0_retry + rx0_avg) >= 10 || ++ (cal1_retry + rx1_avg) >= 10 || ++ rx0_avg == 3 || rx1_avg == 3) ++ break; ++ } ++ ++ rtw_dbg(rtwdev, RTW_DBG_RFK, "RXA_cal_retry = %d\n", cal0_retry); ++ rtw_dbg(rtwdev, RTW_DBG_RFK, "RXB_cal_retry = %d\n", cal1_retry); ++ ++ /* FillIQK Result */ ++ rtw_dbg(rtwdev, RTW_DBG_RFK, "========Path_A =======\n"); ++ ++ if (tx0_finish) ++ rtw8812a_iqk_tx_fill(rtwdev, RF_PATH_A, tx_x0, tx_y0); ++ else ++ rtw8812a_iqk_tx_fill(rtwdev, RF_PATH_A, 0x200, 0x0); ++ ++ if (rx0_finish) ++ rtw8812a_iqk_rx_fill(rtwdev, RF_PATH_A, rx_x0, rx_y0); ++ else ++ rtw8812a_iqk_rx_fill(rtwdev, RF_PATH_A, 0x200, 0x0); ++ ++ rtw_dbg(rtwdev, RTW_DBG_RFK, "========Path_B =======\n"); ++ ++ if (tx1_finish) ++ rtw8812a_iqk_tx_fill(rtwdev, RF_PATH_B, tx_x1, tx_y1); ++ else ++ rtw8812a_iqk_tx_fill(rtwdev, RF_PATH_B, 0x200, 0x0); ++ ++ if (rx1_finish) ++ rtw8812a_iqk_rx_fill(rtwdev, RF_PATH_B, rx_x1, rx_y1); ++ else ++ rtw8812a_iqk_rx_fill(rtwdev, RF_PATH_B, 0x200, 0x0); ++} ++ ++#define MACBB_REG_NUM_8812A 9 ++#define AFE_REG_NUM_8812A 12 ++#define RF_REG_NUM_8812A 3 ++ ++static void rtw8812a_do_iqk(struct rtw_dev *rtwdev) ++{ ++ static const u32 backup_macbb_reg[MACBB_REG_NUM_8812A] = { ++ 0x520, 0x550, 0x808, 0xa04, 0x90c, 0xc00, 0xe00, 0x838, 0x82c ++ }; ++ static const u32 backup_afe_reg[AFE_REG_NUM_8812A] = { ++ 0xc5c, 0xc60, 0xc64, 0xc68, 0xcb0, 0xcb4, ++ 0xe5c, 0xe60, 0xe64, 0xe68, 0xeb0, 0xeb4 ++ }; ++ static const u32 backup_rf_reg[RF_REG_NUM_8812A] = { ++ 0x65, 0x8f, 0x0 ++ }; ++ u32 macbb_backup[MACBB_REG_NUM_8812A] = {}; ++ u32 afe_backup[AFE_REG_NUM_8812A] = {}; ++ u32 rfa_backup[RF_REG_NUM_8812A] = {}; ++ u32 rfb_backup[RF_REG_NUM_8812A] = {}; ++ u32 reg_cb8, reg_eb8; ++ ++ rtw88xxa_iqk_backup_mac_bb(rtwdev, macbb_backup, ++ backup_macbb_reg, MACBB_REG_NUM_8812A); ++ ++ rtw_write32_set(rtwdev, REG_CCASEL, BIT(31)); ++ reg_cb8 = rtw_read32(rtwdev, REG_RFECTL_A); ++ reg_eb8 = rtw_read32(rtwdev, REG_RFECTL_B); ++ rtw_write32_clr(rtwdev, REG_CCASEL, BIT(31)); ++ ++ rtw88xxa_iqk_backup_afe(rtwdev, afe_backup, ++ backup_afe_reg, AFE_REG_NUM_8812A); ++ rtw8812a_iqk_backup_rf(rtwdev, rfa_backup, rfb_backup, ++ backup_rf_reg, RF_REG_NUM_8812A); ++ ++ rtw88xxa_iqk_configure_mac(rtwdev); ++ ++ rtw8812a_iqk(rtwdev); ++ ++ rtw8812a_iqk_restore_rf(rtwdev, RF_PATH_A, backup_rf_reg, ++ rfa_backup, RF_REG_NUM_8812A); ++ rtw8812a_iqk_restore_rf(rtwdev, RF_PATH_B, backup_rf_reg, ++ rfb_backup, RF_REG_NUM_8812A); ++ ++ rtw8812a_iqk_restore_afe(rtwdev, afe_backup, ++ backup_afe_reg, AFE_REG_NUM_8812A); ++ ++ rtw_write32_set(rtwdev, REG_CCASEL, BIT(31)); ++ rtw_write32(rtwdev, REG_RFECTL_A, reg_cb8); ++ rtw_write32(rtwdev, REG_RFECTL_B, reg_eb8); ++ rtw_write32_clr(rtwdev, REG_CCASEL, BIT(31)); ++ ++ rtw88xxa_iqk_restore_mac_bb(rtwdev, macbb_backup, ++ backup_macbb_reg, MACBB_REG_NUM_8812A); ++} ++ ++static void rtw8812a_phy_calibration(struct rtw_dev *rtwdev) ++{ ++ u8 channel = rtwdev->hal.current_channel; ++ ++ rtw8812a_do_iqk(rtwdev); ++ ++ /* The official driver wants to do this after connecting ++ * but before first writing a new igi (phydm_get_new_igi). ++ * Here seems close enough. ++ */ ++ if (channel >= 36 && channel <= 64) ++ rtw_load_table(rtwdev, &rtw8812a_agc_diff_lb_tbl); ++ else if (channel >= 100) ++ rtw_load_table(rtwdev, &rtw8812a_agc_diff_hb_tbl); ++} ++ ++static void rtw8812a_pwr_track(struct rtw_dev *rtwdev) ++{ ++ struct rtw_dm_info *dm_info = &rtwdev->dm_info; ++ ++ if (!dm_info->pwr_trk_triggered) { ++ rtw_write_rf(rtwdev, RF_PATH_A, RF_T_METER, ++ GENMASK(17, 16), 0x03); ++ dm_info->pwr_trk_triggered = true; ++ return; ++ } ++ ++ rtw88xxa_phy_pwrtrack(rtwdev, rtw8812a_do_lck, rtw8812a_do_iqk); ++ dm_info->pwr_trk_triggered = false; ++} ++ ++static void rtw8812a_fill_txdesc_checksum(struct rtw_dev *rtwdev, ++ struct rtw_tx_pkt_info *pkt_info, ++ u8 *txdesc) ++{ ++ fill_txdesc_checksum_common(txdesc, 16); ++} ++ ++static void rtw8812a_coex_cfg_init(struct rtw_dev *rtwdev) ++{ ++} ++ ++static void rtw8812a_coex_cfg_gnt_fix(struct rtw_dev *rtwdev) ++{ ++} ++ ++static void rtw8821a_coex_cfg_rfe_type(struct rtw_dev *rtwdev) ++{ ++} ++ ++static void rtw8821a_coex_cfg_wl_tx_power(struct rtw_dev *rtwdev, u8 wl_pwr) ++{ ++} ++ ++static void rtw8821a_coex_cfg_wl_rx_gain(struct rtw_dev *rtwdev, bool low_gain) ++{ ++} ++ ++static const struct rtw_chip_ops rtw8812a_ops = { ++ .power_on = rtw88xxa_power_on, ++ .power_off = rtw8812a_power_off, ++ .phy_set_param = NULL, ++ .read_efuse = rtw88xxa_read_efuse, ++ .query_phy_status = rtw8812a_query_phy_status, ++ .set_channel = rtw88xxa_set_channel, ++ .mac_init = NULL, ++ .read_rf = rtw88xxa_phy_read_rf, ++ .write_rf = rtw_phy_write_rf_reg_sipi, ++ .set_antenna = NULL, ++ .set_tx_power_index = rtw88xxa_set_tx_power_index, ++ .cfg_ldo25 = rtw8812a_cfg_ldo25, ++ .efuse_grant = rtw88xxa_efuse_grant, ++ .false_alarm_statistics = rtw88xxa_false_alarm_statistics, ++ .phy_calibration = rtw8812a_phy_calibration, ++ .cck_pd_set = rtw88xxa_phy_cck_pd_set, ++ .pwr_track = rtw8812a_pwr_track, ++ .config_bfee = NULL, ++ .set_gid_table = NULL, ++ .cfg_csi_rate = NULL, ++ .fill_txdesc_checksum = rtw8812a_fill_txdesc_checksum, ++ .coex_set_init = rtw8812a_coex_cfg_init, ++ .coex_set_ant_switch = NULL, ++ .coex_set_gnt_fix = rtw8812a_coex_cfg_gnt_fix, ++ .coex_set_gnt_debug = NULL, ++ .coex_set_rfe_type = rtw8821a_coex_cfg_rfe_type, ++ .coex_set_wl_tx_power = rtw8821a_coex_cfg_wl_tx_power, ++ .coex_set_wl_rx_gain = rtw8821a_coex_cfg_wl_rx_gain, ++}; ++ ++static const struct rtw_page_table page_table_8812a[] = { ++ /* hq_num, nq_num, lq_num, exq_num, gapq_num */ ++ {0, 0, 0, 0, 0}, /* SDIO */ ++ {0, 0, 0, 0, 0}, /* PCI */ ++ {16, 0, 0, 0, 1}, /* 2 bulk out endpoints */ ++ {16, 0, 16, 0, 1}, /* 3 bulk out endpoints */ ++ {16, 0, 16, 0, 1}, /* 4 bulk out endpoints */ ++}; ++ ++static const struct rtw_rqpn rqpn_table_8812a[] = { ++ {RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL, ++ RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW, ++ RTW_DMA_MAPPING_EXTRA, RTW_DMA_MAPPING_HIGH}, ++ ++ {RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL, ++ RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW, ++ RTW_DMA_MAPPING_EXTRA, RTW_DMA_MAPPING_HIGH}, ++ ++ {RTW_DMA_MAPPING_HIGH, RTW_DMA_MAPPING_HIGH, ++ RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL, ++ RTW_DMA_MAPPING_HIGH, RTW_DMA_MAPPING_HIGH}, ++ ++ {RTW_DMA_MAPPING_HIGH, RTW_DMA_MAPPING_NORMAL, ++ RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW, ++ RTW_DMA_MAPPING_HIGH, RTW_DMA_MAPPING_HIGH}, ++ ++ {RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL, ++ RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW, ++ RTW_DMA_MAPPING_EXTRA, RTW_DMA_MAPPING_HIGH}, ++}; ++ ++static const struct rtw_prioq_addrs prioq_addrs_8812a = { ++ .prio[RTW_DMA_MAPPING_EXTRA] = { ++ .rsvd = REG_RQPN_NPQ + 2, .avail = REG_RQPN_NPQ + 3, ++ }, ++ .prio[RTW_DMA_MAPPING_LOW] = { ++ .rsvd = REG_RQPN + 1, .avail = REG_FIFOPAGE_CTRL_2 + 1, ++ }, ++ .prio[RTW_DMA_MAPPING_NORMAL] = { ++ .rsvd = REG_RQPN_NPQ, .avail = REG_RQPN_NPQ + 1, ++ }, ++ .prio[RTW_DMA_MAPPING_HIGH] = { ++ .rsvd = REG_RQPN, .avail = REG_FIFOPAGE_CTRL_2, ++ }, ++ .wsize = false, ++}; ++ ++static const struct rtw_hw_reg rtw8812a_dig[] = { ++ [0] = { .addr = REG_RXIGI_A, .mask = 0x7f }, ++ [1] = { .addr = REG_RXIGI_B, .mask = 0x7f }, ++}; ++ ++static const struct rtw_rfe_def rtw8812a_rfe_defs[] = { ++ [0] = { .phy_pg_tbl = &rtw8812a_bb_pg_tbl, ++ .txpwr_lmt_tbl = &rtw8812a_txpwr_lmt_tbl, ++ .pwr_track_tbl = &rtw8812a_rtw_pwr_track_tbl, }, ++ [1] = { .phy_pg_tbl = &rtw8812a_bb_pg_tbl, ++ .txpwr_lmt_tbl = &rtw8812a_txpwr_lmt_tbl, ++ .pwr_track_tbl = &rtw8812a_rtw_pwr_track_tbl, }, ++ [3] = { .phy_pg_tbl = &rtw8812a_bb_pg_rfe3_tbl, ++ .txpwr_lmt_tbl = &rtw8812a_txpwr_lmt_tbl, ++ .pwr_track_tbl = &rtw8812a_rtw_pwr_track_rfe3_tbl, }, ++}; ++ ++static const u8 wl_rssi_step_8812a[] = {101, 45, 101, 40}; ++static const u8 bt_rssi_step_8812a[] = {101, 101, 101, 101}; ++ ++static const struct coex_rf_para rf_para_tx_8812a[] = { ++ {0, 0, false, 7}, /* for normal */ ++ {0, 20, false, 7}, /* for WL-CPT */ ++ {8, 17, true, 4}, ++ {7, 18, true, 4}, ++ {6, 19, true, 4}, ++ {5, 20, true, 4} ++}; ++ ++static const struct coex_rf_para rf_para_rx_8812a[] = { ++ {0, 0, false, 7}, /* for normal */ ++ {0, 20, false, 7}, /* for WL-CPT */ ++ {3, 24, true, 5}, ++ {2, 26, true, 5}, ++ {1, 27, true, 5}, ++ {0, 28, true, 5} ++}; ++ ++static_assert(ARRAY_SIZE(rf_para_tx_8812a) == ARRAY_SIZE(rf_para_rx_8812a)); ++ ++const struct rtw_chip_info rtw8812a_hw_spec = { ++ .ops = &rtw8812a_ops, ++ .id = RTW_CHIP_TYPE_8812A, ++ .fw_name = "rtw88/rtw8812a_fw.bin", ++ .wlan_cpu = RTW_WCPU_11N, ++ .tx_pkt_desc_sz = 40, ++ .tx_buf_desc_sz = 16, ++ .rx_pkt_desc_sz = 24, ++ .rx_buf_desc_sz = 8, ++ .phy_efuse_size = 512, ++ .log_efuse_size = 512, ++ .ptct_efuse_size = 96 + 1, /* TODO or just 18? */ ++ .txff_size = 131072, ++ .rxff_size = 16128, ++ .rsvd_drv_pg_num = 9, ++ .txgi_factor = 1, ++ .is_pwr_by_rate_dec = true, ++ .max_power_index = 0x3f, ++ .csi_buf_pg_num = 0, ++ .band = RTW_BAND_2G | RTW_BAND_5G, ++ .page_size = 512, ++ .dig_min = 0x20, ++ .ht_supported = true, ++ .vht_supported = true, ++ .lps_deep_mode_supported = 0, ++ .sys_func_en = 0xFD, ++ .pwr_on_seq = card_enable_flow_8812a, ++ .pwr_off_seq = card_disable_flow_8812a, ++ .page_table = page_table_8812a, ++ .rqpn_table = rqpn_table_8812a, ++ .prioq_addrs = &prioq_addrs_8812a, ++ .intf_table = NULL, ++ .dig = rtw8812a_dig, ++ .rf_sipi_addr = {REG_LSSI_WRITE_A, REG_LSSI_WRITE_B}, ++ .ltecoex_addr = NULL, ++ .mac_tbl = &rtw8812a_mac_tbl, ++ .agc_tbl = &rtw8812a_agc_tbl, ++ .bb_tbl = &rtw8812a_bb_tbl, ++ .rf_tbl = {&rtw8812a_rf_a_tbl, &rtw8812a_rf_b_tbl}, ++ .rfe_defs = rtw8812a_rfe_defs, ++ .rfe_defs_size = ARRAY_SIZE(rtw8812a_rfe_defs), ++ .rx_ldpc = false, ++ .hw_feature_report = false, ++ .c2h_ra_report_size = 4, ++ .old_datarate_fb_limit = true, ++ .usb_tx_agg_desc_num = 1, ++ .iqk_threshold = 8, ++ .ampdu_density = IEEE80211_HT_MPDU_DENSITY_16, ++ .max_scan_ie_len = IEEE80211_MAX_DATA_LEN, ++ ++ .coex_para_ver = 0, /* no coex code in 8812au driver */ ++ .bt_desired_ver = 0, ++ .scbd_support = false, ++ .new_scbd10_def = false, ++ .ble_hid_profile_support = false, ++ .wl_mimo_ps_support = false, ++ .pstdma_type = COEX_PSTDMA_FORCE_LPSOFF, ++ .bt_rssi_type = COEX_BTRSSI_RATIO, ++ .ant_isolation = 15, ++ .rssi_tolerance = 2, ++ .wl_rssi_step = wl_rssi_step_8812a, ++ .bt_rssi_step = bt_rssi_step_8812a, ++ .table_sant_num = 0, ++ .table_sant = NULL, ++ .table_nsant_num = 0, ++ .table_nsant = NULL, ++ .tdma_sant_num = 0, ++ .tdma_sant = NULL, ++ .tdma_nsant_num = 0, ++ .tdma_nsant = NULL, ++ .wl_rf_para_num = ARRAY_SIZE(rf_para_tx_8812a), ++ .wl_rf_para_tx = rf_para_tx_8812a, ++ .wl_rf_para_rx = rf_para_rx_8812a, ++ .bt_afh_span_bw20 = 0x20, ++ .bt_afh_span_bw40 = 0x30, ++ .afh_5g_num = 0, ++ .afh_5g = NULL, ++ .coex_info_hw_regs_num = 0, ++ .coex_info_hw_regs = NULL, ++}; ++EXPORT_SYMBOL(rtw8812a_hw_spec); ++ ++MODULE_FIRMWARE("rtw88/rtw8812a_fw.bin"); ++ ++MODULE_AUTHOR("Realtek Corporation"); ++MODULE_DESCRIPTION("Realtek 802.11ac wireless 8812a driver"); ++MODULE_LICENSE("Dual BSD/GPL"); +--- /dev/null ++++ b/drivers/net/wireless/realtek/rtw88/rtw8812a.h +@@ -0,0 +1,10 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2024 Realtek Corporation ++ */ ++ ++#ifndef __RTW8812A_H__ ++#define __RTW8812A_H__ ++ ++extern const struct rtw_chip_info rtw8812a_hw_spec; ++ ++#endif diff --git a/package/kernel/mac80211/patches/rtl/044-v6.13-wifi-rtw88-Add-rtw8821au.c-and-rtw8812au.c.patch b/package/kernel/mac80211/patches/rtl/044-v6.13-wifi-rtw88-Add-rtw8821au.c-and-rtw8812au.c.patch new file mode 100644 index 00000000000000..a37f131bab8ffe --- /dev/null +++ b/package/kernel/mac80211/patches/rtl/044-v6.13-wifi-rtw88-Add-rtw8821au.c-and-rtw8812au.c.patch @@ -0,0 +1,80 @@ +From 8f82bb2cfaf7b8992e0e8493cb765138254f87c9 Mon Sep 17 00:00:00 2001 +From: Bitterblue Smith +Date: Wed, 30 Oct 2024 20:29:28 +0200 +Subject: [PATCH] wifi: rtw88: Add rtw8821au.c and rtw8812au.c + +These are the entry points for the new modules rtw88_8821au +(RTL8821AU/RTL8811AU) and rtw88_8812au (RTL8812AU). + +Signed-off-by: Bitterblue Smith +Signed-off-by: Ping-Ke Shih +Link: https://patch.msgid.link/91c495f8-a607-429b-8bc0-5a45d3c1393e@gmail.com +--- + .../net/wireless/realtek/rtw88/rtw8812au.c | 28 +++++++++++++++++++ + .../net/wireless/realtek/rtw88/rtw8821au.c | 28 +++++++++++++++++++ + 2 files changed, 56 insertions(+) + create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8812au.c + create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8821au.c + +--- /dev/null ++++ b/drivers/net/wireless/realtek/rtw88/rtw8812au.c +@@ -0,0 +1,28 @@ ++// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause ++/* Copyright(c) 2024 Realtek Corporation ++ */ ++ ++#include ++#include ++#include "main.h" ++#include "rtw8812a.h" ++#include "usb.h" ++ ++static const struct usb_device_id rtw_8812au_id_table[] = { ++ { USB_DEVICE_AND_INTERFACE_INFO(0x2604, 0x0012, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) }, ++ {}, ++}; ++MODULE_DEVICE_TABLE(usb, rtw_8812au_id_table); ++ ++static struct usb_driver rtw_8812au_driver = { ++ .name = "rtw_8812au", ++ .id_table = rtw_8812au_id_table, ++ .probe = rtw_usb_probe, ++ .disconnect = rtw_usb_disconnect, ++}; ++module_usb_driver(rtw_8812au_driver); ++ ++MODULE_AUTHOR("Bitterblue Smith "); ++MODULE_DESCRIPTION("Realtek 802.11ac wireless 8812au driver"); ++MODULE_LICENSE("Dual BSD/GPL"); +--- /dev/null ++++ b/drivers/net/wireless/realtek/rtw88/rtw8821au.c +@@ -0,0 +1,28 @@ ++// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause ++/* Copyright(c) 2024 Realtek Corporation ++ */ ++ ++#include ++#include ++#include "main.h" ++#include "rtw8821a.h" ++#include "usb.h" ++ ++static const struct usb_device_id rtw_8821au_id_table[] = { ++ { USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x011e, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&(rtw8821a_hw_spec) }, ++ {}, ++}; ++MODULE_DEVICE_TABLE(usb, rtw_8821au_id_table); ++ ++static struct usb_driver rtw_8821au_driver = { ++ .name = "rtw_8821au", ++ .id_table = rtw_8821au_id_table, ++ .probe = rtw_usb_probe, ++ .disconnect = rtw_usb_disconnect, ++}; ++module_usb_driver(rtw_8821au_driver); ++ ++MODULE_AUTHOR("Bitterblue Smith "); ++MODULE_DESCRIPTION("Realtek 802.11ac wireless 8821au/8811au driver"); ++MODULE_LICENSE("Dual BSD/GPL"); diff --git a/package/kernel/mac80211/patches/rtl/045-v6.13-wifi-rtw88-Enable-the-new-RTL8821AU-RTL8812AU-driver.patch b/package/kernel/mac80211/patches/rtl/045-v6.13-wifi-rtw88-Enable-the-new-RTL8821AU-RTL8812AU-driver.patch new file mode 100644 index 00000000000000..6a4a2aff6980d7 --- /dev/null +++ b/package/kernel/mac80211/patches/rtl/045-v6.13-wifi-rtw88-Enable-the-new-RTL8821AU-RTL8812AU-driver.patch @@ -0,0 +1,153 @@ +From 0e3e8284f8e1bf2fc0f7bf247194efe5cfc568c1 Mon Sep 17 00:00:00 2001 +From: Bitterblue Smith +Date: Wed, 30 Oct 2024 20:31:28 +0200 +Subject: [PATCH] wifi: rtw88: Enable the new RTL8821AU/RTL8812AU drivers + +These are older Wifi 5 chips. RTL8821AU is 1x1, with or without +Bluetooth. RTL8812AU is 2x2, without Bluetooth. + +Beamforming is not implemented. It looks like these chips need a +different implementation than what is in bf.c. + +Speed tests with RTL8821AU: 137 Mbps download, 144 Mbps upload. +Speed tests with RTL8812AU: 344 Mbps download, 387 Mbps upload. + +Station mode and AP mode were tested. + +Bluetooth coexistence works. I used my Bluetooth headphones for +several days, listening to music and watching videos. There is only +a problem with the wifi speeds with one router: + +With ISP's HG6544C router: +Official driver: 3/5 Mbps. +rtw88: a bit more, but not steady at all. Not enough to watch a 1080p +Youtube video. + +With my D-Link Eagle R32 router running Openwrt, on the same channel: +Official driver: 6/10 Mbps. +rtw88: download starts around 30, climbs to 50 / upload is 10 Mbps. +I can watch a 1080p Youtube video. + +The music doesn't cut out during any speed tests. + +I also tested transferring files to and from my phone. I don't have +other types of Bluetooth devices to test. + +Signed-off-by: Bitterblue Smith +Signed-off-by: Ping-Ke Shih +Link: https://patch.msgid.link/0b8e8093-8103-4999-86bf-0055ec52ea64@gmail.com +--- +Kconfig.local | 15 ++++++++ + drivers/net/wireless/realtek/rtw88/Kconfig | 40 ++++++++++++++++++++- + drivers/net/wireless/realtek/rtw88/Makefile | 15 ++++++++ + 3 files changed, 69 insertions(+), 1 deletion(-) + +--- a/Kconfig.local ++++ b/Kconfig.local +@@ -1144,6 +1144,15 @@ config BACKPORTED_RTW88_8723D + config BACKPORTED_RTW88_8821C + tristate + default RTW88_8821C ++config BACKPORTED_RTW88_88XXA ++ tristate ++ default RTW88_88XXA ++config BACKPORTED_RTW88_8821A ++ tristate ++ default RTW88_8821A ++config BACKPORTED_RTW88_8812A ++ tristate ++ default RTW88_8812A + config BACKPORTED_RTW88_8822BE + tristate + default RTW88_8822BE +@@ -1183,6 +1192,12 @@ config BACKPORTED_RTW88_8821CS + config BACKPORTED_RTW88_8821CU + tristate + default RTW88_8821CU ++config BACKPORTED_RTW88_8821AU ++ tristate ++ default RTW88_8821AU ++config BACKPORTED_RTW88_8812AU ++ tristate ++ default RTW88_8812AU + config BACKPORTED_RTW88_DEBUG + tristate + default RTW88_DEBUG +--- a/drivers/net/wireless/realtek/rtw88/Kconfig ++++ b/drivers/net/wireless/realtek/rtw88/Kconfig +@@ -54,6 +54,20 @@ config RTW88_8821C + tristate + depends on m + ++config RTW88_88XXA ++ tristate ++ depends on m ++ ++config RTW88_8821A ++ tristate ++ depends on m ++ select RTW88_88XXA ++ ++config RTW88_8812A ++ tristate ++ depends on m ++ select RTW88_88XXA ++ + config RTW88_8822BE + tristate "Realtek 8822BE PCI wireless network adapter" + depends on m +@@ -213,6 +227,30 @@ config RTW88_8821CU + + 802.11ac USB wireless network adapter + ++config RTW88_8821AU ++ tristate "Realtek 8821AU/8811AU USB wireless network adapter" ++ depends on m ++ depends on USB ++ select RTW88_CORE ++ select RTW88_USB ++ select RTW88_8821A ++ help ++ Select this option will enable support for 8821AU and 8811AU chipset ++ ++ 802.11ac USB wireless network adapter ++ ++config RTW88_8812AU ++ tristate "Realtek 8812AU USB wireless network adapter" ++ depends on m ++ depends on USB ++ select RTW88_CORE ++ select RTW88_USB ++ select RTW88_8812A ++ help ++ Select this option will enable support for 8812AU chipset ++ ++ 802.11ac USB wireless network adapter ++ + config RTW88_DEBUG + bool "Realtek rtw88 debug support" + depends on RTW88_CORE +--- a/drivers/net/wireless/realtek/rtw88/Makefile ++++ b/drivers/net/wireless/realtek/rtw88/Makefile +@@ -77,6 +77,21 @@ rtw88_8821cs-objs := rtw8821cs.o + obj-$(CPTCFG_RTW88_8821CU) += rtw88_8821cu.o + rtw88_8821cu-objs := rtw8821cu.o + ++obj-$(CPTCFG_RTW88_88XXA) += rtw88_88xxa.o ++rtw88_88xxa-objs := rtw88xxa.o ++ ++obj-$(CPTCFG_RTW88_8821A) += rtw88_8821a.o ++rtw88_8821a-objs := rtw8821a.o rtw8821a_table.o ++ ++obj-$(CPTCFG_RTW88_8812A) += rtw88_8812a.o ++rtw88_8812a-objs := rtw8812a.o rtw8812a_table.o ++ ++obj-$(CPTCFG_RTW88_8821AU) += rtw88_8821au.o ++rtw88_8821au-objs := rtw8821au.o ++ ++obj-$(CPTCFG_RTW88_8812AU) += rtw88_8812au.o ++rtw88_8812au-objs := rtw8812au.o ++ + obj-$(CPTCFG_RTW88_PCI) += rtw88_pci.o + rtw88_pci-objs := pci.o + diff --git a/package/kernel/mac80211/patches/rtl/046-wifi-rtw88-8821au-Add-additional-devices-to-the-USB_.patch b/package/kernel/mac80211/patches/rtl/046-wifi-rtw88-8821au-Add-additional-devices-to-the-USB_.patch new file mode 100644 index 00000000000000..a83094b3c3ee2b --- /dev/null +++ b/package/kernel/mac80211/patches/rtl/046-wifi-rtw88-8821au-Add-additional-devices-to-the-USB_.patch @@ -0,0 +1,77 @@ +From ff5a1c94e53c0d24f610c2c30add82f75b728737 Mon Sep 17 00:00:00 2001 +From: Larry Finger +Date: Wed, 6 Nov 2024 15:55:31 +0200 +Subject: [PATCH 1/6] wifi: rtw88: 8821au: Add additional devices to the + USB_DEVICE list + +These are the entries that Nick Morrow provided. From +https://github.com/morrownr/8821au-20210708 + +Signed-off-by: Larry Finger +Signed-off-by: Bitterblue Smith +--- + .../net/wireless/realtek/rtw88/rtw8821au.c | 52 ++++++++++++++++++- + 1 file changed, 51 insertions(+), 1 deletion(-) + +--- a/drivers/net/wireless/realtek/rtw88/rtw8821au.c ++++ b/drivers/net/wireless/realtek/rtw88/rtw8821au.c +@@ -9,8 +9,58 @@ + #include "usb.h" + + static const struct usb_device_id rtw_8821au_id_table[] = { +- { USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x011e, 0xff, 0xff, 0xff), ++ { USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0x0811, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&(rtw8821a_hw_spec) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0x0820, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&(rtw8821a_hw_spec) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0x0821, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&(rtw8821a_hw_spec) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0x8822, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8821a_hw_spec) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0x0823, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&(rtw8821a_hw_spec) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0xa811, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&(rtw8821a_hw_spec) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(0x0411, 0x0242, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&(rtw8821a_hw_spec) }, /* Buffalo */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x0411, 0x029b, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&(rtw8821a_hw_spec) }, /* Buffalo */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x04bb, 0x0953, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&(rtw8821a_hw_spec) }, /* I-O DATA */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x056e, 0x4007, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&(rtw8821a_hw_spec) }, /* ELECOM */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x056e, 0x400e, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&(rtw8821a_hw_spec) }, /* ELECOM */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x056e, 0x400f, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&(rtw8821a_hw_spec) }, /* ELECOM */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x0846, 0x9052, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&(rtw8821a_hw_spec) }, /* Netgear */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x0e66, 0x0023, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&(rtw8821a_hw_spec) }, /* HAWKING */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x3314, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&(rtw8821a_hw_spec) }, /* D-Link */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x3318, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&(rtw8821a_hw_spec) }, /* D-Link */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x2019, 0xab32, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&(rtw8821a_hw_spec) }, /* Planex */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x20f4, 0x804b, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&(rtw8821a_hw_spec) }, /* TRENDnet */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x011e, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&(rtw8821a_hw_spec) }, /* TP Link */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x011f, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&(rtw8821a_hw_spec) }, /* TP Link */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x0120, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&(rtw8821a_hw_spec) }, /* TP Link */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x3823, 0x6249, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&(rtw8821a_hw_spec) }, /* Obihai */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x7392, 0xa811, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&(rtw8821a_hw_spec) }, /* Edimax */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x7392, 0xa812, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&(rtw8821a_hw_spec) }, /* Edimax */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x7392, 0xa813, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&(rtw8821a_hw_spec) }, /* Edimax */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x7392, 0xb611, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&(rtw8821a_hw_spec) }, /* Edimax */ + {}, + }; + MODULE_DEVICE_TABLE(usb, rtw_8821au_id_table); diff --git a/package/kernel/mac80211/patches/rtl/047-wifi-rtw88-8812au-Add-more-device-IDs.patch b/package/kernel/mac80211/patches/rtl/047-wifi-rtw88-8812au-Add-more-device-IDs.patch new file mode 100644 index 00000000000000..a93f9219d9fcc2 --- /dev/null +++ b/package/kernel/mac80211/patches/rtl/047-wifi-rtw88-8812au-Add-more-device-IDs.patch @@ -0,0 +1,91 @@ +From d21ad2e4edfb64d3f32685607a457576eea3c5cd Mon Sep 17 00:00:00 2001 +From: Nick Morrow +Date: Wed, 6 Nov 2024 15:57:10 +0200 +Subject: [PATCH 2/6] wifi: rtw88: 8812au: Add more device IDs + +From https://github.com/morrownr/8812au-20210820. + +Signed-off-by: Nick Morrow +Signed-off-by: Bitterblue Smith +--- + .../net/wireless/realtek/rtw88/rtw8812au.c | 68 ++++++++++++++++++- + 1 file changed, 67 insertions(+), 1 deletion(-) + +--- a/drivers/net/wireless/realtek/rtw88/rtw8812au.c ++++ b/drivers/net/wireless/realtek/rtw88/rtw8812au.c +@@ -9,8 +9,74 @@ + #include "usb.h" + + static const struct usb_device_id rtw_8812au_id_table[] = { +- { USB_DEVICE_AND_INTERFACE_INFO(0x2604, 0x0012, 0xff, 0xff, 0xff), ++ { USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0x8812, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0x881a, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0x881b, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0x881c, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(0x0409, 0x0408, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) }, /* NEC */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x0411, 0x025d, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) }, /* Buffalo */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x04bb, 0x0952, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) }, /* I-O DATA */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x050d, 0x1106, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) }, /* Belkin */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x050d, 0x1109, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) }, /* Belkin */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x0586, 0x3426, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) }, /* ZyXEL */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x0789, 0x016e, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) }, /* Logitec */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x07b8, 0x8812, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) }, /* Abocom */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x0846, 0x9051, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) }, /* Netgear */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x0b05, 0x17d2, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) }, /* ASUS */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x0df6, 0x0074, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) }, /* Sitecom */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x0e66, 0x0022, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) }, /* Hawking */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x1058, 0x0632, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) }, /* WD */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x13b1, 0x003f, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) }, /* Linksys */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x148f, 0x9097, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) }, /* Amped Wireless */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x1740, 0x0100, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) }, /* EnGenius */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x330e, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) }, /* D-Link */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x3313, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) }, /* D-Link */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x3315, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) }, /* D-Link */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x3316, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) }, /* D-Link */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x2019, 0xab30, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) }, /* Planex */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x20f4, 0x805b, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) }, /* TRENDnet */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x0101, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) }, /* TP-Link */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x0103, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) }, /* TP-Link */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x010d, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) }, /* TP-Link */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x010e, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) }, /* TP-Link */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x010f, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) }, /* TP-Link */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x0122, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) }, /* TP-Link */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x2604, 0x0012, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) }, /* Tenda */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x7392, 0xa822, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) }, /* Edimax */ + {}, + }; + MODULE_DEVICE_TABLE(usb, rtw_8812au_id_table); diff --git a/package/kernel/mac80211/patches/rtl/048-wifi-rtw88-usb-Support-USB-3-with-RTL8812AU.patch b/package/kernel/mac80211/patches/rtl/048-wifi-rtw88-usb-Support-USB-3-with-RTL8812AU.patch new file mode 100644 index 00000000000000..86ecfcd4a4a0ca --- /dev/null +++ b/package/kernel/mac80211/patches/rtl/048-wifi-rtw88-usb-Support-USB-3-with-RTL8812AU.patch @@ -0,0 +1,69 @@ +From 213dfa630285bb0241f3eaeb778db8ff128f10ba Mon Sep 17 00:00:00 2001 +From: Bitterblue Smith +Date: Fri, 8 Nov 2024 01:41:08 +0200 +Subject: [PATCH 3/6] wifi: rtw88: usb: Support USB 3 with RTL8812AU + +Add the function to automatically switch the RTL8812AU into USB 3 mode. + +Signed-off-by: Bitterblue Smith +--- + drivers/net/wireless/realtek/rtw88/usb.c | 34 ++++++++++++++++++++++-- + 1 file changed, 32 insertions(+), 2 deletions(-) + +--- a/drivers/net/wireless/realtek/rtw88/usb.c ++++ b/drivers/net/wireless/realtek/rtw88/usb.c +@@ -985,6 +985,32 @@ static void rtw_usb_intf_deinit(struct r + usb_set_intfdata(intf, NULL); + } + ++static int rtw_usb_switch_mode_old(struct rtw_dev *rtwdev) ++{ ++ struct rtw_usb *rtwusb = rtw_get_usb_priv(rtwdev); ++ enum usb_device_speed cur_speed = rtwusb->udev->speed; ++ u8 hci_opt; ++ ++ if (cur_speed == USB_SPEED_HIGH) { ++ hci_opt = rtw_read8(rtwdev, REG_HCI_OPT_CTRL); ++ ++ if ((hci_opt & (BIT(2) | BIT(3))) != BIT(3)) { ++ rtw_write8(rtwdev, REG_HCI_OPT_CTRL, 0x8); ++ rtw_write8(rtwdev, REG_SYS_SDIO_CTRL, 0x2); ++ rtw_write8(rtwdev, REG_ACLK_MON, 0x1); ++ rtw_write8(rtwdev, 0x3d, 0x3); ++ /* usb disconnect */ ++ rtw_write8(rtwdev, REG_SYS_PW_CTRL + 1, 0x80); ++ return 1; ++ } ++ } else if (cur_speed == USB_SPEED_SUPER) { ++ rtw_write8_clr(rtwdev, REG_SYS_SDIO_CTRL, BIT(1)); ++ rtw_write8_clr(rtwdev, REG_ACLK_MON, BIT(0)); ++ } ++ ++ return 0; ++} ++ + static int rtw_usb_switch_mode_new(struct rtw_dev *rtwdev) + { + enum usb_device_speed cur_speed; +@@ -1038,7 +1064,8 @@ static int rtw_usb_switch_mode(struct rt + { + u8 id = rtwdev->chip->id; + +- if (id != RTW_CHIP_TYPE_8822C && id != RTW_CHIP_TYPE_8822B) ++ if (id != RTW_CHIP_TYPE_8822C && id != RTW_CHIP_TYPE_8822B && ++ id != RTW_CHIP_TYPE_8812A) + return 0; + + if (!rtwdev->efuse.usb_mode_switch) { +@@ -1053,7 +1080,10 @@ static int rtw_usb_switch_mode(struct rt + return 0; + } + +- return rtw_usb_switch_mode_new(rtwdev); ++ if (id == RTW_CHIP_TYPE_8812A) ++ return rtw_usb_switch_mode_old(rtwdev); ++ else /* RTL8822CU, RTL8822BU */ ++ return rtw_usb_switch_mode_new(rtwdev); + } + + int rtw_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) diff --git a/package/kernel/mac80211/patches/rtl/049-wifi-rtw88-usb-Enable-RX-aggregation-for-8821au-8812.patch b/package/kernel/mac80211/patches/rtl/049-wifi-rtw88-usb-Enable-RX-aggregation-for-8821au-8812.patch new file mode 100644 index 00000000000000..5b4530871b48e0 --- /dev/null +++ b/package/kernel/mac80211/patches/rtl/049-wifi-rtw88-usb-Enable-RX-aggregation-for-8821au-8812.patch @@ -0,0 +1,65 @@ +From 2b38362bd3b8e0a3691f0a8e82444a54f702e384 Mon Sep 17 00:00:00 2001 +From: Bitterblue Smith +Date: Fri, 8 Nov 2024 01:43:50 +0200 +Subject: [PATCH 4/6] wifi: rtw88: usb: Enable RX aggregation for 8821au/8812au + +USB RX aggregation improves the RX speed on certain ARM systems, like +the NanoPi NEO Core2. With RTL8811AU, before: 30 Mbps, after: 224 Mbps. + +The out-of-tree driver uses aggregation size of 7 in USB 3 mode, but +that doesn't work here. rtw88 advertises support for receiving AMSDU +in AMPDU, so the AP sends larger frames, up to ~5100 bytes. With a size +of 7 RTL8812AU frequently tries to aggregate more frames than will fit +in 32768 bytes. Use a size of 6 instead. + +Signed-off-by: Bitterblue Smith +--- + drivers/net/wireless/realtek/rtw88/usb.c | 30 ++++++++++++++++++++++++ + 1 file changed, 30 insertions(+) + +--- a/drivers/net/wireless/realtek/rtw88/usb.c ++++ b/drivers/net/wireless/realtek/rtw88/usb.c +@@ -843,6 +843,32 @@ static void rtw_usb_dynamic_rx_agg_v1(st + rtw_write16(rtwdev, REG_RXDMA_AGG_PG_TH, val16); + } + ++static void rtw_usb_dynamic_rx_agg_v2(struct rtw_dev *rtwdev, bool enable) ++{ ++ struct rtw_usb *rtwusb = rtw_get_usb_priv(rtwdev); ++ u8 size, timeout; ++ u16 val16; ++ ++ if (rtwusb->udev->speed == USB_SPEED_SUPER) { ++ size = 0x6; ++ timeout = 0x1a; ++ } else { ++ size = 0x5; ++ timeout = 0x20; ++ } ++ ++ if (!enable) { ++ size = 0x0; ++ timeout = 0x1; ++ } ++ ++ val16 = u16_encode_bits(size, BIT_RXDMA_AGG_PG_TH) | ++ u16_encode_bits(timeout, BIT_DMA_AGG_TO_V1); ++ ++ rtw_write16(rtwdev, REG_RXDMA_AGG_PG_TH, val16); ++ rtw_write8_set(rtwdev, REG_TXDMA_PQ_MAP, BIT_RXDMA_AGG_EN); ++} ++ + static void rtw_usb_dynamic_rx_agg(struct rtw_dev *rtwdev, bool enable) + { + switch (rtwdev->chip->id) { +@@ -851,6 +877,10 @@ static void rtw_usb_dynamic_rx_agg(struc + case RTW_CHIP_TYPE_8821C: + rtw_usb_dynamic_rx_agg_v1(rtwdev, enable); + break; ++ case RTW_CHIP_TYPE_8821A: ++ case RTW_CHIP_TYPE_8812A: ++ rtw_usb_dynamic_rx_agg_v2(rtwdev, enable); ++ break; + case RTW_CHIP_TYPE_8723D: + /* Doesn't like aggregation. */ + break; diff --git a/package/kernel/mac80211/patches/rtl/051-wifi-rtw88-Add-additional-USB-IDs-for-RTL8812BU.patch b/package/kernel/mac80211/patches/rtl/051-wifi-rtw88-Add-additional-USB-IDs-for-RTL8812BU.patch new file mode 100644 index 00000000000000..e4e26c79751116 --- /dev/null +++ b/package/kernel/mac80211/patches/rtl/051-wifi-rtw88-Add-additional-USB-IDs-for-RTL8812BU.patch @@ -0,0 +1,31 @@ +From acadf3a63b39ad03167a633fa3cea8c0fc2ab87f Mon Sep 17 00:00:00 2001 +From: Nick Morrow +Date: Thu, 7 Nov 2024 08:28:46 +0800 +Subject: [PATCH 6/6] wifi: rtw88: Add additional USB IDs for RTL8812BU + +Add three additional USB IDs found in +https://github.com/morrownr/88x2bu-20210702 +to support more RTL8812BU devices. + +Signed-off-by: Nick Morrow +Signed-off-by: Zenm Chen +Signed-off-by: Mikhail Novosyolov +--- + drivers/net/wireless/realtek/rtw88/rtw8822bu.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +--- a/drivers/net/wireless/realtek/rtw88/rtw8822bu.c ++++ b/drivers/net/wireless/realtek/rtw88/rtw8822bu.c +@@ -67,6 +67,12 @@ static const struct usb_device_id rtw_88 + .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* LiteOn */ + { USB_DEVICE_AND_INTERFACE_INFO(0x20f4, 0x808a, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* TRENDnet TEW-808UBM */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x20f4, 0x805a, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* TRENDnet TEW-805UBH */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x056e, 0x4011, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* ELECOM WDB-867DU3S */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x2c4e, 0x0107, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* Mercusys MA30H */ + {}, + }; + MODULE_DEVICE_TABLE(usb, rtw_8822bu_id_table); diff --git a/package/kernel/mac80211/patches/subsys/130-disable_auto_vif.patch b/package/kernel/mac80211/patches/subsys/130-disable_auto_vif.patch index eea165ccca9bf9..b56531435c67d3 100644 --- a/package/kernel/mac80211/patches/subsys/130-disable_auto_vif.patch +++ b/package/kernel/mac80211/patches/subsys/130-disable_auto_vif.patch @@ -1,6 +1,6 @@ --- a/net/mac80211/main.c +++ b/net/mac80211/main.c -@@ -1581,24 +1581,6 @@ int ieee80211_register_hw(struct ieee802 +@@ -1585,24 +1585,6 @@ int ieee80211_register_hw(struct ieee802 ieee80211_check_wbrf_support(local); diff --git a/package/kernel/mac80211/patches/subsys/220-allow-ibss-mixed.patch b/package/kernel/mac80211/patches/subsys/220-allow-ibss-mixed.patch index 55376362a5b41c..378ca275f5ba80 100644 --- a/package/kernel/mac80211/patches/subsys/220-allow-ibss-mixed.patch +++ b/package/kernel/mac80211/patches/subsys/220-allow-ibss-mixed.patch @@ -16,7 +16,7 @@ and we should ignore this. --- a/net/wireless/core.c +++ b/net/wireless/core.c -@@ -654,21 +654,6 @@ static int wiphy_verify_combinations(str +@@ -678,21 +678,6 @@ int wiphy_verify_iface_combinations(stru c->limits[j].max > 1)) return -EINVAL; diff --git a/package/kernel/mac80211/patches/subsys/230-avoid-crashing-missing-band.patch b/package/kernel/mac80211/patches/subsys/230-avoid-crashing-missing-band.patch index 9e9e3844b7ac5b..b6b3f6af8f17f9 100644 --- a/package/kernel/mac80211/patches/subsys/230-avoid-crashing-missing-band.patch +++ b/package/kernel/mac80211/patches/subsys/230-avoid-crashing-missing-band.patch @@ -18,7 +18,7 @@ Signed-off-by: David Bauer --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c -@@ -2439,6 +2439,13 @@ static void sta_stats_decode_rate(struct +@@ -2446,6 +2446,13 @@ static void sta_stats_decode_rate(struct sband = local->hw.wiphy->bands[band]; diff --git a/package/kernel/mac80211/patches/subsys/301-mac80211-sta-randomize-BA-session-dialog-token-alloc.patch b/package/kernel/mac80211/patches/subsys/301-mac80211-sta-randomize-BA-session-dialog-token-alloc.patch index edec97cce94022..77bc2c0df2384c 100644 --- a/package/kernel/mac80211/patches/subsys/301-mac80211-sta-randomize-BA-session-dialog-token-alloc.patch +++ b/package/kernel/mac80211/patches/subsys/301-mac80211-sta-randomize-BA-session-dialog-token-alloc.patch @@ -28,7 +28,7 @@ Signed-off-by: Johannes Berg --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c -@@ -565,6 +565,7 @@ __sta_info_alloc(struct ieee80211_sub_if +@@ -564,6 +564,7 @@ __sta_info_alloc(struct ieee80211_sub_if spin_lock_init(&sta->ps_lock); INIT_WORK(&sta->drv_deliver_wk, sta_deliver_ps_frames); wiphy_work_init(&sta->ampdu_mlme.work, ieee80211_ba_session_work); diff --git a/package/kernel/mac80211/patches/subsys/305-mac80211-increase-quantum-for-airtime-scheduler.patch b/package/kernel/mac80211/patches/subsys/305-mac80211-increase-quantum-for-airtime-scheduler.patch index 6cf46ce7e51459..a9929875014756 100644 --- a/package/kernel/mac80211/patches/subsys/305-mac80211-increase-quantum-for-airtime-scheduler.patch +++ b/package/kernel/mac80211/patches/subsys/305-mac80211-increase-quantum-for-airtime-scheduler.patch @@ -23,7 +23,7 @@ Signed-off-by: Felix Fietkau --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c -@@ -4081,7 +4081,7 @@ struct ieee80211_txq *ieee80211_next_txq +@@ -4082,7 +4082,7 @@ struct ieee80211_txq *ieee80211_next_txq if (deficit < 0) sta->airtime[txqi->txq.ac].deficit += @@ -32,7 +32,7 @@ Signed-off-by: Felix Fietkau if (deficit < 0 || !aql_check) { list_move_tail(&txqi->schedule_order, -@@ -4224,7 +4224,8 @@ bool ieee80211_txq_may_transmit(struct i +@@ -4227,7 +4227,8 @@ bool ieee80211_txq_may_transmit(struct i } sta = container_of(iter->txq.sta, struct sta_info, sta); if (ieee80211_sta_deficit(sta, ac) < 0) @@ -42,7 +42,7 @@ Signed-off-by: Felix Fietkau list_move_tail(&iter->schedule_order, &local->active_txqs[ac]); } -@@ -4232,7 +4233,7 @@ bool ieee80211_txq_may_transmit(struct i +@@ -4235,7 +4236,7 @@ bool ieee80211_txq_may_transmit(struct i if (sta->airtime[ac].deficit >= 0) goto out; diff --git a/package/kernel/mac80211/patches/subsys/310-cfg80211-allow-grace-period-for-DFS-available-after-.patch b/package/kernel/mac80211/patches/subsys/310-cfg80211-allow-grace-period-for-DFS-available-after-.patch index 7e9be59e044348..ae65ff082fa377 100644 --- a/package/kernel/mac80211/patches/subsys/310-cfg80211-allow-grace-period-for-DFS-available-after-.patch +++ b/package/kernel/mac80211/patches/subsys/310-cfg80211-allow-grace-period-for-DFS-available-after-.patch @@ -11,7 +11,7 @@ Signed-off-by: Felix Fietkau --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h -@@ -187,6 +187,8 @@ enum ieee80211_channel_flags { +@@ -190,6 +190,8 @@ enum ieee80211_channel_flags { * @dfs_state: current state of this channel. Only relevant if radar is required * on this channel. * @dfs_state_entered: timestamp (jiffies) when the dfs state was entered. @@ -20,7 +20,7 @@ Signed-off-by: Felix Fietkau * @dfs_cac_ms: DFS CAC time in milliseconds, this is valid for DFS channels. * @psd: power spectral density (in dBm) */ -@@ -204,6 +206,7 @@ struct ieee80211_channel { +@@ -207,6 +209,7 @@ struct ieee80211_channel { int orig_mag, orig_mpwr; enum nl80211_dfs_state dfs_state; unsigned long dfs_state_entered; @@ -113,7 +113,7 @@ Signed-off-by: Felix Fietkau { --- a/net/wireless/core.h +++ b/net/wireless/core.h -@@ -467,6 +467,8 @@ void cfg80211_set_dfs_state(struct wiphy +@@ -475,6 +475,8 @@ void cfg80211_set_dfs_state(struct wiphy enum nl80211_dfs_state dfs_state); void cfg80211_dfs_channels_update_work(struct work_struct *work); @@ -124,7 +124,7 @@ Signed-off-by: Felix Fietkau --- a/net/wireless/mlme.c +++ b/net/wireless/mlme.c -@@ -1037,6 +1037,8 @@ void cfg80211_dfs_channels_update_work(s +@@ -1032,6 +1032,8 @@ void cfg80211_dfs_channels_update_work(s if (c->dfs_state == NL80211_DFS_UNAVAILABLE) { time_dfs_update = IEEE80211_DFS_MIN_NOP_TIME_MS; radar_event = NL80211_RADAR_NOP_FINISHED; @@ -133,7 +133,7 @@ Signed-off-by: Felix Fietkau } else { if (regulatory_pre_cac_allowed(wiphy) || cfg80211_any_wiphy_oper_chan(wiphy, c)) -@@ -1044,11 +1046,10 @@ void cfg80211_dfs_channels_update_work(s +@@ -1039,11 +1041,10 @@ void cfg80211_dfs_channels_update_work(s time_dfs_update = REG_PRE_CAC_EXPIRY_GRACE_MS; radar_event = NL80211_RADAR_PRE_CAC_EXPIRED; diff --git a/package/kernel/mac80211/patches/subsys/320-mac80211-add-AQL-support-for-broadcast-packets.patch b/package/kernel/mac80211/patches/subsys/320-mac80211-add-AQL-support-for-broadcast-packets.patch index c03f40d9b4f5c2..6ec52af9a47539 100644 --- a/package/kernel/mac80211/patches/subsys/320-mac80211-add-AQL-support-for-broadcast-packets.patch +++ b/package/kernel/mac80211/patches/subsys/320-mac80211-add-AQL-support-for-broadcast-packets.patch @@ -12,7 +12,7 @@ Signed-off-by: Felix Fietkau --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h -@@ -3423,6 +3423,7 @@ enum wiphy_params_flags { +@@ -3426,6 +3426,7 @@ enum wiphy_params_flags { /* The per TXQ device queue limit in airtime */ #define IEEE80211_DEFAULT_AQL_TXQ_LIMIT_L 5000 #define IEEE80211_DEFAULT_AQL_TXQ_LIMIT_H 12000 @@ -70,7 +70,7 @@ Signed-off-by: Felix Fietkau --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h -@@ -1351,10 +1351,12 @@ struct ieee80211_local { +@@ -1360,10 +1360,12 @@ struct ieee80211_local { spinlock_t handle_wake_tx_queue_lock; u16 airtime_flags; @@ -85,7 +85,7 @@ Signed-off-by: Felix Fietkau const struct ieee80211_ops *ops; --- a/net/mac80211/main.c +++ b/net/mac80211/main.c -@@ -952,6 +952,7 @@ struct ieee80211_hw *ieee80211_alloc_hw_ +@@ -954,6 +954,7 @@ struct ieee80211_hw *ieee80211_alloc_hw_ spin_lock_init(&local->rx_path_lock); spin_lock_init(&local->queue_stop_reason_lock); @@ -95,7 +95,7 @@ Signed-off-by: Felix Fietkau spin_lock_init(&local->active_txq_lock[i]); --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c -@@ -2353,13 +2353,28 @@ EXPORT_SYMBOL(ieee80211_sta_recalc_aggre +@@ -2360,13 +2360,28 @@ EXPORT_SYMBOL(ieee80211_sta_recalc_aggre void ieee80211_sta_update_pending_airtime(struct ieee80211_local *local, struct sta_info *sta, u8 ac, @@ -136,7 +136,7 @@ Signed-off-by: Felix Fietkau spin_unlock_irqrestore(&local->ack_status_lock, flags); if (id >= 0) { -@@ -3982,20 +3982,20 @@ begin: +@@ -3983,20 +3983,20 @@ begin: encap_out: info->control.vif = vif; @@ -167,7 +167,7 @@ Signed-off-by: Felix Fietkau } return skb; -@@ -4047,6 +4047,7 @@ struct ieee80211_txq *ieee80211_next_txq +@@ -4048,6 +4048,7 @@ struct ieee80211_txq *ieee80211_next_txq struct ieee80211_txq *ret = NULL; struct txq_info *txqi = NULL, *head = NULL; bool found_eligible_txq = false; @@ -175,7 +175,7 @@ Signed-off-by: Felix Fietkau spin_lock_bh(&local->active_txq_lock[ac]); -@@ -4070,26 +4071,26 @@ struct ieee80211_txq *ieee80211_next_txq +@@ -4071,26 +4072,26 @@ struct ieee80211_txq *ieee80211_next_txq if (!head) head = txqi; @@ -214,7 +214,7 @@ Signed-off-by: Felix Fietkau if (txqi->schedule_round == local->schedule_round[ac]) goto out; -@@ -4154,7 +4155,8 @@ bool ieee80211_txq_airtime_check(struct +@@ -4157,7 +4158,8 @@ bool ieee80211_txq_airtime_check(struct return true; if (!txq->sta) @@ -224,7 +224,7 @@ Signed-off-by: Felix Fietkau if (unlikely(txq->tid == IEEE80211_NUM_TIDS)) return true; -@@ -4203,15 +4205,15 @@ bool ieee80211_txq_may_transmit(struct i +@@ -4206,15 +4208,15 @@ bool ieee80211_txq_may_transmit(struct i spin_lock_bh(&local->active_txq_lock[ac]); diff --git a/package/kernel/mac80211/patches/subsys/321-wifi-mac80211-do-not-pass-a-stopped-vif-to-the-drive.patch b/package/kernel/mac80211/patches/subsys/321-wifi-mac80211-do-not-pass-a-stopped-vif-to-the-drive.patch deleted file mode 100644 index f48fa38e5e96ab..00000000000000 --- a/package/kernel/mac80211/patches/subsys/321-wifi-mac80211-do-not-pass-a-stopped-vif-to-the-drive.patch +++ /dev/null @@ -1,24 +0,0 @@ -From: Felix Fietkau -Date: Wed, 2 Oct 2024 11:45:35 +0200 -Subject: [PATCH] wifi: mac80211: do not pass a stopped vif to the driver in - .get_txpower - -Avoid potentially crashing in the driver because of uninitialized private data - -Fixes: 5b3dc42b1b0d ("mac80211: add support for driver tx power reporting") -Cc: stable@vger.kernel.org -Signed-off-by: Felix Fietkau ---- - ---- a/net/mac80211/cfg.c -+++ b/net/mac80211/cfg.c -@@ -3134,7 +3134,8 @@ static int ieee80211_get_tx_power(struct - struct ieee80211_local *local = wiphy_priv(wiphy); - struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev); - -- if (local->ops->get_txpower) -+ if (local->ops->get_txpower && -+ (sdata->flags & IEEE80211_SDATA_IN_DRIVER)) - return drv_get_txpower(local, sdata, dbm); - - if (local->emulate_chanctx) diff --git a/package/kernel/mac80211/patches/subsys/350-wifi-cfg80211-add-option-for-vif-allowed-radios.patch b/package/kernel/mac80211/patches/subsys/330-wifi-cfg80211-add-option-for-vif-allowed-radios.patch similarity index 86% rename from package/kernel/mac80211/patches/subsys/350-wifi-cfg80211-add-option-for-vif-allowed-radios.patch rename to package/kernel/mac80211/patches/subsys/330-wifi-cfg80211-add-option-for-vif-allowed-radios.patch index d5b42f3a3a519d..dca56f8680fdc8 100644 --- a/package/kernel/mac80211/patches/subsys/350-wifi-cfg80211-add-option-for-vif-allowed-radios.patch +++ b/package/kernel/mac80211/patches/subsys/330-wifi-cfg80211-add-option-for-vif-allowed-radios.patch @@ -23,15 +23,15 @@ Signed-off-by: Felix Fietkau --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h -@@ -6227,6 +6227,7 @@ enum ieee80211_ap_reg_power { +@@ -6274,6 +6274,7 @@ enum ieee80211_ap_reg_power { * entered. - * @links[].cac_time_ms: CAC time in ms + * @links.cac_time_ms: CAC time in ms * @valid_links: bitmap describing what elements of @links are valid + * @radio_mask: Bitmask of radios that this interface is allowed to operate on. */ struct wireless_dev { struct wiphy *wiphy; -@@ -6339,6 +6340,8 @@ struct wireless_dev { +@@ -6386,6 +6387,8 @@ struct wireless_dev { unsigned int cac_time_ms; } links[IEEE80211_MLD_MAX_NUM_LINKS]; u16 valid_links; @@ -40,7 +40,7 @@ Signed-off-by: Felix Fietkau }; static inline const u8 *wdev_address(struct wireless_dev *wdev) -@@ -6525,6 +6528,17 @@ bool cfg80211_radio_chandef_valid(const +@@ -6572,6 +6575,17 @@ bool cfg80211_radio_chandef_valid(const const struct cfg80211_chan_def *chandef); /** @@ -81,7 +81,7 @@ Signed-off-by: Felix Fietkau __NL80211_ATTR_AFTER_LAST, --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c -@@ -829,6 +829,7 @@ static const struct nla_policy nl80211_p +@@ -832,6 +832,7 @@ static const struct nla_policy nl80211_p [NL80211_ATTR_MLO_TTLM_DLINK] = NLA_POLICY_EXACT_LEN(sizeof(u16) * 8), [NL80211_ATTR_MLO_TTLM_ULINK] = NLA_POLICY_EXACT_LEN(sizeof(u16) * 8), [NL80211_ATTR_ASSOC_SPP_AMSDU] = { .type = NLA_FLAG }, @@ -89,7 +89,7 @@ Signed-off-by: Felix Fietkau }; /* policy for the key attributes */ -@@ -3996,7 +3997,8 @@ static int nl80211_send_iface(struct sk_ +@@ -4003,7 +4004,8 @@ static int nl80211_send_iface(struct sk_ nla_put_u32(msg, NL80211_ATTR_GENERATION, rdev->devlist_generation ^ (cfg80211_rdev_list_generation << 2)) || @@ -99,7 +99,7 @@ Signed-off-by: Felix Fietkau goto nla_put_failure; if (rdev->ops->get_channel && !wdev->valid_links) { -@@ -4312,6 +4314,29 @@ static int nl80211_valid_4addr(struct cf +@@ -4324,6 +4326,29 @@ static int nl80211_valid_4addr(struct cf return -EOPNOTSUPP; } @@ -129,7 +129,7 @@ Signed-off-by: Felix Fietkau static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info) { struct cfg80211_registered_device *rdev = info->user_ptr[0]; -@@ -4319,6 +4344,8 @@ static int nl80211_set_interface(struct +@@ -4331,6 +4356,8 @@ static int nl80211_set_interface(struct int err; enum nl80211_iftype otype, ntype; struct net_device *dev = info->user_ptr[1]; @@ -138,7 +138,7 @@ Signed-off-by: Felix Fietkau bool change = false; memset(¶ms, 0, sizeof(params)); -@@ -4332,8 +4359,6 @@ static int nl80211_set_interface(struct +@@ -4344,8 +4371,6 @@ static int nl80211_set_interface(struct } if (info->attrs[NL80211_ATTR_MESH_ID]) { @@ -147,7 +147,7 @@ Signed-off-by: Felix Fietkau if (ntype != NL80211_IFTYPE_MESH_POINT) return -EINVAL; if (otype != NL80211_IFTYPE_MESH_POINT) -@@ -4364,6 +4389,12 @@ static int nl80211_set_interface(struct +@@ -4376,6 +4401,12 @@ static int nl80211_set_interface(struct if (err > 0) change = true; @@ -160,7 +160,7 @@ Signed-off-by: Felix Fietkau if (change) err = cfg80211_change_iface(rdev, dev, ntype, ¶ms); else -@@ -4372,11 +4403,11 @@ static int nl80211_set_interface(struct +@@ -4384,11 +4415,11 @@ static int nl80211_set_interface(struct if (!err && params.use_4addr != -1) dev->ieee80211_ptr->use_4addr = params.use_4addr; @@ -175,7 +175,7 @@ Signed-off-by: Felix Fietkau return err; } -@@ -4387,6 +4418,7 @@ static int _nl80211_new_interface(struct +@@ -4399,6 +4430,7 @@ static int _nl80211_new_interface(struct struct vif_params params; struct wireless_dev *wdev; struct sk_buff *msg; @@ -183,7 +183,7 @@ Signed-off-by: Felix Fietkau int err; enum nl80211_iftype type = NL80211_IFTYPE_UNSPECIFIED; -@@ -4424,6 +4456,10 @@ static int _nl80211_new_interface(struct +@@ -4436,6 +4468,10 @@ static int _nl80211_new_interface(struct if (err < 0) return err; @@ -194,7 +194,7 @@ Signed-off-by: Felix Fietkau msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); if (!msg) return -ENOMEM; -@@ -4465,6 +4501,9 @@ static int _nl80211_new_interface(struct +@@ -4477,6 +4513,9 @@ static int _nl80211_new_interface(struct break; } @@ -204,7 +204,7 @@ Signed-off-by: Felix Fietkau if (nl80211_send_iface(msg, info->snd_portid, info->snd_seq, 0, rdev, wdev, NL80211_CMD_NEW_INTERFACE) < 0) { nlmsg_free(msg); -@@ -9180,6 +9219,9 @@ static bool cfg80211_off_channel_oper_al +@@ -9192,6 +9231,9 @@ static bool cfg80211_off_channel_oper_al lockdep_assert_wiphy(wdev->wiphy); @@ -214,7 +214,7 @@ Signed-off-by: Felix Fietkau if (!cfg80211_beaconing_iface_active(wdev)) return true; -@@ -9392,7 +9434,8 @@ static int nl80211_trigger_scan(struct s +@@ -9404,7 +9446,8 @@ static int nl80211_trigger_scan(struct s } /* ignore disabled channels */ @@ -224,7 +224,7 @@ Signed-off-by: Felix Fietkau continue; request->channels[i] = chan; -@@ -9412,7 +9455,8 @@ static int nl80211_trigger_scan(struct s +@@ -9424,7 +9467,8 @@ static int nl80211_trigger_scan(struct s chan = &wiphy->bands[band]->channels[j]; @@ -236,7 +236,7 @@ Signed-off-by: Felix Fietkau request->channels[i] = chan; --- a/net/wireless/scan.c +++ b/net/wireless/scan.c -@@ -956,7 +956,8 @@ static int cfg80211_scan_6ghz(struct cfg +@@ -953,7 +953,8 @@ static int cfg80211_scan_6ghz(struct cfg struct ieee80211_channel *chan = ieee80211_get_channel(&rdev->wiphy, ap->center_freq); @@ -246,7 +246,7 @@ Signed-off-by: Felix Fietkau continue; for (i = 0; i < rdev_req->n_channels; i++) { -@@ -3490,9 +3491,12 @@ int cfg80211_wext_siwscan(struct net_dev +@@ -3512,9 +3513,12 @@ int cfg80211_wext_siwscan(struct net_dev continue; for (j = 0; j < wiphy->bands[band]->n_channels; j++) { @@ -263,7 +263,7 @@ Signed-off-by: Felix Fietkau /* If we have a wireless request structure and the --- a/net/wireless/util.c +++ b/net/wireless/util.c -@@ -2923,3 +2923,32 @@ bool cfg80211_radio_chandef_valid(const +@@ -2970,3 +2970,32 @@ bool cfg80211_radio_chandef_valid(const return true; } EXPORT_SYMBOL(cfg80211_radio_chandef_valid); @@ -298,7 +298,7 @@ Signed-off-by: Felix Fietkau +EXPORT_SYMBOL(cfg80211_wdev_channel_allowed); --- a/net/wireless/core.c +++ b/net/wireless/core.c -@@ -1415,6 +1415,8 @@ void cfg80211_init_wdev(struct wireless_ +@@ -1431,6 +1431,8 @@ void cfg80211_init_wdev(struct wireless_ /* allow mac80211 to determine the timeout */ wdev->ps_timeout = -1; diff --git a/package/kernel/mac80211/patches/subsys/330-wifi-mac80211-introduce-EHT-rate-support-in-AQL-airt.patch b/package/kernel/mac80211/patches/subsys/330-wifi-mac80211-introduce-EHT-rate-support-in-AQL-airt.patch deleted file mode 100644 index 0a3c8ec53b21a3..00000000000000 --- a/package/kernel/mac80211/patches/subsys/330-wifi-mac80211-introduce-EHT-rate-support-in-AQL-airt.patch +++ /dev/null @@ -1,233 +0,0 @@ -From: Ming Yen Hsieh -Date: Wed, 4 Sep 2024 19:12:56 +0800 -Subject: [PATCH] wifi: mac80211: introduce EHT rate support in AQL airtime - -Add definitions related to EHT mode and airtime calculation -according to the 802.11BE_D4.0. - -Co-developed-by: Bo Jiao -Signed-off-by: Bo Jiao -Signed-off-by: Deren Wu -Signed-off-by: Quan Zhou -Signed-off-by: Ming Yen Hsieh -Link: https://patch.msgid.link/20240904111256.11734-1-mingyen.hsieh@mediatek.com -Signed-off-by: Johannes Berg ---- - ---- a/net/mac80211/airtime.c -+++ b/net/mac80211/airtime.c -@@ -55,10 +55,21 @@ - #define HE_DURATION_S(shift, streams, gi, bps) \ - (HE_DURATION(streams, gi, bps) >> shift) - -+/* gi in HE/EHT is identical. It matches enum nl80211_eht_gi as well */ -+#define EHT_GI_08 HE_GI_08 -+#define EHT_GI_16 HE_GI_16 -+#define EHT_GI_32 HE_GI_32 -+ -+#define EHT_DURATION(streams, gi, bps) \ -+ HE_DURATION(streams, gi, bps) -+#define EHT_DURATION_S(shift, streams, gi, bps) \ -+ HE_DURATION_S(shift, streams, gi, bps) -+ - #define BW_20 0 - #define BW_40 1 - #define BW_80 2 - #define BW_160 3 -+#define BW_320 4 - - /* - * Define group sort order: HT40 -> SGI -> #streams -@@ -68,17 +79,26 @@ - #define IEEE80211_VHT_STREAM_GROUPS 8 /* BW(=4) * SGI(=2) */ - - #define IEEE80211_HE_MAX_STREAMS 8 -+#define IEEE80211_HE_STREAM_GROUPS 12 /* BW(=4) * GI(=3) */ -+ -+#define IEEE80211_EHT_MAX_STREAMS 8 -+#define IEEE80211_EHT_STREAM_GROUPS 15 /* BW(=5) * GI(=3) */ - - #define IEEE80211_HT_GROUPS_NB (IEEE80211_MAX_STREAMS * \ - IEEE80211_HT_STREAM_GROUPS) - #define IEEE80211_VHT_GROUPS_NB (IEEE80211_MAX_STREAMS * \ - IEEE80211_VHT_STREAM_GROUPS) -+#define IEEE80211_HE_GROUPS_NB (IEEE80211_HE_MAX_STREAMS * \ -+ IEEE80211_HE_STREAM_GROUPS) -+#define IEEE80211_EHT_GROUPS_NB (IEEE80211_EHT_MAX_STREAMS * \ -+ IEEE80211_EHT_STREAM_GROUPS) - - #define IEEE80211_HT_GROUP_0 0 - #define IEEE80211_VHT_GROUP_0 (IEEE80211_HT_GROUP_0 + IEEE80211_HT_GROUPS_NB) - #define IEEE80211_HE_GROUP_0 (IEEE80211_VHT_GROUP_0 + IEEE80211_VHT_GROUPS_NB) -+#define IEEE80211_EHT_GROUP_0 (IEEE80211_HE_GROUP_0 + IEEE80211_HE_GROUPS_NB) - --#define MCS_GROUP_RATES 12 -+#define MCS_GROUP_RATES 14 - - #define HT_GROUP_IDX(_streams, _sgi, _ht40) \ - IEEE80211_HT_GROUP_0 + \ -@@ -203,6 +223,69 @@ - #define HE_GROUP(_streams, _gi, _bw) \ - __HE_GROUP(_streams, _gi, _bw, \ - HE_GROUP_SHIFT(_streams, _gi, _bw)) -+ -+#define EHT_BW2VBPS(_bw, r5, r4, r3, r2, r1) \ -+ ((_bw) == BW_320 ? r5 : BW2VBPS(_bw, r4, r3, r2, r1)) -+ -+#define EHT_GROUP_IDX(_streams, _gi, _bw) \ -+ (IEEE80211_EHT_GROUP_0 + \ -+ IEEE80211_EHT_MAX_STREAMS * 3 * (_bw) + \ -+ IEEE80211_EHT_MAX_STREAMS * (_gi) + \ -+ (_streams) - 1) -+ -+#define __EHT_GROUP(_streams, _gi, _bw, _s) \ -+ [EHT_GROUP_IDX(_streams, _gi, _bw)] = { \ -+ .shift = _s, \ -+ .duration = { \ -+ EHT_DURATION_S(_s, _streams, _gi, \ -+ EHT_BW2VBPS(_bw, 1960, 980, 490, 234, 117)), \ -+ EHT_DURATION_S(_s, _streams, _gi, \ -+ EHT_BW2VBPS(_bw, 3920, 1960, 980, 468, 234)), \ -+ EHT_DURATION_S(_s, _streams, _gi, \ -+ EHT_BW2VBPS(_bw, 5880, 2937, 1470, 702, 351)), \ -+ EHT_DURATION_S(_s, _streams, _gi, \ -+ EHT_BW2VBPS(_bw, 7840, 3920, 1960, 936, 468)), \ -+ EHT_DURATION_S(_s, _streams, _gi, \ -+ EHT_BW2VBPS(_bw, 11760, 5880, 2940, 1404, 702)), \ -+ EHT_DURATION_S(_s, _streams, _gi, \ -+ EHT_BW2VBPS(_bw, 15680, 7840, 3920, 1872, 936)), \ -+ EHT_DURATION_S(_s, _streams, _gi, \ -+ EHT_BW2VBPS(_bw, 17640, 8820, 4410, 2106, 1053)), \ -+ EHT_DURATION_S(_s, _streams, _gi, \ -+ EHT_BW2VBPS(_bw, 19600, 9800, 4900, 2340, 1170)), \ -+ EHT_DURATION_S(_s, _streams, _gi, \ -+ EHT_BW2VBPS(_bw, 23520, 11760, 5880, 2808, 1404)), \ -+ EHT_DURATION_S(_s, _streams, _gi, \ -+ EHT_BW2VBPS(_bw, 26133, 13066, 6533, 3120, 1560)), \ -+ EHT_DURATION_S(_s, _streams, _gi, \ -+ EHT_BW2VBPS(_bw, 29400, 14700, 7350, 3510, 1755)), \ -+ EHT_DURATION_S(_s, _streams, _gi, \ -+ EHT_BW2VBPS(_bw, 32666, 16333, 8166, 3900, 1950)), \ -+ EHT_DURATION_S(_s, _streams, _gi, \ -+ EHT_BW2VBPS(_bw, 35280, 17640, 8820, 4212, 2106)), \ -+ EHT_DURATION_S(_s, _streams, _gi, \ -+ EHT_BW2VBPS(_bw, 39200, 19600, 9800, 4680, 2340)) \ -+ } \ -+} -+ -+#define EHT_GROUP_SHIFT(_streams, _gi, _bw) \ -+ GROUP_SHIFT(EHT_DURATION(_streams, _gi, \ -+ EHT_BW2VBPS(_bw, 1960, 980, 490, 234, 117))) -+ -+#define EHT_GROUP(_streams, _gi, _bw) \ -+ __EHT_GROUP(_streams, _gi, _bw, \ -+ EHT_GROUP_SHIFT(_streams, _gi, _bw)) -+ -+#define EHT_GROUP_RANGE(_gi, _bw) \ -+ EHT_GROUP(1, _gi, _bw), \ -+ EHT_GROUP(2, _gi, _bw), \ -+ EHT_GROUP(3, _gi, _bw), \ -+ EHT_GROUP(4, _gi, _bw), \ -+ EHT_GROUP(5, _gi, _bw), \ -+ EHT_GROUP(6, _gi, _bw), \ -+ EHT_GROUP(7, _gi, _bw), \ -+ EHT_GROUP(8, _gi, _bw) -+ - struct mcs_group { - u8 shift; - u16 duration[MCS_GROUP_RATES]; -@@ -376,6 +459,26 @@ static const struct mcs_group airtime_mc - HE_GROUP(6, HE_GI_32, BW_160), - HE_GROUP(7, HE_GI_32, BW_160), - HE_GROUP(8, HE_GI_32, BW_160), -+ -+ EHT_GROUP_RANGE(EHT_GI_08, BW_20), -+ EHT_GROUP_RANGE(EHT_GI_16, BW_20), -+ EHT_GROUP_RANGE(EHT_GI_32, BW_20), -+ -+ EHT_GROUP_RANGE(EHT_GI_08, BW_40), -+ EHT_GROUP_RANGE(EHT_GI_16, BW_40), -+ EHT_GROUP_RANGE(EHT_GI_32, BW_40), -+ -+ EHT_GROUP_RANGE(EHT_GI_08, BW_80), -+ EHT_GROUP_RANGE(EHT_GI_16, BW_80), -+ EHT_GROUP_RANGE(EHT_GI_32, BW_80), -+ -+ EHT_GROUP_RANGE(EHT_GI_08, BW_160), -+ EHT_GROUP_RANGE(EHT_GI_16, BW_160), -+ EHT_GROUP_RANGE(EHT_GI_32, BW_160), -+ -+ EHT_GROUP_RANGE(EHT_GI_08, BW_320), -+ EHT_GROUP_RANGE(EHT_GI_16, BW_320), -+ EHT_GROUP_RANGE(EHT_GI_32, BW_320), - }; - - static u32 -@@ -422,6 +525,9 @@ static u32 ieee80211_get_rate_duration(s - case RATE_INFO_BW_160: - bw = BW_160; - break; -+ case RATE_INFO_BW_320: -+ bw = BW_320; -+ break; - default: - WARN_ON_ONCE(1); - return 0; -@@ -443,14 +549,27 @@ static u32 ieee80211_get_rate_duration(s - idx = status->rate_idx; - group = HE_GROUP_IDX(streams, status->he_gi, bw); - break; -+ case RX_ENC_EHT: -+ streams = status->nss; -+ idx = status->rate_idx; -+ group = EHT_GROUP_IDX(streams, status->eht.gi, bw); -+ break; - default: - WARN_ON_ONCE(1); - return 0; - } - -- if (WARN_ON_ONCE((status->encoding != RX_ENC_HE && streams > 4) || -- (status->encoding == RX_ENC_HE && streams > 8))) -- return 0; -+ switch (status->encoding) { -+ case RX_ENC_EHT: -+ case RX_ENC_HE: -+ if (WARN_ON_ONCE(streams > 8)) -+ return 0; -+ break; -+ default: -+ if (WARN_ON_ONCE(streams > 4)) -+ return 0; -+ break; -+ } - - if (idx >= MCS_GROUP_RATES) - return 0; -@@ -517,7 +636,9 @@ static bool ieee80211_fill_rate_info(str - stat->nss = ri->nss; - stat->rate_idx = ri->mcs; - -- if (ri->flags & RATE_INFO_FLAGS_HE_MCS) -+ if (ri->flags & RATE_INFO_FLAGS_EHT_MCS) -+ stat->encoding = RX_ENC_EHT; -+ else if (ri->flags & RATE_INFO_FLAGS_HE_MCS) - stat->encoding = RX_ENC_HE; - else if (ri->flags & RATE_INFO_FLAGS_VHT_MCS) - stat->encoding = RX_ENC_VHT; -@@ -529,7 +650,14 @@ static bool ieee80211_fill_rate_info(str - if (ri->flags & RATE_INFO_FLAGS_SHORT_GI) - stat->enc_flags |= RX_ENC_FLAG_SHORT_GI; - -- stat->he_gi = ri->he_gi; -+ switch (stat->encoding) { -+ case RX_ENC_EHT: -+ stat->eht.gi = ri->eht_gi; -+ break; -+ default: -+ stat->he_gi = ri->he_gi; -+ break; -+ } - - if (stat->encoding != RX_ENC_LEGACY) - return true; diff --git a/package/kernel/mac80211/patches/subsys/331-wifi-cfg80211-check-radio-iface-combination-for-mult.patch b/package/kernel/mac80211/patches/subsys/331-wifi-cfg80211-check-radio-iface-combination-for-mult.patch deleted file mode 100644 index 76c351aa831f59..00000000000000 --- a/package/kernel/mac80211/patches/subsys/331-wifi-cfg80211-check-radio-iface-combination-for-mult.patch +++ /dev/null @@ -1,122 +0,0 @@ -From: Karthikeyan Periyasamy -Date: Tue, 17 Sep 2024 19:32:39 +0530 -Subject: [PATCH] wifi: cfg80211: check radio iface combination for multi radio - per wiphy - -Currently, wiphy_verify_combinations() fails for the multi-radio per wiphy -due to the condition check on new global interface combination that DFS -only works on one channel. In a multi-radio scenario, new global interface -combination encompasses the capabilities of all radio combinations, so it -supports more than one channel with DFS. For multi-radio per wiphy, -interface combination verification needs to be performed for radio specific -interface combinations. This is necessary as the new global interface -combination combines the capabilities of all radio combinations. - -Fixes: a01b1e9f9955 ("wifi: mac80211: add support for DFS with multiple radios") -Signed-off-by: Karthikeyan Periyasamy ---- - ---- a/net/wireless/core.c -+++ b/net/wireless/core.c -@@ -599,16 +599,20 @@ use_default_name: - } - EXPORT_SYMBOL(wiphy_new_nm); - --static int wiphy_verify_combinations(struct wiphy *wiphy) -+static -+int wiphy_verify_iface_combinations(struct wiphy *wiphy, -+ const struct ieee80211_iface_combination *iface_comb, -+ int n_iface_comb, -+ bool combined_radio) - { - const struct ieee80211_iface_combination *c; - int i, j; - -- for (i = 0; i < wiphy->n_iface_combinations; i++) { -+ for (i = 0; i < n_iface_comb; i++) { - u32 cnt = 0; - u16 all_iftypes = 0; - -- c = &wiphy->iface_combinations[i]; -+ c = &iface_comb[i]; - - /* - * Combinations with just one interface aren't real, -@@ -621,9 +625,13 @@ static int wiphy_verify_combinations(str - if (WARN_ON(!c->num_different_channels)) - return -EINVAL; - -- /* DFS only works on one channel. */ -- if (WARN_ON(c->radar_detect_widths && -- (c->num_different_channels > 1))) -+ /* DFS only works on one channel. Avoid this check -+ * for multi-radio global combination, since it hold -+ * the capabilities of all radio combinations. -+ */ -+ if (!combined_radio && -+ WARN_ON(c->radar_detect_widths && -+ c->num_different_channels > 1)) - return -EINVAL; - - if (WARN_ON(!c->n_limits)) -@@ -644,13 +652,21 @@ static int wiphy_verify_combinations(str - if (WARN_ON(wiphy->software_iftypes & types)) - return -EINVAL; - -- /* Only a single P2P_DEVICE can be allowed */ -- if (WARN_ON(types & BIT(NL80211_IFTYPE_P2P_DEVICE) && -+ /* Only a single P2P_DEVICE can be allowed, avoid this -+ * check for multi-radio global combination, since it -+ * hold the capabilities of all radio combinations. -+ */ -+ if (!combined_radio && -+ WARN_ON(types & BIT(NL80211_IFTYPE_P2P_DEVICE) && - c->limits[j].max > 1)) - return -EINVAL; - -- /* Only a single NAN can be allowed */ -- if (WARN_ON(types & BIT(NL80211_IFTYPE_NAN) && -+ /* Only a single NAN can be allowed, avoid this -+ * check for multi-radio global combination, since it -+ * hold the capabilities of all radio combinations. -+ */ -+ if (!combined_radio && -+ WARN_ON(types & BIT(NL80211_IFTYPE_NAN) && - c->limits[j].max > 1)) - return -EINVAL; - -@@ -674,6 +690,34 @@ static int wiphy_verify_combinations(str - return 0; - } - -+static int wiphy_verify_combinations(struct wiphy *wiphy) -+{ -+ int i, ret; -+ bool combined_radio = false; -+ -+ if (wiphy->n_radio) { -+ for (i = 0; i < wiphy->n_radio; i++) { -+ const struct wiphy_radio *radio = &wiphy->radio[i]; -+ -+ ret = wiphy_verify_iface_combinations(wiphy, -+ radio->iface_combinations, -+ radio->n_iface_combinations, -+ false); -+ if (ret) -+ return ret; -+ } -+ -+ combined_radio = true; -+ } -+ -+ ret = wiphy_verify_iface_combinations(wiphy, -+ wiphy->iface_combinations, -+ wiphy->n_iface_combinations, -+ combined_radio); -+ -+ return ret; -+} -+ - int wiphy_register(struct wiphy *wiphy) - { - struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy); diff --git a/package/kernel/mac80211/patches/subsys/351-wifi-mac80211-use-vif-radio-mask-to-limit-ibss-scan-.patch b/package/kernel/mac80211/patches/subsys/331-wifi-mac80211-use-vif-radio-mask-to-limit-ibss-scan-.patch similarity index 88% rename from package/kernel/mac80211/patches/subsys/351-wifi-mac80211-use-vif-radio-mask-to-limit-ibss-scan-.patch rename to package/kernel/mac80211/patches/subsys/331-wifi-mac80211-use-vif-radio-mask-to-limit-ibss-scan-.patch index 7363c3873f6a2e..fd31a00dc5d7a9 100644 --- a/package/kernel/mac80211/patches/subsys/351-wifi-mac80211-use-vif-radio-mask-to-limit-ibss-scan-.patch +++ b/package/kernel/mac80211/patches/subsys/331-wifi-mac80211-use-vif-radio-mask-to-limit-ibss-scan-.patch @@ -10,7 +10,7 @@ Signed-off-by: Felix Fietkau --- a/net/mac80211/scan.c +++ b/net/mac80211/scan.c -@@ -1178,14 +1178,14 @@ int ieee80211_request_ibss_scan(struct i +@@ -1175,14 +1175,14 @@ int ieee80211_request_ibss_scan(struct i unsigned int n_channels) { struct ieee80211_local *local = sdata->local; @@ -27,7 +27,7 @@ Signed-off-by: Felix Fietkau /* fill internal scan request */ if (!channels) { -@@ -1202,7 +1202,9 @@ int ieee80211_request_ibss_scan(struct i +@@ -1199,7 +1199,9 @@ int ieee80211_request_ibss_scan(struct i &local->hw.wiphy->bands[band]->channels[i]; if (tmp_ch->flags & (IEEE80211_CHAN_NO_IR | @@ -38,7 +38,7 @@ Signed-off-by: Felix Fietkau continue; local->int_scan_req->channels[n_ch] = tmp_ch; -@@ -1211,21 +1213,23 @@ int ieee80211_request_ibss_scan(struct i +@@ -1208,21 +1210,23 @@ int ieee80211_request_ibss_scan(struct i } if (WARN_ON_ONCE(n_ch == 0)) @@ -66,7 +66,7 @@ Signed-off-by: Felix Fietkau local->int_scan_req->n_channels = n_ch; } -@@ -1235,9 +1239,7 @@ int ieee80211_request_ibss_scan(struct i +@@ -1232,9 +1236,7 @@ int ieee80211_request_ibss_scan(struct i memcpy(local->int_scan_req->ssids[0].ssid, ssid, IEEE80211_MAX_SSID_LEN); local->int_scan_req->ssids[0].ssid_len = ssid_len; diff --git a/package/kernel/mac80211/patches/subsys/332-wifi-cfg80211-Set-correct-chandef-when-starting-CAC.patch b/package/kernel/mac80211/patches/subsys/332-wifi-cfg80211-Set-correct-chandef-when-starting-CAC.patch deleted file mode 100644 index 72a3510aacfff1..00000000000000 --- a/package/kernel/mac80211/patches/subsys/332-wifi-cfg80211-Set-correct-chandef-when-starting-CAC.patch +++ /dev/null @@ -1,64 +0,0 @@ -From: Issam Hamdi -Date: Fri, 16 Aug 2024 16:24:18 +0200 -Subject: [PATCH] wifi: cfg80211: Set correct chandef when starting CAC - -When starting CAC in a mode other than AP mode, it return a -"WARNING: CPU: 0 PID: 63 at cfg80211_chandef_dfs_usable+0x20/0xaf [cfg80211]" -caused by the chandef.chan being null at the end of CAC. - -Solution: Ensure the channel definition is set for the different modes -when starting CAC to avoid getting a NULL 'chan' at the end of CAC. - - Call Trace: - ? show_regs.part.0+0x14/0x16 - ? __warn+0x67/0xc0 - ? cfg80211_chandef_dfs_usable+0x20/0xaf [cfg80211] - ? report_bug+0xa7/0x130 - ? exc_overflow+0x30/0x30 - ? handle_bug+0x27/0x50 - ? exc_invalid_op+0x18/0x60 - ? handle_exception+0xf6/0xf6 - ? exc_overflow+0x30/0x30 - ? cfg80211_chandef_dfs_usable+0x20/0xaf [cfg80211] - ? exc_overflow+0x30/0x30 - ? cfg80211_chandef_dfs_usable+0x20/0xaf [cfg80211] - ? regulatory_propagate_dfs_state.cold+0x1b/0x4c [cfg80211] - ? cfg80211_propagate_cac_done_wk+0x1a/0x30 [cfg80211] - ? process_one_work+0x165/0x280 - ? worker_thread+0x120/0x3f0 - ? kthread+0xc2/0xf0 - ? process_one_work+0x280/0x280 - ? kthread_complete_and_exit+0x20/0x20 - ? ret_from_fork+0x19/0x24 - -Reported-by: Kretschmer Mathias -Signed-off-by: Issam Hamdi -Link: https://patch.msgid.link/20240816142418.3381951-1-ih@simonwunderlich.de -[shorten subject, remove OCB, reorder cases to match previous list] -Signed-off-by: Johannes Berg ---- - ---- a/net/wireless/nl80211.c -+++ b/net/wireless/nl80211.c -@@ -10144,7 +10144,20 @@ static int nl80211_start_radar_detection - - err = rdev_start_radar_detection(rdev, dev, &chandef, cac_time_ms); - if (!err) { -- wdev->links[0].ap.chandef = chandef; -+ switch (wdev->iftype) { -+ case NL80211_IFTYPE_AP: -+ case NL80211_IFTYPE_P2P_GO: -+ wdev->links[0].ap.chandef = chandef; -+ break; -+ case NL80211_IFTYPE_ADHOC: -+ wdev->u.ibss.chandef = chandef; -+ break; -+ case NL80211_IFTYPE_MESH_POINT: -+ wdev->u.mesh.chandef = chandef; -+ break; -+ default: -+ break; -+ } - wdev->cac_started = true; - wdev->cac_start_time = jiffies; - wdev->cac_time_ms = cac_time_ms; diff --git a/package/kernel/mac80211/patches/subsys/352-wifi-mac80211-use-vif-radio-mask-to-limit-chanctx-an.patch b/package/kernel/mac80211/patches/subsys/332-wifi-mac80211-use-vif-radio-mask-to-limit-chanctx-an.patch similarity index 86% rename from package/kernel/mac80211/patches/subsys/352-wifi-mac80211-use-vif-radio-mask-to-limit-chanctx-an.patch rename to package/kernel/mac80211/patches/subsys/332-wifi-mac80211-use-vif-radio-mask-to-limit-chanctx-an.patch index ac3d1011489a1b..04d2f2291ac2e7 100644 --- a/package/kernel/mac80211/patches/subsys/352-wifi-mac80211-use-vif-radio-mask-to-limit-chanctx-an.patch +++ b/package/kernel/mac80211/patches/subsys/332-wifi-mac80211-use-vif-radio-mask-to-limit-chanctx-an.patch @@ -9,7 +9,7 @@ Signed-off-by: Felix Fietkau --- a/net/mac80211/chan.c +++ b/net/mac80211/chan.c -@@ -1167,7 +1167,7 @@ ieee80211_replace_chanctx(struct ieee802 +@@ -1169,7 +1169,7 @@ ieee80211_replace_chanctx(struct ieee802 static bool ieee80211_find_available_radio(struct ieee80211_local *local, const struct ieee80211_chan_req *chanreq, @@ -18,7 +18,7 @@ Signed-off-by: Felix Fietkau { struct wiphy *wiphy = local->hw.wiphy; const struct wiphy_radio *radio; -@@ -1178,6 +1178,9 @@ ieee80211_find_available_radio(struct ie +@@ -1180,6 +1180,9 @@ ieee80211_find_available_radio(struct ie return true; for (i = 0; i < wiphy->n_radio; i++) { @@ -28,7 +28,7 @@ Signed-off-by: Felix Fietkau radio = &wiphy->radio[i]; if (!cfg80211_radio_chandef_valid(radio, &chanreq->oper)) continue; -@@ -1211,7 +1214,9 @@ int ieee80211_link_reserve_chanctx(struc +@@ -1213,7 +1216,9 @@ int ieee80211_link_reserve_chanctx(struc new_ctx = ieee80211_find_reservation_chanctx(local, chanreq, mode); if (!new_ctx) { if (ieee80211_can_create_new_chanctx(local, -1) && @@ -39,7 +39,7 @@ Signed-off-by: Felix Fietkau new_ctx = ieee80211_new_chanctx(local, chanreq, mode, false, radio_idx); else -@@ -1881,7 +1886,9 @@ int _ieee80211_link_use_channel(struct i +@@ -1884,7 +1889,9 @@ int _ieee80211_link_use_channel(struct i /* Note: context is now reserved */ if (ctx) reserved = true; diff --git a/package/kernel/mac80211/patches/subsys/333-Revert-wifi-mac80211-move-radar-detect-work-to-sdata.patch b/package/kernel/mac80211/patches/subsys/333-Revert-wifi-mac80211-move-radar-detect-work-to-sdata.patch deleted file mode 100644 index d12df8f53ea8b6..00000000000000 --- a/package/kernel/mac80211/patches/subsys/333-Revert-wifi-mac80211-move-radar-detect-work-to-sdata.patch +++ /dev/null @@ -1,136 +0,0 @@ -From: Aditya Kumar Singh -Date: Fri, 6 Sep 2024 12:14:19 +0530 -Subject: [PATCH] Revert "wifi: mac80211: move radar detect work to sdata" -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -This reverts commit ce9e660ef32e ("wifi: mac80211: move radar detect work to sdata"). - -To enable radar detection with MLO, it’s essential to handle it on a -per-link basis. This is because when using MLO, multiple links may already -be active and beaconing. In this scenario, another link should be able to -initiate a radar detection. Also, if underlying links are associated with -different hardware devices but grouped together for MLO, they could -potentially start radar detection simultaneously. Therefore, it makes -sense to manage radar detection settings separately for each link by moving -them back to a per-link data structure. - -Signed-off-by: Aditya Kumar Singh -Link: https://patch.msgid.link/20240906064426.2101315-2-quic_adisi@quicinc.com -Signed-off-by: Johannes Berg ---- - ---- a/net/mac80211/cfg.c -+++ b/net/mac80211/cfg.c -@@ -1658,7 +1658,7 @@ static int ieee80211_stop_ap(struct wiph - - if (sdata->wdev.cac_started) { - chandef = link_conf->chanreq.oper; -- wiphy_delayed_work_cancel(wiphy, &sdata->dfs_cac_timer_work); -+ wiphy_delayed_work_cancel(wiphy, &link->dfs_cac_timer_work); - cfg80211_cac_event(sdata->dev, &chandef, - NL80211_RADAR_CAC_ABORTED, - GFP_KERNEL); -@@ -3482,7 +3482,7 @@ static int ieee80211_start_radar_detecti - if (err) - goto out_unlock; - -- wiphy_delayed_work_queue(wiphy, &sdata->dfs_cac_timer_work, -+ wiphy_delayed_work_queue(wiphy, &sdata->deflink.dfs_cac_timer_work, - msecs_to_jiffies(cac_time_ms)); - - out_unlock: -@@ -3499,7 +3499,7 @@ static void ieee80211_end_cac(struct wip - - list_for_each_entry(sdata, &local->interfaces, list) { - wiphy_delayed_work_cancel(wiphy, -- &sdata->dfs_cac_timer_work); -+ &sdata->deflink.dfs_cac_timer_work); - - if (sdata->wdev.cac_started) { - ieee80211_link_release_channel(&sdata->deflink); ---- a/net/mac80211/ieee80211_i.h -+++ b/net/mac80211/ieee80211_i.h -@@ -1069,6 +1069,7 @@ struct ieee80211_link_data { - int ap_power_level; /* in dBm */ - - bool radar_required; -+ struct wiphy_delayed_work dfs_cac_timer_work; - - union { - struct ieee80211_link_data_managed mgd; -@@ -1167,8 +1168,6 @@ struct ieee80211_sub_if_data { - struct ieee80211_link_data deflink; - struct ieee80211_link_data __rcu *link[IEEE80211_MLD_MAX_NUM_LINKS]; - -- struct wiphy_delayed_work dfs_cac_timer_work; -- - /* for ieee80211_set_active_links_async() */ - struct wiphy_work activate_links_work; - u16 desired_active_links; ---- a/net/mac80211/iface.c -+++ b/net/mac80211/iface.c -@@ -551,7 +551,7 @@ static void ieee80211_do_stop(struct iee - wiphy_work_cancel(local->hw.wiphy, - &sdata->deflink.color_change_finalize_work); - wiphy_delayed_work_cancel(local->hw.wiphy, -- &sdata->dfs_cac_timer_work); -+ &sdata->deflink.dfs_cac_timer_work); - - if (sdata->wdev.cac_started) { - chandef = sdata->vif.bss_conf.chanreq.oper; -@@ -1744,8 +1744,6 @@ static void ieee80211_setup_sdata(struct - wiphy_work_init(&sdata->work, ieee80211_iface_work); - wiphy_work_init(&sdata->activate_links_work, - ieee80211_activate_links_work); -- wiphy_delayed_work_init(&sdata->dfs_cac_timer_work, -- ieee80211_dfs_cac_timer_work); - - switch (type) { - case NL80211_IFTYPE_P2P_GO: ---- a/net/mac80211/link.c -+++ b/net/mac80211/link.c -@@ -45,6 +45,8 @@ void ieee80211_link_init(struct ieee8021 - ieee80211_color_collision_detection_work); - INIT_LIST_HEAD(&link->assigned_chanctx_list); - INIT_LIST_HEAD(&link->reserved_chanctx_list); -+ wiphy_delayed_work_init(&link->dfs_cac_timer_work, -+ ieee80211_dfs_cac_timer_work); - - if (!deflink) { - switch (sdata->vif.type) { ---- a/net/mac80211/mlme.c -+++ b/net/mac80211/mlme.c -@@ -3031,15 +3031,16 @@ void ieee80211_dynamic_ps_timer(struct t - - void ieee80211_dfs_cac_timer_work(struct wiphy *wiphy, struct wiphy_work *work) - { -- struct ieee80211_sub_if_data *sdata = -- container_of(work, struct ieee80211_sub_if_data, -+ struct ieee80211_link_data *link = -+ container_of(work, struct ieee80211_link_data, - dfs_cac_timer_work.work); -- struct cfg80211_chan_def chandef = sdata->vif.bss_conf.chanreq.oper; -+ struct cfg80211_chan_def chandef = link->conf->chanreq.oper; -+ struct ieee80211_sub_if_data *sdata = link->sdata; - - lockdep_assert_wiphy(sdata->local->hw.wiphy); - - if (sdata->wdev.cac_started) { -- ieee80211_link_release_channel(&sdata->deflink); -+ ieee80211_link_release_channel(link); - cfg80211_cac_event(sdata->dev, &chandef, - NL80211_RADAR_CAC_FINISHED, - GFP_KERNEL); ---- a/net/mac80211/util.c -+++ b/net/mac80211/util.c -@@ -3460,7 +3460,7 @@ void ieee80211_dfs_cac_cancel(struct iee - - list_for_each_entry(sdata, &local->interfaces, list) { - wiphy_delayed_work_cancel(local->hw.wiphy, -- &sdata->dfs_cac_timer_work); -+ &sdata->deflink.dfs_cac_timer_work); - - if (sdata->wdev.cac_started) { - chandef = sdata->vif.bss_conf.chanreq.oper; diff --git a/package/kernel/mac80211/patches/subsys/353-wifi-mac80211-remove-status-ampdu_delimiter_crc.patch b/package/kernel/mac80211/patches/subsys/333-wifi-mac80211-remove-status-ampdu_delimiter_crc.patch similarity index 100% rename from package/kernel/mac80211/patches/subsys/353-wifi-mac80211-remove-status-ampdu_delimiter_crc.patch rename to package/kernel/mac80211/patches/subsys/333-wifi-mac80211-remove-status-ampdu_delimiter_crc.patch diff --git a/package/kernel/mac80211/patches/subsys/354-wifi-cfg80211-pass-net_device-to-.set_monitor_channel.patch b/package/kernel/mac80211/patches/subsys/334-wifi-cfg80211-pass-net_device-to-.set_monitor_channel.patch similarity index 94% rename from package/kernel/mac80211/patches/subsys/354-wifi-cfg80211-pass-net_device-to-.set_monitor_channel.patch rename to package/kernel/mac80211/patches/subsys/334-wifi-cfg80211-pass-net_device-to-.set_monitor_channel.patch index c2a915963c2de6..f1fc9190fc8b56 100644 --- a/package/kernel/mac80211/patches/subsys/354-wifi-cfg80211-pass-net_device-to-.set_monitor_channel.patch +++ b/package/kernel/mac80211/patches/subsys/334-wifi-cfg80211-pass-net_device-to-.set_monitor_channel.patch @@ -49,7 +49,7 @@ Signed-off-by: Felix Fietkau --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h -@@ -4700,6 +4700,7 @@ struct cfg80211_ops { +@@ -4703,6 +4703,7 @@ struct cfg80211_ops { struct ieee80211_channel *chan); int (*set_monitor_channel)(struct wiphy *wiphy, @@ -69,7 +69,7 @@ Signed-off-by: Felix Fietkau struct ieee80211_local *local = wiphy_priv(wiphy); --- a/net/wireless/chan.c +++ b/net/wireless/chan.c -@@ -1673,6 +1673,7 @@ bool cfg80211_reg_check_beaconing(struct +@@ -1679,6 +1679,7 @@ bool cfg80211_reg_check_beaconing(struct EXPORT_SYMBOL(cfg80211_reg_check_beaconing); int cfg80211_set_monitor_channel(struct cfg80211_registered_device *rdev, @@ -77,7 +77,7 @@ Signed-off-by: Felix Fietkau struct cfg80211_chan_def *chandef) { if (!rdev->ops->set_monitor_channel) -@@ -1680,7 +1681,7 @@ int cfg80211_set_monitor_channel(struct +@@ -1686,7 +1687,7 @@ int cfg80211_set_monitor_channel(struct if (!cfg80211_has_monitors_only(rdev)) return -EBUSY; @@ -88,7 +88,7 @@ Signed-off-by: Felix Fietkau bool cfg80211_any_usable_channels(struct wiphy *wiphy, --- a/net/wireless/core.h +++ b/net/wireless/core.h -@@ -510,6 +510,7 @@ static inline unsigned int elapsed_jiffi +@@ -518,6 +518,7 @@ static inline unsigned int elapsed_jiffi } int cfg80211_set_monitor_channel(struct cfg80211_registered_device *rdev, @@ -98,7 +98,7 @@ Signed-off-by: Felix Fietkau int ieee80211_get_ratemask(struct ieee80211_supported_band *sband, --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c -@@ -3562,7 +3562,7 @@ static int __nl80211_set_channel(struct +@@ -3569,7 +3569,7 @@ static int __nl80211_set_channel(struct case NL80211_IFTYPE_MESH_POINT: return cfg80211_set_mesh_channel(rdev, wdev, &chandef); case NL80211_IFTYPE_MONITOR: diff --git a/package/kernel/mac80211/patches/subsys/334-wifi-mac80211-remove-label-usage-in-ieee80211_start_.patch b/package/kernel/mac80211/patches/subsys/334-wifi-mac80211-remove-label-usage-in-ieee80211_start_.patch deleted file mode 100644 index 329b6454628073..00000000000000 --- a/package/kernel/mac80211/patches/subsys/334-wifi-mac80211-remove-label-usage-in-ieee80211_start_.patch +++ /dev/null @@ -1,50 +0,0 @@ -From: Aditya Kumar Singh -Date: Fri, 6 Sep 2024 12:14:20 +0530 -Subject: [PATCH] wifi: mac80211: remove label usage in - ieee80211_start_radar_detection() - -After locks rework [1], ieee80211_start_radar_detection() function is no -longer acquiring any lock as such explicitly. Hence, it is not unlocking -anything as well. However, label "out_unlock" is still used which creates -confusion. Also, now there is no need of goto label as such. - -Get rid of the goto logic and use direct return statements. - -[1]: https://lore.kernel.org/all/20230828135928.b1c6efffe9ad.I4aec875e25abc9ef0b5ad1e70b5747fd483fbd3c@changeid/ - -Signed-off-by: Aditya Kumar Singh -Link: https://patch.msgid.link/20240906064426.2101315-3-quic_adisi@quicinc.com -Signed-off-by: Johannes Berg ---- - ---- a/net/mac80211/cfg.c -+++ b/net/mac80211/cfg.c -@@ -3468,10 +3468,8 @@ static int ieee80211_start_radar_detecti - - lockdep_assert_wiphy(local->hw.wiphy); - -- if (!list_empty(&local->roc_list) || local->scanning) { -- err = -EBUSY; -- goto out_unlock; -- } -+ if (!list_empty(&local->roc_list) || local->scanning) -+ return -EBUSY; - - /* whatever, but channel contexts should not complain about that one */ - sdata->deflink.smps_mode = IEEE80211_SMPS_OFF; -@@ -3480,13 +3478,12 @@ static int ieee80211_start_radar_detecti - err = ieee80211_link_use_channel(&sdata->deflink, &chanreq, - IEEE80211_CHANCTX_SHARED); - if (err) -- goto out_unlock; -+ return err; - - wiphy_delayed_work_queue(wiphy, &sdata->deflink.dfs_cac_timer_work, - msecs_to_jiffies(cac_time_ms)); - -- out_unlock: -- return err; -+ return 0; - } - - static void ieee80211_end_cac(struct wiphy *wiphy, diff --git a/package/kernel/mac80211/patches/subsys/355-wifi-mac80211-add-flag-to-opt-out-of-virtual-monitor.patch b/package/kernel/mac80211/patches/subsys/335-wifi-mac80211-add-flag-to-opt-out-of-virtual-monitor.patch similarity index 90% rename from package/kernel/mac80211/patches/subsys/355-wifi-mac80211-add-flag-to-opt-out-of-virtual-monitor.patch rename to package/kernel/mac80211/patches/subsys/335-wifi-mac80211-add-flag-to-opt-out-of-virtual-monitor.patch index 2510cb0dbe95f1..bb2d5da1a4a00a 100644 --- a/package/kernel/mac80211/patches/subsys/355-wifi-mac80211-add-flag-to-opt-out-of-virtual-monitor.patch +++ b/package/kernel/mac80211/patches/subsys/335-wifi-mac80211-add-flag-to-opt-out-of-virtual-monitor.patch @@ -25,7 +25,7 @@ Signed-off-by: Felix Fietkau * @IEEE80211_HW_NO_AUTO_VIF: The driver would like for no wlanX to * be created. It is expected user-space will create vifs as * desired (and thus have them named as desired). -@@ -2838,6 +2843,7 @@ enum ieee80211_hw_flags { +@@ -2843,6 +2848,7 @@ enum ieee80211_hw_flags { IEEE80211_HW_SUPPORTS_DYNAMIC_PS, IEEE80211_HW_MFP_CAPABLE, IEEE80211_HW_WANT_MONITOR_VIF, @@ -95,7 +95,7 @@ Signed-off-by: Felix Fietkau if (ret) return ret; done: -@@ -3049,7 +3057,8 @@ static int ieee80211_set_tx_power(struct +@@ -3050,7 +3058,8 @@ static int ieee80211_set_tx_power(struct if (wdev) { sdata = IEEE80211_WDEV_TO_SUB_IF(wdev); @@ -105,7 +105,7 @@ Signed-off-by: Felix Fietkau if (!ieee80211_hw_check(&local->hw, WANT_MONITOR_VIF)) return -EOPNOTSUPP; -@@ -3097,7 +3106,8 @@ static int ieee80211_set_tx_power(struct +@@ -3098,7 +3107,8 @@ static int ieee80211_set_tx_power(struct } list_for_each_entry(sdata, &local->interfaces, list) { @@ -115,7 +115,7 @@ Signed-off-by: Felix Fietkau has_monitor = true; continue; } -@@ -3107,7 +3117,8 @@ static int ieee80211_set_tx_power(struct +@@ -3108,7 +3118,8 @@ static int ieee80211_set_tx_power(struct sdata->vif.bss_conf.txpower_type = txp_type; } list_for_each_entry(sdata, &local->interfaces, list) { @@ -125,7 +125,7 @@ Signed-off-by: Felix Fietkau continue; ieee80211_recalc_txpower(sdata, update_txp_type); } -@@ -4299,7 +4310,8 @@ static int ieee80211_cfg_get_channel(str +@@ -4303,7 +4314,8 @@ static int ieee80211_cfg_get_channel(str if (chanctx_conf) { *chandef = link->conf->chanreq.oper; ret = 0; @@ -137,7 +137,7 @@ Signed-off-by: Felix Fietkau *chandef = local->monitor_chanreq.oper; --- a/net/mac80211/chan.c +++ b/net/mac80211/chan.c -@@ -337,6 +337,10 @@ ieee80211_get_chanctx_max_required_bw(st +@@ -339,6 +339,10 @@ ieee80211_get_chanctx_max_required_bw(st case NL80211_IFTYPE_P2P_DEVICE: case NL80211_IFTYPE_NAN: continue; @@ -148,7 +148,7 @@ Signed-off-by: Felix Fietkau case NL80211_IFTYPE_ADHOC: case NL80211_IFTYPE_MESH_POINT: case NL80211_IFTYPE_OCB: -@@ -345,7 +349,6 @@ ieee80211_get_chanctx_max_required_bw(st +@@ -347,7 +351,6 @@ ieee80211_get_chanctx_max_required_bw(st case NL80211_IFTYPE_WDS: case NL80211_IFTYPE_UNSPECIFIED: case NUM_NL80211_IFTYPES: @@ -156,7 +156,7 @@ Signed-off-by: Felix Fietkau case NL80211_IFTYPE_P2P_CLIENT: case NL80211_IFTYPE_P2P_GO: WARN_ON_ONCE(1); -@@ -954,6 +957,10 @@ void ieee80211_recalc_smps_chanctx(struc +@@ -956,6 +959,10 @@ void ieee80211_recalc_smps_chanctx(struc if (!link->sdata->u.mgd.associated) continue; break; @@ -167,7 +167,7 @@ Signed-off-by: Felix Fietkau case NL80211_IFTYPE_AP: case NL80211_IFTYPE_ADHOC: case NL80211_IFTYPE_MESH_POINT: -@@ -966,6 +973,11 @@ void ieee80211_recalc_smps_chanctx(struc +@@ -968,6 +975,11 @@ void ieee80211_recalc_smps_chanctx(struc if (rcu_access_pointer(link->conf->chanctx_conf) != &chanctx->conf) continue; @@ -217,7 +217,7 @@ Signed-off-by: Felix Fietkau } /* Regardless of eth_mac_addr() return we still want to add the -@@ -699,9 +704,11 @@ static void ieee80211_do_stop(struct iee +@@ -705,9 +710,11 @@ static void ieee80211_do_stop(struct iee ieee80211_recalc_idle(local); ieee80211_recalc_offload(local); @@ -230,7 +230,7 @@ Signed-off-by: Felix Fietkau fallthrough; default: if (!going_down) -@@ -1131,7 +1138,8 @@ int ieee80211_add_virtual_monitor(struct +@@ -1140,7 +1147,8 @@ int ieee80211_add_virtual_monitor(struct ASSERT_RTNL(); lockdep_assert_wiphy(local->hw.wiphy); @@ -240,7 +240,7 @@ Signed-off-by: Felix Fietkau return 0; sdata = kzalloc(sizeof(*sdata) + local->hw.vif_data_size, GFP_KERNEL); -@@ -1193,6 +1201,9 @@ void ieee80211_del_virtual_monitor(struc +@@ -1202,6 +1210,9 @@ void ieee80211_del_virtual_monitor(struc { struct ieee80211_sub_if_data *sdata; @@ -250,7 +250,7 @@ Signed-off-by: Felix Fietkau ASSERT_RTNL(); lockdep_assert_wiphy(local->hw.wiphy); -@@ -1328,7 +1339,8 @@ int ieee80211_do_open(struct wireless_de +@@ -1345,7 +1356,8 @@ int ieee80211_do_open(struct wireless_de break; } @@ -284,7 +284,7 @@ Signed-off-by: Felix Fietkau vif = &sdata->vif; break; } -@@ -3952,7 +3953,8 @@ begin: +@@ -3953,7 +3954,8 @@ begin: switch (tx.sdata->vif.type) { case NL80211_IFTYPE_MONITOR: @@ -296,8 +296,8 @@ Signed-off-by: Felix Fietkau } --- a/net/mac80211/util.c +++ b/net/mac80211/util.c -@@ -754,7 +754,8 @@ static void __iterate_interfaces(struct - list_for_each_entry_rcu(sdata, &local->interfaces, list) { +@@ -740,7 +740,8 @@ static void __iterate_interfaces(struct + lockdep_is_held(&local->hw.wiphy->mtx)) { switch (sdata->vif.type) { case NL80211_IFTYPE_MONITOR: - if (!(sdata->u.mntr.flags & MONITOR_FLAG_ACTIVE)) @@ -306,7 +306,7 @@ Signed-off-by: Felix Fietkau continue; break; case NL80211_IFTYPE_AP_VLAN: -@@ -1857,8 +1858,10 @@ int ieee80211_reconfig(struct ieee80211_ +@@ -1860,8 +1861,10 @@ int ieee80211_reconfig(struct ieee80211_ } list_for_each_entry(sdata, &local->interfaces, list) { @@ -318,7 +318,7 @@ Signed-off-by: Felix Fietkau ieee80211_sdata_running(sdata)) { res = drv_add_interface(local, sdata); if (WARN_ON(res)) -@@ -1871,11 +1874,14 @@ int ieee80211_reconfig(struct ieee80211_ +@@ -1874,11 +1877,14 @@ int ieee80211_reconfig(struct ieee80211_ */ if (res) { list_for_each_entry_continue_reverse(sdata, &local->interfaces, diff --git a/package/kernel/mac80211/patches/subsys/335-wifi-trace-unlink-rdev_end_cac-trace-event-from-wiph.patch b/package/kernel/mac80211/patches/subsys/335-wifi-trace-unlink-rdev_end_cac-trace-event-from-wiph.patch deleted file mode 100644 index 98bc0c26fdb8f2..00000000000000 --- a/package/kernel/mac80211/patches/subsys/335-wifi-trace-unlink-rdev_end_cac-trace-event-from-wiph.patch +++ /dev/null @@ -1,42 +0,0 @@ -From: Aditya Kumar Singh -Date: Fri, 6 Sep 2024 12:14:21 +0530 -Subject: [PATCH] wifi: trace: unlink rdev_end_cac trace event from - wiphy_netdev_evt class - -rdev_end_cac trace event is linked with wiphy_netdev_evt event class. -There is no option to pass link ID currently to wiphy_netdev_evt class. -A subsequent change would pass link ID to rdev_end_cac event and hence -it can no longer derive the event class from wiphy_netdev_evt. - -Therefore, unlink rdev_end_cac event from wiphy_netdev_evt and define it's -own independent trace event. Link ID would be passed in subsequent change. - -Signed-off-by: Aditya Kumar Singh -Link: https://patch.msgid.link/20240906064426.2101315-4-quic_adisi@quicinc.com -Signed-off-by: Johannes Berg ---- - ---- a/net/wireless/trace.h -+++ b/net/wireless/trace.h -@@ -805,9 +805,18 @@ DEFINE_EVENT(wiphy_netdev_evt, rdev_flus - TP_ARGS(wiphy, netdev) - ); - --DEFINE_EVENT(wiphy_netdev_evt, rdev_end_cac, -- TP_PROTO(struct wiphy *wiphy, struct net_device *netdev), -- TP_ARGS(wiphy, netdev) -+TRACE_EVENT(rdev_end_cac, -+ TP_PROTO(struct wiphy *wiphy, struct net_device *netdev), -+ TP_ARGS(wiphy, netdev), -+ TP_STRUCT__entry( -+ WIPHY_ENTRY -+ NETDEV_ENTRY -+ ), -+ TP_fast_assign( -+ WIPHY_ASSIGN; -+ NETDEV_ASSIGN; -+ ), -+ TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT, WIPHY_PR_ARG, NETDEV_PR_ARG) - ); - - DECLARE_EVENT_CLASS(station_add_change, diff --git a/package/kernel/mac80211/patches/subsys/356-wifi-cfg80211-add-monitor-SKIP_TX-flag.patch b/package/kernel/mac80211/patches/subsys/336-wifi-cfg80211-add-monitor-SKIP_TX-flag.patch similarity index 87% rename from package/kernel/mac80211/patches/subsys/356-wifi-cfg80211-add-monitor-SKIP_TX-flag.patch rename to package/kernel/mac80211/patches/subsys/336-wifi-cfg80211-add-monitor-SKIP_TX-flag.patch index dfc01c6c9bc546..d60f74fc113291 100644 --- a/package/kernel/mac80211/patches/subsys/356-wifi-cfg80211-add-monitor-SKIP_TX-flag.patch +++ b/package/kernel/mac80211/patches/subsys/336-wifi-cfg80211-add-monitor-SKIP_TX-flag.patch @@ -10,7 +10,7 @@ Signed-off-by: Felix Fietkau --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h -@@ -2272,6 +2272,7 @@ static inline int cfg80211_get_station(s +@@ -2275,6 +2275,7 @@ static inline int cfg80211_get_station(s * @MONITOR_FLAG_OTHER_BSS: disable BSSID filtering * @MONITOR_FLAG_COOK_FRAMES: report frames after processing * @MONITOR_FLAG_ACTIVE: active monitor, ACKs frames on its MAC address @@ -18,7 +18,7 @@ Signed-off-by: Felix Fietkau */ enum monitor_flags { MONITOR_FLAG_CHANGED = BIT(__NL80211_MNTR_FLAG_INVALID), -@@ -2281,6 +2282,7 @@ enum monitor_flags { +@@ -2284,6 +2285,7 @@ enum monitor_flags { MONITOR_FLAG_OTHER_BSS = BIT(NL80211_MNTR_FLAG_OTHER_BSS), MONITOR_FLAG_COOK_FRAMES = BIT(NL80211_MNTR_FLAG_COOK_FRAMES), MONITOR_FLAG_ACTIVE = BIT(NL80211_MNTR_FLAG_ACTIVE), @@ -28,7 +28,7 @@ Signed-off-by: Felix Fietkau /** --- a/include/uapi/linux/nl80211.h +++ b/include/uapi/linux/nl80211.h -@@ -4703,6 +4703,7 @@ enum nl80211_survey_info { +@@ -4709,6 +4709,7 @@ enum nl80211_survey_info { * overrides all other flags. * @NL80211_MNTR_FLAG_ACTIVE: use the configured MAC address * and ACK incoming unicast packets. @@ -36,7 +36,7 @@ Signed-off-by: Felix Fietkau * * @__NL80211_MNTR_FLAG_AFTER_LAST: internal use * @NL80211_MNTR_FLAG_MAX: highest possible monitor flag -@@ -4715,6 +4716,7 @@ enum nl80211_mntr_flags { +@@ -4721,6 +4722,7 @@ enum nl80211_mntr_flags { NL80211_MNTR_FLAG_OTHER_BSS, NL80211_MNTR_FLAG_COOK_FRAMES, NL80211_MNTR_FLAG_ACTIVE, @@ -46,7 +46,7 @@ Signed-off-by: Felix Fietkau __NL80211_MNTR_FLAG_AFTER_LAST, --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c -@@ -4201,6 +4201,7 @@ static const struct nla_policy mntr_flag +@@ -4208,6 +4208,7 @@ static const struct nla_policy mntr_flag [NL80211_MNTR_FLAG_OTHER_BSS] = { .type = NLA_FLAG }, [NL80211_MNTR_FLAG_COOK_FRAMES] = { .type = NLA_FLAG }, [NL80211_MNTR_FLAG_ACTIVE] = { .type = NLA_FLAG }, diff --git a/package/kernel/mac80211/patches/subsys/336-wifi-cfg80211-move-DFS-related-members-to-links-in-w.patch b/package/kernel/mac80211/patches/subsys/336-wifi-cfg80211-move-DFS-related-members-to-links-in-w.patch deleted file mode 100644 index 95dac04de5e411..00000000000000 --- a/package/kernel/mac80211/patches/subsys/336-wifi-cfg80211-move-DFS-related-members-to-links-in-w.patch +++ /dev/null @@ -1,309 +0,0 @@ -From: Aditya Kumar Singh -Date: Fri, 6 Sep 2024 12:14:22 +0530 -Subject: [PATCH] wifi: cfg80211: move DFS related members to links[] in - wireless_dev - -A few members related to DFS handling are currently under per wireless -device data structure. However, in order to support DFS with MLO, there is -a need to have them on a per-link manner. - -Hence, as a preliminary step, move members cac_started, cac_start_time -and cac_time_ms to be on a per-link basis. - -Since currently, link ID is not known at all places, use default value of -0 for now. - -Signed-off-by: Aditya Kumar Singh -Link: https://patch.msgid.link/20240906064426.2101315-5-quic_adisi@quicinc.com -Signed-off-by: Johannes Berg ---- - ---- a/drivers/net/wireless/marvell/mwifiex/11h.c -+++ b/drivers/net/wireless/marvell/mwifiex/11h.c -@@ -117,7 +117,7 @@ void mwifiex_dfs_cac_work_queue(struct w - dfs_cac_work); - - chandef = priv->dfs_chandef; -- if (priv->wdev.cac_started) { -+ if (priv->wdev.links[0].cac_started) { - mwifiex_dbg(priv->adapter, MSG, - "CAC timer finished; No radar detected\n"); - cfg80211_cac_event(priv->netdev, &chandef, -@@ -174,7 +174,7 @@ int mwifiex_stop_radar_detection(struct - */ - void mwifiex_abort_cac(struct mwifiex_private *priv) - { -- if (priv->wdev.cac_started) { -+ if (priv->wdev.links[0].cac_started) { - if (mwifiex_stop_radar_detection(priv, &priv->dfs_chandef)) - mwifiex_dbg(priv->adapter, ERROR, - "failed to stop CAC in FW\n"); ---- a/drivers/net/wireless/marvell/mwifiex/cfg80211.c -+++ b/drivers/net/wireless/marvell/mwifiex/cfg80211.c -@@ -1880,7 +1880,7 @@ mwifiex_cfg80211_del_station(struct wiph - struct mwifiex_sta_node *sta_node; - u8 deauth_mac[ETH_ALEN]; - -- if (!priv->bss_started && priv->wdev.cac_started) { -+ if (!priv->bss_started && priv->wdev.links[0].cac_started) { - mwifiex_dbg(priv->adapter, INFO, "%s: abort CAC!\n", __func__); - mwifiex_abort_cac(priv); - } -@@ -3978,7 +3978,7 @@ mwifiex_cfg80211_channel_switch(struct w - return -EBUSY; - } - -- if (priv->wdev.cac_started) -+ if (priv->wdev.links[0].cac_started) - return -EBUSY; - - if (cfg80211_chandef_identical(¶ms->chandef, ---- a/drivers/net/wireless/quantenna/qtnfmac/event.c -+++ b/drivers/net/wireless/quantenna/qtnfmac/event.c -@@ -520,21 +520,21 @@ static int qtnf_event_handle_radar(struc - cfg80211_radar_event(wiphy, &chandef, GFP_KERNEL); - break; - case QLINK_RADAR_CAC_FINISHED: -- if (!vif->wdev.cac_started) -+ if (!vif->wdev.links[0].cac_started) - break; - - cfg80211_cac_event(vif->netdev, &chandef, - NL80211_RADAR_CAC_FINISHED, GFP_KERNEL); - break; - case QLINK_RADAR_CAC_ABORTED: -- if (!vif->wdev.cac_started) -+ if (!vif->wdev.links[0].cac_started) - break; - - cfg80211_cac_event(vif->netdev, &chandef, - NL80211_RADAR_CAC_ABORTED, GFP_KERNEL); - break; - case QLINK_RADAR_CAC_STARTED: -- if (vif->wdev.cac_started) -+ if (vif->wdev.links[0].cac_started) - break; - - if (!wiphy_ext_feature_isset(wiphy, ---- a/include/net/cfg80211.h -+++ b/include/net/cfg80211.h -@@ -6198,9 +6198,6 @@ enum ieee80211_ap_reg_power { - * @address: The address for this device, valid only if @netdev is %NULL - * @is_running: true if this is a non-netdev device that has been started, e.g. - * the P2P Device. -- * @cac_started: true if DFS channel availability check has been started -- * @cac_start_time: timestamp (jiffies) when the dfs state was entered. -- * @cac_time_ms: CAC time in ms - * @ps: powersave mode is enabled - * @ps_timeout: dynamic powersave timeout - * @ap_unexpected_nlportid: (private) netlink port ID of application -@@ -6224,6 +6221,11 @@ enum ieee80211_ap_reg_power { - * unprotected beacon report - * @links: array of %IEEE80211_MLD_MAX_NUM_LINKS elements containing @addr - * @ap and @client for each link -+ * @links[].cac_started: true if DFS channel availability check has been -+ * started -+ * @links[].cac_start_time: timestamp (jiffies) when the dfs state was -+ * entered. -+ * @links[].cac_time_ms: CAC time in ms - * @valid_links: bitmap describing what elements of @links are valid - */ - struct wireless_dev { -@@ -6265,11 +6267,6 @@ struct wireless_dev { - u32 owner_nlportid; - bool nl_owner_dead; - -- /* FIXME: need to rework radar detection for MLO */ -- bool cac_started; -- unsigned long cac_start_time; -- unsigned int cac_time_ms; -- - #ifdef CPTCFG_CFG80211_WEXT - /* wext data */ - struct { -@@ -6336,6 +6333,10 @@ struct wireless_dev { - struct cfg80211_internal_bss *current_bss; - } client; - }; -+ -+ bool cac_started; -+ unsigned long cac_start_time; -+ unsigned int cac_time_ms; - } links[IEEE80211_MLD_MAX_NUM_LINKS]; - u16 valid_links; - }; ---- a/net/mac80211/cfg.c -+++ b/net/mac80211/cfg.c -@@ -1656,7 +1656,7 @@ static int ieee80211_stop_ap(struct wiph - ieee80211_link_info_change_notify(sdata, link, - BSS_CHANGED_BEACON_ENABLED); - -- if (sdata->wdev.cac_started) { -+ if (sdata->wdev.links[0].cac_started) { - chandef = link_conf->chanreq.oper; - wiphy_delayed_work_cancel(wiphy, &link->dfs_cac_timer_work); - cfg80211_cac_event(sdata->dev, &chandef, -@@ -3498,9 +3498,9 @@ static void ieee80211_end_cac(struct wip - wiphy_delayed_work_cancel(wiphy, - &sdata->deflink.dfs_cac_timer_work); - -- if (sdata->wdev.cac_started) { -+ if (sdata->wdev.links[0].cac_started) { - ieee80211_link_release_channel(&sdata->deflink); -- sdata->wdev.cac_started = false; -+ sdata->wdev.links[0].cac_started = false; - } - } - } -@@ -3955,7 +3955,7 @@ __ieee80211_channel_switch(struct wiphy - if (!list_empty(&local->roc_list) || local->scanning) - return -EBUSY; - -- if (sdata->wdev.cac_started) -+ if (sdata->wdev.links[0].cac_started) - return -EBUSY; - - if (WARN_ON(link_id >= IEEE80211_MLD_MAX_NUM_LINKS)) ---- a/net/mac80211/iface.c -+++ b/net/mac80211/iface.c -@@ -553,7 +553,7 @@ static void ieee80211_do_stop(struct iee - wiphy_delayed_work_cancel(local->hw.wiphy, - &sdata->deflink.dfs_cac_timer_work); - -- if (sdata->wdev.cac_started) { -+ if (sdata->wdev.links[0].cac_started) { - chandef = sdata->vif.bss_conf.chanreq.oper; - WARN_ON(local->suspended); - ieee80211_link_release_channel(&sdata->deflink); ---- a/net/mac80211/mlme.c -+++ b/net/mac80211/mlme.c -@@ -3039,7 +3039,7 @@ void ieee80211_dfs_cac_timer_work(struct - - lockdep_assert_wiphy(sdata->local->hw.wiphy); - -- if (sdata->wdev.cac_started) { -+ if (sdata->wdev.links[0].cac_started) { - ieee80211_link_release_channel(link); - cfg80211_cac_event(sdata->dev, &chandef, - NL80211_RADAR_CAC_FINISHED, ---- a/net/mac80211/scan.c -+++ b/net/mac80211/scan.c -@@ -585,7 +585,7 @@ static bool __ieee80211_can_leave_ch(str - return false; - - list_for_each_entry(sdata_iter, &local->interfaces, list) { -- if (sdata_iter->wdev.cac_started) -+ if (sdata_iter->wdev.links[0].cac_started) - return false; - } - ---- a/net/mac80211/util.c -+++ b/net/mac80211/util.c -@@ -3462,7 +3462,7 @@ void ieee80211_dfs_cac_cancel(struct iee - wiphy_delayed_work_cancel(local->hw.wiphy, - &sdata->deflink.dfs_cac_timer_work); - -- if (sdata->wdev.cac_started) { -+ if (sdata->wdev.links[0].cac_started) { - chandef = sdata->vif.bss_conf.chanreq.oper; - ieee80211_link_release_channel(&sdata->deflink); - cfg80211_cac_event(sdata->dev, ---- a/net/wireless/ibss.c -+++ b/net/wireless/ibss.c -@@ -94,7 +94,7 @@ int __cfg80211_join_ibss(struct cfg80211 - - lockdep_assert_held(&rdev->wiphy.mtx); - -- if (wdev->cac_started) -+ if (wdev->links[0].cac_started) - return -EBUSY; - - if (wdev->u.ibss.ssid_len) ---- a/net/wireless/mesh.c -+++ b/net/wireless/mesh.c -@@ -127,7 +127,7 @@ int __cfg80211_join_mesh(struct cfg80211 - if (!rdev->ops->join_mesh) - return -EOPNOTSUPP; - -- if (wdev->cac_started) -+ if (wdev->links[0].cac_started) - return -EBUSY; - - if (!setup->chandef.chan) { ---- a/net/wireless/mlme.c -+++ b/net/wireless/mlme.c -@@ -1124,13 +1124,14 @@ void cfg80211_cac_event(struct net_devic - - trace_cfg80211_cac_event(netdev, event); - -- if (WARN_ON(!wdev->cac_started && event != NL80211_RADAR_CAC_STARTED)) -+ if (WARN_ON(!wdev->links[0].cac_started && -+ event != NL80211_RADAR_CAC_STARTED)) - return; - - switch (event) { - case NL80211_RADAR_CAC_FINISHED: -- timeout = wdev->cac_start_time + -- msecs_to_jiffies(wdev->cac_time_ms); -+ timeout = wdev->links[0].cac_start_time + -+ msecs_to_jiffies(wdev->links[0].cac_time_ms); - WARN_ON(!time_after_eq(jiffies, timeout)); - cfg80211_set_dfs_state(wiphy, chandef, NL80211_DFS_AVAILABLE); - memcpy(&rdev->cac_done_chandef, chandef, -@@ -1139,10 +1140,10 @@ void cfg80211_cac_event(struct net_devic - cfg80211_sched_dfs_chan_update(rdev); - fallthrough; - case NL80211_RADAR_CAC_ABORTED: -- wdev->cac_started = false; -+ wdev->links[0].cac_started = false; - break; - case NL80211_RADAR_CAC_STARTED: -- wdev->cac_started = true; -+ wdev->links[0].cac_started = true; - break; - default: - WARN_ON(1); ---- a/net/wireless/nl80211.c -+++ b/net/wireless/nl80211.c -@@ -6066,7 +6066,7 @@ static int nl80211_start_ap(struct sk_bu - if (!rdev->ops->start_ap) - return -EOPNOTSUPP; - -- if (wdev->cac_started) -+ if (wdev->links[0].cac_started) - return -EBUSY; - - if (wdev->links[link_id].ap.beacon_interval) -@@ -10122,7 +10122,7 @@ static int nl80211_start_radar_detection - goto unlock; - } - -- if (cfg80211_beaconing_iface_active(wdev) || wdev->cac_started) { -+ if (cfg80211_beaconing_iface_active(wdev) || wdev->links[0].cac_started) { - err = -EBUSY; - goto unlock; - } -@@ -10158,9 +10158,9 @@ static int nl80211_start_radar_detection - default: - break; - } -- wdev->cac_started = true; -- wdev->cac_start_time = jiffies; -- wdev->cac_time_ms = cac_time_ms; -+ wdev->links[0].cac_started = true; -+ wdev->links[0].cac_start_time = jiffies; -+ wdev->links[0].cac_time_ms = cac_time_ms; - } - unlock: - wiphy_unlock(wiphy); ---- a/net/wireless/reg.c -+++ b/net/wireless/reg.c -@@ -4241,7 +4241,7 @@ static void cfg80211_check_and_end_cac(s - list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) { - struct cfg80211_chan_def *chandef; - -- if (!wdev->cac_started) -+ if (!wdev->links[0].cac_started) - continue; - - /* FIXME: radar detection is tied to link 0 for now */ diff --git a/package/kernel/mac80211/patches/subsys/337-wifi-cfg80211-handle-DFS-per-link.patch b/package/kernel/mac80211/patches/subsys/337-wifi-cfg80211-handle-DFS-per-link.patch deleted file mode 100644 index a4e0333642ae5b..00000000000000 --- a/package/kernel/mac80211/patches/subsys/337-wifi-cfg80211-handle-DFS-per-link.patch +++ /dev/null @@ -1,435 +0,0 @@ -From: Aditya Kumar Singh -Date: Fri, 6 Sep 2024 12:14:23 +0530 -Subject: [PATCH] wifi: cfg80211: handle DFS per link - -Currently, during starting a radar detection, no link id information is -parsed and passed down. In order to support starting radar detection -during Multi Link Operation, it is required to pass link id as well. - -Add changes to first parse and then pass link id in the start radar -detection path. - -Additionally, update notification APIs to allow drivers/mac80211 to -pass the link ID. - -However, everything is handled at link 0 only until all API's are ready to -handle it per link. - -Signed-off-by: Aditya Kumar Singh -Link: https://patch.msgid.link/20240906064426.2101315-6-quic_adisi@quicinc.com -Signed-off-by: Johannes Berg ---- - ---- a/drivers/net/wireless/marvell/mwifiex/11h.c -+++ b/drivers/net/wireless/marvell/mwifiex/11h.c -@@ -122,7 +122,7 @@ void mwifiex_dfs_cac_work_queue(struct w - "CAC timer finished; No radar detected\n"); - cfg80211_cac_event(priv->netdev, &chandef, - NL80211_RADAR_CAC_FINISHED, -- GFP_KERNEL); -+ GFP_KERNEL, 0); - } - } - -@@ -182,7 +182,8 @@ void mwifiex_abort_cac(struct mwifiex_pr - "Aborting delayed work for CAC.\n"); - cancel_delayed_work_sync(&priv->dfs_cac_work); - cfg80211_cac_event(priv->netdev, &priv->dfs_chandef, -- NL80211_RADAR_CAC_ABORTED, GFP_KERNEL); -+ NL80211_RADAR_CAC_ABORTED, GFP_KERNEL, -+ 0); - } - } - -@@ -221,7 +222,7 @@ int mwifiex_11h_handle_chanrpt_ready(str - cfg80211_cac_event(priv->netdev, - &priv->dfs_chandef, - NL80211_RADAR_DETECTED, -- GFP_KERNEL); -+ GFP_KERNEL, 0); - } - break; - default: ---- a/drivers/net/wireless/marvell/mwifiex/cfg80211.c -+++ b/drivers/net/wireless/marvell/mwifiex/cfg80211.c -@@ -4145,7 +4145,7 @@ static int - mwifiex_cfg80211_start_radar_detection(struct wiphy *wiphy, - struct net_device *dev, - struct cfg80211_chan_def *chandef, -- u32 cac_time_ms) -+ u32 cac_time_ms, int link_id) - { - struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); - struct mwifiex_radar_params radar_params; ---- a/drivers/net/wireless/quantenna/qtnfmac/cfg80211.c -+++ b/drivers/net/wireless/quantenna/qtnfmac/cfg80211.c -@@ -837,7 +837,7 @@ static int qtnf_channel_switch(struct wi - static int qtnf_start_radar_detection(struct wiphy *wiphy, - struct net_device *ndev, - struct cfg80211_chan_def *chandef, -- u32 cac_time_ms) -+ u32 cac_time_ms, int link_id) - { - struct qtnf_vif *vif = qtnf_netdev_get_priv(ndev); - int ret; ---- a/drivers/net/wireless/quantenna/qtnfmac/event.c -+++ b/drivers/net/wireless/quantenna/qtnfmac/event.c -@@ -524,14 +524,14 @@ static int qtnf_event_handle_radar(struc - break; - - cfg80211_cac_event(vif->netdev, &chandef, -- NL80211_RADAR_CAC_FINISHED, GFP_KERNEL); -+ NL80211_RADAR_CAC_FINISHED, GFP_KERNEL, 0); - break; - case QLINK_RADAR_CAC_ABORTED: - if (!vif->wdev.links[0].cac_started) - break; - - cfg80211_cac_event(vif->netdev, &chandef, -- NL80211_RADAR_CAC_ABORTED, GFP_KERNEL); -+ NL80211_RADAR_CAC_ABORTED, GFP_KERNEL, 0); - break; - case QLINK_RADAR_CAC_STARTED: - if (vif->wdev.links[0].cac_started) -@@ -542,7 +542,7 @@ static int qtnf_event_handle_radar(struc - break; - - cfg80211_cac_event(vif->netdev, &chandef, -- NL80211_RADAR_CAC_STARTED, GFP_KERNEL); -+ NL80211_RADAR_CAC_STARTED, GFP_KERNEL, 0); - break; - default: - pr_warn("%s: unhandled radar event %u\n", ---- a/include/net/cfg80211.h -+++ b/include/net/cfg80211.h -@@ -4841,9 +4841,9 @@ struct cfg80211_ops { - int (*start_radar_detection)(struct wiphy *wiphy, - struct net_device *dev, - struct cfg80211_chan_def *chandef, -- u32 cac_time_ms); -+ u32 cac_time_ms, int link_id); - void (*end_cac)(struct wiphy *wiphy, -- struct net_device *dev); -+ struct net_device *dev, unsigned int link_id); - int (*update_ft_ies)(struct wiphy *wiphy, struct net_device *dev, - struct cfg80211_update_ft_ies_params *ftie); - int (*crit_proto_start)(struct wiphy *wiphy, -@@ -8745,6 +8745,7 @@ void cfg80211_sta_opmode_change_notify(s - * @chandef: chandef for the current channel - * @event: type of event - * @gfp: context flags -+ * @link_id: valid link_id for MLO operation or 0 otherwise. - * - * This function is called when a Channel availability check (CAC) is finished - * or aborted. This must be called to notify the completion of a CAC process, -@@ -8752,7 +8753,8 @@ void cfg80211_sta_opmode_change_notify(s - */ - void cfg80211_cac_event(struct net_device *netdev, - const struct cfg80211_chan_def *chandef, -- enum nl80211_radar_event event, gfp_t gfp); -+ enum nl80211_radar_event event, gfp_t gfp, -+ unsigned int link_id); - - /** - * cfg80211_background_cac_abort - Channel Availability Check offchan abort event ---- a/net/mac80211/cfg.c -+++ b/net/mac80211/cfg.c -@@ -1661,7 +1661,7 @@ static int ieee80211_stop_ap(struct wiph - wiphy_delayed_work_cancel(wiphy, &link->dfs_cac_timer_work); - cfg80211_cac_event(sdata->dev, &chandef, - NL80211_RADAR_CAC_ABORTED, -- GFP_KERNEL); -+ GFP_KERNEL, 0); - } - - drv_stop_ap(sdata->local, sdata, link_conf); -@@ -3459,7 +3459,7 @@ static int ieee80211_set_bitrate_mask(st - static int ieee80211_start_radar_detection(struct wiphy *wiphy, - struct net_device *dev, - struct cfg80211_chan_def *chandef, -- u32 cac_time_ms) -+ u32 cac_time_ms, int link_id) - { - struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); - struct ieee80211_chan_req chanreq = { .oper = *chandef }; -@@ -3487,7 +3487,7 @@ static int ieee80211_start_radar_detecti - } - - static void ieee80211_end_cac(struct wiphy *wiphy, -- struct net_device *dev) -+ struct net_device *dev, unsigned int link_id) - { - struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); - struct ieee80211_local *local = sdata->local; ---- a/net/mac80211/iface.c -+++ b/net/mac80211/iface.c -@@ -559,7 +559,7 @@ static void ieee80211_do_stop(struct iee - ieee80211_link_release_channel(&sdata->deflink); - cfg80211_cac_event(sdata->dev, &chandef, - NL80211_RADAR_CAC_ABORTED, -- GFP_KERNEL); -+ GFP_KERNEL, 0); - } - - if (sdata->vif.type == NL80211_IFTYPE_AP) { ---- a/net/mac80211/mlme.c -+++ b/net/mac80211/mlme.c -@@ -3043,7 +3043,7 @@ void ieee80211_dfs_cac_timer_work(struct - ieee80211_link_release_channel(link); - cfg80211_cac_event(sdata->dev, &chandef, - NL80211_RADAR_CAC_FINISHED, -- GFP_KERNEL); -+ GFP_KERNEL, 0); - } - } - ---- a/net/mac80211/util.c -+++ b/net/mac80211/util.c -@@ -3468,7 +3468,7 @@ void ieee80211_dfs_cac_cancel(struct iee - cfg80211_cac_event(sdata->dev, - &chandef, - NL80211_RADAR_CAC_ABORTED, -- GFP_KERNEL); -+ GFP_KERNEL, 0); - } - } - } ---- a/net/wireless/mlme.c -+++ b/net/wireless/mlme.c -@@ -1111,18 +1111,19 @@ EXPORT_SYMBOL(__cfg80211_radar_event); - - void cfg80211_cac_event(struct net_device *netdev, - const struct cfg80211_chan_def *chandef, -- enum nl80211_radar_event event, gfp_t gfp) -+ enum nl80211_radar_event event, gfp_t gfp, -+ unsigned int link_id) - { - struct wireless_dev *wdev = netdev->ieee80211_ptr; - struct wiphy *wiphy = wdev->wiphy; - struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy); - unsigned long timeout; - -- /* not yet supported */ -- if (wdev->valid_links) -+ if (WARN_ON(wdev->valid_links && -+ !(wdev->valid_links & BIT(link_id)))) - return; - -- trace_cfg80211_cac_event(netdev, event); -+ trace_cfg80211_cac_event(netdev, event, link_id); - - if (WARN_ON(!wdev->links[0].cac_started && - event != NL80211_RADAR_CAC_STARTED)) ---- a/net/wireless/nl80211.c -+++ b/net/wireless/nl80211.c -@@ -10122,7 +10122,20 @@ static int nl80211_start_radar_detection - goto unlock; - } - -- if (cfg80211_beaconing_iface_active(wdev) || wdev->links[0].cac_started) { -+ if (cfg80211_beaconing_iface_active(wdev)) { -+ /* During MLO other link(s) can beacon, only the current link -+ * can not already beacon -+ */ -+ if (wdev->valid_links && -+ !wdev->links[0].ap.beacon_interval) { -+ /* nothing */ -+ } else { -+ err = -EBUSY; -+ goto unlock; -+ } -+ } -+ -+ if (wdev->links[0].cac_started) { - err = -EBUSY; - goto unlock; - } -@@ -10142,7 +10155,8 @@ static int nl80211_start_radar_detection - if (WARN_ON(!cac_time_ms)) - cac_time_ms = IEEE80211_DFS_MIN_CAC_TIME_MS; - -- err = rdev_start_radar_detection(rdev, dev, &chandef, cac_time_ms); -+ err = rdev_start_radar_detection(rdev, dev, &chandef, cac_time_ms, -+ 0); - if (!err) { - switch (wdev->iftype) { - case NL80211_IFTYPE_AP: -@@ -16512,10 +16526,10 @@ nl80211_set_ttlm(struct sk_buff *skb, st - SELECTOR(__sel, NETDEV_UP_NOTMX, \ - NL80211_FLAG_NEED_NETDEV_UP | \ - NL80211_FLAG_NO_WIPHY_MTX) \ -- SELECTOR(__sel, NETDEV_UP_NOTMX_NOMLO, \ -+ SELECTOR(__sel, NETDEV_UP_NOTMX_MLO, \ - NL80211_FLAG_NEED_NETDEV_UP | \ - NL80211_FLAG_NO_WIPHY_MTX | \ -- NL80211_FLAG_MLO_UNSUPPORTED) \ -+ NL80211_FLAG_MLO_VALID_LINK_ID) \ - SELECTOR(__sel, NETDEV_UP_CLEAR, \ - NL80211_FLAG_NEED_NETDEV_UP | \ - NL80211_FLAG_CLEAR_SKB) \ -@@ -17410,7 +17424,7 @@ static const struct genl_small_ops nl802 - .flags = GENL_UNS_ADMIN_PERM, - .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP | - NL80211_FLAG_NO_WIPHY_MTX | -- NL80211_FLAG_MLO_UNSUPPORTED), -+ NL80211_FLAG_MLO_VALID_LINK_ID), - }, - { - .cmd = NL80211_CMD_GET_PROTOCOL_FEATURES, ---- a/net/wireless/rdev-ops.h -+++ b/net/wireless/rdev-ops.h -@@ -1200,26 +1200,27 @@ static inline int - rdev_start_radar_detection(struct cfg80211_registered_device *rdev, - struct net_device *dev, - struct cfg80211_chan_def *chandef, -- u32 cac_time_ms) -+ u32 cac_time_ms, int link_id) - { - int ret = -EOPNOTSUPP; - - trace_rdev_start_radar_detection(&rdev->wiphy, dev, chandef, -- cac_time_ms); -+ cac_time_ms, link_id); - if (rdev->ops->start_radar_detection) - ret = rdev->ops->start_radar_detection(&rdev->wiphy, dev, -- chandef, cac_time_ms); -+ chandef, cac_time_ms, -+ link_id); - trace_rdev_return_int(&rdev->wiphy, ret); - return ret; - } - - static inline void - rdev_end_cac(struct cfg80211_registered_device *rdev, -- struct net_device *dev) -+ struct net_device *dev, unsigned int link_id) - { -- trace_rdev_end_cac(&rdev->wiphy, dev); -+ trace_rdev_end_cac(&rdev->wiphy, dev, link_id); - if (rdev->ops->end_cac) -- rdev->ops->end_cac(&rdev->wiphy, dev); -+ rdev->ops->end_cac(&rdev->wiphy, dev, link_id); - trace_rdev_return_void(&rdev->wiphy); - } - ---- a/net/wireless/reg.c -+++ b/net/wireless/reg.c -@@ -4229,6 +4229,8 @@ EXPORT_SYMBOL(regulatory_pre_cac_allowed - static void cfg80211_check_and_end_cac(struct cfg80211_registered_device *rdev) - { - struct wireless_dev *wdev; -+ unsigned int link_id; -+ - /* If we finished CAC or received radar, we should end any - * CAC running on the same channels. - * the check !cfg80211_chandef_dfs_usable contain 2 options: -@@ -4241,16 +4243,17 @@ static void cfg80211_check_and_end_cac(s - list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) { - struct cfg80211_chan_def *chandef; - -- if (!wdev->links[0].cac_started) -- continue; -+ for_each_valid_link(wdev, link_id) { -+ if (!wdev->links[link_id].cac_started) -+ continue; - -- /* FIXME: radar detection is tied to link 0 for now */ -- chandef = wdev_chandef(wdev, 0); -- if (!chandef) -- continue; -+ chandef = wdev_chandef(wdev, link_id); -+ if (!chandef) -+ continue; - -- if (!cfg80211_chandef_dfs_usable(&rdev->wiphy, chandef)) -- rdev_end_cac(rdev, wdev->netdev); -+ if (!cfg80211_chandef_dfs_usable(&rdev->wiphy, chandef)) -+ rdev_end_cac(rdev, wdev->netdev, link_id); -+ } - } - } - ---- a/net/wireless/trace.h -+++ b/net/wireless/trace.h -@@ -806,17 +806,21 @@ DEFINE_EVENT(wiphy_netdev_evt, rdev_flus - ); - - TRACE_EVENT(rdev_end_cac, -- TP_PROTO(struct wiphy *wiphy, struct net_device *netdev), -- TP_ARGS(wiphy, netdev), -+ TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, -+ unsigned int link_id), -+ TP_ARGS(wiphy, netdev, link_id), - TP_STRUCT__entry( - WIPHY_ENTRY - NETDEV_ENTRY -+ __field(unsigned int, link_id) - ), - TP_fast_assign( - WIPHY_ASSIGN; - NETDEV_ASSIGN; -+ __entry->link_id = link_id; - ), -- TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT, WIPHY_PR_ARG, NETDEV_PR_ARG) -+ TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", link_id: %d", -+ WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->link_id) - ); - - DECLARE_EVENT_CLASS(station_add_change, -@@ -2661,24 +2665,26 @@ TRACE_EVENT(rdev_external_auth, - TRACE_EVENT(rdev_start_radar_detection, - TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, - struct cfg80211_chan_def *chandef, -- u32 cac_time_ms), -- TP_ARGS(wiphy, netdev, chandef, cac_time_ms), -+ u32 cac_time_ms, int link_id), -+ TP_ARGS(wiphy, netdev, chandef, cac_time_ms, link_id), - TP_STRUCT__entry( - WIPHY_ENTRY - NETDEV_ENTRY - CHAN_DEF_ENTRY - __field(u32, cac_time_ms) -+ __field(int, link_id) - ), - TP_fast_assign( - WIPHY_ASSIGN; - NETDEV_ASSIGN; - CHAN_DEF_ASSIGN(chandef); - __entry->cac_time_ms = cac_time_ms; -+ __entry->link_id = link_id; - ), - TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", " CHAN_DEF_PR_FMT -- ", cac_time_ms=%u", -+ ", cac_time_ms=%u, link_id=%d", - WIPHY_PR_ARG, NETDEV_PR_ARG, CHAN_DEF_PR_ARG, -- __entry->cac_time_ms) -+ __entry->cac_time_ms, __entry->link_id) - ); - - TRACE_EVENT(rdev_set_mcast_rate, -@@ -3492,18 +3498,21 @@ TRACE_EVENT(cfg80211_radar_event, - ); - - TRACE_EVENT(cfg80211_cac_event, -- TP_PROTO(struct net_device *netdev, enum nl80211_radar_event evt), -- TP_ARGS(netdev, evt), -+ TP_PROTO(struct net_device *netdev, enum nl80211_radar_event evt, -+ unsigned int link_id), -+ TP_ARGS(netdev, evt, link_id), - TP_STRUCT__entry( - NETDEV_ENTRY - __field(enum nl80211_radar_event, evt) -+ __field(unsigned int, link_id) - ), - TP_fast_assign( - NETDEV_ASSIGN; - __entry->evt = evt; -+ __entry->link_id = link_id; - ), -- TP_printk(NETDEV_PR_FMT ", event: %d", -- NETDEV_PR_ARG, __entry->evt) -+ TP_printk(NETDEV_PR_FMT ", event: %d, link_id=%u", -+ NETDEV_PR_ARG, __entry->evt, __entry->link_id) - ); - - DECLARE_EVENT_CLASS(cfg80211_rx_evt, diff --git a/package/kernel/mac80211/patches/subsys/357-wifi-mac80211-add-support-for-the-monitor-SKIP_TX-fl.patch b/package/kernel/mac80211/patches/subsys/337-wifi-mac80211-add-support-for-the-monitor-SKIP_TX-fl.patch similarity index 93% rename from package/kernel/mac80211/patches/subsys/357-wifi-mac80211-add-support-for-the-monitor-SKIP_TX-fl.patch rename to package/kernel/mac80211/patches/subsys/337-wifi-mac80211-add-support-for-the-monitor-SKIP_TX-fl.patch index e62c15c19d16c9..3cd8baefe137e4 100644 --- a/package/kernel/mac80211/patches/subsys/357-wifi-mac80211-add-support-for-the-monitor-SKIP_TX-fl.patch +++ b/package/kernel/mac80211/patches/subsys/337-wifi-mac80211-add-support-for-the-monitor-SKIP_TX-fl.patch @@ -11,7 +11,7 @@ Signed-off-by: Felix Fietkau --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h -@@ -1374,7 +1374,7 @@ struct ieee80211_local { +@@ -1382,7 +1382,7 @@ struct ieee80211_local { spinlock_t queue_stop_reason_lock; int open_count; @@ -22,7 +22,7 @@ Signed-off-by: Felix Fietkau fif_probe_req; --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c -@@ -1094,6 +1094,8 @@ void ieee80211_adjust_monitor_flags(stru +@@ -1103,6 +1103,8 @@ void ieee80211_adjust_monitor_flags(stru ADJUST(CONTROL, control); ADJUST(CONTROL, pspoll); ADJUST(OTHER_BSS, other_bss); diff --git a/package/kernel/mac80211/patches/subsys/338-wifi-mac80211-handle-DFS-per-link.patch b/package/kernel/mac80211/patches/subsys/338-wifi-mac80211-handle-DFS-per-link.patch deleted file mode 100644 index 388c0575c88582..00000000000000 --- a/package/kernel/mac80211/patches/subsys/338-wifi-mac80211-handle-DFS-per-link.patch +++ /dev/null @@ -1,134 +0,0 @@ -From: Aditya Kumar Singh -Date: Fri, 6 Sep 2024 12:14:24 +0530 -Subject: [PATCH] wifi: mac80211: handle DFS per link - -In order to support DFS with MLO, handle the link ID now passed from -cfg80211, adjust the code to do everything per link and call the -notifications to cfg80211 correctly. - -Signed-off-by: Aditya Kumar Singh -Link: https://patch.msgid.link/20240906064426.2101315-7-quic_adisi@quicinc.com -Signed-off-by: Johannes Berg ---- - ---- a/net/mac80211/cfg.c -+++ b/net/mac80211/cfg.c -@@ -3464,6 +3464,7 @@ static int ieee80211_start_radar_detecti - struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); - struct ieee80211_chan_req chanreq = { .oper = *chandef }; - struct ieee80211_local *local = sdata->local; -+ struct ieee80211_link_data *link_data; - int err; - - lockdep_assert_wiphy(local->hw.wiphy); -@@ -3471,16 +3472,20 @@ static int ieee80211_start_radar_detecti - if (!list_empty(&local->roc_list) || local->scanning) - return -EBUSY; - -+ link_data = sdata_dereference(sdata->link[link_id], sdata); -+ if (!link_data) -+ return -ENOLINK; -+ - /* whatever, but channel contexts should not complain about that one */ -- sdata->deflink.smps_mode = IEEE80211_SMPS_OFF; -- sdata->deflink.needed_rx_chains = local->rx_chains; -+ link_data->smps_mode = IEEE80211_SMPS_OFF; -+ link_data->needed_rx_chains = local->rx_chains; - -- err = ieee80211_link_use_channel(&sdata->deflink, &chanreq, -+ err = ieee80211_link_use_channel(link_data, &chanreq, - IEEE80211_CHANCTX_SHARED); - if (err) - return err; - -- wiphy_delayed_work_queue(wiphy, &sdata->deflink.dfs_cac_timer_work, -+ wiphy_delayed_work_queue(wiphy, &link_data->dfs_cac_timer_work, - msecs_to_jiffies(cac_time_ms)); - - return 0; -@@ -3491,16 +3496,21 @@ static void ieee80211_end_cac(struct wip - { - struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); - struct ieee80211_local *local = sdata->local; -+ struct ieee80211_link_data *link_data; - - lockdep_assert_wiphy(local->hw.wiphy); - - list_for_each_entry(sdata, &local->interfaces, list) { -+ link_data = sdata_dereference(sdata->link[link_id], sdata); -+ if (!link_data) -+ continue; -+ - wiphy_delayed_work_cancel(wiphy, -- &sdata->deflink.dfs_cac_timer_work); -+ &link_data->dfs_cac_timer_work); - -- if (sdata->wdev.links[0].cac_started) { -- ieee80211_link_release_channel(&sdata->deflink); -- sdata->wdev.links[0].cac_started = false; -+ if (sdata->wdev.links[link_id].cac_started) { -+ ieee80211_link_release_channel(link_data); -+ sdata->wdev.links[link_id].cac_started = false; - } - } - } ---- a/net/mac80211/link.c -+++ b/net/mac80211/link.c -@@ -77,6 +77,16 @@ void ieee80211_link_stop(struct ieee8021 - &link->color_change_finalize_work); - wiphy_work_cancel(link->sdata->local->hw.wiphy, - &link->csa.finalize_work); -+ -+ if (link->sdata->wdev.links[link->link_id].cac_started) { -+ wiphy_delayed_work_cancel(link->sdata->local->hw.wiphy, -+ &link->dfs_cac_timer_work); -+ cfg80211_cac_event(link->sdata->dev, -+ &link->conf->chanreq.oper, -+ NL80211_RADAR_CAC_ABORTED, -+ GFP_KERNEL, link->link_id); -+ } -+ - ieee80211_link_release_channel(link); - } - ---- a/net/mac80211/util.c -+++ b/net/mac80211/util.c -@@ -3455,20 +3455,30 @@ void ieee80211_dfs_cac_cancel(struct iee - { - struct ieee80211_sub_if_data *sdata; - struct cfg80211_chan_def chandef; -+ struct ieee80211_link_data *link; -+ unsigned int link_id; - - lockdep_assert_wiphy(local->hw.wiphy); - - list_for_each_entry(sdata, &local->interfaces, list) { -- wiphy_delayed_work_cancel(local->hw.wiphy, -- &sdata->deflink.dfs_cac_timer_work); -+ for (link_id = 0; link_id < IEEE80211_MLD_MAX_NUM_LINKS; -+ link_id++) { -+ link = sdata_dereference(sdata->link[link_id], -+ sdata); -+ if (!link) -+ continue; - -- if (sdata->wdev.links[0].cac_started) { -- chandef = sdata->vif.bss_conf.chanreq.oper; -- ieee80211_link_release_channel(&sdata->deflink); -- cfg80211_cac_event(sdata->dev, -- &chandef, -+ wiphy_delayed_work_cancel(local->hw.wiphy, -+ &link->dfs_cac_timer_work); -+ -+ if (!sdata->wdev.links[link_id].cac_started) -+ continue; -+ -+ chandef = link->conf->chanreq.oper; -+ ieee80211_link_release_channel(link); -+ cfg80211_cac_event(sdata->dev, &chandef, - NL80211_RADAR_CAC_ABORTED, -- GFP_KERNEL, 0); -+ GFP_KERNEL, link_id); - } - } - } diff --git a/package/kernel/mac80211/patches/subsys/358-wifi-mac80211-refactor-ieee80211_rx_monitor.patch b/package/kernel/mac80211/patches/subsys/338-wifi-mac80211-refactor-ieee80211_rx_monitor.patch similarity index 100% rename from package/kernel/mac80211/patches/subsys/358-wifi-mac80211-refactor-ieee80211_rx_monitor.patch rename to package/kernel/mac80211/patches/subsys/338-wifi-mac80211-refactor-ieee80211_rx_monitor.patch diff --git a/package/kernel/mac80211/patches/subsys/339-wifi-cfg80211-mac80211-use-proper-link-ID-for-DFS.patch b/package/kernel/mac80211/patches/subsys/339-wifi-cfg80211-mac80211-use-proper-link-ID-for-DFS.patch deleted file mode 100644 index 53079b6cf629e0..00000000000000 --- a/package/kernel/mac80211/patches/subsys/339-wifi-cfg80211-mac80211-use-proper-link-ID-for-DFS.patch +++ /dev/null @@ -1,168 +0,0 @@ -From: Aditya Kumar Singh -Date: Fri, 6 Sep 2024 12:14:25 +0530 -Subject: [PATCH] wifi: cfg80211/mac80211: use proper link ID for DFS - -Now that all APIs have support to handle DFS per link, use proper link ID -instead of 0. - -Signed-off-by: Aditya Kumar Singh -Link: https://patch.msgid.link/20240906064426.2101315-8-quic_adisi@quicinc.com -Signed-off-by: Johannes Berg ---- - ---- a/net/mac80211/cfg.c -+++ b/net/mac80211/cfg.c -@@ -1656,12 +1656,12 @@ static int ieee80211_stop_ap(struct wiph - ieee80211_link_info_change_notify(sdata, link, - BSS_CHANGED_BEACON_ENABLED); - -- if (sdata->wdev.links[0].cac_started) { -+ if (sdata->wdev.links[link_id].cac_started) { - chandef = link_conf->chanreq.oper; - wiphy_delayed_work_cancel(wiphy, &link->dfs_cac_timer_work); - cfg80211_cac_event(sdata->dev, &chandef, - NL80211_RADAR_CAC_ABORTED, -- GFP_KERNEL, 0); -+ GFP_KERNEL, link_id); - } - - drv_stop_ap(sdata->local, sdata, link_conf); -@@ -3965,7 +3965,7 @@ __ieee80211_channel_switch(struct wiphy - if (!list_empty(&local->roc_list) || local->scanning) - return -EBUSY; - -- if (sdata->wdev.links[0].cac_started) -+ if (sdata->wdev.links[link_id].cac_started) - return -EBUSY; - - if (WARN_ON(link_id >= IEEE80211_MLD_MAX_NUM_LINKS)) ---- a/net/mac80211/mlme.c -+++ b/net/mac80211/mlme.c -@@ -3039,11 +3039,11 @@ void ieee80211_dfs_cac_timer_work(struct - - lockdep_assert_wiphy(sdata->local->hw.wiphy); - -- if (sdata->wdev.links[0].cac_started) { -+ if (sdata->wdev.links[link->link_id].cac_started) { - ieee80211_link_release_channel(link); - cfg80211_cac_event(sdata->dev, &chandef, - NL80211_RADAR_CAC_FINISHED, -- GFP_KERNEL, 0); -+ GFP_KERNEL, link->link_id); - } - } - ---- a/net/mac80211/scan.c -+++ b/net/mac80211/scan.c -@@ -575,6 +575,7 @@ static bool __ieee80211_can_leave_ch(str - { - struct ieee80211_local *local = sdata->local; - struct ieee80211_sub_if_data *sdata_iter; -+ unsigned int link_id; - - lockdep_assert_wiphy(local->hw.wiphy); - -@@ -585,8 +586,9 @@ static bool __ieee80211_can_leave_ch(str - return false; - - list_for_each_entry(sdata_iter, &local->interfaces, list) { -- if (sdata_iter->wdev.links[0].cac_started) -- return false; -+ for_each_valid_link(&sdata_iter->wdev, link_id) -+ if (sdata_iter->wdev.links[link_id].cac_started) -+ return false; - } - - return true; ---- a/net/wireless/mlme.c -+++ b/net/wireless/mlme.c -@@ -1125,14 +1125,14 @@ void cfg80211_cac_event(struct net_devic - - trace_cfg80211_cac_event(netdev, event, link_id); - -- if (WARN_ON(!wdev->links[0].cac_started && -+ if (WARN_ON(!wdev->links[link_id].cac_started && - event != NL80211_RADAR_CAC_STARTED)) - return; - - switch (event) { - case NL80211_RADAR_CAC_FINISHED: -- timeout = wdev->links[0].cac_start_time + -- msecs_to_jiffies(wdev->links[0].cac_time_ms); -+ timeout = wdev->links[link_id].cac_start_time + -+ msecs_to_jiffies(wdev->links[link_id].cac_time_ms); - WARN_ON(!time_after_eq(jiffies, timeout)); - cfg80211_set_dfs_state(wiphy, chandef, NL80211_DFS_AVAILABLE); - memcpy(&rdev->cac_done_chandef, chandef, -@@ -1141,10 +1141,10 @@ void cfg80211_cac_event(struct net_devic - cfg80211_sched_dfs_chan_update(rdev); - fallthrough; - case NL80211_RADAR_CAC_ABORTED: -- wdev->links[0].cac_started = false; -+ wdev->links[link_id].cac_started = false; - break; - case NL80211_RADAR_CAC_STARTED: -- wdev->links[0].cac_started = true; -+ wdev->links[link_id].cac_started = true; - break; - default: - WARN_ON(1); ---- a/net/wireless/nl80211.c -+++ b/net/wireless/nl80211.c -@@ -6066,7 +6066,7 @@ static int nl80211_start_ap(struct sk_bu - if (!rdev->ops->start_ap) - return -EOPNOTSUPP; - -- if (wdev->links[0].cac_started) -+ if (wdev->links[link_id].cac_started) - return -EBUSY; - - if (wdev->links[link_id].ap.beacon_interval) -@@ -10073,6 +10073,7 @@ static int nl80211_start_radar_detection - struct cfg80211_registered_device *rdev = info->user_ptr[0]; - struct net_device *dev = info->user_ptr[1]; - struct wireless_dev *wdev = dev->ieee80211_ptr; -+ int link_id = nl80211_link_id(info->attrs); - struct wiphy *wiphy = wdev->wiphy; - struct cfg80211_chan_def chandef; - enum nl80211_dfs_regions dfs_region; -@@ -10127,7 +10128,7 @@ static int nl80211_start_radar_detection - * can not already beacon - */ - if (wdev->valid_links && -- !wdev->links[0].ap.beacon_interval) { -+ !wdev->links[link_id].ap.beacon_interval) { - /* nothing */ - } else { - err = -EBUSY; -@@ -10135,7 +10136,7 @@ static int nl80211_start_radar_detection - } - } - -- if (wdev->links[0].cac_started) { -+ if (wdev->links[link_id].cac_started) { - err = -EBUSY; - goto unlock; - } -@@ -10156,7 +10157,7 @@ static int nl80211_start_radar_detection - cac_time_ms = IEEE80211_DFS_MIN_CAC_TIME_MS; - - err = rdev_start_radar_detection(rdev, dev, &chandef, cac_time_ms, -- 0); -+ link_id); - if (!err) { - switch (wdev->iftype) { - case NL80211_IFTYPE_AP: -@@ -10172,9 +10173,9 @@ static int nl80211_start_radar_detection - default: - break; - } -- wdev->links[0].cac_started = true; -- wdev->links[0].cac_start_time = jiffies; -- wdev->links[0].cac_time_ms = cac_time_ms; -+ wdev->links[link_id].cac_started = true; -+ wdev->links[link_id].cac_start_time = jiffies; -+ wdev->links[link_id].cac_time_ms = cac_time_ms; - } - unlock: - wiphy_unlock(wiphy); diff --git a/package/kernel/mac80211/patches/subsys/359-wifi-mac80211-filter-on-monitor-interfaces-based-on-.patch b/package/kernel/mac80211/patches/subsys/339-wifi-mac80211-filter-on-monitor-interfaces-based-on-.patch similarity index 100% rename from package/kernel/mac80211/patches/subsys/359-wifi-mac80211-filter-on-monitor-interfaces-based-on-.patch rename to package/kernel/mac80211/patches/subsys/339-wifi-mac80211-filter-on-monitor-interfaces-based-on-.patch diff --git a/package/kernel/mac80211/patches/subsys/360-wifi-cfg80211-report-per-wiphy-radio-antenna-mask.patch b/package/kernel/mac80211/patches/subsys/340-wifi-cfg80211-report-per-wiphy-radio-antenna-mask.patch similarity index 88% rename from package/kernel/mac80211/patches/subsys/360-wifi-cfg80211-report-per-wiphy-radio-antenna-mask.patch rename to package/kernel/mac80211/patches/subsys/340-wifi-cfg80211-report-per-wiphy-radio-antenna-mask.patch index 178e01dc163ca8..8ce24cd3e642d3 100644 --- a/package/kernel/mac80211/patches/subsys/360-wifi-cfg80211-report-per-wiphy-radio-antenna-mask.patch +++ b/package/kernel/mac80211/patches/subsys/340-wifi-cfg80211-report-per-wiphy-radio-antenna-mask.patch @@ -11,7 +11,7 @@ Signed-off-by: Felix Fietkau --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h -@@ -5443,6 +5443,8 @@ struct wiphy_radio_freq_range { +@@ -5446,6 +5446,8 @@ struct wiphy_radio_freq_range { * @iface_combinations: Valid interface combinations array, should not * list single interface types. * @n_iface_combinations: number of entries in @iface_combinations array. @@ -20,7 +20,7 @@ Signed-off-by: Felix Fietkau */ struct wiphy_radio { const struct wiphy_radio_freq_range *freq_range; -@@ -5450,6 +5452,8 @@ struct wiphy_radio { +@@ -5453,6 +5455,8 @@ struct wiphy_radio { const struct ieee80211_iface_combination *iface_combinations; int n_iface_combinations; @@ -31,7 +31,7 @@ Signed-off-by: Felix Fietkau #define CFG80211_HW_TIMESTAMP_ALL_PEERS 0xffff --- a/include/uapi/linux/nl80211.h +++ b/include/uapi/linux/nl80211.h -@@ -8038,6 +8038,8 @@ enum nl80211_ap_settings_flags { +@@ -8044,6 +8044,8 @@ enum nl80211_ap_settings_flags { * @NL80211_WIPHY_RADIO_ATTR_INTERFACE_COMBINATION: Supported interface * combination for this radio. Attribute may be present multiple times * and contains attributes defined in &enum nl80211_if_combination_attrs. @@ -40,7 +40,7 @@ Signed-off-by: Felix Fietkau * * @__NL80211_WIPHY_RADIO_ATTR_LAST: Internal * @NL80211_WIPHY_RADIO_ATTR_MAX: Highest attribute -@@ -8048,6 +8050,7 @@ enum nl80211_wiphy_radio_attrs { +@@ -8054,6 +8056,7 @@ enum nl80211_wiphy_radio_attrs { NL80211_WIPHY_RADIO_ATTR_INDEX, NL80211_WIPHY_RADIO_ATTR_FREQ_RANGE, NL80211_WIPHY_RADIO_ATTR_INTERFACE_COMBINATION, @@ -50,7 +50,7 @@ Signed-off-by: Felix Fietkau __NL80211_WIPHY_RADIO_ATTR_LAST, --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c -@@ -2431,6 +2431,11 @@ static int nl80211_put_radio(struct wiph +@@ -2438,6 +2438,11 @@ static int nl80211_put_radio(struct wiph if (nla_put_u32(msg, NL80211_WIPHY_RADIO_ATTR_INDEX, idx)) goto nla_put_failure; diff --git a/package/kernel/mac80211/patches/subsys/340-wifi-mac80211-handle-ieee80211_radar_detected-for-ML.patch b/package/kernel/mac80211/patches/subsys/340-wifi-mac80211-handle-ieee80211_radar_detected-for-ML.patch deleted file mode 100644 index 3f64864bd41f2e..00000000000000 --- a/package/kernel/mac80211/patches/subsys/340-wifi-mac80211-handle-ieee80211_radar_detected-for-ML.patch +++ /dev/null @@ -1,360 +0,0 @@ -From: Aditya Kumar Singh -Date: Fri, 6 Sep 2024 12:14:26 +0530 -Subject: [PATCH] wifi: mac80211: handle ieee80211_radar_detected() for MLO - -Currently DFS works under assumption there could be only one channel -context in the hardware. Hence, drivers just calls the function -ieee80211_radar_detected() passing the hardware structure. However, with -MLO, this obviously will not work since number of channel contexts will be -more than one and hence drivers would need to pass the channel information -as well on which the radar is detected. - -Also, when radar is detected in one of the links, other link's CAC should -not be cancelled. - -Hence, in order to support DFS with MLO, do the following changes - - * Add channel context conf pointer as an argument to the function - ieee80211_radar_detected(). During MLO, drivers would have to pass on - which channel context conf radar is detected. Otherwise, drivers could - just pass NULL. - * ieee80211_radar_detected() will iterate over all channel contexts - present and - * if channel context conf is passed, only mark that as radar - detected - * if NULL is passed, then mark all channel contexts as radar - detected - * Then as usual, schedule the radar detected work. - * In the worker, go over all the contexts again and for all such context - which is marked with radar detected, cancel the ongoing CAC by calling - ieee80211_dfs_cac_cancel() and then notify cfg80211 via - cfg80211_radar_event(). - * To cancel the CAC, pass the channel context as well where radar is - detected to ieee80211_dfs_cac_cancel(). This ensures that CAC is - canceled only on the links using the provided context, leaving other - links unaffected. - -This would also help in scenarios where there is split phy 5 GHz radio, -which is capable of DFS channels in both lower and upper band. In this -case, simultaneous radars can be detected. - -Signed-off-by: Aditya Kumar Singh -Link: https://patch.msgid.link/20240906064426.2101315-9-quic_adisi@quicinc.com -Signed-off-by: Johannes Berg ---- - ---- a/drivers/net/wireless/ath/ath10k/debug.c -+++ b/drivers/net/wireless/ath/ath10k/debug.c -@@ -3,7 +3,7 @@ - * Copyright (c) 2005-2011 Atheros Communications Inc. - * Copyright (c) 2011-2017 Qualcomm Atheros, Inc. - * Copyright (c) 2018, The Linux Foundation. All rights reserved. -- * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. -+ * Copyright (c) 2022, 2024 Qualcomm Innovation Center, Inc. All rights reserved. - */ - - #include -@@ -1774,7 +1774,7 @@ static ssize_t ath10k_write_simulate_rad - if (!arvif->is_started) - return -EINVAL; - -- ieee80211_radar_detected(ar->hw); -+ ieee80211_radar_detected(ar->hw, NULL); - - return count; - } ---- a/drivers/net/wireless/ath/ath10k/mac.c -+++ b/drivers/net/wireless/ath/ath10k/mac.c -@@ -1437,7 +1437,7 @@ static void ath10k_recalc_radar_detectio - * by indicating that radar was detected. - */ - ath10k_warn(ar, "failed to start CAC: %d\n", ret); -- ieee80211_radar_detected(ar->hw); -+ ieee80211_radar_detected(ar->hw, NULL); - } - } - ---- a/drivers/net/wireless/ath/ath10k/wmi.c -+++ b/drivers/net/wireless/ath/ath10k/wmi.c -@@ -3990,7 +3990,7 @@ static void ath10k_radar_detected(struct - if (ar->dfs_block_radar_events) - ath10k_info(ar, "DFS Radar detected, but ignored as requested\n"); - else -- ieee80211_radar_detected(ar->hw); -+ ieee80211_radar_detected(ar->hw, NULL); - } - - static void ath10k_radar_confirmation_work(struct work_struct *work) ---- a/drivers/net/wireless/ath/ath11k/wmi.c -+++ b/drivers/net/wireless/ath/ath11k/wmi.c -@@ -8358,7 +8358,7 @@ ath11k_wmi_pdev_dfs_radar_detected_event - if (ar->dfs_block_radar_events) - ath11k_info(ab, "DFS Radar detected, but ignored as requested\n"); - else -- ieee80211_radar_detected(ar->hw); -+ ieee80211_radar_detected(ar->hw, NULL); - - exit: - rcu_read_unlock(); ---- a/drivers/net/wireless/ath/ath12k/wmi.c -+++ b/drivers/net/wireless/ath/ath12k/wmi.c -@@ -6789,7 +6789,7 @@ ath12k_wmi_pdev_dfs_radar_detected_event - if (ar->dfs_block_radar_events) - ath12k_info(ab, "DFS Radar detected, but ignored as requested\n"); - else -- ieee80211_radar_detected(ath12k_ar_to_hw(ar)); -+ ieee80211_radar_detected(ath12k_ar_to_hw(ar), NULL); - - exit: - rcu_read_unlock(); ---- a/drivers/net/wireless/ath/ath9k/dfs.c -+++ b/drivers/net/wireless/ath/ath9k/dfs.c -@@ -280,7 +280,7 @@ ath9k_dfs_process_radar_pulse(struct ath - if (!pd->add_pulse(pd, pe, NULL)) - return; - DFS_STAT_INC(sc, radar_detected); -- ieee80211_radar_detected(sc->hw); -+ ieee80211_radar_detected(sc->hw, NULL); - } - - /* ---- a/drivers/net/wireless/ath/ath9k/dfs_debug.c -+++ b/drivers/net/wireless/ath/ath9k/dfs_debug.c -@@ -116,7 +116,7 @@ static ssize_t write_file_simulate_radar - { - struct ath_softc *sc = file->private_data; - -- ieee80211_radar_detected(sc->hw); -+ ieee80211_radar_detected(sc->hw, NULL); - - return count; - } ---- a/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c -+++ b/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c -@@ -394,7 +394,7 @@ mt7615_mcu_rx_radar_detected(struct mt76 - if (mt76_phy_dfs_state(mphy) < MT_DFS_STATE_CAC) - return; - -- ieee80211_radar_detected(mphy->hw); -+ ieee80211_radar_detected(mphy->hw, NULL); - dev->hw_pattern++; - } - ---- a/drivers/net/wireless/mediatek/mt76/mt76x02_dfs.c -+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_dfs.c -@@ -630,7 +630,7 @@ static void mt76x02_dfs_tasklet(struct t - radar_detected = mt76x02_dfs_check_detection(dev); - if (radar_detected) { - /* sw detector rx radar pattern */ -- ieee80211_radar_detected(dev->mt76.hw); -+ ieee80211_radar_detected(dev->mt76.hw, NULL); - mt76x02_dfs_detector_reset(dev); - - return; -@@ -658,7 +658,7 @@ static void mt76x02_dfs_tasklet(struct t - - /* hw detector rx radar pattern */ - dfs_pd->stats[i].hw_pattern++; -- ieee80211_radar_detected(dev->mt76.hw); -+ ieee80211_radar_detected(dev->mt76.hw, NULL); - mt76x02_dfs_detector_reset(dev); - - return; ---- a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c -+++ b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c -@@ -293,7 +293,7 @@ mt7915_mcu_rx_radar_detected(struct mt79 - &dev->rdd2_chandef, - GFP_ATOMIC); - else -- ieee80211_radar_detected(mphy->hw); -+ ieee80211_radar_detected(mphy->hw, NULL); - dev->hw_pattern++; - } - ---- a/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c -+++ b/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c -@@ -371,7 +371,7 @@ mt7996_mcu_rx_radar_detected(struct mt79 - &dev->rdd2_chandef, - GFP_ATOMIC); - else -- ieee80211_radar_detected(mphy->hw); -+ ieee80211_radar_detected(mphy->hw, NULL); - dev->hw_pattern++; - } - ---- a/drivers/net/wireless/ti/wl18xx/event.c -+++ b/drivers/net/wireless/ti/wl18xx/event.c -@@ -142,7 +142,7 @@ int wl18xx_process_mailbox_events(struct - wl18xx_radar_type_decode(mbox->radar_type)); - - if (!wl->radar_debug_mode) -- ieee80211_radar_detected(wl->hw); -+ ieee80211_radar_detected(wl->hw, NULL); - } - - if (vector & PERIODIC_SCAN_REPORT_EVENT_ID) { ---- a/drivers/net/wireless/virtual/mac80211_hwsim.c -+++ b/drivers/net/wireless/virtual/mac80211_hwsim.c -@@ -1146,7 +1146,7 @@ static int hwsim_write_simulate_radar(vo - { - struct mac80211_hwsim_data *data = dat; - -- ieee80211_radar_detected(data->hw); -+ ieee80211_radar_detected(data->hw, NULL); - - return 0; - } ---- a/include/net/mac80211.h -+++ b/include/net/mac80211.h -@@ -6717,8 +6717,11 @@ void ieee80211_cqm_beacon_loss_notify(st - * ieee80211_radar_detected - inform that a radar was detected - * - * @hw: pointer as obtained from ieee80211_alloc_hw() -+ * @chanctx_conf: Channel context on which radar is detected. Mandatory to -+ * pass a valid pointer during MLO. For non-MLO %NULL can be passed - */ --void ieee80211_radar_detected(struct ieee80211_hw *hw); -+void ieee80211_radar_detected(struct ieee80211_hw *hw, -+ struct ieee80211_chanctx_conf *chanctx_conf); - - /** - * ieee80211_chswitch_done - Complete channel switch process ---- a/net/mac80211/chan.c -+++ b/net/mac80211/chan.c -@@ -681,6 +681,7 @@ ieee80211_alloc_chanctx(struct ieee80211 - ctx->mode = mode; - ctx->conf.radar_enabled = false; - ctx->conf.radio_idx = radio_idx; -+ ctx->radar_detected = false; - _ieee80211_recalc_chanctx_min_def(local, ctx, NULL, false); - - return ctx; ---- a/net/mac80211/ieee80211_i.h -+++ b/net/mac80211/ieee80211_i.h -@@ -895,6 +895,8 @@ struct ieee80211_chanctx { - struct ieee80211_chan_req req; - - struct ieee80211_chanctx_conf conf; -+ -+ bool radar_detected; - }; - - struct mac80211_qos_map { -@@ -2632,7 +2634,8 @@ void ieee80211_recalc_chanctx_min_def(st - bool ieee80211_is_radar_required(struct ieee80211_local *local); - - void ieee80211_dfs_cac_timer_work(struct wiphy *wiphy, struct wiphy_work *work); --void ieee80211_dfs_cac_cancel(struct ieee80211_local *local); -+void ieee80211_dfs_cac_cancel(struct ieee80211_local *local, -+ struct ieee80211_chanctx *chanctx); - void ieee80211_dfs_radar_detected_work(struct wiphy *wiphy, - struct wiphy_work *work); - int ieee80211_send_action_csa(struct ieee80211_sub_if_data *sdata, ---- a/net/mac80211/pm.c -+++ b/net/mac80211/pm.c -@@ -32,7 +32,7 @@ int __ieee80211_suspend(struct ieee80211 - - ieee80211_scan_cancel(local); - -- ieee80211_dfs_cac_cancel(local); -+ ieee80211_dfs_cac_cancel(local, NULL); - - ieee80211_roc_purge(local, NULL); - ---- a/net/mac80211/util.c -+++ b/net/mac80211/util.c -@@ -3451,11 +3451,16 @@ u64 ieee80211_calculate_rx_timestamp(str - return ts; - } - --void ieee80211_dfs_cac_cancel(struct ieee80211_local *local) -+/* Cancel CAC for the interfaces under the specified @local. If @ctx is -+ * also provided, only the interfaces using that ctx will be canceled. -+ */ -+void ieee80211_dfs_cac_cancel(struct ieee80211_local *local, -+ struct ieee80211_chanctx *ctx) - { - struct ieee80211_sub_if_data *sdata; - struct cfg80211_chan_def chandef; - struct ieee80211_link_data *link; -+ struct ieee80211_chanctx_conf *chanctx_conf; - unsigned int link_id; - - lockdep_assert_wiphy(local->hw.wiphy); -@@ -3468,6 +3473,11 @@ void ieee80211_dfs_cac_cancel(struct iee - if (!link) - continue; - -+ chanctx_conf = sdata_dereference(link->conf->chanctx_conf, -+ sdata); -+ if (ctx && &ctx->conf != chanctx_conf) -+ continue; -+ - wiphy_delayed_work_cancel(local->hw.wiphy, - &link->dfs_cac_timer_work); - -@@ -3488,9 +3498,8 @@ void ieee80211_dfs_radar_detected_work(s - { - struct ieee80211_local *local = - container_of(work, struct ieee80211_local, radar_detected_work); -- struct cfg80211_chan_def chandef = local->hw.conf.chandef; -+ struct cfg80211_chan_def chandef; - struct ieee80211_chanctx *ctx; -- int num_chanctx = 0; - - lockdep_assert_wiphy(local->hw.wiphy); - -@@ -3498,25 +3507,46 @@ void ieee80211_dfs_radar_detected_work(s - if (ctx->replace_state == IEEE80211_CHANCTX_REPLACES_OTHER) - continue; - -- num_chanctx++; -+ if (!ctx->radar_detected) -+ continue; -+ -+ ctx->radar_detected = false; -+ - chandef = ctx->conf.def; -+ -+ ieee80211_dfs_cac_cancel(local, ctx); -+ cfg80211_radar_event(local->hw.wiphy, &chandef, GFP_KERNEL); - } -+} - -- ieee80211_dfs_cac_cancel(local); -+static void -+ieee80211_radar_mark_chan_ctx_iterator(struct ieee80211_hw *hw, -+ struct ieee80211_chanctx_conf *chanctx_conf, -+ void *data) -+{ -+ struct ieee80211_chanctx *ctx = -+ container_of(chanctx_conf, struct ieee80211_chanctx, -+ conf); - -- if (num_chanctx > 1) -- /* XXX: multi-channel is not supported yet */ -- WARN_ON(1); -- else -- cfg80211_radar_event(local->hw.wiphy, &chandef, GFP_KERNEL); -+ if (ctx->replace_state == IEEE80211_CHANCTX_REPLACES_OTHER) -+ return; -+ -+ if (data && data != chanctx_conf) -+ return; -+ -+ ctx->radar_detected = true; - } - --void ieee80211_radar_detected(struct ieee80211_hw *hw) -+void ieee80211_radar_detected(struct ieee80211_hw *hw, -+ struct ieee80211_chanctx_conf *chanctx_conf) - { - struct ieee80211_local *local = hw_to_local(hw); - - trace_api_radar_detected(local); - -+ ieee80211_iter_chan_contexts_atomic(hw, ieee80211_radar_mark_chan_ctx_iterator, -+ chanctx_conf); -+ - wiphy_work_queue(hw->wiphy, &local->radar_detected_work); - } - EXPORT_SYMBOL(ieee80211_radar_detected); diff --git a/package/kernel/mac80211/patches/subsys/341-wifi-mac80211-fix-vif-addr-when-switching-from-monit.patch b/package/kernel/mac80211/patches/subsys/341-wifi-mac80211-fix-vif-addr-when-switching-from-monit.patch new file mode 100644 index 00000000000000..4e6d2ee5e9366b --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/341-wifi-mac80211-fix-vif-addr-when-switching-from-monit.patch @@ -0,0 +1,63 @@ +From: Felix Fietkau +Date: Fri, 15 Nov 2024 12:28:43 +0100 +Subject: [PATCH] wifi: mac80211: fix vif addr when switching from monitor + to station + +Since adding support for opting out of virtual monitor support, a zero vif +addr was used to indicate passive vs active monitor to the driver. +This would break the vif->addr when changing the netdev mac address before +switching the interface from monitor to sta mode. +Fix the regression by adding a separate flag to indicate whether vif->addr +is valid. + +Reported-by: syzbot+9ea265d998de25ac6a46@syzkaller.appspotmail.com +Fixes: 9d40f7e32774 ("wifi: mac80211: add flag to opt out of virtual monitor support") +Signed-off-by: Felix Fietkau +--- + +--- a/include/net/mac80211.h ++++ b/include/net/mac80211.h +@@ -1972,6 +1972,8 @@ enum ieee80211_neg_ttlm_res { + * @neg_ttlm: negotiated TID to link mapping info. + * see &struct ieee80211_neg_ttlm. + * @addr: address of this interface ++ * @addr_valid: indicates if the address is actively used. Set to false for ++ * passive monitor interfaces, true in all other cases. + * @p2p: indicates whether this AP or STA interface is a p2p + * interface, i.e. a GO or p2p-sta respectively + * @netdev_features: tx netdev features supported by the hardware for this +@@ -2011,6 +2013,7 @@ struct ieee80211_vif { + u16 valid_links, active_links, dormant_links, suspended_links; + struct ieee80211_neg_ttlm neg_ttlm; + u8 addr[ETH_ALEN] __aligned(2); ++ bool addr_valid; + bool p2p; + + u8 cab_queue; +--- a/net/mac80211/iface.c ++++ b/net/mac80211/iface.c +@@ -279,13 +279,8 @@ static int _ieee80211_change_mac(struct + ret = eth_mac_addr(sdata->dev, sa); + + if (ret == 0) { +- if (check_dup) { +- memcpy(sdata->vif.addr, sa->sa_data, ETH_ALEN); +- ether_addr_copy(sdata->vif.bss_conf.addr, sdata->vif.addr); +- } else { +- memset(sdata->vif.addr, 0, ETH_ALEN); +- memset(sdata->vif.bss_conf.addr, 0, ETH_ALEN); +- } ++ memcpy(sdata->vif.addr, sa->sa_data, ETH_ALEN); ++ ether_addr_copy(sdata->vif.bss_conf.addr, sdata->vif.addr); + } + + /* Regardless of eth_mac_addr() return we still want to add the +@@ -1336,6 +1331,8 @@ int ieee80211_do_open(struct wireless_de + } + } + ++ sdata->vif.addr_valid = sdata->vif.type != NL80211_IFTYPE_MONITOR || ++ (sdata->u.mntr.flags & MONITOR_FLAG_ACTIVE); + switch (sdata->vif.type) { + case NL80211_IFTYPE_AP_VLAN: + /* no need to tell driver, but set carrier and chanctx */ diff --git a/package/kernel/mac80211/patches/subsys/341-wifi-mac80211-skip-non-uploaded-keys-in-ieee80211_it.patch b/package/kernel/mac80211/patches/subsys/341-wifi-mac80211-skip-non-uploaded-keys-in-ieee80211_it.patch deleted file mode 100644 index b426d68c326fd0..00000000000000 --- a/package/kernel/mac80211/patches/subsys/341-wifi-mac80211-skip-non-uploaded-keys-in-ieee80211_it.patch +++ /dev/null @@ -1,79 +0,0 @@ -From: Felix Fietkau -Date: Sun, 6 Oct 2024 17:34:08 +0200 -Subject: [PATCH] wifi: mac80211: skip non-uploaded keys in ieee80211_iter_keys - -Sync iterator conditions with ieee80211_iter_keys_rcu. - -Fixes: 830af02f24fb ("mac80211: allow driver to iterate keys") -Signed-off-by: Felix Fietkau ---- - ---- a/net/mac80211/key.c -+++ b/net/mac80211/key.c -@@ -987,6 +987,26 @@ void ieee80211_reenable_keys(struct ieee - } - } - -+static void -+ieee80211_key_iter(struct ieee80211_hw *hw, -+ struct ieee80211_vif *vif, -+ struct ieee80211_key *key, -+ void (*iter)(struct ieee80211_hw *hw, -+ struct ieee80211_vif *vif, -+ struct ieee80211_sta *sta, -+ struct ieee80211_key_conf *key, -+ void *data), -+ void *iter_data) -+{ -+ /* skip keys of station in removal process */ -+ if (key->sta && key->sta->removed) -+ return; -+ if (!(key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE)) -+ return; -+ iter(hw, vif, key->sta ? &key->sta->sta : NULL, -+ &key->conf, iter_data); -+} -+ - void ieee80211_iter_keys(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - void (*iter)(struct ieee80211_hw *hw, -@@ -1005,16 +1025,13 @@ void ieee80211_iter_keys(struct ieee8021 - if (vif) { - sdata = vif_to_sdata(vif); - list_for_each_entry_safe(key, tmp, &sdata->key_list, list) -- iter(hw, &sdata->vif, -- key->sta ? &key->sta->sta : NULL, -- &key->conf, iter_data); -+ ieee80211_key_iter(hw, vif, key, iter, iter_data); - } else { - list_for_each_entry(sdata, &local->interfaces, list) - list_for_each_entry_safe(key, tmp, - &sdata->key_list, list) -- iter(hw, &sdata->vif, -- key->sta ? &key->sta->sta : NULL, -- &key->conf, iter_data); -+ ieee80211_key_iter(hw, &sdata->vif, key, -+ iter, iter_data); - } - } - EXPORT_SYMBOL(ieee80211_iter_keys); -@@ -1031,17 +1048,8 @@ _ieee80211_iter_keys_rcu(struct ieee8021 - { - struct ieee80211_key *key; - -- list_for_each_entry_rcu(key, &sdata->key_list, list) { -- /* skip keys of station in removal process */ -- if (key->sta && key->sta->removed) -- continue; -- if (!(key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE)) -- continue; -- -- iter(hw, &sdata->vif, -- key->sta ? &key->sta->sta : NULL, -- &key->conf, iter_data); -- } -+ list_for_each_entry_rcu(key, &sdata->key_list, list) -+ ieee80211_key_iter(hw, &sdata->vif, key, iter, iter_data); - } - - void ieee80211_iter_keys_rcu(struct ieee80211_hw *hw, diff --git a/package/kernel/mac80211/patches/subsys/350-wifi-mac80211-Add-link-iteration-macro-for-link-data.patch b/package/kernel/mac80211/patches/subsys/350-wifi-mac80211-Add-link-iteration-macro-for-link-data.patch new file mode 100644 index 00000000000000..fd6e5dc169108f --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/350-wifi-mac80211-Add-link-iteration-macro-for-link-data.patch @@ -0,0 +1,47 @@ +From 4e1916dec9850cd49dd5792200ab649061cbedc1 Mon Sep 17 00:00:00 2001 +From: Maharaja Kennadyrajan +Date: Fri, 18 Jul 2025 11:38:35 +0530 +Subject: [PATCH] wifi: mac80211: Add link iteration macro for link data with + rcu_dereference + +Currently, the existing macro for_each_link_data() uses sdata_dereference() +which requires the wiphy lock. This lock cannot be used in atomic or RCU +read-side contexts, such as in the RX path. + +Introduce a new macro, for_each_link_data_rcu(), that iterates over link of +sdata using rcu_dereference(), making it safe to use in RCU contexts. This +allows callers to access link data without requiring the wiphy lock. + +The macro takes into account the vif.valid_links bitmap and ensures only +valid links are accessed safely. Callers are responsible for ensuring that +rcu_read_lock() is held when using this macro. + +Signed-off-by: Maharaja Kennadyrajan +Link: https://patch.msgid.link/20250718060837.59371-3-maharaja.kennadyrajan@oss.qualcomm.com +Signed-off-by: Johannes Berg +--- + net/mac80211/ieee80211_i.h | 13 +++++++++++++ + 1 file changed, 13 insertions(+) + +--- a/net/mac80211/ieee80211_i.h ++++ b/net/mac80211/ieee80211_i.h +@@ -1220,6 +1220,19 @@ struct ieee80211_sub_if_data *vif_to_sda + ((__link) = sdata_dereference((__sdata)->link[__link_id], \ + (__sdata)))) + ++/* ++ * for_each_link_data_rcu should be used under RCU read lock. ++ */ ++#define for_each_link_data_rcu(sdata, __link) \ ++ /* outer loop just to define the variable ... */ \ ++ for (struct ieee80211_sub_if_data *__sdata = (sdata); __sdata; \ ++ __sdata = NULL /* always stop */) \ ++ for (int __link_id = 0; \ ++ __link_id < ARRAY_SIZE((__sdata)->link); __link_id++) \ ++ if ((!(__sdata)->vif.valid_links || \ ++ (__sdata)->vif.valid_links & BIT(__link_id)) && \ ++ ((__link) = rcu_dereference((__sdata)->link[__link_id]))) \ ++ + static inline int + ieee80211_get_mbssid_beacon_len(struct cfg80211_mbssid_elems *elems, + struct cfg80211_rnr_elems *rnr_elems, diff --git a/package/kernel/mac80211/patches/subsys/351-wifi-mac80211-extend-beacon-monitoring-for-MLO.patch b/package/kernel/mac80211/patches/subsys/351-wifi-mac80211-extend-beacon-monitoring-for-MLO.patch new file mode 100644 index 00000000000000..7722bcf64c9299 --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/351-wifi-mac80211-extend-beacon-monitoring-for-MLO.patch @@ -0,0 +1,77 @@ +From: Maharaja Kennadyrajan +Date: Fri, 18 Jul 2025 11:38:36 +0530 +Subject: [PATCH] wifi: mac80211: extend beacon monitoring for MLO + +Currently, reset beacon monitor (ieee80211_sta_reset_beacon_monitor()) +timer is handled only for non-AP non-MLD STA and do not support non-AP MLD +STA. When the beacon loss occurs in non-AP MLD STA with the current +implementation, it is treated as a single link and the timer will reset +based on the timeout of the deflink, without checking all the links. + +Check the CSA flags for all the links in the MLO and decide whether to +schedule the work queue for beacon loss. If any of the links has CSA +active, then beacon loss work is not scheduled. + +Also, call the functions ieee80211_sta_reset_beacon_monitor() and +ieee80211_sta_reset_conn_monitor() from ieee80211_csa_switch_work() only +when all the links are CSA active. + +Signed-off-by: Maharaja Kennadyrajan +Link: https://patch.msgid.link/20250718060837.59371-4-maharaja.kennadyrajan@oss.qualcomm.com +Signed-off-by: Johannes Berg +--- + +--- a/net/mac80211/mlme.c ++++ b/net/mac80211/mlme.c +@@ -2167,6 +2167,21 @@ static void ieee80211_csa_switch_work(st + } + } + ++ /* ++ * It is not necessary to reset these timers if any link does not ++ * have an active CSA and that link still receives the beacons ++ * when other links have active CSA. ++ */ ++ for_each_link_data(sdata, link) { ++ if (!link->conf->csa_active) ++ return; ++ } ++ ++ /* ++ * Reset the beacon monitor and connection monitor timers when CSA ++ * is active for all links in MLO when channel switch occurs in all ++ * the links. ++ */ + ieee80211_sta_reset_beacon_monitor(sdata); + ieee80211_sta_reset_conn_monitor(sdata); + } +@@ -7892,6 +7907,29 @@ void ieee80211_sta_work(struct ieee80211 + } + } + ++static bool ++ieee80211_is_csa_in_progress(struct ieee80211_sub_if_data *sdata) ++{ ++ /* ++ * In MLO, check the CSA flags 'active' and 'waiting_bcn' for all ++ * the links. ++ */ ++ struct ieee80211_link_data *link; ++ bool ret = true; ++ ++ rcu_read_lock(); ++ for_each_link_data_rcu(sdata, link) { ++ if (!(link->conf->csa_active && ++ !link->u.mgd.csa.waiting_bcn)) { ++ ret = false; ++ break; ++ } ++ } ++ rcu_read_unlock(); ++ ++ return ret; ++} ++ + static void ieee80211_sta_bcn_mon_timer(struct timer_list *t) + { + struct ieee80211_sub_if_data *sdata = diff --git a/package/kernel/mac80211/patches/subsys/352-wifi-mac80211-extend-connection-monitoring-for-MLO.patch b/package/kernel/mac80211/patches/subsys/352-wifi-mac80211-extend-connection-monitoring-for-MLO.patch new file mode 100644 index 00000000000000..9f16bea626a21a --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/352-wifi-mac80211-extend-connection-monitoring-for-MLO.patch @@ -0,0 +1,141 @@ +From: Maharaja Kennadyrajan +Date: Fri, 18 Jul 2025 11:38:37 +0530 +Subject: [PATCH] wifi: mac80211: extend connection monitoring for MLO + +Currently, reset connection monitor (ieee80211_sta_reset_conn_monitor()) +timer is handled only for non-AP non-MLD STA and do not support non-AP MLD +STA. The current implementation checks for the CSA active and update the +monitor timer with the timeout value of deflink and reset the timer based +on the deflink's timeout value else schedule the connection loss work when +the deflink is timed out and it won't work for the non-AP MLD STA. + +Handle the reset connection monitor timer for non-AP MLD STA by updating +the monitor timer with the timeout value which is determined based on the +link that will expire last among all the links in MLO. If at least one link +has not timed out, the timer is updated accordingly with the latest timeout +value else schedule the connection loss work when all links have timed out. + +Remove the MLO-related WARN_ON() checks in the beacon and connection +monitoring logic code paths as they support MLO now. + +Signed-off-by: Maharaja Kennadyrajan +Link: https://patch.msgid.link/20250718060837.59371-5-maharaja.kennadyrajan@oss.qualcomm.com +Signed-off-by: Johannes Berg +--- + +--- a/net/mac80211/mlme.c ++++ b/net/mac80211/mlme.c +@@ -3841,9 +3841,6 @@ static void ieee80211_mgd_probe_ap_send( + + lockdep_assert_wiphy(sdata->local->hw.wiphy); + +- if (WARN_ON(ieee80211_vif_is_mld(&sdata->vif))) +- return; +- + /* + * Try sending broadcast probe requests for the last three + * probe requests after the first ones failed since some +@@ -3889,9 +3886,6 @@ static void ieee80211_mgd_probe_ap(struc + + lockdep_assert_wiphy(sdata->local->hw.wiphy); + +- if (WARN_ON_ONCE(ieee80211_vif_is_mld(&sdata->vif))) +- return; +- + if (!ieee80211_sdata_running(sdata)) + return; + +@@ -7950,36 +7944,73 @@ static void ieee80211_sta_bcn_mon_timer( + &sdata->u.mgd.beacon_connection_loss_work); + } + ++static unsigned long ++ieee80211_latest_active_link_conn_timeout(struct ieee80211_sub_if_data *sdata) ++{ ++ unsigned long latest_timeout = 0; ++ unsigned int link_id; ++ struct sta_info *sta; ++ ++ rcu_read_lock(); ++ ++ sta = sta_info_get(sdata, sdata->vif.cfg.ap_addr); ++ if (!sta) ++ goto out; ++ ++ for (link_id = 0; link_id < ARRAY_SIZE(sta->link); ++ link_id++) { ++ struct link_sta_info *link_sta; ++ unsigned long timeout; ++ ++ link_sta = rcu_dereference(sta->link[link_id]); ++ if (!link_sta) ++ continue; ++ ++ timeout = link_sta->status_stats.last_ack; ++ if (time_before(timeout, link_sta->rx_stats.last_rx)) ++ timeout = link_sta->rx_stats.last_rx; ++ ++ timeout += IEEE80211_CONNECTION_IDLE_TIME; ++ ++ /* ++ * latest_timeout holds the timeout of the link ++ * that will expire last among all links in an ++ * non-AP MLD STA. This ensures that the connection ++ * monitor timer is only reset if at least one link ++ * is still active, and it is scheduled to fire at ++ * the latest possible timeout. ++ */ ++ if (time_is_after_jiffies(timeout) && ++ time_after(timeout, latest_timeout)) ++ latest_timeout = timeout; ++ } ++ ++out: ++ rcu_read_unlock(); ++ ++ return latest_timeout; ++} ++ + static void ieee80211_sta_conn_mon_timer(struct timer_list *t) + { + struct ieee80211_sub_if_data *sdata = + from_timer(sdata, t, u.mgd.conn_mon_timer); + struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; + struct ieee80211_local *local = sdata->local; +- struct sta_info *sta; +- unsigned long timeout; ++ unsigned long latest_timeout; + +- if (WARN_ON(ieee80211_vif_is_mld(&sdata->vif))) ++ if (ieee80211_is_csa_in_progress(sdata)) + return; + +- if (sdata->vif.bss_conf.csa_active && +- !sdata->deflink.u.mgd.csa.waiting_bcn) +- return; +- +- sta = sta_info_get(sdata, sdata->vif.cfg.ap_addr); +- if (!sta) +- return; +- +- timeout = sta->deflink.status_stats.last_ack; +- if (time_before(sta->deflink.status_stats.last_ack, sta->deflink.rx_stats.last_rx)) +- timeout = sta->deflink.rx_stats.last_rx; +- timeout += IEEE80211_CONNECTION_IDLE_TIME; ++ latest_timeout = ieee80211_latest_active_link_conn_timeout(sdata); + +- /* If timeout is after now, then update timer to fire at +- * the later date, but do not actually probe at this time. +- */ +- if (time_is_after_jiffies(timeout)) { +- mod_timer(&ifmgd->conn_mon_timer, round_jiffies_up(timeout)); ++ /* ++ * If latest timeout is after now, then update timer to fire at ++ * the later date, but do not actually probe at this time. ++ */ ++ if (latest_timeout) { ++ mod_timer(&ifmgd->conn_mon_timer, ++ round_jiffies_up(latest_timeout)); + return; + } + diff --git a/package/kernel/mac80211/patches/subsys/353-wifi-mac80211-Make-CONNECTION_MONITOR-optional-for-M.patch b/package/kernel/mac80211/patches/subsys/353-wifi-mac80211-Make-CONNECTION_MONITOR-optional-for-M.patch new file mode 100644 index 00000000000000..bbc02cc21d9d38 --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/353-wifi-mac80211-Make-CONNECTION_MONITOR-optional-for-M.patch @@ -0,0 +1,25 @@ +From: Lorenzo Bianconi +Date: Tue, 26 Aug 2025 13:54:31 +0200 +Subject: [PATCH] wifi: mac80211: Make CONNECTION_MONITOR optional for MLO sta + +Since commit '1bc892d76a6f ("wifi: mac80211: extend connection +monitoring for MLO")' mac80211 supports connection monitor for MLO +client interfaces. Remove the CONNECTION_MONITOR requirement in +ieee80211_register_hw routine. + +Fixes: 1bc892d76a6f ("wifi: mac80211: extend connection monitoring for MLO") +Signed-off-by: Lorenzo Bianconi +--- + +--- a/net/mac80211/main.c ++++ b/net/mac80211/main.c +@@ -1174,9 +1174,6 @@ int ieee80211_register_hw(struct ieee802 + if (WARN_ON(!ieee80211_hw_check(hw, MFP_CAPABLE))) + return -EINVAL; + +- if (WARN_ON(!ieee80211_hw_check(hw, CONNECTION_MONITOR))) +- return -EINVAL; +- + if (WARN_ON(ieee80211_hw_check(hw, NEED_DTIM_BEFORE_ASSOC))) + return -EINVAL; + diff --git a/package/kernel/mac80211/realtek.mk b/package/kernel/mac80211/realtek.mk index 4a6f10cddc51bb..6ac4b1aee9873c 100644 --- a/package/kernel/mac80211/realtek.mk +++ b/package/kernel/mac80211/realtek.mk @@ -4,6 +4,7 @@ PKG_DRIVERS += \ rtl8723bs rtl8821ae rtl8xxxu rtw88 rtw88-pci rtw88-usb rtw88-sdio rtw88-8821c \ rtw88-8822b rtw88-8822c rtw88-8723x rtw88-8723d rtw88-8821ce rtw88-8821cu \ rtw88-8822be rtw88-8822bu rtw88-8822ce rtw88-8822cu rtw88-8723de rtw88-8723ds \ + rtw88-88xxa rtw88-8821a rtw88-8812a rtw88-8821au rtw88-8812au \ rtw88-8723du rtw89 rtw89-pci rtw89-8851be rtw89-8852ae rtw89-8852b-common \ rtw89-8852be rtw89-8852ce rtw89-8922ae @@ -48,6 +49,11 @@ config-$(call config_package,rtw88-8723d) += RTW88_8723D config-$(call config_package,rtw88-8723de) += RTW88_8723DE config-$(call config_package,rtw88-8723ds) += RTW88_8723DS config-$(call config_package,rtw88-8723du) += RTW88_8723DU +config-$(call config_package,rtw88-88xxa) += RTW88_88XXA +config-$(call config_package,rtw88-8821a) += RTW88_8821A +config-$(call config_package,rtw88-8812a) += RTW88_8812A +config-$(call config_package,rtw88-8821au) += RTW88_8821AU +config-$(call config_package,rtw88-8812au) += RTW88_8812AU config-$(CONFIG_PACKAGE_RTW88_DEBUG) += RTW88_DEBUG config-$(CONFIG_PACKAGE_RTW88_DEBUGFS) += RTW88_DEBUGFS @@ -255,6 +261,33 @@ define KernelPackage/rtw88-usb HIDDEN:=1 endef +define KernelPackage/rtw88-88xxa + $(call KernelPackage/mac80211/Default) + TITLE:=Realtek RTL8812A/RTL8821A family support + DEPENDS+= +@DRIVER_11AC_SUPPORT +kmod-rtw88-usb + FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtw88/rtw88_88xxa.ko + AUTOLOAD:=$(call AutoProbe,rtw88_88xxa) + HIDDEN:=1 +endef + +define KernelPackage/rtw88-8821a + $(call KernelPackage/mac80211/Default) + TITLE:=Realtek RTL8821A family support + DEPENDS+= +kmod-rtw88-88xxa + FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtw88/rtw88_8821a.ko + AUTOLOAD:=$(call AutoProbe,rtw88_8821a) + HIDDEN:=1 +endef + +define KernelPackage/rtw88-8812a + $(call KernelPackage/mac80211/Default) + TITLE:=Realtek RTL8812A family support + DEPENDS+= +kmod-rtw88-88xxa + FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtw88/rtw88_8812a.ko + AUTOLOAD:=$(call AutoProbe,rtw88_8812a) + HIDDEN:=1 +endef + define KernelPackage/rtw88-8821c $(call KernelPackage/mac80211/Default) TITLE:=Realtek RTL8821C family support @@ -300,6 +333,22 @@ define KernelPackage/rtw88-8723d HIDDEN:=1 endef +define KernelPackage/rtw88-8821au + $(call KernelPackage/mac80211/Default) + TITLE:=Realtek RTL8821AU support + DEPENDS+= +kmod-rtw88-8821a +rtl8821a-firmware + FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtw88/rtw88_8821au.ko + AUTOLOAD:=$(call AutoProbe,rtw88_8821au) +endef + +define KernelPackage/rtw88-8812au + $(call KernelPackage/mac80211/Default) + TITLE:=Realtek RTL8812AU support + DEPENDS+= +kmod-rtw88-8812a +rtl8812a-firmware + FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtw88/rtw88_8812au.ko + AUTOLOAD:=$(call AutoProbe,rtw88_8812au) +endef + define KernelPackage/rtw88-8821ce $(call KernelPackage/mac80211/Default) TITLE:=Realtek RTL8821CE support diff --git a/package/kernel/mt76/Makefile b/package/kernel/mt76/Makefile index 73f34d8edadf18..b5b9b22873751d 100644 --- a/package/kernel/mt76/Makefile +++ b/package/kernel/mt76/Makefile @@ -8,9 +8,9 @@ PKG_LICENSE_FILES:= PKG_SOURCE_URL:=https://github.com/openwrt/mt76 PKG_SOURCE_PROTO:=git -PKG_SOURCE_DATE:=2024-10-11.1 -PKG_SOURCE_VERSION:=ecca0e77b4bce629ec1f79d83bbd14a68f919188 -PKG_MIRROR_HASH:=770823f282c76532567a651bb020208c3ddd5a728c656fcde43129fc95edf538 +PKG_SOURCE_DATE:=2025-08-27 +PKG_SOURCE_VERSION:=de1df8b888bd1c99ee191f451af47b4fa9658e8c +PKG_MIRROR_HASH:=4ead68e97fc6472a682dae2f96f9dbb377f23c316511f625b85af15de46e9397 PKG_MAINTAINER:=Felix Fietkau PKG_USE_NINJA:=0 diff --git a/package/kernel/mt76/patches/100-api_compat.patch b/package/kernel/mt76/patches/100-api_compat.patch new file mode 100644 index 00000000000000..989967164bd57e --- /dev/null +++ b/package/kernel/mt76/patches/100-api_compat.patch @@ -0,0 +1,84 @@ +--- a/mt7915/main.c ++++ b/mt7915/main.c +@@ -1224,10 +1224,9 @@ static void mt7915_sta_rc_work(void *dat + + static void mt7915_sta_rc_update(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, +- struct ieee80211_link_sta *link_sta, ++ struct ieee80211_sta *sta, + u32 changed) + { +- struct ieee80211_sta *sta = link_sta->sta; + struct mt7915_phy *phy = mt7915_hw_phy(hw); + struct mt7915_dev *dev = phy->dev; + struct mt7915_sta *msta = (struct mt7915_sta *)sta->drv_priv; +@@ -1771,7 +1770,7 @@ const struct ieee80211_ops mt7915_ops = + .stop_ap = mt7915_stop_ap, + .sta_state = mt76_sta_state, + .sta_pre_rcu_remove = mt76_sta_pre_rcu_remove, +- .link_sta_rc_update = mt7915_sta_rc_update, ++ .sta_rc_update = mt7915_sta_rc_update, + .set_key = mt7915_set_key, + .ampdu_action = mt7915_ampdu_action, + .set_rts_threshold = mt7915_set_rts_threshold, +--- a/mt7996/main.c ++++ b/mt7996/main.c +@@ -715,8 +715,7 @@ static void mt7996_configure_filter(stru + } + + static int +-mt7996_get_txpower(struct ieee80211_hw *hw, struct ieee80211_vif *vif, +- unsigned int link_id, int *dbm) ++mt7996_get_txpower(struct ieee80211_hw *hw, struct ieee80211_vif *vif, int *dbm) + { + struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv; + struct mt7996_phy *phy = mt7996_vif_link_phy(&mvif->deflink); +@@ -1687,13 +1686,12 @@ out: + rcu_read_unlock(); + } + +-static void mt7996_link_sta_rc_update(struct ieee80211_hw *hw, +- struct ieee80211_vif *vif, +- struct ieee80211_link_sta *link_sta, +- u32 changed) ++static void mt7996_sta_rc_update(struct ieee80211_hw *hw, ++ struct ieee80211_vif *vif, ++ struct ieee80211_sta *sta, ++ u32 changed) + { + struct mt7996_dev *dev = mt7996_hw_dev(hw); +- struct ieee80211_sta *sta = link_sta->sta; + + mt7996_link_rate_ctrl_update(&changed, sta); + ieee80211_queue_work(hw, &dev->rc_work); +@@ -2186,7 +2184,7 @@ const struct ieee80211_ops mt7996_ops = + .link_info_changed = mt7996_link_info_changed, + .sta_state = mt7996_sta_state, + .sta_pre_rcu_remove = mt76_sta_pre_rcu_remove, +- .link_sta_rc_update = mt7996_link_sta_rc_update, ++ .sta_rc_update = mt7996_sta_rc_update, + .set_key = mt7996_set_key, + .ampdu_action = mt7996_ampdu_action, + .set_rts_threshold = mt7996_set_rts_threshold, +--- a/mac80211.c ++++ b/mac80211.c +@@ -1745,7 +1745,7 @@ s8 mt76_get_power_bound(struct mt76_phy + EXPORT_SYMBOL_GPL(mt76_get_power_bound); + + int mt76_get_txpower(struct ieee80211_hw *hw, struct ieee80211_vif *vif, +- unsigned int link_id, int *dbm) ++ int *dbm) + { + struct mt76_phy *phy = mt76_vif_phy(hw, vif); + int n_chains, delta; +--- a/mt76.h ++++ b/mt76.h +@@ -1521,7 +1521,7 @@ int mt76_get_min_avg_rssi(struct mt76_de + s8 mt76_get_power_bound(struct mt76_phy *phy, s8 txpower); + + int mt76_get_txpower(struct ieee80211_hw *hw, struct ieee80211_vif *vif, +- unsigned int link_id, int *dbm); ++ int *dbm); + int mt76_init_sar_power(struct ieee80211_hw *hw, + const struct cfg80211_sar_specs *sar); + int mt76_get_sar_power(struct mt76_phy *phy, diff --git a/package/kernel/mwlwifi/Makefile b/package/kernel/mwlwifi/Makefile index 3f2d5e0949377d..07c3acc5f909c9 100644 --- a/package/kernel/mwlwifi/Makefile +++ b/package/kernel/mwlwifi/Makefile @@ -8,16 +8,16 @@ include $(TOPDIR)/rules.mk PKG_NAME:=mwlwifi -PKG_RELEASE=2 +PKG_RELEASE=1 PKG_LICENSE:=ISC PKG_LICENSE_FILES:= PKG_SOURCE_URL:=https://github.com/kaloz/mwlwifi PKG_SOURCE_PROTO:=git -PKG_SOURCE_DATE:=2024-04-19 -PKG_SOURCE_VERSION:=a737d348ef4fe00434b2bc44b2b6a68ea833d95b -PKG_MIRROR_HASH:=d55f69c2fa48d02ba535b72b108fc77f5f13a52b29130a631489a053f1670d2c +PKG_SOURCE_DATE:=2025-02-06 +PKG_SOURCE_VERSION:=db97edf20fadea2617805006f5230665fadc6a8c +PKG_MIRROR_HASH:=b5464cf6d57d87f6ce5f13bd2320c7e7e671a3152a74f4ef004382f898b89ecf PKG_MAINTAINER:=Imre Kaloz PKG_BUILD_PARALLEL:=1 diff --git a/package/kernel/mwlwifi/patches/001-Simplify-coredump-memcpy-in-mwl_fwcmd_get_fw_core_dump.patch b/package/kernel/mwlwifi/patches/001-Simplify-coredump-memcpy-in-mwl_fwcmd_get_fw_core_dump.patch index 4b0feeb17e6257..20e1cce382c254 100644 --- a/package/kernel/mwlwifi/patches/001-Simplify-coredump-memcpy-in-mwl_fwcmd_get_fw_core_dump.patch +++ b/package/kernel/mwlwifi/patches/001-Simplify-coredump-memcpy-in-mwl_fwcmd_get_fw_core_dump.patch @@ -20,7 +20,7 @@ Signed-off-by: Christian Marangi --- a/hif/fwcmd.c +++ b/hif/fwcmd.c -@@ -3622,11 +3622,7 @@ int mwl_fwcmd_get_fw_core_dump(struct ie +@@ -3624,11 +3624,7 @@ int mwl_fwcmd_get_fw_core_dump(struct ie core_dump->context = pcmd->cmd_data.coredump.context; core_dump->size_kb = pcmd->cmd_data.coredump.size_kb; core_dump->flags = pcmd->cmd_data.coredump.flags; diff --git a/package/kernel/mwlwifi/patches/002-Correctly-use-PTR_ERR-in-pcie_bf_mimo_ctrl_decode.patch b/package/kernel/mwlwifi/patches/002-Correctly-use-PTR_ERR-in-pcie_bf_mimo_ctrl_decode.patch index f204e9fe73d29f..f6c398cf661b16 100644 --- a/package/kernel/mwlwifi/patches/002-Correctly-use-PTR_ERR-in-pcie_bf_mimo_ctrl_decode.patch +++ b/package/kernel/mwlwifi/patches/002-Correctly-use-PTR_ERR-in-pcie_bf_mimo_ctrl_decode.patch @@ -19,7 +19,7 @@ Signed-off-by: Christian Marangi --- a/hif/pcie/pcie.c +++ b/hif/pcie/pcie.c -@@ -1466,8 +1466,8 @@ static void pcie_bf_mimo_ctrl_decode(str +@@ -1449,8 +1449,8 @@ static void pcie_bf_mimo_ctrl_decode(str &fp_data->f_pos); filp_close(fp_data, current->files); } else { diff --git a/package/kernel/mwlwifi/patches/003-Use-zu-and-zd-for-ssize_t-and-size_t.patch b/package/kernel/mwlwifi/patches/003-Use-zu-and-zd-for-ssize_t-and-size_t.patch index d615e1338001f7..816fb222c05f5f 100644 --- a/package/kernel/mwlwifi/patches/003-Use-zu-and-zd-for-ssize_t-and-size_t.patch +++ b/package/kernel/mwlwifi/patches/003-Use-zu-and-zd-for-ssize_t-and-size_t.patch @@ -14,7 +14,7 @@ Signed-off-by: Christian Marangi --- a/debugfs.c +++ b/debugfs.c -@@ -1342,7 +1342,7 @@ done: +@@ -1394,7 +1394,7 @@ done: priv->reg_value); else len += scnprintf(p + len, size - len, diff --git a/package/kernel/mwlwifi/patches/010-mwlwifi-fix-PCIe-DT-node-null-pointer-dereference.patch b/package/kernel/mwlwifi/patches/010-mwlwifi-fix-PCIe-DT-node-null-pointer-dereference.patch deleted file mode 100644 index f37d2f8171a8df..00000000000000 --- a/package/kernel/mwlwifi/patches/010-mwlwifi-fix-PCIe-DT-node-null-pointer-dereference.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 8e809b241695252e397bf0d7fc5f36e115c38831 Mon Sep 17 00:00:00 2001 -From: Robert Marko -Date: Fri, 5 Mar 2021 11:47:59 +0100 -Subject: [PATCH] mwlwifi: fix PCIe DT node null pointer dereference - -pci_bus_to_OF_node() used to get the PCI bus DT node -returns node if found or NULL if none is found. - -Since the return of pci_bus_to_OF_node() is not checked in -the DT node name print it will cause a null pointer -dereference and crash the kernel. - -So first check whether the node is not NULL and then print. - -Signed-off-by: Robert Marko ---- - hif/pcie/pcie.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - ---- a/hif/pcie/pcie.c -+++ b/hif/pcie/pcie.c -@@ -685,7 +685,8 @@ static struct device_node *pcie_get_devi - struct device_node *dev_node; - - dev_node = pci_bus_to_OF_node(pcie_priv->pdev->bus); -- wiphy_info(priv->hw->wiphy, "device node: %s\n", dev_node->full_name); -+ if (dev_node) -+ wiphy_info(priv->hw->wiphy, "device node: %s\n", dev_node->full_name); - - return dev_node; - } diff --git a/package/kernel/mwlwifi/patches/020-mac80211_update.patch b/package/kernel/mwlwifi/patches/020-mac80211_update.patch index 1c5d5819392118..1d4afabb51db3f 100644 --- a/package/kernel/mwlwifi/patches/020-mac80211_update.patch +++ b/package/kernel/mwlwifi/patches/020-mac80211_update.patch @@ -13,7 +13,7 @@ --- a/debugfs.c +++ b/debugfs.c -@@ -498,9 +498,9 @@ static ssize_t mwl_debugfs_vif_read(stru +@@ -550,9 +550,9 @@ static ssize_t mwl_debugfs_vif_read(stru switch (vif->type) { case NL80211_IFTYPE_AP: len += scnprintf(p + len, size - len, "type: ap\n"); @@ -26,7 +26,7 @@ len += scnprintf(p + len, size - len, "ssid: %s\n", ssid); len += scnprintf(p + len, size - len, -@@ -522,8 +522,8 @@ static ssize_t mwl_debugfs_vif_read(stru +@@ -574,8 +574,8 @@ static ssize_t mwl_debugfs_vif_read(stru "type: unknown\n"); break; } @@ -37,7 +37,7 @@ len += scnprintf(p + len, size - len, "channel: %d: width: %d\n", chan_def->chan->hw_value, -@@ -596,18 +596,18 @@ static ssize_t mwl_debugfs_sta_read(stru +@@ -648,18 +648,18 @@ static ssize_t mwl_debugfs_sta_read(stru sta_info->wds ? "true" : "false", sta_info->ba_hist.enable ? "enable" : "disable", sta_info->is_amsdu_allowed ? sta_info->amsdu_ctrl.cap : 0 , @@ -68,7 +68,7 @@ sta->tdls, sta->tdls_initiator, sta->wme, -@@ -1158,7 +1158,7 @@ static ssize_t mwl_debugfs_dfs_radar_wri +@@ -1210,7 +1210,7 @@ static ssize_t mwl_debugfs_dfs_radar_wri struct mwl_priv *priv = (struct mwl_priv *)file->private_data; wiphy_info(priv->hw->wiphy, "simulate radar detected\n"); @@ -127,7 +127,7 @@ a_band = true; else return -EINVAL; -@@ -2090,7 +2094,7 @@ int mwl_fwcmd_set_beacon(struct ieee8021 +@@ -2092,7 +2096,7 @@ int mwl_fwcmd_set_beacon(struct ieee8021 if (mwl_fwcmd_set_wsc_ie(hw, b_inf->ie_wsc_len, b_inf->ie_wsc_ptr)) goto err; @@ -136,7 +136,7 @@ goto err; if (b_inf->cap_info & WLAN_CAPABILITY_SPECTRUM_MGMT) -@@ -2152,38 +2156,38 @@ int mwl_fwcmd_set_new_stn_add(struct iee +@@ -2154,38 +2158,38 @@ int mwl_fwcmd_set_new_stn_add(struct iee ether_addr_copy(pcmd->mac_addr, sta->addr); if (hw->conf.chandef.chan->band == NL80211_BAND_2GHZ) @@ -189,7 +189,7 @@ } pcmd->is_qos_sta = sta->wme; -@@ -2239,38 +2243,38 @@ int mwl_fwcmd_set_new_stn_add_sc4(struct +@@ -2241,38 +2245,38 @@ int mwl_fwcmd_set_new_stn_add_sc4(struct ether_addr_copy(pcmd->mac_addr, sta->addr); if (hw->conf.chandef.chan->band == NL80211_BAND_2GHZ) @@ -242,7 +242,7 @@ } pcmd->is_qos_sta = sta->wme; -@@ -2787,9 +2791,9 @@ int mwl_fwcmd_create_ba(struct ieee80211 +@@ -2789,9 +2793,9 @@ int mwl_fwcmd_create_ba(struct ieee80211 pcmd->ba_info.create_params.flags = cpu_to_le32(ba_flags); pcmd->ba_info.create_params.queue_id = stream->idx; pcmd->ba_info.create_params.param_info = @@ -254,7 +254,7 @@ IEEE80211_HT_AMPDU_PARM_DENSITY); if (direction == BA_FLAG_DIRECTION_UP) { pcmd->ba_info.create_params.reset_seq_no = 0; -@@ -2799,9 +2803,9 @@ int mwl_fwcmd_create_ba(struct ieee80211 +@@ -2801,9 +2805,9 @@ int mwl_fwcmd_create_ba(struct ieee80211 pcmd->ba_info.create_params.current_seq = cpu_to_le16(0); } if (priv->chip_type == MWL8964 && @@ -268,16 +268,16 @@ } --- a/hif/pcie/8864/tx.c +++ b/hif/pcie/8864/tx.c -@@ -490,7 +490,7 @@ static void pcie_non_pfu_tx_done(struct - } else - memmove(dma_data->data - hdrlen, &dma_data->wh, hdrlen); - skb_pull(done_skb, sizeof(*dma_data) - hdrlen); -- ieee80211_tx_status(priv->hw, done_skb); -+ ieee80211_tx_status_skb(priv->hw, done_skb); - dev_kfree_skb_any(done_skb); - done_skb = NULL; - } -@@ -743,7 +743,7 @@ void pcie_8864_tx_xmit(struct ieee80211_ +@@ -478,7 +478,7 @@ static void pcie_non_pfu_tx_done(struct + } else + memmove(dma_data->data - hdrlen, &dma_data->wh, hdrlen); + skb_pull(done_skb, sizeof(*dma_data) - hdrlen); +- ieee80211_tx_status(priv->hw, done_skb); ++ ieee80211_tx_status_skb(priv->hw, done_skb); + next: + tx_hndl = tx_hndl->pnext; + tx_desc = tx_hndl->pdesc; +@@ -730,7 +730,7 @@ void pcie_8864_tx_xmit(struct ieee80211_ index = SYSADPT_TX_WMM_QUEUES - index - 1; txpriority = index; @@ -286,7 +286,7 @@ !(xmitcontrol & EAGLE_TXD_XMITCTRL_USE_MC_RATE) && ieee80211_is_data_qos(wh->frame_control)) { tid = qos & 0xf; -@@ -925,4 +925,4 @@ void pcie_8864_tx_del_sta_amsdu_pkts(str +@@ -912,4 +912,4 @@ void pcie_8864_tx_del_sta_amsdu_pkts(str } } spin_unlock_bh(&sta_info->amsdu_lock); @@ -313,7 +313,7 @@ bypass_ack: if (++tx_done_tail >= MAX_TX_RING_DONE_SIZE) -@@ -596,13 +596,13 @@ void pcie_tx_xmit_ndp(struct ieee80211_h +@@ -593,13 +593,13 @@ void pcie_tx_xmit_ndp(struct ieee80211_h ack_skb = skb_copy(skb, GFP_ATOMIC); ack_info = IEEE80211_SKB_CB(ack_skb); pcie_tx_prepare_info(priv, 0, ack_info); @@ -340,16 +340,16 @@ pcie_priv->txbd_ring_size); for (num = 0; num < PCIE_MAX_TXRX_BD; num++) { -@@ -444,7 +444,7 @@ static void pcie_pfu_tx_done(struct mwl_ - } else - memmove(dma_data->data - hdrlen, &dma_data->wh, hdrlen); - skb_pull(done_skb, sizeof(*pfu_dma) - hdrlen); -- ieee80211_tx_status(priv->hw, done_skb); -+ ieee80211_tx_status_skb(priv->hw, done_skb); - } +@@ -431,7 +431,7 @@ static void pcie_pfu_tx_done(struct mwl_ + } else + memmove(dma_data->data - hdrlen, &dma_data->wh, hdrlen); + skb_pull(done_skb, sizeof(*pfu_dma) - hdrlen); +- ieee80211_tx_status(priv->hw, done_skb); ++ ieee80211_tx_status_skb(priv->hw, done_skb); } next: -@@ -694,7 +694,7 @@ void pcie_8997_tx_xmit(struct ieee80211_ + memset(data_buf, 0, sizeof(*data_buf)); +@@ -682,7 +682,7 @@ void pcie_8997_tx_xmit(struct ieee80211_ index = SYSADPT_TX_WMM_QUEUES - index - 1; txpriority = index; @@ -358,7 +358,7 @@ !(xmitcontrol & EAGLE_TXD_XMITCTRL_USE_MC_RATE) && ieee80211_is_data_qos(wh->frame_control)) { tid = qos & 0xf; -@@ -875,4 +875,4 @@ void pcie_8997_tx_del_sta_amsdu_pkts(str +@@ -863,4 +863,4 @@ void pcie_8997_tx_del_sta_amsdu_pkts(str } } spin_unlock_bh(&sta_info->amsdu_lock); @@ -376,7 +376,7 @@ { mwl_fwcmd_radio_disable(hw); -@@ -368,15 +368,15 @@ static void mwl_mac80211_bss_info_change +@@ -390,15 +390,15 @@ static void mwl_mac80211_bss_info_change } } @@ -395,7 +395,7 @@ { struct mwl_priv *priv = hw->priv; struct mwl_vif *mwl_vif; -@@ -426,8 +426,8 @@ static void mwl_mac80211_bss_info_change +@@ -448,8 +448,8 @@ static void mwl_mac80211_bss_info_change if (changed & (BSS_CHANGED_BEACON_INT | BSS_CHANGED_BEACON)) { struct sk_buff *skb; @@ -406,7 +406,7 @@ (!info->hidden_ssid)) { if (mwl_vif->broadcast_ssid != true) { mwl_fwcmd_broadcast_ssid_enable(hw, vif, true); -@@ -441,7 +441,7 @@ static void mwl_mac80211_bss_info_change +@@ -463,7 +463,7 @@ static void mwl_mac80211_bss_info_change } if (!mwl_vif->set_beacon) { @@ -415,7 +415,7 @@ if (skb) { mwl_fwcmd_set_beacon(hw, vif, skb->data, skb->len); -@@ -458,7 +458,7 @@ static void mwl_mac80211_bss_info_change +@@ -480,7 +480,7 @@ static void mwl_mac80211_bss_info_change static void mwl_mac80211_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_bss_conf *info, @@ -424,7 +424,7 @@ { switch (vif->type) { case NL80211_IFTYPE_AP: -@@ -583,10 +583,10 @@ static int mwl_mac80211_sta_add(struct i +@@ -605,10 +605,10 @@ static int mwl_mac80211_sta_add(struct i if (vif->type == NL80211_IFTYPE_MESH_POINT) sta_info->is_mesh_node = true; @@ -437,7 +437,7 @@ sta_info->amsdu_ctrl.cap = MWL_AMSDU_SIZE_8K; sta_info->amsdu_ctrl.amsdu_allow_size = SYSADPT_AMSDU_8K_MAX_SIZE; } -@@ -670,7 +670,7 @@ static int mwl_mac80211_sta_remove(struc +@@ -692,7 +692,7 @@ static int mwl_mac80211_sta_remove(struc static int mwl_mac80211_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif, @@ -446,7 +446,7 @@ const struct ieee80211_tx_queue_params *params) { struct mwl_priv *priv = hw->priv; -@@ -934,4 +934,9 @@ const struct ieee80211_ops mwl_mac80211_ +@@ -956,4 +956,9 @@ const struct ieee80211_ops mwl_mac80211_ .pre_channel_switch = mwl_mac80211_chnl_switch, .sw_scan_start = mwl_mac80211_sw_scan_start, .sw_scan_complete = mwl_mac80211_sw_scan_complete, @@ -502,7 +502,7 @@ case TX_RATE_FORMAT_LEGACY: --- a/hif/pcie/pcie.c +++ b/hif/pcie/pcie.c -@@ -546,7 +546,7 @@ static irqreturn_t pcie_isr_8864(struct +@@ -533,7 +533,7 @@ static irqreturn_t pcie_isr_8864(struct if (int_status & MACREG_A2HRIC_BIT_RADAR_DETECT) { wiphy_info(hw->wiphy, "radar detected by firmware\n"); @@ -510,8 +510,8 @@ + ieee80211_radar_detected(hw, NULL); } - if (int_status & MACREG_A2HRIC_BIT_CHAN_SWITCH) ieee80211_queue_work(hw, &priv->chnl_switch_handle); -@@ -593,7 +593,7 @@ static irqreturn_t pcie_isr_8997(struct + if (int_status & MACREG_A2HRIC_BIT_CHAN_SWITCH) +@@ -575,7 +575,7 @@ static irqreturn_t pcie_isr_8997(struct if (int_status & MACREG_A2HRIC_BIT_RADAR_DETECT) { wiphy_info(hw->wiphy, "radar detected by firmware\n"); @@ -520,7 +520,7 @@ } if (int_status & MACREG_A2HRIC_BIT_CHAN_SWITCH) -@@ -1071,7 +1071,7 @@ static irqreturn_t pcie_isr_ndp(struct i +@@ -1053,7 +1053,7 @@ static irqreturn_t pcie_isr_ndp(struct i if (int_status & MACREG_A2HRIC_NEWDP_DFS) { wiphy_info(hw->wiphy, "radar detected by firmware\n"); diff --git a/package/kernel/r8101/Makefile b/package/kernel/r8101/Makefile index 2a09855c0503c1..4b528036a2122a 100644 --- a/package/kernel/r8101/Makefile +++ b/package/kernel/r8101/Makefile @@ -2,7 +2,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=r8101 PKG_VERSION:=1.039.00 -PKG_RELEASE:=2 +PKG_RELEASE:=3 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2 PKG_SOURCE_URL:=https://github.com/openwrt/rtl8101/releases/download/$(PKG_VERSION) @@ -20,7 +20,7 @@ define KernelPackage/r8101 TITLE:=Realtek RTL8101 PCI Fast Ethernet driver DEPENDS:=@PCI_SUPPORT +kmod-libphy FILES:=$(PKG_BUILD_DIR)/src/r8101.ko - AUTOLOAD:=$(call AutoProbe,r8101) + AUTOLOAD:=$(call AutoProbe,r8101,1) PROVIDES:=kmod-r8169 endef diff --git a/package/kernel/r8125/Makefile b/package/kernel/r8125/Makefile index ef95b52e679549..7cb28c99804825 100644 --- a/package/kernel/r8125/Makefile +++ b/package/kernel/r8125/Makefile @@ -1,12 +1,12 @@ include $(TOPDIR)/rules.mk PKG_NAME:=r8125 -PKG_VERSION:=9.013.02 -PKG_RELEASE:=4 +PKG_VERSION:=9.016.01 +PKG_RELEASE:=1 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2 PKG_SOURCE_URL:=https://github.com/openwrt/rtl8125/releases/download/$(PKG_VERSION) -PKG_HASH:=d36410ee99c956f250d9cd08340d8c36567d190f420a8ee128ff6e51225aac0c +PKG_HASH:=5434b26500538a62541c55cd09eea099177f59bd9cc48d16969089a9bcdbbd41 PKG_BUILD_PARALLEL:=1 PKG_LICENSE:=GPLv2 @@ -20,9 +20,10 @@ define KernelPackage/r8125 TITLE:=Realtek RTL8125 PCI 2.5 Gigabit Ethernet driver DEPENDS:=@PCI_SUPPORT +kmod-libphy FILES:=$(PKG_BUILD_DIR)/src/r8125.ko - AUTOLOAD:=$(call AutoProbe,r8125) + AUTOLOAD:=$(call AutoProbe,r8125,1) PROVIDES:=kmod-r8169 VARIANT:=regular + PKG_MAKE_FLAGS += CONFIG_ASPM=n endef define KernelPackage/r8125-rss @@ -33,7 +34,9 @@ $(call KernelPackage/r8125) endef ifeq ($(BUILD_VARIANT),rss) - PKG_MAKE_FLAGS += ENABLE_RSS_SUPPORT=y + PKG_MAKE_FLAGS += \ + ENABLE_MULTIPLE_TX_QUEUE=y \ + ENABLE_RSS_SUPPORT=y endif define Build/Compile diff --git a/package/kernel/r8125/patches/100-r8125_rss-silence-rxnfc-log.patch b/package/kernel/r8125/patches/100-r8125_rss-silence-rxnfc-log.patch deleted file mode 100644 index 58eb470037f2d2..00000000000000 --- a/package/kernel/r8125/patches/100-r8125_rss-silence-rxnfc-log.patch +++ /dev/null @@ -1,26 +0,0 @@ -From cd20cf48c0ec2a01fd9f512e25218a6ac8131794 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= -Date: Sat, 17 Aug 2024 22:07:23 +0200 -Subject: [PATCH] r8125_rss: silence rxnfc log -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -This log is noisy and useless, just ignore it. - -Signed-off-by: Chukun Pan ---- - src/r8125_rss.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/src/r8125_rss.c -+++ b/src/r8125_rss.c -@@ -91,7 +91,7 @@ int rtl8125_get_rxnfc(struct net_device - struct rtl8125_private *tp = netdev_priv(dev); - int ret = -EOPNOTSUPP; - -- netif_info(tp, drv, tp->dev, "rss get rxnfc\n"); -+ netif_dbg(tp, drv, tp->dev, "rss get rxnfc\n"); - - if (!(dev->features & NETIF_F_RXHASH)) - return ret; diff --git a/package/kernel/r8125/patches/200-r8125-print-link-speed-and-duplex-mode.patch b/package/kernel/r8125/patches/200-r8125-print-link-speed-and-duplex-mode.patch index df649c9ae9f619..4f1917e74b8767 100644 --- a/package/kernel/r8125/patches/200-r8125-print-link-speed-and-duplex-mode.patch +++ b/package/kernel/r8125/patches/200-r8125-print-link-speed-and-duplex-mode.patch @@ -18,11 +18,12 @@ Signed-off-by: Álvaro Fernández Rojas --- a/src/r8125.h +++ b/src/r8125.h -@@ -1563,6 +1563,8 @@ enum RTL8125_register_content { +@@ -1726,6 +1726,9 @@ enum RTL8125_register_content { LinkStatus = 0x02, FullDup = 0x01, +#define RTL8125_FULL_DUPLEX_MASK (_2500bpsF | _1000bpsF | FullDup) ++#define RTL8125_SPEED_1000_MASK (_1000bpsF | _1000bpsL | _2500bpsL) + /* DBG_reg */ Fix_Nak_1 = (1 << 4), @@ -37,11 +38,11 @@ Signed-off-by: Álvaro Fernández Rojas #include #include #include -@@ -5112,6 +5113,38 @@ rtl8125_link_down_patch(struct net_devic +@@ -5051,6 +5052,38 @@ rtl8125_link_down_patch(struct net_devic #endif } -+static unsigned int rtl8125_phy_duplex(u16 status) ++static unsigned int rtl8125_phy_duplex(u32 status) +{ + unsigned int duplex = DUPLEX_UNKNOWN; + @@ -55,14 +56,14 @@ Signed-off-by: Álvaro Fernández Rojas + return duplex; +} + -+static int rtl8125_phy_speed(u16 status) ++static int rtl8125_phy_speed(u32 status) +{ + int speed = SPEED_UNKNOWN; + + if (status & LinkStatus) { + if (status & _2500bpsF) + speed = SPEED_2500; -+ else if (status & _1000bpsF) ++ else if (status & RTL8125_SPEED_1000_MASK) + speed = SPEED_1000; + else if (status & _100bps) + speed = SPEED_100; @@ -74,16 +75,16 @@ Signed-off-by: Álvaro Fernández Rojas +} + static void - _rtl8125_check_link_status(struct net_device *dev) + _rtl8125_check_link_status(struct net_device *dev, unsigned int link_state) { -@@ -5120,11 +5153,18 @@ _rtl8125_check_link_status(struct net_de - if (tp->link_ok(dev)) { +@@ -5063,11 +5096,18 @@ _rtl8125_check_link_status(struct net_de + if (link_state == R8125_LINK_STATE_ON) { rtl8125_link_on_patch(dev); - if (netif_msg_ifup(tp)) - printk(KERN_INFO PFX "%s: link up\n", dev->name); + if (netif_msg_ifup(tp)) { -+ const u16 phy_status = RTL_R16(tp, PHYstatus); ++ const u32 phy_status = RTL_R32(tp, PHYstatus); + const unsigned int phy_duplex = rtl8125_phy_duplex(phy_status); + const int phy_speed = rtl8125_phy_speed(phy_status); + printk(KERN_INFO PFX "%s: Link is Up - %s/%s\n", diff --git a/package/kernel/r8126/Makefile b/package/kernel/r8126/Makefile index c269cdcadc4ba6..6bc39a936a5c00 100644 --- a/package/kernel/r8126/Makefile +++ b/package/kernel/r8126/Makefile @@ -1,12 +1,12 @@ include $(TOPDIR)/rules.mk PKG_NAME:=r8126 -PKG_VERSION:=10.013.00 -PKG_RELEASE:=4 +PKG_VERSION:=10.016.00 +PKG_RELEASE:=1 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2 PKG_SOURCE_URL:=https://github.com/openwrt/rtl8126/releases/download/$(PKG_VERSION) -PKG_HASH:=b41bda6ff3bbb7d9bc5b81c5c21355f031587d3a3a5862abcd4d766e942272e7 +PKG_HASH:=50c8d3d49592d2e8f372bd7ece8e7df9b50a71b055c077d42eacc42302914440 PKG_BUILD_PARALLEL:=1 PKG_LICENSE:=GPLv2 @@ -20,7 +20,7 @@ define KernelPackage/r8126 TITLE:=Realtek RTL8126 PCI 5 Gigabit Ethernet driver DEPENDS:=@PCI_SUPPORT +kmod-libphy FILES:=$(PKG_BUILD_DIR)/src/r8126.ko - AUTOLOAD:=$(call AutoProbe,r8126) + AUTOLOAD:=$(call AutoProbe,r8126,1) PROVIDES:=kmod-r8169 VARIANT:=regular endef @@ -33,7 +33,9 @@ $(call KernelPackage/r8126) endef ifeq ($(BUILD_VARIANT),rss) - PKG_MAKE_FLAGS += ENABLE_RSS_SUPPORT=y + PKG_MAKE_FLAGS += \ + ENABLE_MULTIPLE_TX_QUEUE=y \ + ENABLE_RSS_SUPPORT=y endif define Build/Compile diff --git a/package/kernel/r8126/patches/001-r8126.h-use-BIT_ULL.patch b/package/kernel/r8126/patches/001-r8126.h-use-BIT_ULL.patch deleted file mode 100644 index cfbf31fcbb3e44..00000000000000 --- a/package/kernel/r8126/patches/001-r8126.h-use-BIT_ULL.patch +++ /dev/null @@ -1,21 +0,0 @@ -From 9649df50a239d1379cc8d9febd4854a0c7ca0731 Mon Sep 17 00:00:00 2001 -From: Mieczyslaw Nalewaj -Date: Sat, 10 Aug 2024 17:42:44 +0200 -Subject: [PATCH] r8126.h: use BIT_ULL - -Fixes compilation on 32 bit systems. ---- - src/r8126.h | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/src/r8126.h -+++ b/src/r8126.h -@@ -678,7 +678,7 @@ This is free software, and you are welco - #ifndef ADVERTISED_2500baseX_Full - #define ADVERTISED_2500baseX_Full 0x8000 - #endif --#define RTK_ADVERTISED_5000baseX_Full BIT(48) -+#define RTK_ADVERTISED_5000baseX_Full BIT_ULL(48) - - #define RTK_ADVERTISE_2500FULL 0x80 - #define RTK_ADVERTISE_5000FULL 0x100 diff --git a/package/kernel/r8126/patches/100-r8126_rss-silence-rxnfc-log.patch b/package/kernel/r8126/patches/100-r8126_rss-silence-rxnfc-log.patch deleted file mode 100644 index d06406004c7c68..00000000000000 --- a/package/kernel/r8126/patches/100-r8126_rss-silence-rxnfc-log.patch +++ /dev/null @@ -1,27 +0,0 @@ -From cd20cf48c0ec2a01fd9f512e25218a6ac8131794 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= -Date: Sat, 17 Aug 2024 22:07:23 +0200 -Subject: [PATCH] r8126_rss: silence rxnfc log -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -This log is noisy and useless, just ignore it. - -Signed-off-by: Chukun Pan -Signed-off-by: Álvaro Fernández Rojas ---- - src/r8126_rss.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/src/r8126_rss.c -+++ b/src/r8126_rss.c -@@ -91,7 +91,7 @@ int rtl8126_get_rxnfc(struct net_device - struct rtl8126_private *tp = netdev_priv(dev); - int ret = -EOPNOTSUPP; - -- netif_info(tp, drv, tp->dev, "rss get rxnfc\n"); -+ netif_dbg(tp, drv, tp->dev, "rss get rxnfc\n"); - - if (!(dev->features & NETIF_F_RXHASH)) - return ret; diff --git a/package/kernel/r8126/patches/200-r8126-print-link-speed-and-duplex-mode.patch b/package/kernel/r8126/patches/200-r8126-print-link-speed-and-duplex-mode.patch index 308d2494b3e952..61e2666e1f0be8 100644 --- a/package/kernel/r8126/patches/200-r8126-print-link-speed-and-duplex-mode.patch +++ b/package/kernel/r8126/patches/200-r8126-print-link-speed-and-duplex-mode.patch @@ -18,11 +18,13 @@ Signed-off-by: Álvaro Fernández Rojas --- a/src/r8126.h +++ b/src/r8126.h -@@ -1561,6 +1561,8 @@ enum RTL8126_register_content { +@@ -1752,6 +1752,10 @@ enum RTL8126_register_content { LinkStatus = 0x02, FullDup = 0x01, +#define RTL8126_FULL_DUPLEX_MASK (_5000bpsF | _2500bpsF | _1000bpsF | FullDup) ++#define RTL8126_SPEED_1000_MASK (_1000bpsF | _1000bpsL | _2500bpsL) ++#define RTL8126_SPEED_2500_MASK (_2500bpsF | _5000bpsL) + /* DBG_reg */ Fix_Nak_1 = (1 << 4), @@ -37,11 +39,11 @@ Signed-off-by: Álvaro Fernández Rojas #include #include #include -@@ -4740,6 +4741,40 @@ rtl8126_link_down_patch(struct net_devic - #endif +@@ -4410,6 +4411,40 @@ rtl8126_link_down_patch(struct net_devic + //rtl8126_set_speed(dev, tp->autoneg, tp->speed, tp->duplex, tp->advertising); } -+static unsigned int rtl8126_phy_duplex(u16 status) ++static unsigned int rtl8126_phy_duplex(u32 status) +{ + unsigned int duplex = DUPLEX_UNKNOWN; + @@ -55,16 +57,16 @@ Signed-off-by: Álvaro Fernández Rojas + return duplex; +} + -+static int rtl8126_phy_speed(u16 status) ++static int rtl8126_phy_speed(u32 status) +{ + int speed = SPEED_UNKNOWN; + + if (status & LinkStatus) { + if (status & _5000bpsF) + speed = SPEED_5000; -+ else if (status & _2500bpsF) ++ else if (status & RTL8126_SPEED_2500_MASK) + speed = SPEED_2500; -+ else if (status & _1000bpsF) ++ else if (status & RTL8126_SPEED_1000_MASK) + speed = SPEED_1000; + else if (status & _100bps) + speed = SPEED_100; @@ -76,16 +78,16 @@ Signed-off-by: Álvaro Fernández Rojas +} + static void - _rtl8126_check_link_status(struct net_device *dev) + _rtl8126_check_link_status(struct net_device *dev, unsigned int link_state) { -@@ -4748,11 +4783,18 @@ _rtl8126_check_link_status(struct net_de - if (tp->link_ok(dev)) { +@@ -4422,11 +4457,18 @@ _rtl8126_check_link_status(struct net_de + if (link_state == R8126_LINK_STATE_ON) { rtl8126_link_on_patch(dev); - if (netif_msg_ifup(tp)) - printk(KERN_INFO PFX "%s: link up\n", dev->name); + if (netif_msg_ifup(tp)) { -+ const u16 phy_status = RTL_R16(tp, PHYstatus); ++ const u32 phy_status = RTL_R32(tp, PHYstatus); + const unsigned int phy_duplex = rtl8126_phy_duplex(phy_status); + const int phy_speed = rtl8126_phy_speed(phy_status); + printk(KERN_INFO PFX "%s: Link is Up - %s/%s\n", diff --git a/package/kernel/r8127/Makefile b/package/kernel/r8127/Makefile new file mode 100644 index 00000000000000..38be4ae82d7c78 --- /dev/null +++ b/package/kernel/r8127/Makefile @@ -0,0 +1,49 @@ +include $(TOPDIR)/rules.mk + +PKG_NAME:=r8127 +PKG_VERSION:=11.015.00 +PKG_RELEASE:=1 + +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2 +PKG_SOURCE_URL:=https://github.com/openwrt/rtl8127/releases/download/$(PKG_VERSION) +PKG_HASH:=ab21bf69368fb9de7f591b2e81cf1a815988bbf086ecbf41af7de9787b10594b + +PKG_BUILD_PARALLEL:=1 +PKG_LICENSE:=GPLv2 +PKG_MAINTAINER:=Alvaro Fernandez Rojas + +include $(INCLUDE_DIR)/kernel.mk +include $(INCLUDE_DIR)/package.mk + +define KernelPackage/r8127 + SUBMENU:=Network Devices + TITLE:=Realtek RTL8127 PCI 10 Gigabit Ethernet driver + DEPENDS:=@PCI_SUPPORT +kmod-libphy + FILES:=$(PKG_BUILD_DIR)/src/r8127.ko + AUTOLOAD:=$(call AutoProbe,r8127,1) + PROVIDES:=kmod-r8169 + VARIANT:=regular +endef + +define KernelPackage/r8127-rss +$(call KernelPackage/r8127) + CONFLICTS:=kmod-r8127 + TITLE+= (RSS) + VARIANT:=rss +endef + +ifeq ($(BUILD_VARIANT),rss) + PKG_MAKE_FLAGS += \ + ENABLE_MULTIPLE_TX_QUEUE=y \ + ENABLE_RSS_SUPPORT=y +endif + +define Build/Compile + +$(KERNEL_MAKE) $(PKG_JOBS) \ + $(PKG_MAKE_FLAGS) \ + M="$(PKG_BUILD_DIR)/src" \ + modules +endef + +$(eval $(call KernelPackage,r8127)) +$(eval $(call KernelPackage,r8127-rss)) diff --git a/package/kernel/r8127/patches/200-r8127-print-link-speed-and-duplex-mode.patch b/package/kernel/r8127/patches/200-r8127-print-link-speed-and-duplex-mode.patch new file mode 100644 index 00000000000000..275feb823405f2 --- /dev/null +++ b/package/kernel/r8127/patches/200-r8127-print-link-speed-and-duplex-mode.patch @@ -0,0 +1,107 @@ +From 5ca1d47e065c0318774a946ffdf76010c78cc164 Mon Sep 17 00:00:00 2001 +From: Chukun Pan +Date: Sat, 10 Aug 2024 20:16:32 +0800 +Subject: [PATCH] r8127: print link speed and duplex mode +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Like other Ethernet drivers, print link speed and duplex mode +when the interface is up. Formatting output at the same time. + +Signed-off-by: Chukun Pan +Signed-off-by: Álvaro Fernández Rojas +--- + src/r8127.h | 2 ++ + src/r8127_n.c | 48 +++++++++++++++++++++++++++++++++++++++++++++--- + 2 files changed, 47 insertions(+), 3 deletions(-) + +--- a/src/r8127.h ++++ b/src/r8127.h +@@ -1770,6 +1770,11 @@ enum RTL8127_register_content { + LinkStatus = 0x02, + FullDup = 0x01, + ++#define RTL8127_FULL_DUPLEX_MASK (_10000bpsF | _5000bpsF | _2500bpsF | _1000bpsF | FullDup) ++#define RTL8127_SPEED_1000_MASK (_1000bpsF | _1000bpsL | _2500bpsL) ++#define RTL8127_SPEED_2500_MASK (_2500bpsF | _5000bpsL) ++#define RTL8127_SPEED_5000_MASK (_5000bpsF | _10000bpsL) ++ + /* DBG_reg */ + Fix_Nak_1 = (1 << 4), + Fix_Nak_2 = (1 << 3), +--- a/src/r8127_n.c ++++ b/src/r8127_n.c +@@ -39,6 +39,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -4734,6 +4735,42 @@ rtl8127_link_down_patch(struct net_devic + #endif + } + ++static unsigned int rtl8127_phy_duplex(u32 status) ++{ ++ unsigned int duplex = DUPLEX_UNKNOWN; ++ ++ if (status & LinkStatus) { ++ if (status & RTL8127_FULL_DUPLEX_MASK) ++ duplex = DUPLEX_FULL; ++ else ++ duplex = DUPLEX_HALF; ++ } ++ ++ return duplex; ++} ++ ++static int rtl8127_phy_speed(u32 status) ++{ ++ int speed = SPEED_UNKNOWN; ++ ++ if (status & LinkStatus) { ++ if (status & _10000bpsF) ++ speed = SPEED_10000; ++ else if (status & RTL8127_SPEED_5000_MASK) ++ speed = SPEED_5000; ++ else if (status & RTL8127_SPEED_2500_MASK) ++ speed = SPEED_2500; ++ else if (status & RTL8127_SPEED_1000_MASK) ++ speed = SPEED_1000; ++ else if (status & _100bps) ++ speed = SPEED_100; ++ else if (status & _10bps) ++ speed = SPEED_10; ++ } ++ ++ return speed; ++} ++ + static void + _rtl8127_check_link_status(struct net_device *dev, unsigned int link_state) + { +@@ -4746,11 +4783,18 @@ _rtl8127_check_link_status(struct net_de + if (link_state == R8127_LINK_STATE_ON) { + rtl8127_link_on_patch(dev); + +- if (netif_msg_ifup(tp)) +- printk(KERN_INFO PFX "%s: link up\n", dev->name); ++ if (netif_msg_ifup(tp)) { ++ const u32 phy_status = RTL_R32(tp, PHYstatus); ++ const unsigned int phy_duplex = rtl8127_phy_duplex(phy_status); ++ const int phy_speed = rtl8127_phy_speed(phy_status); ++ printk(KERN_INFO PFX "%s: Link is Up - %s/%s\n", ++ dev->name, ++ phy_speed_to_str(phy_speed), ++ phy_duplex_to_str(phy_duplex)); ++ } + } else { + if (netif_msg_ifdown(tp)) +- printk(KERN_INFO PFX "%s: link down\n", dev->name); ++ printk(KERN_INFO PFX "%s: Link is Down\n", dev->name); + + rtl8127_link_down_patch(dev); + } diff --git a/package/kernel/r8168/Makefile b/package/kernel/r8168/Makefile index 2604425deac2bc..182950a6240f26 100644 --- a/package/kernel/r8168/Makefile +++ b/package/kernel/r8168/Makefile @@ -1,12 +1,12 @@ include $(TOPDIR)/rules.mk PKG_NAME:=r8168 -PKG_VERSION:=8.054.00 -PKG_RELEASE:=1 +PKG_VERSION:=8.055.00 +PKG_RELEASE:=4 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2 PKG_SOURCE_URL:=https://github.com/openwrt/rtl8168/releases/download/$(PKG_VERSION) -PKG_HASH:=5480120cf823e991e8cbd325118c1ec0c57d8f42760ba1a7334bd07d291d235d +PKG_HASH:=61deb2a9cb7d6b08748ad51734b108da95d629712b64b204e2e6bd3f16d0a48f PKG_BUILD_PARALLEL:=1 PKG_LICENSE:=GPLv2 @@ -20,14 +20,30 @@ define KernelPackage/r8168 TITLE:=Realtek RTL8168 PCI Gigabit Ethernet driver DEPENDS:=@PCI_SUPPORT +kmod-libphy FILES:=$(PKG_BUILD_DIR)/src/r8168.ko - AUTOLOAD:=$(call AutoProbe,r8168) + AUTOLOAD:=$(call AutoProbe,r8168,1) PROVIDES:=kmod-r8169 + VARIANT:=regular endef +define KernelPackage/r8168-rss +$(call KernelPackage/r8168) + CONFLICTS:=kmod-r8168 + TITLE+= (RSS) + VARIANT:=rss +endef + +ifeq ($(BUILD_VARIANT),rss) + PKG_MAKE_FLAGS += \ + ENABLE_MULTIPLE_TX_QUEUE=y \ + ENABLE_RSS_SUPPORT=y +endif + define Build/Compile +$(KERNEL_MAKE) $(PKG_JOBS) \ + $(PKG_MAKE_FLAGS) \ M="$(PKG_BUILD_DIR)/src" \ modules endef $(eval $(call KernelPackage,r8168)) +$(eval $(call KernelPackage,r8168-rss)) diff --git a/package/kernel/r8168/patches/001-r8168_n-fix-proc_dump_rx_desc_2-on-32-bits.patch b/package/kernel/r8168/patches/001-r8168_n-fix-proc_dump_rx_desc_2-on-32-bits.patch index b53819a0cbb90e..bb00411e06094d 100644 --- a/package/kernel/r8168/patches/001-r8168_n-fix-proc_dump_rx_desc_2-on-32-bits.patch +++ b/package/kernel/r8168/patches/001-r8168_n-fix-proc_dump_rx_desc_2-on-32-bits.patch @@ -13,7 +13,7 @@ Signed-off-by: Álvaro Fernández Rojas --- a/src/r8168_n.c +++ b/src/r8168_n.c -@@ -1655,9 +1655,9 @@ static int proc_dump_rx_desc_2(struct se +@@ -1668,9 +1668,9 @@ static int proc_dump_rx_desc_2(struct se j, k); for (i=0; i<(tp->RxDescLength/4); i++) { if (!(i % 4)) diff --git a/package/kernel/r8168/patches/200-r8168-print-link-speed-and-duplex-mode.patch b/package/kernel/r8168/patches/200-r8168-print-link-speed-and-duplex-mode.patch index 0212ae9bc41c39..150c41d63249ab 100644 --- a/package/kernel/r8168/patches/200-r8168-print-link-speed-and-duplex-mode.patch +++ b/package/kernel/r8168/patches/200-r8168-print-link-speed-and-duplex-mode.patch @@ -18,7 +18,7 @@ Signed-off-by: Chukun Pan --- a/src/r8168.h +++ b/src/r8168.h -@@ -1385,6 +1385,8 @@ enum RTL8168_register_content { +@@ -1480,6 +1480,8 @@ enum RTL8168_register_content { LinkStatus = 0x02, FullDup = 0x01, @@ -37,7 +37,7 @@ Signed-off-by: Chukun Pan #include #include #include -@@ -5373,6 +5374,36 @@ rtl8168_link_down_patch(struct net_devic +@@ -5396,6 +5397,38 @@ rtl8168_link_down_patch(struct net_devic #endif } @@ -66,6 +66,8 @@ Signed-off-by: Chukun Pan + speed = SPEED_100; + else if (status & _10bps) + speed = SPEED_10; ++ else if (eee_giga_lite) ++ speed = SPEED_1000; + } + + return speed; @@ -74,7 +76,7 @@ Signed-off-by: Chukun Pan static void rtl8168_check_link_status(struct net_device *dev) { -@@ -5392,11 +5423,18 @@ rtl8168_check_link_status(struct net_dev +@@ -5415,11 +5448,18 @@ rtl8168_check_link_status(struct net_dev if (link_status_on) { rtl8168_link_on_patch(dev); diff --git a/package/kernel/ubootenv-nvram/src/ubootenv-nvram.c b/package/kernel/ubootenv-nvram/src/ubootenv-nvram.c index f6244142167b0b..106e41231c9094 100644 --- a/package/kernel/ubootenv-nvram/src/ubootenv-nvram.c +++ b/package/kernel/ubootenv-nvram/src/ubootenv-nvram.c @@ -146,7 +146,6 @@ static struct platform_driver ubootenv_driver = { .remove = ubootenv_remove, .driver = { .name = NAME, - .owner = THIS_MODULE, .of_match_table = of_ubootenv_match, }, }; diff --git a/package/libs/elfutils/Makefile b/package/libs/elfutils/Makefile index ac5841c604b235..b47bb5240683d9 100644 --- a/package/libs/elfutils/Makefile +++ b/package/libs/elfutils/Makefile @@ -7,15 +7,16 @@ include $(TOPDIR)/rules.mk PKG_NAME:=elfutils -PKG_VERSION:=0.191 +PKG_VERSION:=0.192 PKG_RELEASE:=1 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2 -PKG_SOURCE_URL:=https://sourceware.org/$(PKG_NAME)/ftp/$(PKG_VERSION) -PKG_HASH:=df76db71366d1d708365fc7a6c60ca48398f14367eb2b8954efc8897147ad871 +PKG_SOURCE_URL:=https://sourceware.org/$(PKG_NAME)/ftp/$(PKG_VERSION) \ + https://mirrors.kernel.org/sourceware/$(PKG_NAME)/$(PKG_VERSION) +PKG_HASH:=616099beae24aba11f9b63d86ca6cc8d566d968b802391334c91df54eab416b4 PKG_MAINTAINER:=Luiz Angelo Daros de Luca -PKG_LICENSE:=GPL-3.0-or-later +PKG_LICENSE:=GPL-2.0-or-later OR LGPL-3.0-or-later PKG_LICENSE_FILES:=COPYING COPYING-GPLV2 COPYING-LGPLV3 PKG_CPE_ID:=cpe:/a:elfutils_project:elfutils diff --git a/package/libs/elfutils/patches/003-libintl-compatibility.patch b/package/libs/elfutils/patches/003-libintl-compatibility.patch index 1271796af54fd4..eda9f2204a928c 100644 --- a/package/libs/elfutils/patches/003-libintl-compatibility.patch +++ b/package/libs/elfutils/patches/003-libintl-compatibility.patch @@ -11,7 +11,7 @@ Requires.private: zlib @LIBZSTD@ --- a/configure.ac +++ b/configure.ac -@@ -717,6 +717,9 @@ dnl AM_GNU_GETTEXT_REQUIRE_VERSION suppo +@@ -728,6 +728,9 @@ dnl AM_GNU_GETTEXT_REQUIRE_VERSION suppo AM_GNU_GETTEXT_VERSION([0.19.6]) AM_GNU_GETTEXT_REQUIRE_VERSION([0.19.6]) diff --git a/package/libs/elfutils/patches/005-build_only_libs.patch b/package/libs/elfutils/patches/005-build_only_libs.patch index 598b734874e764..177ac659e62403 100644 --- a/package/libs/elfutils/patches/005-build_only_libs.patch +++ b/package/libs/elfutils/patches/005-build_only_libs.patch @@ -8,4 +8,4 @@ + libasm EXTRA_DIST = elfutils.spec GPG-KEY NOTES CONTRIBUTING SECURITY \ - COPYING COPYING-GPLV2 COPYING-LGPLV3 + COPYING COPYING-GPLV2 COPYING-LGPLV3 CONDUCT diff --git a/package/libs/elfutils/patches/006-Fix-build-on-aarch64-musl.patch b/package/libs/elfutils/patches/006-Fix-build-on-aarch64-musl.patch index d8066c5ca717cf..a7786ed2c011a0 100644 --- a/package/libs/elfutils/patches/006-Fix-build-on-aarch64-musl.patch +++ b/package/libs/elfutils/patches/006-Fix-build-on-aarch64-musl.patch @@ -32,8 +32,8 @@ Signed-off-by: Hongxu Jia +# include # include # include - /* Deal with old glibc defining user_pt_regs instead of user_regs_struct. */ -@@ -82,7 +82,7 @@ aarch64_set_initial_registers_tid (pid_t + # include +@@ -94,7 +94,7 @@ aarch64_set_initial_registers_tid (pid_t Dwarf_Word dwarf_fregs[32]; for (int r = 0; r < 32; r++) diff --git a/package/libs/elfutils/patches/007-add-libeu-symbols-to-libelf.patch b/package/libs/elfutils/patches/007-add-libeu-symbols-to-libelf.patch new file mode 100644 index 00000000000000..23489b562570e7 --- /dev/null +++ b/package/libs/elfutils/patches/007-add-libeu-symbols-to-libelf.patch @@ -0,0 +1,31 @@ +From f5d6e088f84dd05278c4698a21cbf1ff4569978d Mon Sep 17 00:00:00 2001 +From: Mark Wielaard +Date: Tue, 22 Oct 2024 15:03:42 +0200 +Subject: [PATCH] libelf: Add libeu objects to libelf.a static archive + +libelf might use some symbols from libeu.a, specifically the eu-search +wrappers. But we don't ship libeu.a separately. So include the libeu +objects in the libelf.a archive to facilitate static linking. + + * libelf/Makefile.am (libeu_objects): New variable. + (libelf_a_LIBADD): New, add libeu_objects. + +https://sourceware.org/bugzilla/show_bug.cgi?id=32293 + +Signed-off-by: Mark Wielaard +--- + libelf/Makefile.am | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/libelf/Makefile.am ++++ b/libelf/Makefile.am +@@ -122,6 +122,9 @@ libelf.so: $(srcdir)/libelf.map $(libelf + @$(textrel_check) + $(AM_V_at)ln -fs $@ $@.$(VERSION) + ++libeu_objects = $(shell $(AR) t ../lib/libeu.a) ++libelf_a_LIBADD = $(addprefix ../lib/,$(libeu_objects)) ++ + install: install-am libelf.so + $(mkinstalldirs) $(DESTDIR)$(libdir) + $(INSTALL_PROGRAM) libelf.so $(DESTDIR)$(libdir)/libelf-$(PACKAGE_VERSION).so diff --git a/package/libs/elfutils/patches/008-fix-autoconf-ENABLE_IMA_VERIFICATION.patch b/package/libs/elfutils/patches/008-fix-autoconf-ENABLE_IMA_VERIFICATION.patch new file mode 100644 index 00000000000000..e5732d2b0821fd --- /dev/null +++ b/package/libs/elfutils/patches/008-fix-autoconf-ENABLE_IMA_VERIFICATION.patch @@ -0,0 +1,24 @@ +From f3c664d069d81a4872a1ec8241ee709f37c53e9c Mon Sep 17 00:00:00 2001 +From: Aaron Merey +Date: Tue, 29 Oct 2024 14:16:57 -0400 +Subject: [PATCH] configure.ac: Fix ENABLE_IMA_VERIFICATION conditional + +Fix test statement for ENABLE_IMA_VERIFICATION always evalutating to +false due to a missing 'x'. + +Signed-off-by: Aaron Merey +--- + configure.ac | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/configure.ac ++++ b/configure.ac +@@ -895,7 +895,7 @@ AS_IF([test "x$enable_debuginfod" != "xn + AM_CONDITIONAL([DEBUGINFOD],[test "x$enable_debuginfod" = "xyes"]) + AS_IF([test "x$enable_debuginfod_ima_verification" = "xyes"],AC_DEFINE([ENABLE_IMA_VERIFICATION],[1],[Build IMA verification])) + AS_IF([test "x$have_libarchive" = "xyes"],AC_DEFINE([HAVE_LIBARCHIVE],[1],[Define to 1 if libarchive is available])) +-AM_CONDITIONAL([ENABLE_IMA_VERIFICATION],[test "$enable_debuginfod_ima_verification" = "xyes"]) ++AM_CONDITIONAL([ENABLE_IMA_VERIFICATION],[test "x$enable_debuginfod_ima_verification" = "xyes"]) + AM_CONDITIONAL([OLD_LIBMICROHTTPD],[test "x$old_libmicrohttpd" = "xyes"]) + + dnl for /etc/profile.d/elfutils.{csh,sh} diff --git a/package/libs/elfutils/patches/009-fix-null-dereference-with-lto.patch b/package/libs/elfutils/patches/009-fix-null-dereference-with-lto.patch new file mode 100644 index 00000000000000..1179a1e1a01f67 --- /dev/null +++ b/package/libs/elfutils/patches/009-fix-null-dereference-with-lto.patch @@ -0,0 +1,193 @@ +From 8707194a9f2f0b13e53041b03ebfdbdbd2942e43 Mon Sep 17 00:00:00 2001 +From: Mark Wielaard +Date: Tue, 5 Nov 2024 23:31:14 +0100 +Subject: [PATCH 1/1] libelf: Only fetch shdr once in elf_compress[_gnu] + +Some compilers assume the second call to elf[32|64]_getshdr can fail +and produce error: potential null pointer dereference. Just store the +result of the first call and reuse (when not NULL). + + * libelf/elf_compress.c (elf_compress): Store getshdr result in + a shdr union var. + * libelf/elf_compress_gnu.c (): Likewise + +https://sourceware.org/bugzilla/show_bug.cgi?id=32311 + +Signed-off-by: Mark Wielaard +--- + libelf/elf_compress.c | 55 +++++++++++++++++++++------------------ + libelf/elf_compress_gnu.c | 45 ++++++++++++++------------------ + 2 files changed, 48 insertions(+), 52 deletions(-) + +--- a/libelf/elf_compress.c ++++ b/libelf/elf_compress.c +@@ -584,25 +584,30 @@ elf_compress (Elf_Scn *scn, int type, un + Elf64_Xword sh_flags; + Elf64_Word sh_type; + Elf64_Xword sh_addralign; ++ union shdr ++ { ++ Elf32_Shdr *s32; ++ Elf64_Shdr *s64; ++ } shdr; + if (elfclass == ELFCLASS32) + { +- Elf32_Shdr *shdr = elf32_getshdr (scn); +- if (shdr == NULL) ++ shdr.s32 = elf32_getshdr (scn); ++ if (shdr.s32 == NULL) + return -1; + +- sh_flags = shdr->sh_flags; +- sh_type = shdr->sh_type; +- sh_addralign = shdr->sh_addralign; ++ sh_flags = shdr.s32->sh_flags; ++ sh_type = shdr.s32->sh_type; ++ sh_addralign = shdr.s32->sh_addralign; + } + else + { +- Elf64_Shdr *shdr = elf64_getshdr (scn); +- if (shdr == NULL) ++ shdr.s64 = elf64_getshdr (scn); ++ if (shdr.s64 == NULL) + return -1; + +- sh_flags = shdr->sh_flags; +- sh_type = shdr->sh_type; +- sh_addralign = shdr->sh_addralign; ++ sh_flags = shdr.s64->sh_flags; ++ sh_type = shdr.s64->sh_type; ++ sh_addralign = shdr.s64->sh_addralign; + } + + if ((sh_flags & SHF_ALLOC) != 0) +@@ -679,17 +684,17 @@ elf_compress (Elf_Scn *scn, int type, un + correctly and ignored when SHF_COMPRESSED is set. */ + if (elfclass == ELFCLASS32) + { +- Elf32_Shdr *shdr = elf32_getshdr (scn); +- shdr->sh_size = new_size; +- shdr->sh_addralign = __libelf_type_align (ELFCLASS32, ELF_T_CHDR); +- shdr->sh_flags |= SHF_COMPRESSED; ++ shdr.s32->sh_size = new_size; ++ shdr.s32->sh_addralign = __libelf_type_align (ELFCLASS32, ++ ELF_T_CHDR); ++ shdr.s32->sh_flags |= SHF_COMPRESSED; + } + else + { +- Elf64_Shdr *shdr = elf64_getshdr (scn); +- shdr->sh_size = new_size; +- shdr->sh_addralign = __libelf_type_align (ELFCLASS64, ELF_T_CHDR); +- shdr->sh_flags |= SHF_COMPRESSED; ++ shdr.s64->sh_size = new_size; ++ shdr.s64->sh_addralign = __libelf_type_align (ELFCLASS64, ++ ELF_T_CHDR); ++ shdr.s64->sh_flags |= SHF_COMPRESSED; + } + + __libelf_reset_rawdata (scn, out_buf, new_size, 1, ELF_T_CHDR); +@@ -731,17 +736,15 @@ elf_compress (Elf_Scn *scn, int type, un + correctly and ignored when SHF_COMPRESSED is set. */ + if (elfclass == ELFCLASS32) + { +- Elf32_Shdr *shdr = elf32_getshdr (scn); +- shdr->sh_size = scn->zdata_size; +- shdr->sh_addralign = scn->zdata_align; +- shdr->sh_flags &= ~SHF_COMPRESSED; ++ shdr.s32->sh_size = scn->zdata_size; ++ shdr.s32->sh_addralign = scn->zdata_align; ++ shdr.s32->sh_flags &= ~SHF_COMPRESSED; + } + else + { +- Elf64_Shdr *shdr = elf64_getshdr (scn); +- shdr->sh_size = scn->zdata_size; +- shdr->sh_addralign = scn->zdata_align; +- shdr->sh_flags &= ~SHF_COMPRESSED; ++ shdr.s64->sh_size = scn->zdata_size; ++ shdr.s64->sh_addralign = scn->zdata_align; ++ shdr.s64->sh_flags &= ~SHF_COMPRESSED; + } + + __libelf_reset_rawdata (scn, scn->zdata_base, +--- a/libelf/elf_compress_gnu.c ++++ b/libelf/elf_compress_gnu.c +@@ -59,25 +59,30 @@ elf_compress_gnu (Elf_Scn *scn, int infl + Elf64_Xword sh_flags; + Elf64_Word sh_type; + Elf64_Xword sh_addralign; ++ union shdr ++ { ++ Elf32_Shdr *s32; ++ Elf64_Shdr *s64; ++ } shdr; + if (elfclass == ELFCLASS32) + { +- Elf32_Shdr *shdr = elf32_getshdr (scn); +- if (shdr == NULL) ++ shdr.s32 = elf32_getshdr (scn); ++ if (shdr.s32 == NULL) + return -1; + +- sh_flags = shdr->sh_flags; +- sh_type = shdr->sh_type; +- sh_addralign = shdr->sh_addralign; ++ sh_flags = shdr.s32->sh_flags; ++ sh_type = shdr.s32->sh_type; ++ sh_addralign = shdr.s32->sh_addralign; + } + else + { +- Elf64_Shdr *shdr = elf64_getshdr (scn); +- if (shdr == NULL) ++ shdr.s64 = elf64_getshdr (scn); ++ if (shdr.s64 == NULL) + return -1; + +- sh_flags = shdr->sh_flags; +- sh_type = shdr->sh_type; +- sh_addralign = shdr->sh_addralign; ++ sh_flags = shdr.s64->sh_flags; ++ sh_type = shdr.s64->sh_type; ++ sh_addralign = shdr.s64->sh_addralign; + } + + /* Allocated sections, or sections that are already are compressed +@@ -122,15 +127,9 @@ elf_compress_gnu (Elf_Scn *scn, int infl + sh_flags won't have a SHF_COMPRESSED hint in the GNU format. + Just adjust the sh_size. */ + if (elfclass == ELFCLASS32) +- { +- Elf32_Shdr *shdr = elf32_getshdr (scn); +- shdr->sh_size = new_size; +- } ++ shdr.s32->sh_size = new_size; + else +- { +- Elf64_Shdr *shdr = elf64_getshdr (scn); +- shdr->sh_size = new_size; +- } ++ shdr.s64->sh_size = new_size; + + __libelf_reset_rawdata (scn, out_buf, new_size, 1, ELF_T_BYTE); + +@@ -187,15 +186,9 @@ elf_compress_gnu (Elf_Scn *scn, int infl + sh_flags won't have a SHF_COMPRESSED hint in the GNU format. + Just adjust the sh_size. */ + if (elfclass == ELFCLASS32) +- { +- Elf32_Shdr *shdr = elf32_getshdr (scn); +- shdr->sh_size = size; +- } ++ shdr.s32->sh_size = size; + else +- { +- Elf64_Shdr *shdr = elf64_getshdr (scn); +- shdr->sh_size = size; +- } ++ shdr.s64->sh_size = size; + + __libelf_reset_rawdata (scn, buf_out, size, sh_addralign, + __libelf_data_type (&ehdr, sh_type, diff --git a/package/libs/elfutils/patches/102-fix-potential-deref-of-null-error.patch b/package/libs/elfutils/patches/102-fix-potential-deref-of-null-error.patch new file mode 100644 index 00000000000000..6710e4ef9cf176 --- /dev/null +++ b/package/libs/elfutils/patches/102-fix-potential-deref-of-null-error.patch @@ -0,0 +1,55 @@ +strip.c: Pointer `arhdr` created at strip.c:2741 and then dereferenced without NULL-check. +The same situation for the `arhdr` pointer at the objdump.c:313 and +the `h` pointer at the readelf.c:13545. + +Triggers found by static analyzer Svace. + +Signed-off-by: Maks Mishin +--- + src/objdump.c | 5 +++++ + src/readelf.c | 5 +++++ + src/strip.c | 5 +++++ + 3 files changed, 15 insertions(+) + +--- a/src/objdump.c ++++ b/src/objdump.c +@@ -311,6 +311,11 @@ handle_ar (int fd, Elf *elf, const char + { + /* The the header for this element. */ + Elf_Arhdr *arhdr = elf_getarhdr (subelf); ++ if (arhdr == NULL) ++ { ++ printf ("cannot get arhdr: %s\n", elf_errmsg (-1)); ++ exit (1); ++ } + + /* Skip over the index entries. */ + if (strcmp (arhdr->ar_name, "/") != 0 +--- a/src/readelf.c ++++ b/src/readelf.c +@@ -13543,6 +13543,11 @@ dump_archive_index (Elf *elf, const char + as_off, fname, elf_errmsg (-1)); + + const Elf_Arhdr *h = elf_getarhdr (subelf); ++ if (h == NULL) ++ { ++ printf ("cannot get arhdr: %s\n", elf_errmsg (-1)); ++ exit (1); ++ } + + printf (_("Archive member '%s' contains:\n"), h->ar_name); + +--- a/src/strip.c ++++ b/src/strip.c +@@ -2739,6 +2739,11 @@ handle_ar (int fd, Elf *elf, const char + { + /* The the header for this element. */ + Elf_Arhdr *arhdr = elf_getarhdr (subelf); ++ if (arhdr == NULL) ++ { ++ printf ("cannot get arhdr: %s\n", elf_errmsg (-1)); ++ exit (1); ++ } + + if (elf_kind (subelf) == ELF_K_ELF) + result |= handle_elf (fd, subelf, new_prefix, arhdr->ar_name, 0, NULL); diff --git a/package/libs/gettext-full/Makefile b/package/libs/gettext-full/Makefile index 0a7782c1f1e4f6..36615f3fd28b04 100644 --- a/package/libs/gettext-full/Makefile +++ b/package/libs/gettext-full/Makefile @@ -18,7 +18,8 @@ PKG_BUILD_DIR:=$(BUILD_DIR)/gettext-$(PKG_VERSION) HOST_BUILD_DIR:=$(BUILD_DIR_HOST)/gettext-$(PKG_VERSION) PKG_MAINTAINER:=Jo-Philipp Wich -PKG_LICENSE:=GPL-3.0-or-later +PKG_LICENSE:=LGPL-2.1-or-later +PKG_LICENSE_FILES:=gettext-runtime/intl/COPYING.LIB PKG_CPE_ID:=cpe:/a:gnu:gettext PKG_INSTALL:=1 diff --git a/package/libs/libbpf/Makefile b/package/libs/libbpf/Makefile index 89fe730a98adfe..4d918e7bbfd8f0 100644 --- a/package/libs/libbpf/Makefile +++ b/package/libs/libbpf/Makefile @@ -8,11 +8,11 @@ include $(TOPDIR)/rules.mk PKG_NAME:=libbpf -PKG_VERSION:=1.4.6 +PKG_VERSION:=1.5.0 PKG_RELEASE:=1 PKG_SOURCE_URL:=https://github.com/libbpf/libbpf -PKG_MIRROR_HASH:=0d0d70750c8e45baba19f8cc065771e5d842a90f3ad1637003cae6887dabf11e +PKG_MIRROR_HASH:=7699fcfa89bf0f6e756c4555fbd3fdb8cbcfcc770e5944aebdd0e9244031f022 PKG_SOURCE_PROTO:=git PKG_SOURCE_VERSION:=v$(PKG_VERSION) PKG_ABI_VERSION:=$(firstword $(subst .,$(space),$(PKG_VERSION))) diff --git a/package/libs/libiconv-full/Makefile b/package/libs/libiconv-full/Makefile index 0c793973a05f8a..8837942585903f 100644 --- a/package/libs/libiconv-full/Makefile +++ b/package/libs/libiconv-full/Makefile @@ -9,7 +9,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=libiconv-full PKG_VERSION:=1.17 -PKG_RELEASE:=1 +PKG_RELEASE:=2 PKG_SOURCE:=libiconv-$(PKG_VERSION).tar.gz PKG_SOURCE_URL:=@GNU/libiconv diff --git a/package/libs/libiconv-full/patches/001-Fix-a-clang-warning-a-function-declaration-without-a.patch b/package/libs/libiconv-full/patches/001-Fix-a-clang-warning-a-function-declaration-without-a.patch new file mode 100644 index 00000000000000..86cd2bc973c5c0 --- /dev/null +++ b/package/libs/libiconv-full/patches/001-Fix-a-clang-warning-a-function-declaration-without-a.patch @@ -0,0 +1,33 @@ +From e46dee2f581c1167137bcd045e114e96a9f00483 Mon Sep 17 00:00:00 2001 +From: Bruno Haible +Date: Sun, 29 Jan 2023 20:07:21 +0100 +Subject: [PATCH] Fix a clang warning "a function declaration without a + prototype...". + +* lib/loop_wchar.h (mbrtowc): Don't declare. Drop portability to BeOS. +--- + lib/loop_wchar.h | 3 +-- + 1 file changed, 1 insertions(+), 2 deletions(-) + +diff --git a/lib/loop_wchar.h b/lib/loop_wchar.h +index b3edc2925c60..9eb508e81a4f 100644 +--- a/lib/loop_wchar.h ++++ b/lib/loop_wchar.h +@@ -1,5 +1,5 @@ + /* +- * Copyright (C) 2000-2002, 2005-2006, 2008-2009, 2011 Free Software Foundation, Inc. ++ * Copyright (C) 2000-2002, 2005-2006, 2008-2009, 2011, 2023 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it +@@ -36,7 +36,6 @@ + # include + # define BUF_SIZE 64 /* assume MB_LEN_MAX <= 64 */ + /* Some systems, like BeOS, have multibyte encodings but lack mbstate_t. */ +- extern size_t mbrtowc (); + # ifdef mbstate_t + # define mbrtowc(pwc, s, n, ps) (mbrtowc)(pwc, s, n, 0) + # define mbsinit(ps) 1 +-- +2.49.0 + diff --git a/package/libs/libnftnl/Makefile b/package/libs/libnftnl/Makefile index b512d4d58fe616..f06b223993c2be 100644 --- a/package/libs/libnftnl/Makefile +++ b/package/libs/libnftnl/Makefile @@ -9,12 +9,12 @@ include $(TOPDIR)/rules.mk PKG_NAME:=libnftnl PKG_CPE_ID:=cpe:/a:netfilter:libnftnl -PKG_VERSION:=1.2.6 +PKG_VERSION:=1.2.8 PKG_RELEASE:=1 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz PKG_SOURCE_URL:=https://netfilter.org/projects/$(PKG_NAME)/files -PKG_HASH:=ceeaea2cd92147da19f13a35a7f1a4bc2767ff897e838e4b479cf54b59c777f4 +PKG_HASH:=37fea5d6b5c9b08de7920d298de3cdc942e7ae64b1a3e8b880b2d390ae67ad95 PKG_MAINTAINER:=Steven Barth PKG_LICENSE:=GPL-2.0-or-later diff --git a/package/libs/libnl-tiny/Makefile b/package/libs/libnl-tiny/Makefile index c211288f8eb150..d08100169361fc 100644 --- a/package/libs/libnl-tiny/Makefile +++ b/package/libs/libnl-tiny/Makefile @@ -12,9 +12,9 @@ PKG_RELEASE:=1 PKG_SOURCE_PROTO:=git PKG_SOURCE_URL=$(PROJECT_GIT)/project/libnl-tiny.git -PKG_SOURCE_DATE:=2023-12-05 -PKG_SOURCE_VERSION:=965c4bf49658342ced0bd6e7cb069571b4a1ddff -PKG_MIRROR_HASH:=4b56499e71f5f10b123e1c7ee13dbfcd970de560bff8d16ab39dc25c9ff743cb +PKG_SOURCE_DATE:=2025-03-19 +PKG_SOURCE_VERSION:=c0df580adbd4d555ecc1962dbe88e91d75b67a4e +PKG_MIRROR_HASH:=1064a27824d99a93cbf8dbc808caf2cb277f1825b378ec6076d2ecfb8866a81f CMAKE_INSTALL:=1 PKG_LICENSE:=LGPL-2.1 diff --git a/package/libs/libpcap/Makefile b/package/libs/libpcap/Makefile index 09aab0981ccfc3..052358b1f5c08f 100644 --- a/package/libs/libpcap/Makefile +++ b/package/libs/libpcap/Makefile @@ -9,7 +9,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=libpcap PKG_VERSION:=1.10.5 -PKG_RELEASE:=1 +PKG_RELEASE:=2 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz PKG_SOURCE_URL:=https://www.tcpdump.org/release/ @@ -22,7 +22,11 @@ PKG_CPE_ID:=cpe:/a:tcpdump:libpcap PKG_ASLR_PIE_REGULAR:=1 -PKG_CONFIG_DEPENDS := CONFIG_PACKAGE_rpcapd +PKG_CONFIG_DEPENDS := \ + CONFIG_PACKAGE_rpcapd \ + CONFIG_PCAP_HAS_USB \ + CONFIG_PCAP_HAS_BT \ + CONFIG_PCAP_HAS_NETFILTER include $(INCLUDE_DIR)/package.mk include $(INCLUDE_DIR)/cmake.mk diff --git a/package/libs/libpcap/patches/001-Add-support-for-Realtek-Ethertype-DSA-data.patch b/package/libs/libpcap/patches/001-Add-support-for-Realtek-Ethertype-DSA-data.patch new file mode 100644 index 00000000000000..5ec0e22afacd4c --- /dev/null +++ b/package/libs/libpcap/patches/001-Add-support-for-Realtek-Ethertype-DSA-data.patch @@ -0,0 +1,28 @@ +From fcb2cbc3a306afcf7785a60a74dbea431e609d76 Mon Sep 17 00:00:00 2001 +From: Luiz Angelo Daros de Luca +Date: Thu, 6 Jan 2022 15:51:54 -0300 +Subject: [PATCH 1/2] Add support for Realtek (Ethertype) DSA data + +Realtek switchtag rtl4a (4 bytes long, protocol 0xA) and rtl8_4 (8 bytes +long, protocol 0x04) are Ethertype DSA tags, inserted in the Ethernet +header similar to an 802.1Q tag. Both shares the same Ethertype 0x8899 +as other Realtek proprietary protocols. + +Realtek switchtag rtl8_4t is identical to rtl8_4 but positioned before +the CRC, at the end of the Ethernet frame. +--- + pcap-linux.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/pcap-linux.c ++++ b/pcap-linux.c +@@ -5281,6 +5281,9 @@ static struct dsa_proto { + { "brcm-prepend", DLT_DSA_TAG_BRCM_PREPEND }, + { "dsa", DLT_DSA_TAG_DSA }, + { "edsa", DLT_DSA_TAG_EDSA }, ++ { "rtl4a", DLT_EN10MB }, ++ { "rtl8_4", DLT_EN10MB }, ++ { "rtl8_4t", DLT_EN10MB }, + }; + + static int diff --git a/package/libs/libpcap/patches/002-Linux-handle-other-DSA-tags.patch b/package/libs/libpcap/patches/002-Linux-handle-other-DSA-tags.patch new file mode 100644 index 00000000000000..dc87d4010d727f --- /dev/null +++ b/package/libs/libpcap/patches/002-Linux-handle-other-DSA-tags.patch @@ -0,0 +1,322 @@ +From 7d298976beff0cce310fb53a430f82b53f43a394 Mon Sep 17 00:00:00 2001 +From: Guy Harris +Date: Fri, 14 Feb 2025 19:12:24 -0800 +Subject: [PATCH 2/2] Linux: handle other DSA tags. + +Many of those entries need their own LINKTYPE_/DLT_? values, including +tcpdump and Wireshark support for same, but at least this lets you see +raw hex data from a capture. + +Fixes #1367. + +Supercedes #1451. +--- + pcap-linux.c | 284 ++++++++++++++++++++++++++++++++++++++++++++++++++- + 1 file changed, 280 insertions(+), 4 deletions(-) + +--- a/pcap-linux.c ++++ b/pcap-linux.c +@@ -5267,23 +5267,299 @@ iface_get_offload(pcap_t *handle _U_) + } + #endif /* SIOCETHTOOL */ + ++/* ++ * As per ++ * ++ * https://www.kernel.org/doc/html/latest/networking/dsa/dsa.html#switch-tagging-protocols ++ * ++ * Type 1 means that the tag is prepended to the Ethernet packet. ++ * LINKTYPE_ETHERNET/DLT_EN10MB doesn't work, as it would try to ++ * dissect the tag data as the Ethernet header. These should get ++ * their own LINKTYPE_DLT_ values. ++ * ++ * Type 2 means that the tag is inserted into the Ethernet header ++ * after the source address and before the type/length field. ++ * ++ * Type 3 means that tag is a packet trailer. LINKTYPE_ETHERNET/DLT_EN10MB ++ * works, unless the next-layer protocol has no length field of its own, ++ * so that the tag might be treated as part of the payload. These should ++ * get their own LINKTYPE_/DLT_ values. ++ * ++ * If you get an "unsupported DSA tag" error, please add the tag to here, ++ * complete with a full comment indicating whether it's type 1, 2, or 3, ++ * and, for type 2, indicating whether it has an Ethertype and, if so ++ * what that type is, and whether it's registered with the IEEE or is ++ * self-assigned. Also, point to *something* that indicates the format ++ * of the tag. ++ */ + static struct dsa_proto { + const char *name; + bpf_u_int32 linktype; + } dsa_protos[] = { + /* +- * None is special and indicates that the interface does not have +- * any tagging protocol configured, and is therefore a standard +- * Ethernet interface. ++ * Type 1. See ++ * ++ * https://elixir.bootlin.com/linux/v6.13.2/source/net/dsa/tag_ar9331.c ++ */ ++ { "ar9331", DLT_EN10MB }, ++ ++ /* ++ * Type 2, without an Ethertype at the beginning, ++ * assigned a LINKTYPE_/DLT_ value. + */ +- { "none", DLT_EN10MB }, + { "brcm", DLT_DSA_TAG_BRCM }, ++ ++ /* ++ * Type 2, with Ethertype 0x8874, assigned to Broadcom. ++ * ++ * This doies not require a LINKTYPE_/DLT_ value, it ++ * just requires that Ethertype 0x8874 be dissected ++ * properly. ++ */ ++ { "brcm-legacy", DLT_EN10MB }, ++ ++ /* ++ * Type 1. ++ */ + { "brcm-prepend", DLT_DSA_TAG_BRCM_PREPEND }, ++ ++ /* ++ * Type 2, without an Etherype at he beginning, ++ * assigned a LINKTYPE_/DLT_ value. ++ */ + { "dsa", DLT_DSA_TAG_DSA }, ++ ++ /* ++ * Type 2, with an Ethertype field, but without ++ * an assigned Ethertype value that can be relied ++ * on; assigned a LINKTYPE_/DLT_ value. ++ */ + { "edsa", DLT_DSA_TAG_EDSA }, ++ ++ /* ++ * Type 1, with different transmit and receive headers, ++ * so can't really be handled well with the current ++ * libpcap API and with pcap files. Use DLT_LINUX_SLL, ++ * to get the direction? ++ * ++ * See ++ * ++ * https://elixir.bootlin.com/linux/v6.13.2/source/net/dsa/tag_gswip.c ++ */ ++ { "gswip", DLT_EN10MB }, ++ ++ /* ++ * Type 3. See ++ * ++ * https://elixir.bootlin.com/linux/v6.13.2/source/net/dsa/tag_hellcreek.c ++ */ ++ { "hellcreek", DLT_EN10MB }, ++ ++ /* ++ * Type 3, with different transmit and receive headers, ++ * so can't really be handled well with the current ++ * libpcap API and with pcap files. Use DLT_LINUX_SLL, ++ * to get the direction? ++ * ++ * See ++ * ++ * https://elixir.bootlin.com/linux/v6.13.2/source/net/dsa/tag_ksz.c#L102 ++ */ ++ { "ksz8795", DLT_EN10MB }, ++ ++ /* ++ * Type 3, with different transmit and receive headers, ++ * so can't really be handled well with the current ++ * libpcap API and with pcap files. Use DLT_LINUX_SLL, ++ * to get the direction? ++ * ++ * See ++ * ++ * https://elixir.bootlin.com/linux/v6.13.2/source/net/dsa/tag_ksz.c#L160 ++ */ ++ { "ksz9477", DLT_EN10MB }, ++ ++ /* ++ * Type 3, with different transmit and receive headers, ++ * so can't really be handled well with the current ++ * libpcap API and with pcap files. Use DLT_LINUX_SLL, ++ * to get the direction? ++ * ++ * See ++ * ++ * https://elixir.bootlin.com/linux/v6.13.2/source/net/dsa/tag_ksz.c#L341 ++ */ ++ { "ksz9893", DLT_EN10MB }, ++ ++ /* ++ * Type 3, with different transmit and receive headers, ++ * so can't really be handled well with the current ++ * libpcap API and with pcap files. Use DLT_LINUX_SLL, ++ * to get the direction? ++ * ++ * See ++ * ++ * https://elixir.bootlin.com/linux/v6.13.2/source/net/dsa/tag_ksz.c#L386 ++ */ ++ { "lan937x", DLT_EN10MB }, ++ ++ /* ++ * Type 2, with Ethertype 0x8100; the VID can be interpreted ++ * as per ++ * ++ * https://elixir.bootlin.com/linux/v6.13.2/source/net/dsa/tag_lan9303.c#L24 ++ * ++ * so giving its own LINKTYPE_/DLT_ value would allow a ++ * dissector to do so. ++ */ ++ { "lan9303", DLT_EN10MB }, ++ ++ /* ++ * Type 2, without an Etherype at he beginning, ++ * should be assigned a LINKTYPE_/DLT_ value. ++ * ++ * See ++ * ++ * https://elixir.bootlin.com/linux/v6.13.2/source/net/dsa/tag_mtk.c#L15 ++ */ ++ { "mtk", DLT_EN10MB }, ++ ++ /* ++ * None is special and indicates that the interface does not have ++ * any tagging protocol configured, and is therefore a standard ++ * Ethernet interface. ++ */ ++ { "none", DLT_EN10MB }, ++ ++ /* ++ * Type 1. ++ * ++ * See ++ * ++ * https://elixir.bootlin.com/linux/v6.13.2/source/net/dsa/tag_ocelot.c ++ */ ++ { "ocelot", DLT_EN10MB }, ++ ++ /* ++ * Type 1. ++ * ++ * See ++ * ++ * https://elixir.bootlin.com/linux/v6.13.2/source/net/dsa/tag_ocelot.c ++ */ ++ { "seville", DLT_EN10MB }, ++ ++ /* ++ * Type 2, with Ethertype 0x8100; the VID can be interpreted ++ * as per ++ * ++ * https://elixir.bootlin.com/linux/v6.13.2/source/net/dsa/tag_8021q.c#L15 ++ * ++ * so giving its own LINKTYPE_/DLT_ value would allow a ++ * dissector to do so. ++ */ ++ { "ocelot-8021q", DLT_EN10MB }, ++ ++ /* ++ * Type 2, without an Etherype at he beginning, ++ * should be assigned a LINKTYPE_/DLT_ value. ++ * ++ * See ++ * ++ * https://elixir.bootlin.com/linux/v6.13.2/source/net/dsa/tag_qca.c ++ */ ++ { "qca", DLT_EN10MB }, ++ ++ /* ++ * Type 2, with Ethertype 0x8899, assigned to Realtek; ++ * they use it for several on-the-Ethernet protocols ++ * as well, but there are fields that allow the two ++ * tag formats, and all the protocols in question, ++ * to be distinguiished from one another. ++ * ++ * This doies not require a LINKTYPE_/DLT_ value, it ++ * just requires that Ethertype 0x8899 be dissected ++ * properly. ++ * ++ * See ++ * ++ * https://elixir.bootlin.com/linux/v6.13.2/source/net/dsa/tag_rtl4_a.c ++ * ++ * http://realtek.info/pdf/rtl8306sd%28m%29_datasheet_1.1.pdf ++ * ++ * and various pages in tcpdump's print-realtek.c and Wireshark's ++ * epan/dissectors/packet-realtek.c for the other protocols. ++ */ + { "rtl4a", DLT_EN10MB }, ++ ++ /* ++ * Type 2, with Ethertype 0x8899, assigned to Realtek; ++ * see above. ++ */ + { "rtl8_4", DLT_EN10MB }, ++ ++ /* ++ * Type 3, with the same tag format as rtl8_4. ++ */ + { "rtl8_4t", DLT_EN10MB }, ++ ++ /* ++ * Type 2, with Ethertype 0xe001; that's probably ++ * self-assigned, so this really should ahve its ++ * own LINKTYPE_/DLT_ value. ++ * ++ * See ++ * ++ * https://elixir.bootlin.com/linux/v6.13.2/source/net/dsa/tag_rzn1_a5psw.c ++ */ ++ { "a5psw", DLT_EN10MB }, ++ ++ /* ++ * Type 2, with Ethertype 0x8100 or the self-assigned ++ * 0xdadb, so this really should ahve its own ++ * LINKTYPE_/DLT_ value; that would also allow the ++ * VID of the tag to be dissected as per ++ * ++ * https://elixir.bootlin.com/linux/v6.13.2/source/net/dsa/tag_8021q.c#L15 ++ */ ++ { "sja1105", DLT_EN10MB }, ++ ++ /* ++ * Type "none of the above", with both a header and trailer, ++ * with different transmit and receive tags. Has ++ * Ethertype 0xdadc, which is probably self-assigned. ++ * This should really have its own LINKTYPE_/DLT_ value. ++ */ ++ { "sja1110", DLT_EN10MB }, ++ ++ /* ++ * Type 3, as the name suggests. ++ * ++ * See ++ * ++ * https://elixir.bootlin.com/linux/v6.13.2/source/net/dsa/tag_trailer.c ++ */ ++ { "trailer", DLT_EN10MB }, ++ ++ /* ++ * Type 2, with Ethertype 0x8100; the VID can be interpreted ++ * as per ++ * ++ * https://elixir.bootlin.com/linux/v6.13.2/source/net/dsa/tag_8021q.c#L15 ++ * ++ * so giving its own LINKTYPE_/DLT_ value would allow a ++ * dissector to do so. ++ */ ++ { "vsc73xx-8021q", DLT_EN10MB }, ++ ++ /* ++ * Type 3. ++ * ++ * See ++ * ++ * https://elixir.bootlin.com/linux/v6.13.2/source/net/dsa/tag_xrs700x.c ++ */ ++ { "xrs700x", DLT_EN10MB }, + }; + + static int diff --git a/package/libs/libubox/Makefile b/package/libs/libubox/Makefile index 22abfd4372e38b..48ec2e05bb2900 100644 --- a/package/libs/libubox/Makefile +++ b/package/libs/libubox/Makefile @@ -5,10 +5,11 @@ PKG_RELEASE=1 PKG_SOURCE_PROTO:=git PKG_SOURCE_URL=$(PROJECT_GIT)/project/libubox.git -PKG_MIRROR_HASH:=a4f671d10840fd8487394335636051a6df5edf6d8854af4fcb834a590efb240a -PKG_SOURCE_DATE:=2024-03-29 -PKG_SOURCE_VERSION:=eb9bcb64185ac155c02cc1a604692c4b00368324 -PKG_ABI_VERSION:=$(call abi_version_str,$(PKG_SOURCE_DATE)) +PKG_MIRROR_HASH:=51b48648a3a64eed74bcb1ab352aaad6ef7679a574df4445d2914b990aba5bbf +PKG_SOURCE_DATE:=2025-07-23 +PKG_SOURCE_DATE_ABI:=2024-03-29 +PKG_SOURCE_VERSION:=49056d178f42da98048a5d4c23f83a6f6bc6dd80 +PKG_ABI_VERSION:=$(call abi_version_str,$(PKG_SOURCE_DATE_ABI)) CMAKE_INSTALL:=1 PKG_LICENSE:=ISC diff --git a/package/libs/libxml2/Makefile b/package/libs/libxml2/Makefile index c2a804b98f365e..c9ad81c128eaf4 100644 --- a/package/libs/libxml2/Makefile +++ b/package/libs/libxml2/Makefile @@ -1,12 +1,12 @@ include $(TOPDIR)/rules.mk PKG_NAME:=libxml2 -PKG_VERSION:=2.13.4 +PKG_VERSION:=2.14.5 PKG_RELEASE:=1 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz PKG_SOURCE_URL:=@GNOME/libxml2/$(basename $(PKG_VERSION)) -PKG_HASH:=65d042e1c8010243e617efb02afda20b85c2160acdbfbcb5b26b80cec6515650 +PKG_HASH:=03d006f3537616833c16c53addcdc32a0eb20e55443cba4038307e3fa7d8d44b PKG_LICENSE:=MIT PKG_LICENSE_FILES:=COPYING @@ -24,6 +24,7 @@ define Package/libxml2 TITLE:=Gnome XML library URL:=http://xmlsoft.org/ DEPENDS:=+libpthread +zlib $(ICONV_DEPENDS) + ABI_VERSION:=16 endef define Package/libxml2/description @@ -61,7 +62,7 @@ endef CMAKE_HOST_OPTIONS += \ -DBUILD_SHARED_LIBS=OFF \ -DLIBXML2_WITH_C14N=ON \ - -DLIBXML2_WITH_CATALOG=OFF \ + -DLIBXML2_WITH_CATALOG=ON \ -DLIBXML2_WITH_DEBUG=ON \ -DLIBXML2_WITH_FTP=OFF \ -DLIBXML2_WITH_HTML=ON \ @@ -99,7 +100,7 @@ CMAKE_HOST_OPTIONS += \ CMAKE_OPTIONS += \ -DBUILD_SHARED_LIBS=ON \ -DLIBXML2_WITH_C14N=ON \ - -DLIBXML2_WITH_CATALOG=OFF \ + -DLIBXML2_WITH_CATALOG=ON \ -DLIBXML2_WITH_DEBUG=ON \ -DLIBXML2_WITH_FTP=OFF \ -DLIBXML2_WITH_HTML=ON \ @@ -160,9 +161,6 @@ define Build/InstallDev $(INSTALL_DIR) $(1)/usr/lib/pkgconfig $(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/libxml-2.0.pc $(1)/usr/lib/pkgconfig/ - - $(INSTALL_DIR) $(2)/share/aclocal/ - $(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/share/aclocal/* $(2)/share/aclocal endef define Host/Install @@ -190,9 +188,6 @@ define Package/libxml2-dev/install $(INSTALL_DIR) $(1)/usr/lib/{cmake,pkgconfig} $(CP) $(PKG_INSTALL_DIR)/usr/lib/{cmake,pkgconfig} $(1)/usr/lib/ $(SED) "s,$(STAGING_DIR),,g" $(1)/usr/lib/pkgconfig/*.pc - - $(INSTALL_DIR) $(1)/usr/share/aclocal - $(CP) $(PKG_INSTALL_DIR)/usr/share/aclocal/* $(1)/usr/share/aclocal endef define Package/libxml2-utils/install diff --git a/package/libs/mbedtls/Config.in b/package/libs/mbedtls/Config.in index 51f8bcbbdd36a0..2009d5db96f3c8 100644 --- a/package/libs/mbedtls/Config.in +++ b/package/libs/mbedtls/Config.in @@ -8,6 +8,10 @@ config MBEDTLS_AES_C bool "MBEDTLS_AES_C" default y +config MBEDTLS_ARIA_C + bool "MBEDTLS_ARIA_C" + default n + config MBEDTLS_CAMELLIA_C bool "MBEDTLS_CAMELLIA_C" default n @@ -80,6 +84,10 @@ config MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED bool "MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED" default n +config MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED + bool "MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED" + default n + comment "Curves - unselect old or less-used curves to reduce binary size" config MBEDTLS_ECP_DP_SECP192R1_ENABLED diff --git a/package/libs/mbedtls/Makefile b/package/libs/mbedtls/Makefile index 2efdf86cd207f9..d6dc0f7805aa46 100644 --- a/package/libs/mbedtls/Makefile +++ b/package/libs/mbedtls/Makefile @@ -8,13 +8,13 @@ include $(TOPDIR)/rules.mk PKG_NAME:=mbedtls -PKG_VERSION:=3.6.2 +PKG_VERSION:=3.6.4 PKG_RELEASE:=1 PKG_BUILD_FLAGS:=no-mips16 gc-sections no-lto PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2 PKG_SOURCE_URL=https://github.com/Mbed-TLS/$(PKG_NAME)/releases/download/$(PKG_NAME)-$(PKG_VERSION) -PKG_HASH:=8b54fb9bcf4d5a7078028e0520acddefb7900b3e66fec7f7175bb5b7d85ccdca +PKG_HASH:=ec35b18a6c593cf98c3e30db8b98ff93e8940a8c4e690e66b41dfc011d678110 PKG_LICENSE:=GPL-2.0-or-later PKG_LICENSE_FILES:=LICENSE @@ -37,6 +37,7 @@ MBEDTLS_BUILD_OPTS_CURVES= \ MBEDTLS_BUILD_OPTS_CIPHERS= \ CONFIG_MBEDTLS_AES_C \ + CONFIG_MBEDTLS_ARIA_C \ CONFIG_MBEDTLS_CAMELLIA_C \ CONFIG_MBEDTLS_CCM_C \ CONFIG_MBEDTLS_CMAC_C \ @@ -52,6 +53,7 @@ MBEDTLS_BUILD_OPTS_CIPHERS= \ CONFIG_MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED \ CONFIG_MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED \ CONFIG_MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED \ + CONFIG_MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED \ CONFIG_MBEDTLS_NIST_KW_C \ CONFIG_MBEDTLS_RIPEMD160_C \ CONFIG_MBEDTLS_RSA_NO_CRT \ diff --git a/package/libs/mbedtls/patches/101-remove-test.patch b/package/libs/mbedtls/patches/101-remove-test.patch index 5ac5e7c1e85a11..e584a8036c7069 100644 --- a/package/libs/mbedtls/patches/101-remove-test.patch +++ b/package/libs/mbedtls/patches/101-remove-test.patch @@ -1,6 +1,7 @@ --- a/programs/CMakeLists.txt +++ b/programs/CMakeLists.txt -@@ -1,13 +1,9 @@ +@@ -3,14 +3,10 @@ add_custom_target(${programs_target}) + add_subdirectory(aes) add_subdirectory(cipher) -if (NOT WIN32) diff --git a/package/libs/openssl/Makefile b/package/libs/openssl/Makefile index 959424ce12c540..25a71fa7a438c0 100644 --- a/package/libs/openssl/Makefile +++ b/package/libs/openssl/Makefile @@ -8,7 +8,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=openssl -PKG_VERSION:=3.0.15 +PKG_VERSION:=3.0.17 PKG_RELEASE:=1 PKG_BUILD_FLAGS:=no-mips16 gc-sections no-lto @@ -21,7 +21,7 @@ PKG_SOURCE_URL:= \ https://www.openssl.org/source/old/$(PKG_BASE)/ \ https://github.com/openssl/openssl/releases/download/$(PKG_NAME)-$(PKG_VERSION)/ -PKG_HASH:=23c666d0edf20f14249b3d8f0368acaee9ab585b09e1de82107c66e1f3ec9533 +PKG_HASH:=dfdd77e4ea1b57ff3a6dbde6b0bdc3f31db5ac99e7fdd4eaf9e1fbb6ec2db8ce PKG_LICENSE:=Apache-2.0 PKG_LICENSE_FILES:=LICENSE diff --git a/package/libs/openssl/patches/100-Configure-afalg-support.patch b/package/libs/openssl/patches/100-Configure-afalg-support.patch index e9cd7bf9c1afa6..7ce5cd43835e87 100644 --- a/package/libs/openssl/patches/100-Configure-afalg-support.patch +++ b/package/libs/openssl/patches/100-Configure-afalg-support.patch @@ -10,7 +10,7 @@ Signed-off-by: Eneas U de Queiroz --- a/Configure +++ b/Configure -@@ -1677,7 +1677,9 @@ $config{CFLAGS} = [ map { $_ eq '--ossl- +@@ -1678,7 +1678,9 @@ $config{CFLAGS} = [ map { $_ eq '--ossl- unless ($disabled{afalgeng}) { $config{afalgeng}=""; diff --git a/package/libs/readline/Makefile b/package/libs/readline/Makefile index 11b9e0172f844a..03e56f36ed4d15 100644 --- a/package/libs/readline/Makefile +++ b/package/libs/readline/Makefile @@ -69,7 +69,7 @@ endef define Package/libreadline/install $(INSTALL_DIR) $(1)/usr/lib - $(CP) $(PKG_INSTALL_DIR)/usr/lib/lib{history,readline}.so.* $(1)/usr/lib/ + $(CP) $(PKG_INSTALL_DIR)/usr/lib/lib{history,readline}.so* $(1)/usr/lib/ endef $(eval $(call HostBuild)) diff --git a/package/libs/udebug/Makefile b/package/libs/udebug/Makefile index bfb13cf788428b..fe9ac872194ae2 100644 --- a/package/libs/udebug/Makefile +++ b/package/libs/udebug/Makefile @@ -11,9 +11,9 @@ PKG_NAME:=udebug CMAKE_INSTALL:=1 PKG_SOURCE_PROTO:=git PKG_SOURCE_URL=$(PROJECT_GIT)/project/udebug.git -PKG_MIRROR_HASH:=4dfe98b5d5813066dccd46d112502565b6961a4a7382083c529dfb423a626c2b -PKG_SOURCE_DATE:=2023-12-06 -PKG_SOURCE_VERSION:=6d3f51f9fda706f0cf4732c762e4dbe8c21e12cf +PKG_MIRROR_HASH:=5e7b713aa1bff3b6480d4bd94d607b9cafed787b3d1cb27513883c83e56b0273 +PKG_SOURCE_DATE:=2025-08-24 +PKG_SOURCE_VERSION:=edeb4d6dc690acb476a47e6b11633b5632b08437 PKG_ABI_VERSION:=$(call abi_version_str,$(PKG_SOURCE_DATE)) PKG_LICENSE:=GPL-2.0 @@ -51,7 +51,7 @@ define Package/udebug-cli SECTION:=utils CATEGORY:=Utilities TITLE:=OpenWrt debug service CLI - DEPENDS:=+udebugd +ucode-mod-udebug + DEPENDS:=+udebugd +ucode-mod-udebug +ucode-mod-uloop +ucode-mod-ubus endef define Package/libudebug/install diff --git a/package/libs/wolfssl/Makefile b/package/libs/wolfssl/Makefile index bac4a8ef52bc83..ee6baefddcd462 100644 --- a/package/libs/wolfssl/Makefile +++ b/package/libs/wolfssl/Makefile @@ -8,12 +8,15 @@ include $(TOPDIR)/rules.mk PKG_NAME:=wolfssl -PKG_VERSION:=5.7.2-stable +PKG_VERSION:=5.7.6 +PKG_REAL_VERSION:=$(PKG_VERSION)-stable PKG_RELEASE:=1 -PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz -PKG_SOURCE_URL:=https://github.com/wolfSSL/wolfssl/archive/v$(PKG_VERSION) -PKG_HASH:=0f2ed82e345b833242705bbc4b08a2a2037a33f7bf9c610efae6464f6b10e305 +PKG_SOURCE:=$(PKG_NAME)-$(PKG_REAL_VERSION).tar.gz +PKG_SOURCE_URL:=https://github.com/wolfSSL/wolfssl/archive/v$(PKG_REAL_VERSION) +PKG_HASH:=52b1e439e30d1ed8162a16308a8525a862183b67aa30373b11166ecbab000d63 + +PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(BUILD_VARIANT)/$(PKG_NAME)-$(PKG_REAL_VERSION) PKG_FIXUP:=libtool libtool-abiver PKG_INSTALL:=1 @@ -40,7 +43,7 @@ PKG_CONFIG_DEPENDS:=\ CONFIG_WOLFSSL_HAS_TLSV13 \ CONFIG_WOLFSSL_HAS_WPAS -PKG_ABI_VERSION:=$(patsubst %-stable,%,$(PKG_VERSION)).$(call version_abbrev,$(call confvar,$(PKG_CONFIG_DEPENDS))) +PKG_ABI_VERSION:=$(PKG_VERSION).$(call version_abbrev,$(call confvar,$(PKG_CONFIG_DEPENDS))) PKG_CONFIG_DEPENDS+=\ CONFIG_PACKAGE_libwolfssl-benchmark \ diff --git a/package/libs/wolfssl/patches/100-disable-hardening-check.patch b/package/libs/wolfssl/patches/100-disable-hardening-check.patch index 174e657982b3fe..ab695d391d83c9 100644 --- a/package/libs/wolfssl/patches/100-disable-hardening-check.patch +++ b/package/libs/wolfssl/patches/100-disable-hardening-check.patch @@ -1,6 +1,6 @@ --- a/wolfssl/wolfcrypt/settings.h +++ b/wolfssl/wolfcrypt/settings.h -@@ -3046,7 +3046,7 @@ extern void uITRON4_free(void *p) ; +@@ -3722,7 +3722,7 @@ extern void uITRON4_free(void *p) ; /* warning for not using harden build options (default with ./configure) */ /* do not warn if big integer support is disabled */ diff --git a/package/network/config/firewall4/Makefile b/package/network/config/firewall4/Makefile index 6aacc05e365b45..9b53349275bf2c 100644 --- a/package/network/config/firewall4/Makefile +++ b/package/network/config/firewall4/Makefile @@ -9,9 +9,9 @@ PKG_RELEASE:=1 PKG_SOURCE_PROTO:=git PKG_SOURCE_URL=$(PROJECT_GIT)/project/firewall4.git -PKG_SOURCE_DATE:=2024-05-21 -PKG_SOURCE_VERSION:=4c01d1ebf99e8ecfa69758a9b4f450ecef7b93cd -PKG_MIRROR_HASH:=bbc5622bc03e3b43116fcc86e3fa2d2372bfc07b3a00d2b3a6efac4f7454a403 +PKG_SOURCE_DATE:=2024-12-18 +PKG_SOURCE_VERSION:=18fc0ead19faf06b8ce7ec5be84957278e942dfa +PKG_MIRROR_HASH:=123d1b5d00cdbbfa77813b3eb694d00949171037a0fa26e6d36a75a37066ba48 PKG_MAINTAINER:=Jo-Philipp Wich PKG_LICENSE:=ISC diff --git a/package/network/config/ltq-adsl-app/Makefile b/package/network/config/ltq-adsl-app/Makefile index b96a3f71e5bd1c..3da37f884d9ba6 100644 --- a/package/network/config/ltq-adsl-app/Makefile +++ b/package/network/config/ltq-adsl-app/Makefile @@ -10,7 +10,7 @@ include $(INCLUDE_DIR)/kernel.mk PKG_NAME:=dsl_cpe_control_danube PKG_VERSION:=3.24.4.4 -PKG_RELEASE:=13 +PKG_RELEASE:=14 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz PKG_BUILD_DIR:=$(BUILD_DIR)/dsl_cpe_control-$(PKG_VERSION) PKG_SOURCE_URL:=@OPENWRT diff --git a/package/network/config/ltq-vdsl-vr11-app/Makefile b/package/network/config/ltq-vdsl-vr11-app/Makefile index f1782db285c064..2aacbbd785103c 100644 --- a/package/network/config/ltq-vdsl-vr11-app/Makefile +++ b/package/network/config/ltq-vdsl-vr11-app/Makefile @@ -9,7 +9,7 @@ include $(INCLUDE_DIR)/kernel.mk PKG_NAME:=ltq-vdsl-vr11-app PKG_VERSION:=4.23.1 -PKG_RELEASE:=5 +PKG_RELEASE:=6 PKG_BASE_NAME:=dsl_cpe_control UGW_VERSION=8.5.2.10 diff --git a/package/network/config/ltq-vdsl-vr9-app/Makefile b/package/network/config/ltq-vdsl-vr9-app/Makefile index 51b88231f7e4b8..c1b3b12e1cddb6 100644 --- a/package/network/config/ltq-vdsl-vr9-app/Makefile +++ b/package/network/config/ltq-vdsl-vr9-app/Makefile @@ -9,7 +9,7 @@ include $(INCLUDE_DIR)/kernel.mk PKG_NAME:=ltq-vdsl-vr9-app PKG_VERSION:=4.17.18.6 -PKG_RELEASE:=7 +PKG_RELEASE:=8 PKG_BASE_NAME:=dsl_cpe_control PKG_SOURCE:=$(PKG_BASE_NAME)_vrx-$(PKG_VERSION).tar.gz PKG_SOURCE_URL:=@OPENWRT @@ -29,7 +29,7 @@ define Package/ltq-vdsl-vr9-app CATEGORY:=Network TITLE:=Lantiq VDSL userland tool URL:=http://www.lantiq.com/ - DEPENDS:=@TARGET_lantiq_xrx200 +libpthread +librt +ltq-dsl-base +libubox +libubus + DEPENDS:=@(TARGET_lantiq_xrx200||TARGET_lantiq_xrx200_legacy) +libpthread +librt +ltq-dsl-base +libubox +libubus PROVIDES:=ltq-dsl-app endef diff --git a/package/network/config/ltq-vdsl-vr9-app/src/src/dsl_cpe_ubus.c b/package/network/config/ltq-vdsl-vr9-app/src/src/dsl_cpe_ubus.c index 77a1c67b6aebc2..0636fbc8cae7df 100644 --- a/package/network/config/ltq-vdsl-vr9-app/src/src/dsl_cpe_ubus.c +++ b/package/network/config/ltq-vdsl-vr9-app/src/src/dsl_cpe_ubus.c @@ -447,7 +447,7 @@ static void pilot_tones_status(int fd) { } static void band_border_status(int fd, DSL_AccessDir_t direction) { - IOCTL(DSL_BandBorderStatus_t, DSL_FIO_BAND_BORDER_STATUS_GET); + IOCTL_DIR(DSL_BandBorderStatus_t, DSL_FIO_BAND_BORDER_STATUS_GET, direction); void *c, *c2; diff --git a/package/network/config/netifd/Makefile b/package/network/config/netifd/Makefile index 771d7dadafd119..86a2713e81395b 100644 --- a/package/network/config/netifd/Makefile +++ b/package/network/config/netifd/Makefile @@ -5,9 +5,9 @@ PKG_RELEASE:=1 PKG_SOURCE_PROTO:=git PKG_SOURCE_URL=$(PROJECT_GIT)/project/netifd.git -PKG_SOURCE_DATE:=2024-10-06 -PKG_SOURCE_VERSION:=3c6265fdbd02ebd35fa3e7a58d6dfeed081a09d7 -PKG_MIRROR_HASH:=00b01243b99995dc52a047e5663cf5c7732f8defd6b726f73ac15e142b02b4fa +PKG_SOURCE_DATE:=2025-05-23 +PKG_SOURCE_VERSION:=7901e66c5f273bceee8981bc8a0c8b0e60945f60 +PKG_MIRROR_HASH:=8b85ec64e446ae065b1466c520b2d3aae329b6167221e425af903777278f557e PKG_MAINTAINER:=Felix Fietkau PKG_LICENSE:=GPL-2.0 diff --git a/package/network/config/netifd/files/etc/init.d/network b/package/network/config/netifd/files/etc/init.d/network index dc208c4ce0a1f5..b8b2a219b18482 100755 --- a/package/network/config/netifd/files/etc/init.d/network +++ b/package/network/config/netifd/files/etc/init.d/network @@ -30,12 +30,11 @@ reload_service() { init_switch ubus call network reload || rv=1 - /sbin/wifi reload_legacy return $rv } stop_service() { - /sbin/wifi down + [ -x /sbin/wifi ] && /sbin/wifi down ifdown -a sleep 1 } diff --git a/package/network/config/netifd/files/usr/libexec/network/packet-steering.uc b/package/network/config/netifd/files/usr/libexec/network/packet-steering.uc index a578e288791d7d..34df46d18ef5d8 100755 --- a/package/network/config/netifd/files/usr/libexec/network/packet-steering.uc +++ b/package/network/config/netifd/files/usr/libexec/network/packet-steering.uc @@ -65,8 +65,9 @@ function cpu_mask(cpu) return sprintf("%x", mask); } -function set_netdev_cpu(dev, cpu) { - let queues = glob(`/sys/class/net/${dev}/queues/rx-*/rps_cpus`); +function set_netdev_cpu(dev, cpu, rx_queue) { + rx_queue ??= "rx-*"; + let queues = glob(`/sys/class/net/${dev}/queues/${rx_queue}/rps_cpus`); let val = cpu_mask(cpu); if (disable) val = 0; @@ -76,7 +77,7 @@ function set_netdev_cpu(dev, cpu) { if (!do_nothing) writefile(queue, `${val}`); } - queues = glob(`/sys/class/net/${dev}/queues/rx-*/rps_flow_cnt`); + queues = glob(`/sys/class/net/${dev}/queues/${rx_queue}/rps_flow_cnt`); for (let queue in queues) { if (debug || do_nothing) warn(`echo ${local_flows} > ${queue}\n`); @@ -87,7 +88,7 @@ function set_netdev_cpu(dev, cpu) { function task_device_match(name, device) { - let napi_match = match(name, /napi\/([^-+])-\d+/); + let napi_match = match(name, /napi\/([^-]*)-\d+/); if (!napi_match) napi_match = match(name, /mt76-tx (phy\d+)/); if (napi_match && @@ -160,6 +161,9 @@ for (let dev in netdevs) { netdev: [], phy: [], tasks: [], + rx_tasks: [], + rx_queues: map(glob(`/sys/class/net/${dev}/queues/rx-*/rps_cpus`), + (v) => basename(dirname(v))), }; } @@ -187,11 +191,51 @@ for (let path in glob("/proc/*/exe")) { continue; push(dev.tasks, pid); + + let napi_match = match(name, /napi\/([^-]*)-(\d+)/); + if (napi_match && napi_match[2] > 0) + push(dev.rx_tasks, pid); break; } } +function assign_dev_queues_cpu(dev) { + let num = length(dev.rx_queues); + if (num < length(dev.rx_tasks)) + num = length(dev.rx_tasks); + + for (let i = 0; i < num; i++) { + let cpu; + + let task = dev.rx_tasks[i]; + if (num >= length(cpus)) + cpu = i % length(cpus); + else if (task) + cpu = get_next_cpu(napi_weight); + else + cpu = -1; + set_task_cpu(task, cpu); + + let rxq = dev.rx_queues[i]; + if (!rxq) + continue; + + if (num >= length(cpus)) + cpu = (i + 1) % length(cpus); + else if (all_cpus) + cpu = -1; + else + cpu = get_next_cpu(napi_weight, cpu); + for (let netdev in dev.netdev) + set_netdev_cpu(netdev, cpu, rxq); + } +} + function assign_dev_cpu(dev) { + if (length(dev.rx_queues) > 1 && + length(dev.rx_tasks) > 1) + return assign_dev_queues_cpu(dev); + if (length(dev.tasks) > 0) { let cpu = dev.napi_cpu = get_next_cpu(napi_weight); for (let task in dev.tasks) @@ -204,7 +248,6 @@ function assign_dev_cpu(dev) { cpu = -1; else cpu = get_next_cpu(rx_weight, dev.napi_cpu); - dev.rx_cpu = cpu; for (let netdev in dev.netdev) set_netdev_cpu(netdev, cpu); } diff --git a/package/network/config/wifi-scripts/files/lib/netifd/hostapd.sh b/package/network/config/wifi-scripts/files/lib/netifd/hostapd.sh index 817ead71afd063..6bdd0236cf994e 100644 --- a/package/network/config/wifi-scripts/files/lib/netifd/hostapd.sh +++ b/package/network/config/wifi-scripts/files/lib/netifd/hostapd.sh @@ -428,9 +428,36 @@ hostapd_set_psk() { local ifname="$1" rm -f /var/run/hostapd-${ifname}.psk + case "$auth_type" in + psk|psk-sae) ;; + *) return ;; + esac for_each_station hostapd_set_psk_file ${ifname} } +hostapd_set_sae_file() { + local ifname="$1" + local vlan="$2" + local vlan_id="" + + json_get_vars mac vid key + set_default mac "ff:ff:ff:ff:ff:ff" + [ -n "$mac" ] && mac="|mac=$mac" + [ -n "$vid" ] && vlan_id="|vlanid=$vid" + printf '%s%s%s\n' "${key}" "${mac}" "${vlan_id}" >> /var/run/hostapd-${ifname}.sae +} + +hostapd_set_sae() { + local ifname="$1" + + rm -f /var/run/hostapd-${ifname}.sae + case "$auth_type" in + sae|psk-sae) ;; + *) return ;; + esac + for_each_station hostapd_set_sae_file ${ifname} +} + append_iw_roaming_consortium() { [ -n "$1" ] && append bss_conf "roaming_consortium=$1" "$N" } @@ -686,7 +713,7 @@ hostapd_set_bss_options() { wps_not_configured=1 ;; psk|sae|psk-sae) - json_get_vars key wpa_psk_file + json_get_vars key wpa_psk_file sae_password_file if [ "$ppsk" -ne 0 ]; then json_get_vars auth_secret auth_port set_default auth_port 1812 @@ -697,15 +724,20 @@ hostapd_set_bss_options() { append bss_conf "wpa_psk=$key" "$N" elif [ ${#key} -ge 8 ] && [ ${#key} -le 63 ]; then append bss_conf "wpa_passphrase=$key" "$N" - elif [ -n "$key" ] || [ -z "$wpa_psk_file" ]; then + elif [ -n "$key" ]; then wireless_setup_vif_failed INVALID_WPA_PSK return 1 fi [ -z "$wpa_psk_file" ] && set_default wpa_psk_file /var/run/hostapd-$ifname.psk - [ -n "$wpa_psk_file" ] && { + [ -n "$wpa_psk_file" ] && [ "$auth_type" = "psk" -o "$auth_type" = "psk-sae" ] && { [ -e "$wpa_psk_file" ] || touch "$wpa_psk_file" append bss_conf "wpa_psk_file=$wpa_psk_file" "$N" } + [ -z "$sae_password_file" ] && set_default sae_password_file /var/run/hostapd-$ifname.sae + [ -n "$sae_password_file" ] && [ "$auth_type" = "sae" -o "$auth_type" = "psk-sae" ] && { + [ -e "$sae_password_file" ] || touch "$sae_password_file" + append bss_conf "sae_password_file=$sae_password_file" "$N" + } [ "$eapol_version" -ge "1" -a "$eapol_version" -le "2" ] && append bss_conf "eapol_version=$eapol_version" "$N" set_default dynamic_vlan 0 @@ -1329,11 +1361,13 @@ wpa_supplicant_add_network() { json_get_vars \ ssid bssid key \ - basic_rate mcast_rate \ + mcast_rate \ ieee80211w ieee80211r fils ocv \ multi_ap \ default_disabled + json_get_values basic_rate_list basic_rate + case "$auth_type" in sae|owe|eap2|eap192) set_default ieee80211w 2 @@ -1594,12 +1628,21 @@ wpa_supplicant_add_network() { [ -n "$bssid_blacklist" ] && append network_data "bssid_blacklist=$bssid_blacklist" "$N$T" [ -n "$bssid_whitelist" ] && append network_data "bssid_whitelist=$bssid_whitelist" "$N$T" - [ -n "$basic_rate" ] && { - local br rate_list= - for br in $basic_rate; do - wpa_supplicant_add_rate rate_list "$br" - done - [ -n "$rate_list" ] && append network_data "rates=$rate_list" "$N$T" + [ -n "$basic_rate_list" ] && { + local br rate rate_list= + + if [ "$mode" = mesh ]; then + for br in $basic_rate_list; do + rate="$(($br / 100))" + append rate_list "$rate" " " + done + [ -n "$rate_list" ] && append network_data "mesh_basic_rates=$rate_list" "$N$T" + else + for br in $basic_rate_list; do + wpa_supplicant_add_rate rate_list "$br" + done + [ -n "$rate_list" ] && append network_data "rates=$rate_list" "$N$T" + fi } [ -n "$mcast_rate" ] && { diff --git a/package/network/config/wifi-scripts/files/lib/netifd/netifd-wireless.sh b/package/network/config/wifi-scripts/files/lib/netifd/netifd-wireless.sh index 5b852e0937631a..c3772bb44312d4 100644 --- a/package/network/config/wifi-scripts/files/lib/netifd/netifd-wireless.sh +++ b/package/network/config/wifi-scripts/files/lib/netifd/netifd-wireless.sh @@ -379,6 +379,7 @@ _wdev_common_device_config() { _wdev_common_iface_config() { config_add_string mode ssid encryption 'key:wpakey' config_add_boolean bridge_isolate + config_add_array tags } _wdev_common_vlan_config() { diff --git a/package/network/config/wifi-scripts/files/lib/netifd/wireless/mac80211.sh b/package/network/config/wifi-scripts/files/lib/netifd/wireless/mac80211.sh index 9998e26ec13189..eea18e830efc94 100755 --- a/package/network/config/wifi-scripts/files/lib/netifd/wireless/mac80211.sh +++ b/package/network/config/wifi-scripts/files/lib/netifd/wireless/mac80211.sh @@ -12,7 +12,7 @@ MP_CONFIG_INT="mesh_retry_timeout mesh_confirm_timeout mesh_holding_timeout mesh mesh_hwmp_rann_interval mesh_gate_announcements mesh_sync_offset_max_neighor mesh_rssi_threshold mesh_hwmp_active_path_to_root_timeout mesh_hwmp_root_interval mesh_hwmp_confirmation_interval mesh_awake_window mesh_plink_timeout" -MP_CONFIG_BOOL="mesh_auto_open_plinks mesh_fwding" +MP_CONFIG_BOOL="mesh_auto_open_plinks mesh_fwding mesh_nolearn" MP_CONFIG_STRING="mesh_power_mode" wdev_tool() { @@ -29,6 +29,8 @@ drv_mac80211_init_device_config() { config_add_string path phy 'macaddr:macaddr' config_add_string tx_burst config_add_string distance + config_add_string ifname_prefix + config_add_string macaddr_base config_add_int radio beacon_int chanbw frag rts config_add_int rxantenna txantenna txpower min_tx_power config_add_int num_global_macaddr multiple_bssid @@ -208,7 +210,7 @@ mac80211_hostapd_setup_base() { dsss_cck_40:1 ht_cap_mask=0 - for cap in $(iw phy "$phy" info | grep 'Capabilities:' | cut -d: -f2); do + for cap in $(iw phy "$phy" info | grep -E '^\s*Capabilities:' | cut -d: -f2); do ht_cap_mask="$(($ht_cap_mask | $cap))" done @@ -529,6 +531,7 @@ ${hostapd_noscan:+noscan=1} ${tx_burst:+tx_queue_data2_burst=$tx_burst} ${multiple_bssid:+mbssid=$multiple_bssid} #num_global_macaddr=$num_global_macaddr +#macaddr_base=$macaddr_base $base_cfg EOF @@ -560,6 +563,7 @@ mac80211_hostapd_setup_bss() { $hostapd_cfg bssid=$macaddr ${default_macaddr:+#default_macaddr} +${random_macaddr:+#random_macaddr} ${dtim_period:+dtim_period=$dtim_period} ${max_listen_int:+max_listen_interval=$max_listen_int} EOF @@ -576,7 +580,7 @@ mac80211_generate_mac() { local phy="$1" local id="${macidx:-0}" - wdev_tool "$phy$phy_suffix" get_macaddr id=$id num_global=$num_global_macaddr mbssid=${multiple_bssid:-0} + wdev_tool "$phy$phy_suffix" get_macaddr id=$id num_global=$num_global_macaddr mbssid=${multiple_bssid:-0} macaddr_base=${macaddr_base} } get_board_phy_name() ( @@ -660,15 +664,15 @@ mac80211_check_ap() { } mac80211_set_ifname() { - local phy="$1" - local prefix="$2" - eval "ifname=\"$phy-$prefix\${idx_$prefix:-0}\"; idx_$prefix=\$((\${idx_$prefix:-0 } + 1))" + local prefix="$1" + local type="$2" + eval "ifname=\"$prefix$type\${idx_$type:-0}\"; idx_$type=\$((\${idx_$type:-0 } + 1))" } mac80211_prepare_vif() { json_select config - json_get_vars ifname mode ssid wds powersave macaddr enable wpa_psk_file vlan_file + json_get_vars ifname mode ssid wds powersave macaddr enable wpa_psk_file sae_password_file vlan_file [ -n "$ifname" ] || { local prefix; @@ -679,7 +683,7 @@ mac80211_prepare_vif() { monitor) prefix=mon;; esac - mac80211_set_ifname "$phy$vif_phy_suffix" "$prefix" + mac80211_set_ifname "$ifname_prefix" "$prefix" } append active_ifnames "$ifname" @@ -688,12 +692,14 @@ mac80211_prepare_vif() { json_add_string _ifname "$ifname" default_macaddr= + random_macaddr= if [ -z "$macaddr" ]; then macaddr="$(mac80211_generate_mac $phy)" macidx="$(($macidx + 1))" default_macaddr=1 elif [ "$macaddr" = 'random' ]; then macaddr="$(macaddr_random)" + random_macaddr=1 fi json_add_string _macaddr "$macaddr" json_add_string _default_macaddr "$default_macaddr" @@ -701,7 +707,12 @@ mac80211_prepare_vif() { [ "$mode" == "ap" ] && { + json_select config + wireless_vif_parse_encryption + json_select .. + [ -z "$wpa_psk_file" ] && hostapd_set_psk "$ifname" + [ -z "$sae_password_file" ] && hostapd_set_sae "$ifname" [ -z "$vlan_file" ] && hostapd_set_vlan "$ifname" } @@ -732,8 +743,10 @@ mac80211_prepare_vif() { mac80211_prepare_iw_htmode() { case "$htmode" in - VHT20|HT20|HE20) iw_htmode=HT20;; - HT40*|VHT40|VHT160|HE40) + HT20|VHT20|HE20|EHT20) + iw_htmode=HT20 + ;; + HT40*|VHT40|HE40|EHT40) case "$band" in 2g) case "$htmode" in @@ -757,8 +770,11 @@ mac80211_prepare_iw_htmode() { esac [ "$auto_channel" -gt 0 ] && iw_htmode="HT40+" ;; - VHT80|HE80) - iw_htmode="80MHZ" + VHT80|HE80|EHT80) + iw_htmode="80MHz" + ;; + VHT160|HE160|EHT160) + iw_htmode="160MHz" ;; NONE|NOHT) iw_htmode="NOHT" @@ -836,11 +852,22 @@ mac80211_setup_adhoc() { mac80211_setup_mesh() { json_get_vars ssid mesh_id mcast_rate + json_get_values iface_basic_rate_list basic_rate mcval= [ -n "$mcast_rate" ] && wpa_supplicant_add_rate mcval "$mcast_rate" [ -n "$mesh_id" ] && ssid="$mesh_id" + br_list="$basic_rate_list" + if [ -n "$iface_basic_rate_list" ]; then + br_list="$iface_basic_rate_list" + fi + + brstr= + for br in $br_list; do + wpa_supplicant_add_rate brstr "$br" + done + local prev json_set_namespace wdev_uc prev @@ -851,6 +878,7 @@ mac80211_setup_mesh() { json_add_string freq "$freq" json_add_string htmode "$iw_htmode" [ -n "$mcval" ] && json_add_string mcast-rate "$mcval" + [ -n "$brstr" ] && json_add_string basic-rates "$brstr" json_add_int beacon-interval "$beacon_int" mac80211_add_mesh_params @@ -933,6 +961,7 @@ wpa_supplicant_set_config() { json_add_string phy "$phy" json_add_int radio "$radio" json_add_int num_global_macaddr "$num_global_macaddr" + json_add_string macaddr_base "$macaddr_base" json_add_boolean defer 1 local data="$(json_dump)" @@ -979,7 +1008,7 @@ wpa_supplicant_start() { [ -n "$wpa_supp_init" ] || return 0 - ubus_call wpa_supplicant config_set '{ "phy": "'"$phy"'", "radio": '"$radio"', "num_global_macaddr": '"$num_global_macaddr"' }' > /dev/null + ubus_call wpa_supplicant config_set '{ "phy": "'"$phy"'", "radio": '"$radio"', "num_global_macaddr": '"$num_global_macaddr"', "macaddr_base": "'"$macaddr_base"'" }' > /dev/null } mac80211_setup_supplicant() { @@ -1017,7 +1046,7 @@ mac80211_setup_vif() { json_get_vars $MP_CONFIG_INT $MP_CONFIG_BOOL $MP_CONFIG_STRING wireless_vif_parse_encryption [ -z "$htmode" ] && htmode="NOHT"; - if wpa_supplicant -vmesh; then + if [ -x /usr/sbin/wpa_supplicant ] && wpa_supplicant -vmesh; then mac80211_setup_supplicant || failed=1 else mac80211_setup_mesh @@ -1105,7 +1134,8 @@ drv_mac80211_setup() { txpower \ rxantenna txantenna \ frag rts beacon_int:100 htmode \ - num_global_macaddr:1 multiple_bssid + num_global_macaddr:1 multiple_bssid \ + ifname_prefix macaddr_base json_get_values basic_rate_list basic_rate json_get_values scan_list scan_list json_select .. @@ -1124,6 +1154,8 @@ drv_mac80211_setup() { return 1 } + set_default ifname_prefix "$phy$vif_phy_suffix-" + local wdev local cwdev local found @@ -1198,6 +1230,14 @@ drv_mac80211_setup() { wdev_tool "$phy$phy_suffix" set_config "$(json_dump)" $active_ifnames json_set_namespace "$prev" + [ -z "$phy_suffix" ] && { + if [ -n "$txpower" ]; then + iw phy "$phy" set txpower fixed "${txpower%%.*}00" + else + iw phy "$phy" set txpower auto + fi + } + for_each_interface "ap sta adhoc mesh monitor" mac80211_set_vif_txpower wireless_set_up } diff --git a/package/network/config/wifi-scripts/files/sbin/wifi b/package/network/config/wifi-scripts/files/sbin/wifi index f937dba7e6d92d..c70723560b767d 100755 --- a/package/network/config/wifi-scripts/files/sbin/wifi +++ b/package/network/config/wifi-scripts/files/sbin/wifi @@ -37,135 +37,22 @@ wifi_isup() { return 0 } -find_net_config() {( - local vif="$1" - local cfg - local ifname - - config_get cfg "$vif" network - - [ -z "$cfg" ] && { - include /lib/network - scan_interfaces - - config_get ifname "$vif" ifname - - cfg="$(find_config "$ifname")" - } - [ -z "$cfg" ] && return 0 - echo "$cfg" -)} - - -bridge_interface() {( - local cfg="$1" - [ -z "$cfg" ] && return 0 - - include /lib/network - scan_interfaces - - for cfg in $cfg; do - config_get iftype "$cfg" type - [ "$iftype" = bridge ] && config_get "$cfg" ifname - prepare_interface_bridge "$cfg" - return $? - done -)} - -prepare_key_wep() { - local key="$1" - local hex=1 - - echo -n "$key" | grep -qE "[^a-fA-F0-9]" && hex=0 - [ "${#key}" -eq 10 -a $hex -eq 1 ] || \ - [ "${#key}" -eq 26 -a $hex -eq 1 ] || { - [ "${key:0:2}" = "s:" ] && key="${key#s:}" - key="$(echo -n "$key" | hexdump -ve '1/1 "%02x" ""')" - } - echo "$key" -} - -wifi_fixup_hwmode() { - local device="$1" - local default="$2" - local hwmode hwmode_11n - - config_get channel "$device" channel - config_get hwmode "$device" hwmode - case "$hwmode" in - 11bg) hwmode=bg;; - 11a) hwmode=a;; - 11ad) hwmode=ad;; - 11b) hwmode=b;; - 11g) hwmode=g;; - 11n*) - hwmode_11n="${hwmode##11n}" - case "$hwmode_11n" in - a|g) ;; - default) hwmode_11n="$default" - esac - config_set "$device" hwmode_11n "$hwmode_11n" - ;; - *) - hwmode= - if [ "${channel:-0}" -gt 0 ]; then - if [ "${channel:-0}" -gt 14 ]; then - hwmode=a - else - hwmode=g - fi - else - hwmode="$default" - fi - ;; - esac - config_set "$device" hwmode "$hwmode" -} - -_wifi_updown() { - for device in ${2:-$DEVICES}; do ( - config_get disabled "$device" disabled - [ "$disabled" = "1" ] && { - echo "'$device' is disabled" - set disable - } - config_get iftype "$device" type - if eval "type ${1}_$iftype" 2>/dev/null >/dev/null; then - eval "scan_$iftype '$device'" - eval "${1}_$iftype '$device'" || echo "$device($iftype): ${1} failed" - elif [ ! -f /lib/netifd/wireless/$iftype.sh ]; then - echo "$device($iftype): Interface type not supported" - fi - ); done -} - wifi_updown() { cmd=down [ enable = "$1" ] && { - _wifi_updown disable "$2" ubus_wifi_cmd "$cmd" "$2" ubus call network reload - scan_wifi cmd=up } [ reconf = "$1" ] && { ubus call network reload - scan_wifi cmd=reconf } ubus_wifi_cmd "$cmd" "$2" - _wifi_updown "$@" -} - -wifi_reload_legacy() { - _wifi_updown "disable" "$1" - scan_wifi - _wifi_updown "enable" "$1" } wifi_reload() { ubus call network reload - wifi_reload_legacy } wifi_detect_notice() { @@ -189,75 +76,9 @@ wifi_config() { ); done } -start_net() {( - local iface="$1" - local config="$2" - local vifmac="$3" - - [ -f "/var/run/$iface.pid" ] && kill "$(cat /var/run/${iface}.pid)" 2>/dev/null - [ -z "$config" ] || { - include /lib/network - scan_interfaces - for config in $config; do - setup_interface "$iface" "$config" "" "$vifmac" - done - } -)} - -set_wifi_up() { - local cfg="$1" - local ifname="$2" - uci_set_state wireless "$cfg" up 1 - uci_set_state wireless "$cfg" ifname "$ifname" -} - -set_wifi_down() { - local cfg="$1" - local vifs vif vifstr - - [ -f "/var/run/wifi-${cfg}.pid" ] && - kill "$(cat "/var/run/wifi-${cfg}.pid")" 2>/dev/null - uci_revert_state wireless "$cfg" - config_get vifs "$cfg" vifs - for vif in $vifs; do - uci_revert_state wireless "$vif" - done -} - -scan_wifi() { - local cfgfile="$1" - DEVICES= - config_cb() { - local type="$1" - local section="$2" - - # section start - case "$type" in - wifi-device) - append DEVICES "$section" - config_set "$section" vifs "" - config_set "$section" ht_capab "" - ;; - esac - - # section end - config_get TYPE "$CONFIG_SECTION" TYPE - case "$TYPE" in - wifi-iface) - config_get device "$CONFIG_SECTION" device - config_get vifs "$device" vifs - append vifs "$CONFIG_SECTION" - config_set "$device" vifs "$vifs" - ;; - esac - } - config_load "${cfgfile:-wireless}" -} - DEVICES= DRIVERS= include /lib/wifi -scan_wifi case "$1" in down) wifi_updown "disable" "$2";; @@ -266,7 +87,6 @@ case "$1" in status) ubus_wifi_cmd "status" "$2";; isup) wifi_isup "$2"; exit $?;; reload) wifi_reload "$2";; - reload_legacy) wifi_reload_legacy "$2";; --help|help) usage;; reconf) wifi_updown "reconf" "$2";; ''|up) wifi_updown "enable" "$2";; diff --git a/package/network/config/wifi-scripts/files/usr/share/hostap/common.uc b/package/network/config/wifi-scripts/files/usr/share/hostap/common.uc index c6bfb62ef3c5d0..31b526b6aee78b 100644 --- a/package/network/config/wifi-scripts/files/usr/share/hostap/common.uc +++ b/package/network/config/wifi-scripts/files/usr/share/hostap/common.uc @@ -213,7 +213,12 @@ const phy_proto = { if (!base_mask) return null; - if (base_mask == "00:00:00:00:00:00" && + if (base_mask == "00:00:00:00:00:00") + base_mask = "ff:ff:ff:ff:ff:ff"; + + if (data.macaddr_base) + base_addr = data.macaddr_base; + else if (base_mask == "ff:ff:ff:ff:ff:ff" && (radio_idx > 0 || idx >= num_global)) { let addrs = split(phy_sysfs_file(phy, "addresses"), "\n"); @@ -225,8 +230,6 @@ const phy_proto = { } else { if (idx < length(addrs)) return addrs[idx]; - - base_mask = "ff:ff:ff:ff:ff:ff"; } } diff --git a/package/network/config/wifi-scripts/files/usr/share/hostap/wdev.uc b/package/network/config/wifi-scripts/files/usr/share/hostap/wdev.uc index d836a930fc4f9a..166e9403dfce72 100644 --- a/package/network/config/wifi-scripts/files/usr/share/hostap/wdev.uc +++ b/package/network/config/wifi-scripts/files/usr/share/hostap/wdev.uc @@ -45,7 +45,7 @@ function iface_start(wdev) system(cmd); } else if (wdev.mode == "mesh") { let cmd = [ "iw", "dev", ifname, "mesh", "join", wdev.ssid, "freq", wdev.freq, htmode ]; - for (let key in [ "mcast-rate", "beacon-interval" ]) + for (let key in [ "basic-rates", "mcast-rate", "beacon-interval" ]) if (wdev[key]) push(cmd, key, wdev[key]); system(cmd); diff --git a/package/network/ipv6/odhcp6c/Makefile b/package/network/ipv6/odhcp6c/Makefile index 894f388945fc50..c16ecfa083c3bf 100644 --- a/package/network/ipv6/odhcp6c/Makefile +++ b/package/network/ipv6/odhcp6c/Makefile @@ -8,13 +8,13 @@ include $(TOPDIR)/rules.mk PKG_NAME:=odhcp6c -PKG_RELEASE:=20 +PKG_RELEASE:=1 PKG_SOURCE_PROTO:=git PKG_SOURCE_URL=$(PROJECT_GIT)/project/odhcp6c.git -PKG_SOURCE_DATE:=2023-05-12 -PKG_SOURCE_VERSION:=bcd283632ac13391aac3ebdd074d1fd832d76fa3 -PKG_MIRROR_HASH:=0c18c578045f9251bd86a5b8fb0518b69c519e83f69907bf76583a2985482508 +PKG_SOURCE_DATE:=2024-09-25 +PKG_SOURCE_VERSION:=b6ae9ffaeb0e18e9fa3d5be62faa8d3c9f340a58 +PKG_MIRROR_HASH:=25499b6a0d403815e6b04869a02d2d5a32582348bff2bc2626559d297425a908 PKG_MAINTAINER:=Hans Dedecker PKG_LICENSE:=GPL-2.0 diff --git a/package/network/services/dnsmasq/Makefile b/package/network/services/dnsmasq/Makefile index 0a597c03ce405b..47a5ae54ae7f5c 100644 --- a/package/network/services/dnsmasq/Makefile +++ b/package/network/services/dnsmasq/Makefile @@ -10,7 +10,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=dnsmasq PKG_UPSTREAM_VERSION:=2.90 PKG_VERSION:=$(subst test,~~test,$(subst rc,~rc,$(PKG_UPSTREAM_VERSION))) -PKG_RELEASE:=3 +PKG_RELEASE:=4 PKG_SOURCE:=$(PKG_NAME)-$(PKG_UPSTREAM_VERSION).tar.xz PKG_SOURCE_URL:=https://thekelleys.org.uk/dnsmasq/ diff --git a/package/network/services/dnsmasq/files/dnsmasq.init b/package/network/services/dnsmasq/files/dnsmasq.init index b864ea90699f48..e9afcc78d3176e 100755 --- a/package/network/services/dnsmasq/files/dnsmasq.init +++ b/package/network/services/dnsmasq/files/dnsmasq.init @@ -226,6 +226,14 @@ append_interface_name() { xappend "--interface-name=$1,$2" } +append_filter_rr() { + xappend "--filter-rr=$1" +} + +append_cache_rr() { + xappend "--cache-rr=$1" +} + filter_dnsmasq() { local cfg="$1" func="$2" match_cfg="$3" found_cfg @@ -1000,8 +1008,8 @@ dnsmasq_start() # deprecate or remove filter-X in favor of filter-rr? append_bool "$cfg" filter_aaaa "--filter-AAAA" append_bool "$cfg" filter_a "--filter-A" - append_parm "$cfg" filter_rr "--filter-rr" - append_parm "$cfg" cache_rr "--cache-rr" + config_list_foreach "$cfg" filter_rr append_filter_rr + config_list_foreach "$cfg" cache_rr append_cache_rr append_parm "$cfg" logfacility "--log-facility" config_get logfacility "$cfg" "logfacility" diff --git a/package/network/services/dnsmasq/patches/0003-Handle-DS-queries-to-auth-zones.patch b/package/network/services/dnsmasq/patches/0003-Handle-DS-queries-to-auth-zones.patch new file mode 100644 index 00000000000000..bd7270c904cc10 --- /dev/null +++ b/package/network/services/dnsmasq/patches/0003-Handle-DS-queries-to-auth-zones.patch @@ -0,0 +1,98 @@ +From 8ce27433f8b2e17c557cb55e4f16941d309deeac Mon Sep 17 00:00:00 2001 +From: Simon Kelley +Date: Fri, 17 Jan 2025 17:49:29 +0000 +Subject: [PATCH] Handle DS queries to auth zones. +Origin: upstream, v2.91test8 + +When dnsmasq is configured to act as an authoritative server and has +an authoritative zone configured, and recieves a query for +that zone _as_forwarder_ it answers the query directly rather +than forwarding it. This doesn't affect the answer, but it +saves dnsmasq forwarding the query to the recusor upstream, +whch then bounces it back to dnsmasq in auth mode. The +exception should be when the query is for the root of zone, for a DS +RR. The answer to that has to come from the parent, via the +recursor, and will typically be a proof-of-nonexistence since +dnsmasq doesn't support signed zones. This patch suppresses +local answers and forces forwarding to the upstream recursor +for such queries. It stops breakage when a DNSSEC validating +client makes queries to dnsmasq acting as forwarder for a zone +for which it is authoritative. + +[ukleinek: drop changes to CHANGELOG to prevent conflicts] +--- + src/forward.c | 52 +++++++++++++++++++++++++++++++++++++-------------- + 1 file changed, 38 insertions(+), 14 deletions(-) + +--- a/src/forward.c ++++ b/src/forward.c +@@ -1744,15 +1744,27 @@ void receive_query(struct listener *list + #endif + + #ifdef HAVE_AUTH +- /* find queries for zones we're authoritative for, and answer them directly */ ++ /* Find queries for zones we're authoritative for, and answer them directly. ++ The exception to this is DS queries for the zone route. They ++ have to come from the parent zone. Since dnsmasq's auth server ++ can't do DNSSEC, the zone will be unsigned, and anything using ++ dnsmasq as a forwarder and doing validation will be expecting to ++ see the proof of non-existence from the parent. */ + if (!auth_dns && !option_bool(OPT_LOCALISE)) + for (zone = daemon->auth_zones; zone; zone = zone->next) +- if (in_zone(zone, daemon->namebuff, NULL)) +- { +- auth_dns = 1; +- local_auth = 1; +- break; +- } ++ { ++ char *cut; ++ ++ if (in_zone(zone, daemon->namebuff, &cut)) ++ { ++ if (type != T_DS || cut) ++ { ++ auth_dns = 1; ++ local_auth = 1; ++ } ++ break; ++ } ++ } + #endif + + #ifdef HAVE_LOOP +@@ -2268,15 +2280,27 @@ unsigned char *tcp_request(int confd, ti + &peer_addr, auth_dns ? "auth" : "query", qtype); + + #ifdef HAVE_AUTH +- /* find queries for zones we're authoritative for, and answer them directly */ ++ /* Find queries for zones we're authoritative for, and answer them directly. ++ The exception to this is DS queries for the zone route. They ++ have to come from the parent zone. Since dnsmasq's auth server ++ can't do DNSSEC, the zone will be unsigned, and anything using ++ dnsmasq as a forwarder and doing validation will be expecting to ++ see the proof of non-existence from the parent. */ + if (!auth_dns && !option_bool(OPT_LOCALISE)) + for (zone = daemon->auth_zones; zone; zone = zone->next) +- if (in_zone(zone, daemon->namebuff, NULL)) +- { +- auth_dns = 1; +- local_auth = 1; +- break; +- } ++ { ++ char *cut; ++ ++ if (in_zone(zone, daemon->namebuff, &cut)) ++ { ++ if (qtype != T_DS || cut) ++ { ++ auth_dns = 1; ++ local_auth = 1; ++ } ++ break; ++ } ++ } + #endif + } + } diff --git a/package/network/services/dropbear/Makefile b/package/network/services/dropbear/Makefile index e9f3bd693c617c..e13b6c2145b716 100644 --- a/package/network/services/dropbear/Makefile +++ b/package/network/services/dropbear/Makefile @@ -8,14 +8,14 @@ include $(TOPDIR)/rules.mk PKG_NAME:=dropbear -PKG_VERSION:=2024.85 +PKG_VERSION:=2024.86 PKG_RELEASE:=1 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2 PKG_SOURCE_URL:= \ https://matt.ucc.asn.au/dropbear/releases/ \ https://dropbear.nl/mirror/releases/ -PKG_HASH:=86b036c433a69d89ce51ebae335d65c47738ccf90d13e5eb0fea832e556da502 +PKG_HASH:=e78936dffc395f2e0db099321d6be659190966b99712b55c530dd0a1822e0a5e PKG_LICENSE:=MIT PKG_LICENSE_FILES:=LICENSE libtomcrypt/LICENSE libtommath/LICENSE diff --git a/package/network/services/dropbear/files/dropbear.config b/package/network/services/dropbear/files/dropbear.config index 2139ba0bbeaac7..7eb59754490683 100644 --- a/package/network/services/dropbear/files/dropbear.config +++ b/package/network/services/dropbear/files/dropbear.config @@ -1,4 +1,6 @@ -config dropbear +# See https://openwrt.org/docs/guide-user/base-system/dropbear +config dropbear main + option enable '1' option PasswordAuth 'on' option RootPasswordAuth 'on' option Port '22' diff --git a/package/network/services/dropbear/files/dropbear.init b/package/network/services/dropbear/files/dropbear.init index 708fabd3269af2..395237f9bc206a 100755 --- a/package/network/services/dropbear/files/dropbear.init +++ b/package/network/services/dropbear/files/dropbear.init @@ -361,7 +361,7 @@ dropbear_instance() load_interfaces() { local enable - config_get enable "$1" enable 1 + config_get_bool enable "$1" enable 1 [ "${enable}" = "1" ] || return 0 local direct_iface iface diff --git a/package/network/services/dropbear/patches/110-change_user.patch b/package/network/services/dropbear/patches/110-change_user.patch index 9cb073cf940d46..9ef8f0cfbc4981 100644 --- a/package/network/services/dropbear/patches/110-change_user.patch +++ b/package/network/services/dropbear/patches/110-change_user.patch @@ -1,6 +1,6 @@ --- a/src/svr-chansession.c +++ b/src/svr-chansession.c -@@ -987,12 +987,12 @@ static void execchild(const void *user_d +@@ -984,12 +984,12 @@ static void execchild(const void *user_d /* We can only change uid/gid as root ... */ if (getuid() == 0) { diff --git a/package/network/services/hostapd/Makefile b/package/network/services/hostapd/Makefile index 0e3396262d0c13..8753782012e5a3 100644 --- a/package/network/services/hostapd/Makefile +++ b/package/network/services/hostapd/Makefile @@ -5,7 +5,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=hostapd -PKG_RELEASE:=1 +PKG_RELEASE:=2 PKG_SOURCE_URL:=https://w1.fi/hostap.git PKG_SOURCE_PROTO:=git @@ -84,7 +84,11 @@ ifneq ($(CONFIG_DRIVER_11BE_SUPPORT),) HOSTAPD_IEEE80211BE:=y endif -CORE_DEPENDS = +ucode +libubus +libucode +ucode-mod-fs +ucode-mod-nl80211 +ucode-mod-rtnl +ucode-mod-ubus +ucode-mod-uloop +libblobmsg-json +libudebug + +CORE_DEPENDS = +ucode +libucode \ + +ucode-mod-fs +ucode-mod-nl80211 +ucode-mod-rtnl +ucode-mod-ubus +ucode-mod-uloop \ + +libubus +libblobmsg-json \ + +libudebug OPENSSL_DEPENDS = +PACKAGE_$(1):libopenssl +PACKAGE_$(1):libopenssl-legacy DRIVER_MAKEOPTS= \ @@ -716,7 +720,13 @@ define Install/supplicant endef define Package/hostapd-common/install - $(INSTALL_DIR) $(1)/etc/capabilities $(1)/etc/rc.button $(1)/etc/hotplug.d/ieee80211 $(1)/etc/init.d $(1)/lib/netifd $(1)/usr/share/acl.d $(1)/usr/share/hostap + $(INSTALL_DIR) \ + $(1)/etc/capabilities \ + $(1)/etc/rc.button \ + $(1)/etc/hotplug.d/ieee80211 \ + $(1)/etc/init.d $(1)/lib/netifd \ + $(1)/usr/share/acl.d \ + $(1)/usr/share/hostap $(INSTALL_BIN) ./files/dhcp-get-server.sh $(1)/lib/netifd/dhcp-get-server.sh $(INSTALL_BIN) ./files/wpad.init $(1)/etc/init.d/wpad $(INSTALL_BIN) ./files/wps-hotplug.sh $(1)/etc/rc.button/wps diff --git a/package/network/services/hostapd/files/hostapd.uc b/package/network/services/hostapd/files/hostapd.uc index 2d9ce2874901d2..5c172de5dfcc8e 100644 --- a/package/network/services/hostapd/files/hostapd.uc +++ b/package/network/services/hostapd/files/hostapd.uc @@ -10,6 +10,7 @@ hostapd.data.pending_config = {}; hostapd.data.file_fields = { vlan_file: true, wpa_psk_file: true, + sae_password_file: true, accept_mac_file: true, deny_mac_file: true, eap_user_file: true, @@ -186,7 +187,7 @@ function __iface_pending_next(pending, state, ret, data) pending.call("wpa_supplicant", "phy_status", { phy: phydev.phy, - radio: phydev.radio, + radio: phydev.radio ?? -1, }); return "check_phy"; case "check_phy": @@ -199,7 +200,7 @@ function __iface_pending_next(pending, state, ret, data) } pending.call("wpa_supplicant", "phy_set_state", { phy: phydev.phy, - radio: phydev.radio, + radio: phydev.radio ?? -1, stop: true }); return "wpas_stopped"; @@ -208,7 +209,7 @@ function __iface_pending_next(pending, state, ret, data) hostapd.printf(`hostapd.add_iface failed for phy ${phy} ifname=${bss.ifname}`); pending.call("wpa_supplicant", "phy_set_state", { phy: phydev.phy, - radio: phydev.radio, + radio: phydev.radio ?? -1, stop: false }); return null; @@ -278,6 +279,7 @@ function iface_macaddr_init(phydev, config, macaddr_list) { let macaddr_data = { num_global: config.num_global_macaddr ?? 1, + macaddr_base: config.macaddr_base, mbssid: config.mbssid ?? 0, }; @@ -364,6 +366,7 @@ function bss_remove_file_fields(config) for (let key in config.hash) new_cfg.hash[key] = config.hash[key]; delete new_cfg.hash.wpa_psk_file; + delete new_cfg.hash.sae_password_file; delete new_cfg.hash.vlan_file; return new_cfg; @@ -482,7 +485,9 @@ function iface_reload_config(name, phydev, config, old_config) // try to preserve MAC address of this BSS by reassigning another // BSS if necessary - if (cur_config.default_macaddr && + if ((cur_config.default_macaddr || cur_config.random_macaddr) && + cur_config.random_macaddr == prev_config.random_macaddr && + cur_config.default_macaddr == prev_config.default_macaddr && !macaddr_list[prev_config.bssid]) { macaddr_list[prev_config.bssid] = i; cur_config.bssid = prev_config.bssid; @@ -745,9 +750,12 @@ function iface_load_config(phy, radio, filename) continue; } - if (val[0] == "#num_global_macaddr" || - val[0] == "mbssid") + if (val[0] == "#num_global_macaddr") config[substr(val[0], 1)] = int(val[1]); + else if (val[0] == "#macaddr_base") + config[substr(val[0], 1)] = val[1]; + else if (val[0] == "mbssid") + config[val[0]] = int(val[1]); push(config.radio.data, line); } @@ -755,6 +763,8 @@ function iface_load_config(phy, radio, filename) while ((line = rtrim(f.read("line"), "\n")) != null) { if (line == "#default_macaddr") bss.default_macaddr = true; + if (line == "#random_macaddr") + bss.random_macaddr = true; let val = split(line, "=", 2); if (!val[0]) @@ -827,7 +837,7 @@ let main_obj = { let phy_list = req.args.phy ? [ phy_name(req.args.phy, req.args.radio) ] : keys(hostapd.data.config); for (let phy_name in phy_list) { let phy = hostapd.data.config[phy_name]; - let config = iface_load_config(phy.phy, radio, phy.orig_file); + let config = iface_load_config(phy.phy, phy.radio_idx, phy.orig_file); iface_set_config(phy_name, config); } diff --git a/package/network/services/hostapd/files/wpa_supplicant.uc b/package/network/services/hostapd/files/wpa_supplicant.uc index fbea27628e341d..f288121e9d4b03 100644 --- a/package/network/services/hostapd/files/wpa_supplicant.uc +++ b/package/network/services/hostapd/files/wpa_supplicant.uc @@ -68,7 +68,7 @@ function prepare_config(config, radio) return { config }; } -function set_config(config_name, phy_name, radio, num_global_macaddr, config_list) +function set_config(config_name, phy_name, radio, num_global_macaddr, macaddr_base, config_list) { let phy = wpas.data.config[config_name]; @@ -83,6 +83,7 @@ function set_config(config_name, phy_name, radio, num_global_macaddr, config_lis phy.radio = radio; phy.num_global_macaddr = num_global_macaddr; + phy.macaddr_base = macaddr_base; let values = []; for (let config in config_list) @@ -106,7 +107,10 @@ function start_pending(phy_name) } let macaddr_list = wpas.data.macaddr_list[phy_name]; - phydev.macaddr_init(macaddr_list, { num_global: phy.num_global_macaddr }); + phydev.macaddr_init(macaddr_list, { + num_global: phy.num_global_macaddr, + macaddr_base: phy.macaddr_base, + }); for (let ifname in phy.data) iface_start(phydev, phy.data[ifname]); @@ -210,6 +214,7 @@ let main_obj = { phy: "", radio: 0, num_global_macaddr: 0, + macaddr_base: "", config: [], defer: true, }, @@ -221,7 +226,7 @@ let main_obj = { wpas.printf(`Set new config for phy ${phy}`); try { if (req.args.config) - set_config(phy, req.args.phy, req.args.radio, req.args.num_global_macaddr, req.args.config); + set_config(phy, req.args.phy, req.args.radio, req.args.num_global_macaddr, req.args.macaddr_base, req.args.config); if (!req.args.defer) start_pending(phy); diff --git a/package/network/services/hostapd/patches/601-ucode_support.patch b/package/network/services/hostapd/patches/601-ucode_support.patch index 5a88687cf222ef..13fd2b1b518a7b 100644 --- a/package/network/services/hostapd/patches/601-ucode_support.patch +++ b/package/network/services/hostapd/patches/601-ucode_support.patch @@ -816,7 +816,7 @@ as adding/removing interfaces. if (vlan_id) *vlan_id = 0; if (psk_len) -@@ -446,13 +447,16 @@ static const u8 * hostapd_wpa_auth_get_p +@@ -446,13 +447,18 @@ static const u8 * hostapd_wpa_auth_get_p * returned psk which should not be returned again. * logic list (all hostapd_get_psk; all sta->psk) */ @@ -830,16 +830,23 @@ as adding/removing interfaces. *vlan_id = 0; psk = sta->psk->psk; - for (pos = sta->psk; pos; pos = pos->next) { ++ if (vlan_id) ++ sta->psk_idx = psk_idx; + for (pos = sta->psk; pos; pos = pos->next, psk_idx++) { if (pos->is_passphrase) { if (pbkdf2_sha1(pos->passphrase, hapd->conf->ssid.ssid, -@@ -469,6 +473,8 @@ static const u8 * hostapd_wpa_auth_get_p +@@ -466,9 +472,13 @@ static const u8 * hostapd_wpa_auth_get_p + } + if (pos->psk == prev_psk) { + psk = pos->next ? pos->next->psk : NULL; ++ if (vlan_id) ++ sta->psk_idx = psk_idx + 1; break; } } -+ if (psk) -+ sta->psk_idx = psk_idx; ++ if (vlan_id && !psk) ++ sta->psk_idx = 0; } return psk; } diff --git a/package/network/services/hostapd/patches/701-reload_config_inline.patch b/package/network/services/hostapd/patches/701-reload_config_inline.patch index 54045476477fe6..24d3aa86d057d5 100644 --- a/package/network/services/hostapd/patches/701-reload_config_inline.patch +++ b/package/network/services/hostapd/patches/701-reload_config_inline.patch @@ -8,7 +8,7 @@ as adding/removing interfaces. --- a/hostapd/config_file.c +++ b/hostapd/config_file.c -@@ -5207,7 +5207,12 @@ struct hostapd_config * hostapd_config_r +@@ -5207,7 +5207,14 @@ struct hostapd_config * hostapd_config_r int errors = 0; size_t i; @@ -19,6 +19,8 @@ as adding/removing interfaces. + } else { + f = fopen(fname, "r"); + } ++ wpa_printf(MSG_INFO, "Configuration file: Reading configuration file '%s'", ++ fname); if (f == NULL) { wpa_printf(MSG_ERROR, "Could not open configuration file '%s' " "for reading.", fname); @@ -39,3 +41,35 @@ as adding/removing interfaces. if (f == NULL) { wpa_printf(MSG_ERROR, "Failed to open config file '%s', " "error: %s", name, strerror(errno)); +--- a/hostapd/main.c ++++ b/hostapd/main.c +@@ -406,7 +406,11 @@ hostapd_interface_init(struct hapd_inter + struct hostapd_iface *iface; + int k; + +- wpa_printf(MSG_DEBUG, "Configuration file: %s", config_fname); ++ if (!strncmp(config_fname, "data:", 5)) { ++ wpa_printf(MSG_DEBUG, "Configuration file: %s", ""); ++ } else { ++ wpa_printf(MSG_DEBUG, "Configuration file: %s", config_fname); ++ } + iface = hostapd_init(interfaces, config_fname); + if (!iface) + return NULL; +--- a/src/ap/hostapd.c ++++ b/src/ap/hostapd.c +@@ -2893,7 +2893,12 @@ hostapd_interface_init_bss(struct hapd_i + } + } + +- wpa_printf(MSG_INFO, "Configuration file: %s (phy %s)%s", +- config_fname, phy, iface ? "" : " --> new PHY"); ++ if (!strncmp(config_fname, "data:", 5)) { ++ wpa_printf(MSG_INFO, "Configuration file: %s (phy %s)%s", ++ "", phy, iface ? "" : " --> new PHY"); ++ } else { ++ wpa_printf(MSG_INFO, "Configuration file: %s (phy %s)%s", ++ config_fname, phy, iface ? "" : " --> new PHY"); ++ } + if (iface) { + struct hostapd_config *conf; diff --git a/package/network/services/hostapd/patches/730-ft_iface.patch b/package/network/services/hostapd/patches/730-ft_iface.patch index ac7d3abd78af7c..f021f1f99ba4b2 100644 --- a/package/network/services/hostapd/patches/730-ft_iface.patch +++ b/package/network/services/hostapd/patches/730-ft_iface.patch @@ -29,7 +29,7 @@ a VLAN interface on top of the bridge, instead of using the bridge directly int bridge_hairpin; /* hairpin_mode on bridge members */ --- a/src/ap/wpa_auth_glue.c +++ b/src/ap/wpa_auth_glue.c -@@ -1821,8 +1821,12 @@ int hostapd_setup_wpa(struct hostapd_dat +@@ -1825,8 +1825,12 @@ int hostapd_setup_wpa(struct hostapd_dat wpa_key_mgmt_ft(hapd->conf->wpa_key_mgmt)) { const char *ft_iface; diff --git a/package/network/services/hostapd/patches/804-hostapd-Fix-clearing-up-settings-for-color-switch.patch b/package/network/services/hostapd/patches/804-hostapd-Fix-clearing-up-settings-for-color-switch.patch new file mode 100644 index 00000000000000..87d68911c79d71 --- /dev/null +++ b/package/network/services/hostapd/patches/804-hostapd-Fix-clearing-up-settings-for-color-switch.patch @@ -0,0 +1,28 @@ +From 161327f91d956771996c96ea1b6e4e1cb8dc074c Mon Sep 17 00:00:00 2001 +From: Stone Zhang +Date: Mon, 14 Oct 2024 18:47:32 +0800 +Subject: [PATCH] hostapd: Fix clearing up settings for color switch + +Settings for color switch (struct cca_settings settings) +is used without zero clearing, which causes the member +settings->ubpr->unsol_bcast_probe_resp_intervalettings +to be a random value. It is againsts the NLA policy of +NL80211_UNSOL_BCAST_PROBE_RESP_ATTR_INT and causes +BSS color switch failure. + +Fixes: 654d2395dddf ("BSS coloring: Handling of collision events and triggering CCA") +Signed-off-by: Stone Zhang +--- + src/ap/hostapd.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/src/ap/hostapd.c ++++ b/src/ap/hostapd.c +@@ -4813,6 +4813,7 @@ static void hostapd_switch_color_timeout + struct cca_settings settings; + int ret; + ++ os_memset(&settings, 0, sizeof(settings)); + hostapd_cleanup_cca_params(bss); + bss->cca_color = r; + bss->cca_count = 10; diff --git a/package/network/services/hostapd/src/src/ap/ucode.c b/package/network/services/hostapd/src/src/ap/ucode.c index 2da2b4dc938738..3b1f052abcc1ea 100644 --- a/package/network/services/hostapd/src/src/ap/ucode.c +++ b/package/network/services/hostapd/src/src/ap/ucode.c @@ -10,6 +10,7 @@ #include "dfs.h" #include "acs.h" #include "ieee802_11_auth.h" +#include "neighbor_db.h" #include static uc_resource_type_t *global_type, *bss_type, *iface_type; @@ -23,7 +24,7 @@ hostapd_ucode_bss_get_uval(struct hostapd_data *hapd) uc_value_t *val; if (hapd->ucode.idx) - return wpa_ucode_registry_get(bss_registry, hapd->ucode.idx); + return ucv_get(wpa_ucode_registry_get(bss_registry, hapd->ucode.idx)); val = uc_resource_new(bss_type, hapd); hapd->ucode.idx = wpa_ucode_registry_add(bss_registry, val); @@ -37,7 +38,7 @@ hostapd_ucode_iface_get_uval(struct hostapd_iface *hapd) uc_value_t *val; if (hapd->ucode.idx) - return wpa_ucode_registry_get(iface_registry, hapd->ucode.idx); + return ucv_get(wpa_ucode_registry_get(iface_registry, hapd->ucode.idx)); val = uc_resource_new(iface_type, hapd); hapd->ucode.idx = wpa_ucode_registry_add(iface_registry, val); @@ -54,12 +55,11 @@ hostapd_ucode_update_bss_list(struct hostapd_iface *iface, uc_value_t *if_bss, u list = ucv_array_new(vm); for (i = 0; iface->bss && i < iface->num_bss; i++) { struct hostapd_data *hapd = iface->bss[i]; - uc_value_t *val = hostapd_ucode_bss_get_uval(hapd); - ucv_array_set(list, i, ucv_get(ucv_string_new(hapd->conf->iface))); - ucv_object_add(bss, hapd->conf->iface, ucv_get(val)); + ucv_array_set(list, i, ucv_string_new(hapd->conf->iface)); + ucv_object_add(bss, hapd->conf->iface, hostapd_ucode_bss_get_uval(hapd)); } - ucv_object_add(if_bss, iface->phy, ucv_get(list)); + ucv_object_add(if_bss, iface->phy, list); } static void @@ -73,13 +73,14 @@ hostapd_ucode_update_interfaces(void) for (i = 0; i < interfaces->count; i++) { struct hostapd_iface *iface = interfaces->iface[i]; - ucv_object_add(ifs, iface->phy, ucv_get(hostapd_ucode_iface_get_uval(iface))); + ucv_object_add(ifs, iface->phy, hostapd_ucode_iface_get_uval(iface)); hostapd_ucode_update_bss_list(iface, if_bss, bss); } - ucv_object_add(ucv_prototype_get(global), "interfaces", ucv_get(ifs)); - ucv_object_add(ucv_prototype_get(global), "interface_bss", ucv_get(if_bss)); - ucv_object_add(ucv_prototype_get(global), "bss", ucv_get(bss)); + ucv_object_add(ucv_prototype_get(global), "interfaces", ifs); + ucv_object_add(ucv_prototype_get(global), "interface_bss", if_bss); + ucv_object_add(ucv_prototype_get(global), "bss", bss); + ucv_gc(vm); } @@ -258,7 +259,11 @@ uc_hostapd_bss_set_config(uc_vm_t *vm, size_t nargs) hapd->conf = conf->bss[idx]; conf->bss[idx] = old_bss; + if (hapd == iface->bss[0]) + memcpy(hapd->own_addr, hapd->conf->bssid, ETH_ALEN); + hostapd_setup_bss(hapd, hapd == iface->bss[0], true); + hostapd_neighbor_set_own_report(hapd); hostapd_ucode_update_interfaces(); hostapd_owe_update_trans(iface); @@ -362,6 +367,10 @@ uc_hostapd_iface_add_bss(uc_vm_t *vm, size_t nargs) hapd->driver = iface->bss[0]->driver; hapd->drv_priv = iface->bss[0]->drv_priv; +#ifdef CONFIG_IEEE80211BE + os_strlcpy(hapd->ctrl_sock_iface, hapd->conf->iface, + sizeof(hapd->ctrl_sock_iface)); +#endif if (interfaces->ctrl_iface_init && interfaces->ctrl_iface_init(hapd) < 0) goto free_hapd; @@ -380,6 +389,7 @@ uc_hostapd_iface_add_bss(uc_vm_t *vm, size_t nargs) iface->conf->bss[iface->conf->num_bss] = bss; conf->bss[idx] = NULL; ret = hostapd_ucode_bss_get_uval(hapd); + hostapd_neighbor_set_own_report(hapd); hostapd_ucode_update_interfaces(); hostapd_owe_update_trans(iface); goto out; @@ -721,11 +731,10 @@ int hostapd_ucode_sta_auth(struct hostapd_data *hapd, struct sta_info *sta) if (wpa_ucode_call_prepare("sta_auth")) return 0; - uc_value_push(ucv_get(ucv_string_new(hapd->conf->iface))); + uc_value_push(ucv_string_new(hapd->conf->iface)); snprintf(addr, sizeof(addr), MACSTR, MAC2STR(sta->addr)); - val = ucv_string_new(addr); - uc_value_push(ucv_get(val)); + uc_value_push(ucv_string_new(addr)); val = wpa_ucode_call(2); @@ -787,16 +796,15 @@ void hostapd_ucode_sta_connected(struct hostapd_data *hapd, struct sta_info *sta if (wpa_ucode_call_prepare("sta_connected")) return; - uc_value_push(ucv_get(ucv_string_new(hapd->conf->iface))); + uc_value_push(ucv_string_new(hapd->conf->iface)); snprintf(addr, sizeof(addr), MACSTR, MAC2STR(sta->addr)); - val = ucv_string_new(addr); - uc_value_push(ucv_get(val)); + uc_value_push(ucv_string_new(addr)); val = ucv_object_new(vm); if (sta->psk_idx) ucv_object_add(val, "psk_idx", ucv_int64_new(sta->psk_idx - 1)); - uc_value_push(ucv_get(val)); + uc_value_push(val); val = wpa_ucode_call(3); if (ucv_type(val) != UC_OBJECT) @@ -878,7 +886,7 @@ void hostapd_ucode_free(void) void hostapd_ucode_free_iface(struct hostapd_iface *iface) { - wpa_ucode_registry_remove(iface_registry, iface->ucode.idx); + ucv_put(wpa_ucode_registry_remove(iface_registry, iface->ucode.idx)); } void hostapd_ucode_bss_cb(struct hostapd_data *hapd, const char *type) @@ -889,10 +897,11 @@ void hostapd_ucode_bss_cb(struct hostapd_data *hapd, const char *type) return; val = hostapd_ucode_bss_get_uval(hapd); - uc_value_push(ucv_get(ucv_string_new(hapd->iface->phy))); - uc_value_push(ucv_get(ucv_string_new(hapd->conf->iface))); + uc_value_push(ucv_string_new(hapd->iface->phy)); + uc_value_push(ucv_string_new(hapd->conf->iface)); uc_value_push(ucv_get(val)); ucv_put(wpa_ucode_call(3)); + ucv_put(val); ucv_gc(vm); } @@ -911,6 +920,8 @@ void hostapd_ucode_free_bss(struct hostapd_data *hapd) uc_value_push(ucv_string_new(hapd->conf->iface)); uc_value_push(ucv_get(val)); ucv_put(wpa_ucode_call(2)); + + ucv_put(val); ucv_gc(vm); } @@ -923,10 +934,11 @@ void hostapd_ucode_apup_newpeer(struct hostapd_data *hapd, const char *ifname) return; val = hostapd_ucode_bss_get_uval(hapd); - uc_value_push(ucv_get(ucv_string_new(hapd->conf->iface))); // BSS ifname + uc_value_push(ucv_string_new(hapd->conf->iface)); // BSS ifname uc_value_push(ucv_get(val)); - uc_value_push(ucv_get(ucv_string_new(ifname))); // APuP peer ifname + uc_value_push(ucv_string_new(ifname)); // APuP peer ifname ucv_put(wpa_ucode_call(2)); + ucv_put(val); ucv_gc(vm); } #endif // def CONFIG_APUP diff --git a/package/network/services/hostapd/src/src/utils/ucode.c b/package/network/services/hostapd/src/src/utils/ucode.c index 29c753c326905d..7636e46aaf2894 100644 --- a/package/network/services/hostapd/src/src/utils/ucode.c +++ b/package/network/services/hostapd/src/src/utils/ucode.c @@ -171,7 +171,7 @@ uc_value_t *uc_wpa_freq_info(uc_vm_t *vm, size_t nargs) ucv_object_add(ret, "op_class", ucv_int64_new(op_class)); ucv_object_add(ret, "channel", ucv_int64_new(channel)); ucv_object_add(ret, "hw_mode", ucv_int64_new(hw_mode)); - ucv_object_add(ret, "hw_mode_str", ucv_get(ucv_string_new(modestr))); + ucv_object_add(ret, "hw_mode_str", ucv_string_new(modestr)); ucv_object_add(ret, "sec_channel", ucv_int64_new(sec_channel)); ucv_object_add(ret, "frequency", ucv_int64_new(freq_val)); @@ -425,7 +425,7 @@ uc_value_t *wpa_ucode_global_init(const char *name, uc_resource_type_t *global_t uc_vm_registry_set(&vm, "hostap.global", global); proto = ucv_prototype_get(global); - ucv_object_add(proto, "data", ucv_get(ucv_object_new(&vm))); + ucv_object_add(proto, "data", ucv_object_new(&vm)); #define ADD_CONST(x) ucv_object_add(proto, #x, ucv_int64_new(x)) ADD_CONST(MSG_EXCESSIVE); @@ -470,6 +470,7 @@ uc_value_t *wpa_ucode_registry_remove(uc_value_t *reg, int idx) if (!val) return NULL; + ucv_get(val); ucv_array_set(reg, idx - 1, NULL); dataptr = ucv_resource_dataptr(val, NULL); if (dataptr) diff --git a/package/network/services/hostapd/src/wpa_supplicant/ucode.c b/package/network/services/hostapd/src/wpa_supplicant/ucode.c index 9380b301c36eeb..8335a27e892b88 100644 --- a/package/network/services/hostapd/src/wpa_supplicant/ucode.c +++ b/package/network/services/hostapd/src/wpa_supplicant/ucode.c @@ -20,7 +20,7 @@ wpas_ucode_iface_get_uval(struct wpa_supplicant *wpa_s) uc_value_t *val; if (wpa_s->ucode.idx) - return wpa_ucode_registry_get(iface_registry, wpa_s->ucode.idx); + return ucv_get(wpa_ucode_registry_get(iface_registry, wpa_s->ucode.idx)); val = uc_resource_new(iface_type, wpa_s); wpa_s->ucode.idx = wpa_ucode_registry_add(iface_registry, val); @@ -36,9 +36,9 @@ wpas_ucode_update_interfaces(void) int i; for (wpa_s = wpa_global->ifaces; wpa_s; wpa_s = wpa_s->next) - ucv_object_add(ifs, wpa_s->ifname, ucv_get(wpas_ucode_iface_get_uval(wpa_s))); + ucv_object_add(ifs, wpa_s->ifname, wpas_ucode_iface_get_uval(wpa_s)); - ucv_object_add(ucv_prototype_get(global), "interfaces", ucv_get(ifs)); + ucv_object_add(ucv_prototype_get(global), "interfaces", ifs); ucv_gc(vm); } @@ -49,8 +49,8 @@ void wpas_ucode_add_bss(struct wpa_supplicant *wpa_s) if (wpa_ucode_call_prepare("iface_add")) return; - uc_value_push(ucv_get(ucv_string_new(wpa_s->ifname))); - uc_value_push(ucv_get(wpas_ucode_iface_get_uval(wpa_s))); + uc_value_push(ucv_string_new(wpa_s->ifname)); + uc_value_push(wpas_ucode_iface_get_uval(wpa_s)); ucv_put(wpa_ucode_call(2)); ucv_gc(vm); } @@ -67,9 +67,10 @@ void wpas_ucode_free_bss(struct wpa_supplicant *wpa_s) if (wpa_ucode_call_prepare("iface_remove")) return; - uc_value_push(ucv_get(ucv_string_new(wpa_s->ifname))); + uc_value_push(ucv_string_new(wpa_s->ifname)); uc_value_push(ucv_get(val)); ucv_put(wpa_ucode_call(2)); + ucv_put(val); ucv_gc(vm); } @@ -86,9 +87,9 @@ void wpas_ucode_update_state(struct wpa_supplicant *wpa_s) return; state = wpa_supplicant_state_txt(wpa_s->wpa_state); - uc_value_push(ucv_get(ucv_string_new(wpa_s->ifname))); + uc_value_push(ucv_string_new(wpa_s->ifname)); uc_value_push(ucv_get(val)); - uc_value_push(ucv_get(ucv_string_new(state))); + uc_value_push(ucv_string_new(state)); ucv_put(wpa_ucode_call(3)); ucv_gc(vm); } @@ -108,9 +109,9 @@ void wpas_ucode_event(struct wpa_supplicant *wpa_s, int event, union wpa_event_d if (wpa_ucode_call_prepare("event")) return; - uc_value_push(ucv_get(ucv_string_new(wpa_s->ifname))); + uc_value_push(ucv_string_new(wpa_s->ifname)); uc_value_push(ucv_get(val)); - uc_value_push(ucv_get(ucv_string_new(event_to_string(event)))); + uc_value_push(ucv_string_new(event_to_string(event))); val = ucv_object_new(vm); uc_value_push(ucv_get(val)); @@ -212,15 +213,14 @@ uc_wpas_iface_status(uc_vm_t *vm, size_t nargs) { struct wpa_supplicant *wpa_s = uc_fn_thisval("wpas.iface"); struct wpa_bss *bss; - uc_value_t *ret, *val; + uc_value_t *ret; if (!wpa_s) return NULL; ret = ucv_object_new(vm); - val = ucv_string_new(wpa_supplicant_state_txt(wpa_s->wpa_state)); - ucv_object_add(ret, "state", ucv_get(val)); + ucv_object_add(ret, "state", ucv_string_new(wpa_supplicant_state_txt(wpa_s->wpa_state))); bss = wpa_s->current_bss; if (bss) { diff --git a/package/network/services/lldpd/Makefile b/package/network/services/lldpd/Makefile index f34cd28faac965..3fbd0bf4f93ae8 100644 --- a/package/network/services/lldpd/Makefile +++ b/package/network/services/lldpd/Makefile @@ -8,12 +8,12 @@ include $(TOPDIR)/rules.mk PKG_NAME:=lldpd -PKG_VERSION:=1.0.17 -PKG_RELEASE:=5 +PKG_VERSION:=1.0.18 +PKG_RELEASE:=2 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz PKG_SOURCE_URL:=https://github.com/lldpd/lldpd/releases/download/$(PKG_VERSION)/ -PKG_HASH:=89ae691a4917ac9e0ec3b8b2c1e634cc402d43b804f98850c73bd1c7df380882 +PKG_HASH:=38cd319aa02ab61d9a2ad130e22f906795ccca9ac73a0a0d9dac19ca99a8a870 PKG_MAINTAINER:=Stijn Tintel PKG_LICENSE:=ISC @@ -90,6 +90,8 @@ endif ifneq ($(CONFIG_LLDPD_WITH_LLDPMED),y) sed -i -e 's/CONFIG_LLDPD_WITH_LLDPMED=y/CONFIG_LLDPD_WITH_LLDPMED=n/g' $(1)/etc/init.d/lldpd sed -i -e '/agentxsocket/d' $(1)/etc/config/lldpd + sed -i -e '/lldp_class/d' $(1)/etc/config/lldpd + sed -i -e '/lldp_location/d' $(1)/etc/config/lldpd endif endef diff --git a/package/network/services/lldpd/files/lldpd.init b/package/network/services/lldpd/files/lldpd.init index 3922b676b52e69..e59b5d9800b919 100644 --- a/package/network/services/lldpd/files/lldpd.init +++ b/package/network/services/lldpd/files/lldpd.init @@ -1,6 +1,6 @@ #!/bin/sh /etc/rc.common # Copyright (C) 2008-2015 OpenWrt.org -# shellcheck disable=1091,2034,3037,3043,3045 +# shellcheck disable=1091,2034,3037,3043,3045,3057 START=90 STOP=01 @@ -24,22 +24,69 @@ LLDPD_RESTART_HASH=${LLDPD_RUN}/lldpd.restart_hash . "$IPKG_INSTROOT/lib/functions/network.sh" +# Load release info once for all 'find_*' functions +[ -s /etc/os-release ] && . /etc/os-release + +# Helper function to truncate output to 31 characters +truncate_output() { + # Some devices have trouble decoding inventory TLV strings > 31 chars + # lldpd truncates inventory TLV to a total TLV length of 36 (of which string = 32) + echo "${1:0:31}" +} + find_release_info() { - [ -s /etc/os-release ] && . /etc/os-release [ -z "$PRETTY_NAME" ] && [ -s /etc/openwrt_version ] && \ PRETTY_NAME="$(cat /etc/openwrt_version)" echo "${PRETTY_NAME:-Unknown OpenWrt release} @ $(cat /proc/sys/kernel/hostname)" } +find_hardware_revision() +{ + echo "${OPENWRT_DEVICE_REVISION:-Unknown hardware revision}" +} + +find_firmware_info() +{ + echo "${PRETTY_NAME:-Unknown firmware release}" +} + +find_software_revision() +{ + echo "${BUILD_ID:-Unknown software revision}" +} + +# Helper function to extract JSON values using jsonfilter +extract_json_field() { + local _path="$1" + jsonfilter -q -i /etc/board.json -e "$_path" 2>/dev/null +} + +find_manufacturer_info() +{ + local _id + # extract the model->id field, e.g.: "id": "glinet,gl-mt6000", + _id=$(extract_json_field '@.model.id') + # stash text up to first comma + _id="${_id%%,*}" + echo "${_id:-Unknown manufacturer}" +} + +find_model_info() +{ + local _name + # extract the model->name field, e.g.: "name": "GL.iNet GL-MT6000" + _name=$(extract_json_field '@.model.name') + echo "${_name:-Unknown model name}" +} + get_config_restart_hash() { local var="$1" local _string _hash v config_load 'lldpd' - config_get v 'config' 'lldp_class'; append _string "$v" "," if [ "$CONFIG_LLDPD_WITH_SNMP" = "y" ]; then config_get v 'config' 'agentxsocket'; append _string "$v" "," fi @@ -49,6 +96,7 @@ get_config_restart_hash() { config_get_bool v 'config' 'lldp_no_version'; append _string "$v" "," if [ "$CONFIG_LLDPD_WITH_LLDPMED" = "y" ]; then config_get_bool v 'config' 'lldpmed_no_inventory'; append _string "$v" "," + config_get v 'config' 'lldp_class'; append _string "$v" "," fi config_get_bool v 'config' 'enable_lldp' 1; append _string "$v" "," config_get_bool v 'config' 'force_lldp'; append _string "$v" "," @@ -75,9 +123,9 @@ get_config_restart_hash() { export -n "$var=$_hash" } -get_config_cid_ifaces() { +get_interface_csv() { local _ifaces - config_get _ifaces 'config' "$2" + config_get _ifaces "$2" "$3" local _iface _ifnames="" # Set noglob to prevent '*' capturing diverse file names in the for ... in @@ -98,6 +146,21 @@ get_config_cid_ifaces() { export -n "${1}=$_ifnames" } +add_custom_tlv_callback() +{ + # syntax: configure [ports ethX[,…]] lldp custom-tlv [add|replace] oui XX,XX,XX subtype XX oui-info XX[,XX,...] + # ex: configure ports br-lan,eth0 lldp custom-tlv replace oui 33,44,55 subtype 254 oui-info 55,55,55,55,55 + # ex: configure lldp custom-tlv oui 33,44,44 subtype 232 + + local _ports + local _tlv + # CSV of device ports + get_interface_csv _ports "$1" 'ports' + config_get _tlv "$1" 'tlv' + + echo "configure ${_ports:+ports $_ports }lldp custom-tlv $_tlv" >> "$LLDPD_CONF" +} + write_lldpd_conf() { local lldp_description @@ -105,11 +168,53 @@ write_lldpd_conf() config_load 'lldpd' config_get lldp_description 'config' 'lldp_description' "$(find_release_info)" + # Check the 'do not send inventory' flag + local lldpmed_no_inventory + config_get_bool lldpmed_no_inventory 'config' 'lldpmed_no_inventory' 0 + + if [ "$lldpmed_no_inventory" = 0 ]; then + # lldpmed_no_inventory=1 ('-i' in start_service()) prevents these from being sent + # TIA TR-41 TLV 127 subtype 0x05 + local lldp_med_inv_hardware_revision + config_get lldp_med_inv_hardware_revision 'config' 'lldp_med_inv_hardware_revision' "$(find_hardware_revision)" + lldp_med_inv_hardware_revision=$(truncate_output "$lldp_med_inv_hardware_revision") + + # TIA TR-41 TLV 127 subtype 0x06 + local lldp_med_inv_firmware_revision + config_get lldp_med_inv_firmware_revision 'config' 'lldp_med_inv_firmware_revision' "$(find_firmware_info)" + lldp_med_inv_firmware_revision=$(truncate_output "$lldp_med_inv_firmware_revision") + + # TIA TR-41 TLV 127 subtype 0x07 + local lldp_med_inv_software_revision + config_get lldp_med_inv_software_revision 'config' 'lldp_med_inv_software_revision' "$(find_software_revision)" + lldp_med_inv_software_revision=$(truncate_output "$lldp_med_inv_software_revision") + + # TIA TR-41 TLV 127 subtype 0x08 + local lldp_med_inv_serial_number + config_get lldp_med_inv_serial_number 'config' 'lldp_med_inv_serial_number' + lldp_med_inv_serial_number=$(truncate_output "$lldp_med_inv_serial_number") + + # TIA TR-41 TLV 127 subtype 0x09 + local lldp_med_inv_manufacturer_name + config_get lldp_med_inv_manufacturer_name 'config' 'lldp_med_inv_manufacturer_name' "$(find_manufacturer_info)" + lldp_med_inv_manufacturer_name=$(truncate_output "$lldp_med_inv_manufacturer_name") + + # TIA TR-41 TLV 127 subtype 0x0a + local lldp_med_inv_model_name + config_get lldp_med_inv_model_name 'config' 'lldp_med_inv_model_name' "$(find_model_info)" + lldp_med_inv_model_name=$(truncate_output "$lldp_med_inv_model_name") + + # TIA TR-41 TLV 127 subtype 0x0b + local lldp_med_inv_asset_id + config_get lldp_med_inv_asset_id 'config' 'lldp_med_inv_asset_id' + lldp_med_inv_asset_id=$(truncate_output "$lldp_med_inv_asset_id") + fi + local lldp_hostname config_get lldp_hostname 'config' 'lldp_hostname' "$(cat /proc/sys/kernel/hostname)" local ifnames - get_config_cid_ifaces ifnames "interface" + get_interface_csv ifnames 'config' "interface" local lldp_mgmt_ip config_get lldp_mgmt_ip 'config' 'lldp_mgmt_ip' @@ -167,6 +272,17 @@ write_lldpd_conf() [ -n "$lldp_mgmt_ip" ] && echo "configure system ip management pattern" "\"$lldp_mgmt_ip\"" >> "$LLDPD_CONF" [ -n "$lldp_syscapabilities" ] && echo "configure system capabilities enabled $lldp_syscapabilities" >> "$LLDPD_CONF" + if [ "$lldpmed_no_inventory" = 0 ]; then + # Hardware inventory info + [ -n "$lldp_med_inv_hardware_revision" ] && echo "configure inventory hardware-revision \"$lldp_med_inv_hardware_revision\"" >> "$LLDPD_CONF" + [ -n "$lldp_med_inv_firmware_revision" ] && echo "configure inventory firmware-revision \"$lldp_med_inv_firmware_revision\"" >> "$LLDPD_CONF" + [ -n "$lldp_med_inv_software_revision" ] && echo "configure inventory software-revision \"$lldp_med_inv_software_revision\"" >> "$LLDPD_CONF" + [ -n "$lldp_med_inv_serial_number" ] && echo "configure inventory serial-number \"$lldp_med_inv_serial_number\"" >> "$LLDPD_CONF" + [ -n "$lldp_med_inv_manufacturer_name" ] && echo "configure inventory manufacturer \"$lldp_med_inv_manufacturer_name\"" >> "$LLDPD_CONF" + [ -n "$lldp_med_inv_model_name" ] && echo "configure inventory model \"$lldp_med_inv_model_name\"" >> "$LLDPD_CONF" + [ -n "$lldp_med_inv_asset_id" ] && echo "configure inventory asset \"$lldp_med_inv_asset_id\"" >> "$LLDPD_CONF" + fi + if [ "$CONFIG_LLDPD_WITH_LLDPMED" = "y" ] && [ "$lldpmed_fast_start" -gt 0 ]; then if [ "$lldpmed_fast_start_tx_interval" -gt 0 ]; then echo "configure med fast-start tx-interval $lldpmed_fast_start_tx_interval" >> "$LLDPD_CONF" @@ -197,6 +313,9 @@ write_lldpd_conf() [ "$lldp_mgmt_addr_advertisements" -gt 0 ] && echo "configure lldp management-addresses-advertisements" >> "$LLDPD_CONF" ||\ echo "unconfigure lldp management-addresses-advertisements" >> "$LLDPD_CONF" + # Custom TLV handling + config_foreach add_custom_tlv_callback 'custom-tlv' + # Since lldpd's sysconfdir is /tmp, we'll symlink /etc/lldpd.d to /tmp/$LLDPD_CONFS_DIR [ -e "$LLDPD_CONFS_DIR" ] || ln -s /etc/lldpd.d "$LLDPD_CONFS_DIR" } @@ -243,10 +362,10 @@ start_service() { config_get_bool enable_edp 'config' 'enable_edp' 0 config_get_bool force_edp 'config' 'force_edp' 0 fi - config_get lldp_class 'config' 'lldp_class' config_get_bool lldp_no_version 'config' 'lldp_no_version' 0 if [ "$CONFIG_LLDPD_WITH_LLDPMED" = "y" ]; then config_get_bool lldpmed_no_inventory 'config' 'lldpmed_no_inventory' 0 + config_get lldp_class 'config' 'lldp_class' fi config_get_bool readonly_mode 'config' 'readonly_mode' 0 if [ "$CONFIG_LLDPD_WITH_SNMP" = "y" ]; then @@ -335,7 +454,7 @@ start_service() { # ChassisID interfaces local ifnames - get_config_cid_ifaces ifnames "cid_interface" + get_interface_csv ifnames 'config' "cid_interface" [ -n "$ifnames" ] && procd_append_param command -C "$ifnames" @@ -383,6 +502,14 @@ reload_service() { unconfigure system hostname unconfigure system ip management pattern unconfigure system platform + # Hardware inventory info + unconfigure inventory hardware-revision + unconfigure inventory firmware-revision + unconfigure inventory software-revision + unconfigure inventory serial-number + unconfigure inventory manufacturer + unconfigure inventory model + unconfigure inventory asset EOF if [ "$CONFIG_LLDPD_WITH_LLDPMED" = "y" ]; then $LLDPCLI -u "$LLDPSOCKET" >/dev/null 2>&1 <<-EOF diff --git a/package/network/services/omcproxy/Makefile b/package/network/services/omcproxy/Makefile index 0ca0970af2b9f1..a295431cb553e5 100644 --- a/package/network/services/omcproxy/Makefile +++ b/package/network/services/omcproxy/Makefile @@ -8,13 +8,13 @@ include $(TOPDIR)/rules.mk PKG_NAME:=omcproxy -PKG_RELEASE:=9 +PKG_RELEASE:=1 PKG_SOURCE_PROTO:=git PKG_SOURCE_URL=$(PROJECT_GIT)/project/omcproxy.git -PKG_MIRROR_HASH:=61f03d76b14149e417360b6aaa630e920b75a31a6a497353b7160b3a374b20b2 -PKG_SOURCE_DATE:=2021-11-04 -PKG_SOURCE_VERSION:=bfba2aa75802ff1a70ef2fd3eba53409a8c6e93a +PKG_MIRROR_HASH:=b18c6dcc323dc35cfeb3503562dd3d8b9fb27fcf6ddd98690a64bd709920ff3d +PKG_SOURCE_DATE:=2025-02-27 +PKG_SOURCE_VERSION:=582cd8d3ae7e6af0073ce1d9198387af48affd60 PKG_MAINTAINER:=Steven Barth PKG_LICENSE:=Apache-2.0 diff --git a/package/network/services/ppp/patches/400-simplify_kernel_checks.patch b/package/network/services/ppp/patches/400-simplify_kernel_checks.patch index 137937c2448de0..311bb8752f9d44 100644 --- a/package/network/services/ppp/patches/400-simplify_kernel_checks.patch +++ b/package/network/services/ppp/patches/400-simplify_kernel_checks.patch @@ -10,7 +10,14 @@ Signed-off-by: Jo-Philipp Wich --- a/pppd/sys-linux.c +++ b/pppd/sys-linux.c -@@ -231,7 +231,7 @@ static int driver_is_old = 0; +@@ -224,14 +224,10 @@ static fd_set in_fds; /* set of fds tha + static int max_in_fd; /* highest fd set in in_fds */ + + static int has_proxy_arp = 0; +-static int driver_version = 0; +-static int driver_modification = 0; +-static int driver_patch = 0; +-static int driver_is_old = 0; static int restore_term = 0; /* 1 => we've munged the terminal */ static struct termios inittermios; /* Initial TTY termios */ @@ -19,17 +26,18 @@ Signed-off-by: Jo-Philipp Wich static char loop_name[20]; static unsigned char inbuf[512]; /* buffer for chars read from loopback */ -@@ -250,8 +250,8 @@ static int looped; /* 1 if using loop +@@ -249,9 +245,8 @@ static int dynaddr_set; /* 1 if ip_dyna + static int looped; /* 1 if using loop */ static int link_mtu; /* mtu for the link (not bundle) */ - static struct utsname utsname; /* for the kernel version */ +-static struct utsname utsname; /* for the kernel version */ -static int kernel_version; #define KVERSION(j,n,p) ((j)*1000000 + (n)*1000 + (p)) -+static const int kernel_version = KVERSION(2,6,37); ++static const int kernel_version = KVERSION(4,9,0); #define MAX_IFS 100 -@@ -1970,11 +1970,12 @@ int ccp_fatal_error (int unit) +@@ -1970,11 +1965,12 @@ int ccp_fatal_error (int unit) * * path_to_procfs - find the path to the proc file system mount point */ @@ -44,7 +52,7 @@ Signed-off-by: Jo-Philipp Wich struct mntent *mntent; FILE *fp; -@@ -1996,6 +1997,7 @@ static char *path_to_procfs(const char * +@@ -1996,6 +1992,7 @@ static char *path_to_procfs(const char * fclose (fp); } } @@ -52,35 +60,24 @@ Signed-off-by: Jo-Philipp Wich strlcpy(proc_path + proc_path_len, tail, sizeof(proc_path) - proc_path_len); -@@ -2895,15 +2897,19 @@ int ppp_check_kernel_support(void) - int my_version, my_modification, my_patch; - int osmaj, osmin, ospatch; +@@ -2889,6 +2886,8 @@ ppp_registered(void) + int ppp_check_kernel_support(void) + { ++ return 1; /* OpenWrt support ppp device "/dev/ppp" by default */ +#if 0 - /* get the kernel version now, since we are called before sys_init */ - uname(&utsname); - osmaj = osmin = ospatch = 0; - sscanf(utsname.release, "%d.%d.%d", &osmaj, &osmin, &ospatch); - kernel_version = KVERSION(osmaj, osmin, ospatch); -+#endif - - fd = open("/dev/ppp", O_RDWR); - if (fd >= 0) { -+#if 0 - new_style_driver = 1; + int s, ok, fd; + struct ifreq ifr; + int size; +@@ -3016,6 +3015,7 @@ int ppp_check_kernel_support(void) + } + close(s); + return ok; +#endif + } - /* XXX should get from driver */ - driver_version = 2; -@@ -2963,6 +2969,7 @@ int ppp_check_kernel_support(void) - - if (ok && ((ifr.ifr_hwaddr.sa_family & ~0xFF) != ARPHRD_PPP)) - ok = 0; -+ return ok; - - /* - * This is the PPP device. Validate the version of the driver at this -@@ -3577,6 +3584,7 @@ get_pty(int *master_fdp, int *slave_fdp, + #ifndef HAVE_LOGWTMP +@@ -3577,6 +3577,7 @@ get_pty(int *master_fdp, int *slave_fdp, } #endif /* TIOCGPTN */ @@ -88,7 +85,7 @@ Signed-off-by: Jo-Philipp Wich if (sfd < 0) { /* the old way - scan through the pty name space */ for (i = 0; i < 64; ++i) { -@@ -3601,6 +3609,7 @@ get_pty(int *master_fdp, int *slave_fdp, +@@ -3601,6 +3602,7 @@ get_pty(int *master_fdp, int *slave_fdp, } } } @@ -96,23 +93,35 @@ Signed-off-by: Jo-Philipp Wich if (sfd < 0) return 0; +@@ -3716,6 +3718,7 @@ get_host_seed(void) + int + sys_check_options(void) + { ++#if 0 + if (demand && driver_is_old) { + ppp_option_error("demand dialling is not supported by kernel driver " + "version %d.%d.%d", driver_version, driver_modification, +@@ -3726,6 +3729,7 @@ sys_check_options(void) + warn("Warning: multilink is not supported by the kernel driver"); + multilink = 0; + } ++#endif + return 1; + } + --- a/pppd/plugins/pppoatm/pppoatm.c +++ b/pppd/plugins/pppoatm/pppoatm.c -@@ -179,14 +179,6 @@ static void disconnect_pppoatm(void) - +@@ -180,10 +180,6 @@ static void disconnect_pppoatm(void) void plugin_init(void) { --#ifdef linux + #ifdef linux - extern int new_style_driver; /* From sys-linux.c */ - if (!ppp_check_kernel_support() && !new_style_driver) - fatal("Kernel doesn't support ppp_generic - " - "needed for PPPoATM"); --#else -- fatal("No PPPoATM support on this OS"); --#endif - ppp_add_options(pppoa_options); - } - + #else + fatal("No PPPoATM support on this OS"); + #endif --- a/pppd/plugins/pppoe/plugin.c +++ b/pppd/plugins/pppoe/plugin.c @@ -57,9 +57,6 @@ static char const RCSID[] = @@ -138,17 +147,14 @@ Signed-off-by: Jo-Philipp Wich info("PPPoE plugin from pppd %s", PPPD_VERSION); --- a/pppd/plugins/pppol2tp/pppol2tp.c +++ b/pppd/plugins/pppol2tp/pppol2tp.c -@@ -500,12 +500,7 @@ static void pppol2tp_cleanup(void) - +@@ -501,10 +501,6 @@ static void pppol2tp_cleanup(void) void plugin_init(void) { --#if defined(__linux__) + #if defined(__linux__) - extern int new_style_driver; /* From sys-linux.c */ - if (!ppp_check_kernel_support() && !new_style_driver) - fatal("Kernel doesn't support ppp_generic - " - "needed for PPPoL2TP"); --#else -+#if !defined(__linux__) + #else fatal("No PPPoL2TP support on this OS"); #endif - ppp_add_options(pppol2tp_options); diff --git a/package/network/services/uhttpd/Makefile b/package/network/services/uhttpd/Makefile index ea76fa65ea8114..3899c5827199b0 100644 --- a/package/network/services/uhttpd/Makefile +++ b/package/network/services/uhttpd/Makefile @@ -12,9 +12,9 @@ PKG_RELEASE:=4 PKG_SOURCE_PROTO:=git PKG_SOURCE_URL=$(PROJECT_GIT)/project/uhttpd.git -PKG_SOURCE_DATE:=2023-06-25 -PKG_SOURCE_VERSION:=34a8a74dbdec3c0de38abc1b08f6a73c51263792 -PKG_MIRROR_HASH:=0603019dabb89b1b207d0f7916616c95ce8194a7ff9fd71f0ddd845dd2de944e +PKG_SOURCE_DATE:=2025-07-06 +PKG_SOURCE_VERSION:=7e64e8bad2415cec0a6d9770ec379db54273c7a7 +PKG_MIRROR_HASH:=61a7ad046f31f229f6a8620b890e448c5df397391edb5f7bd2a84446486eaff4 PKG_MAINTAINER:=Felix Fietkau PKG_LICENSE:=ISC diff --git a/package/network/services/umdns/Makefile b/package/network/services/umdns/Makefile index 606dc7274fe3ea..9a2763d5b2dba3 100644 --- a/package/network/services/umdns/Makefile +++ b/package/network/services/umdns/Makefile @@ -12,9 +12,9 @@ PKG_RELEASE:=1 PKG_SOURCE_URL=$(PROJECT_GIT)/project/mdnsd.git PKG_SOURCE_PROTO:=git -PKG_SOURCE_DATE:=2024-09-17 -PKG_SOURCE_VERSION:=fbaca4b6f530d4b2f361ee15c266aa19a708242b -PKG_MIRROR_HASH:=e3fc47a019ea54722b8d7dfc8158307a9fb4a9d18945a1a6794616e3b80d5d3b +PKG_SOURCE_DATE:=2025-02-10 +PKG_SOURCE_VERSION:=c5ca22a71b2ecb83a2a28b46391dac443be315c2 +PKG_MIRROR_HASH:=2d595fa1e58f028a7ff6813b110ee6bcbc8e6ccce81b2792200508c6db9c276a PKG_MAINTAINER:=John Crispin PKG_LICENSE:=LGPL-2.1 diff --git a/package/network/services/umdns/files/umdns.init b/package/network/services/umdns/files/umdns.init index e9a2c05e093e30..61b2a338d677f6 100644 --- a/package/network/services/umdns/files/umdns.init +++ b/package/network/services/umdns/files/umdns.init @@ -35,6 +35,23 @@ start_service() { procd_set_param command "$PROG" [ -f /etc/seccomp/umdns.json ] && procd_set_param seccomp /etc/seccomp/umdns.json procd_set_param respawn + + procd_open_data + json_add_array firewall + + for n in $network; do + json_add_object "" + json_add_string type rule + json_add_string proto udp + json_add_string src "$n" + json_add_int dest_port 5353 + json_add_string target ACCEPT + json_close_object + done + + json_close_array + procd_close_data + procd_open_trigger procd_add_config_trigger "config.change" "umdns" /etc/init.d/umdns reload for n in $network; do diff --git a/package/network/services/unetd/Makefile b/package/network/services/unetd/Makefile index 018f6b8ea9707e..3a0ded804e73b8 100644 --- a/package/network/services/unetd/Makefile +++ b/package/network/services/unetd/Makefile @@ -10,9 +10,9 @@ include $(TOPDIR)/rules.mk PKG_NAME:=unetd PKG_SOURCE_PROTO:=git PKG_SOURCE_URL=$(PROJECT_GIT)/project/unetd.git -PKG_SOURCE_DATE:=2024-03-31 -PKG_SOURCE_VERSION:=806457664ab6e952a7f4febb82e891f596fe577c -PKG_MIRROR_HASH:=f469d65fd83721a8da0e5253d1ba871a6734233da6f23b631009b17b3af82455 +PKG_SOURCE_DATE:=2025-03-09 +PKG_SOURCE_VERSION:=6c9c8fbd81285a2cba7dd1c2c1ac2bf25ca99e27 +PKG_MIRROR_HASH:=9dc06c945713a6a289ed0838ebe59e65b4fbb333e02d5159a8e87d29754808a6 PKG_LICENSE:=GPL-2.0 PKG_MAINTAINER:=Felix Fietkau @@ -32,7 +32,7 @@ define Package/unetd SECTION:=net CATEGORY:=Network TITLE:=WireGuard based VPN connection manager for OpenWrt - DEPENDS:=+libubox +libubus +libblobmsg-json +libnl-tiny +kmod-wireguard +UNETD_VXLAN_SUPPORT:libbpf + DEPENDS:=+libubox +libubus +libudebug +libblobmsg-json +libnl-tiny +kmod-wireguard +UNETD_VXLAN_SUPPORT:libbpf endef define Package/unetd/config @@ -40,6 +40,7 @@ define Package/unetd/config bool "VXLAN support" depends on PACKAGE_unetd depends on HAS_BPF_TOOLCHAIN + select NEED_BPF_TOOLCHAIN default y endef diff --git a/package/network/services/unetd/files/unetd.init b/package/network/services/unetd/files/unetd.init index c1124821ee8fa1..7c980e3d0d541b 100644 --- a/package/network/services/unetd/files/unetd.init +++ b/package/network/services/unetd/files/unetd.init @@ -13,5 +13,20 @@ start_service() { procd_set_param command "$PROG" -h /var/run/unetd/hosts -u /var/run/unetd/socket procd_set_param respawn procd_set_param limits core="unlimited" + + procd_open_data + json_add_array firewall + + json_add_object "" + json_add_string type rule + json_add_string proto udp + json_add_string src "*" + json_add_int dest_port 51819 + json_add_string target ACCEPT + json_close_object + + json_close_array + procd_close_data + procd_close_instance } diff --git a/package/network/services/unetd/files/unetd.sh b/package/network/services/unetd/files/unetd.sh index 2f0f0c478c78a9..726ee765654210 100644 --- a/package/network/services/unetd/files/unetd.sh +++ b/package/network/services/unetd/files/unetd.sh @@ -18,6 +18,7 @@ proto_unet_init_config() { proto_config_add_string domain proto_config_add_boolean dht proto_config_add_array "tunnels:list(string)" + proto_config_add_array "local_network:list(string)" proto_config_add_array "connect:list(string)" proto_config_add_array "peer_data:list(string)" no_device=1 @@ -25,6 +26,17 @@ proto_unet_init_config() { no_proto_task=1 } +add_array() { + local name="$1" + local val="$2" + + json_add_array "$name" + for c in $val; do + json_add_string "" "$c" + done + json_close_array +} + proto_unet_setup() { local config="$1" @@ -33,6 +45,7 @@ proto_unet_setup() { json_get_values tunnels tunnels json_get_values connect connect json_get_values peer_data peer_data + json_get_values local_network local_network device="${device:-$config}" [ -n "$auth_key" ] && type="${type:-dynamic}" @@ -58,17 +71,9 @@ proto_unet_setup() { done json_close_object - json_add_array auth_connect - for c in $connect; do - json_add_string "" "$c" - done - json_close_array - - json_add_array peer_data - for c in $peer_data; do - json_add_string "" "$c" - done - json_close_array + add_array local_network "$local_network" + add_array auth_connect "$connect" + add_array peer_data "$peer_data" ip link del dev "$device" >/dev/null 2>&1 ip link add dev "$device" type wireguard || { @@ -82,11 +87,10 @@ proto_unet_setup() { proto_unet_teardown() { local config="$1" - local iface="$2" local device json_get_vars device - device="${device:-$iface}" + device="${device:-$config}" json_init json_add_string name "$device" diff --git a/package/network/utils/bpftool/Makefile b/package/network/utils/bpftool/Makefile index f2726d18969090..b2fdfc16325e06 100644 --- a/package/network/utils/bpftool/Makefile +++ b/package/network/utils/bpftool/Makefile @@ -8,13 +8,13 @@ include $(TOPDIR)/rules.mk PKG_NAME:=bpftool -PKG_VERSION:=7.4.0 +PKG_VERSION:=7.5.0 PKG_RELEASE:=1 PKG_SOURCE_URL:=https://github.com/libbpf/bpftool -PKG_MIRROR_HASH:=18e22f72e67ff402b5ecaf314445f25c40bfe23299cb783b5834a496297c51ed +PKG_MIRROR_HASH:=1da7c08959e7819772145774322ffd876f3180065be1c3759336dca98ac9f666 PKG_SOURCE_PROTO:=git -PKG_SOURCE_VERSION:=v7.4.0 +PKG_SOURCE_VERSION:=v$(PKG_VERSION) PKG_MAINTAINER:=Tony Ambardar @@ -97,7 +97,7 @@ HOST_MAKE_FLAGS += \ $(if $(findstring c,$(OPENWRT_VERBOSE)),V=1,V='') \ check_feat=0 \ feature-clang-bpf-co-re=0 \ - feature-libbfd=1 \ + feature-libbfd=0 \ feature-llvm=0 \ feature-libcap=0 \ feature-disassembler-four-args=1 \ diff --git a/package/network/utils/ethtool/Makefile b/package/network/utils/ethtool/Makefile index cfb4cfaeb947f2..5da65273ca937f 100644 --- a/package/network/utils/ethtool/Makefile +++ b/package/network/utils/ethtool/Makefile @@ -8,13 +8,13 @@ include $(TOPDIR)/rules.mk PKG_NAME:=ethtool -PKG_VERSION:=6.10 +PKG_VERSION:=6.11 PKG_RELEASE:=1 PKG_MAINTAINER:=Felix Fietkau PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz PKG_SOURCE_URL:=@KERNEL/software/network/ethtool -PKG_HASH:=cc613fe8a2bcddee17a1e6e0d763c0f3ea33c7e930658d2d7f601aa65e426a1f +PKG_HASH:=8d91f5c72ae3f25b7e88d4781279dcb320f71e30058914370b1c574c96b31202 PKG_LICENSE:=GPL-2.0 PKG_LICENSE_FILES:=COPYING @@ -57,6 +57,11 @@ else CONFIGURE_ARGS += --disable-netlink --disable-pretty-dump endif +# enable support for input_xfrm with kernels newer than 6.6 +ifeq ($(CONFIG_LINUX_6_6),) +CONFIGURE_ARGS += --enable-rss-input-xfrm +endif + define Package/ethtool/install $(INSTALL_DIR) $(1)/usr/sbin $(INSTALL_BIN) $(PKG_BUILD_DIR)/ethtool $(1)/usr/sbin diff --git a/package/network/utils/ethtool/patches/0001-ethtool-make-building-for-RSS-input-xfrm-optional.patch b/package/network/utils/ethtool/patches/0001-ethtool-make-building-for-RSS-input-xfrm-optional.patch new file mode 100644 index 00000000000000..4c8403dcbc5d18 --- /dev/null +++ b/package/network/utils/ethtool/patches/0001-ethtool-make-building-for-RSS-input-xfrm-optional.patch @@ -0,0 +1,67 @@ +From c88eb6f4e9b2d8f71f3391db2bf0ec82ecccae81 Mon Sep 17 00:00:00 2001 +From: Daniel Golle +Date: Wed, 12 Feb 2025 04:12:42 +0000 +Subject: [PATCH] ethtool: make building for RSS input xfrm optional + +Unfortunately there is no way to detect at runtime if the kernel the +support for RSS input transformation, and the default value +RXH_XFRM_NO_CHANGE (0xff) used by newer ethtool results in breakage +with older kernels. +As a stop-gap solution simply don't compile with support for input +xfrm by default. + +Signed-off-by: Daniel Golle +--- + configure.ac | 10 ++++++++++ + ethtool.c | 10 ++++++++++ + 2 files changed, 20 insertions(+) + +--- a/configure.ac ++++ b/configure.ac +@@ -45,6 +45,16 @@ if test x$enable_pretty_dump = xyes; the + fi + AM_CONDITIONAL([ETHTOOL_ENABLE_PRETTY_DUMP], [test x$enable_pretty_dump = xyes]) + ++AC_ARG_ENABLE(rss-input-xfrm, ++ [ --enable-rss-input-xfrm build with support for RSS input transformation (disabled by default)], ++ , ++ enable_rss_input_xfrm=no) ++if test x$enable_rss_input_xfrm = xyes; then ++ AC_DEFINE(ETHTOOL_ENABLE_RSS_INPUT_XFRM, 1, ++ [Define this to enable building with support for RSS input transformation.]) ++fi ++AM_CONDITIONAL([ETHTOOL_ENABLE_RSS_INPUT_XFRM], [test x$enable_rss_input_xfrm = xyes]) ++ + AC_ARG_WITH([bash-completion-dir], + AS_HELP_STRING([--with-bash-completion-dir[=PATH]], + [Install the bash-completion script in this directory. @<:@default=yes@:>@]), +--- a/ethtool.c ++++ b/ethtool.c +@@ -4109,9 +4109,11 @@ static int do_grxfh(struct cmd_context * + (const char *)hfuncs->data + i * ETH_GSTRING_LEN, + (rss->hfunc & (1 << i)) ? "on" : "off"); + ++#ifdef ETHTOOL_ENABLE_RSS_INPUT_XFRM + printf("RSS input transformation:\n"); + printf(" symmetric-xor: %s\n", + (rss->input_xfrm & RXH_XFRM_SYM_XOR) ? "on" : "off"); ++#endif + + out: + free(hfuncs); +@@ -4431,7 +4433,15 @@ static int do_srxfh(struct cmd_context * + rss->cmd = ETHTOOL_SRSSH; + rss->rss_context = rss_context; + rss->hfunc = req_hfunc; ++#ifdef ETHTOOL_ENABLE_RSS_INPUT_XFRM + rss->input_xfrm = req_input_xfrm; ++#else ++ if (req_input_xfrm != 0xff) { ++ perror("Compiled for kernel without support for input transformation"); ++ err = 1; ++ goto free; ++ } ++#endif + if (delete) { + rss->indir_size = rss->key_size = 0; + } else { diff --git a/package/network/utils/nftables/Makefile b/package/network/utils/nftables/Makefile index 38a8199d11dc09..06b3fcfcdad7ad 100644 --- a/package/network/utils/nftables/Makefile +++ b/package/network/utils/nftables/Makefile @@ -6,12 +6,12 @@ include $(TOPDIR)/rules.mk PKG_NAME:=nftables -PKG_VERSION:=1.0.9 +PKG_VERSION:=1.1.1 PKG_RELEASE:=1 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz PKG_SOURCE_URL:=https://netfilter.org/projects/$(PKG_NAME)/files -PKG_HASH:=a3c304cd9ba061239ee0474f9afb938a9bb99d89b960246f66f0c3a0a85e14cd +PKG_HASH:=6358830f3a64f31e39b0ad421d7dadcd240b72343ded48d8ef13b8faf204865a PKG_MAINTAINER:= PKG_LICENSE:=GPL-2.0 diff --git a/package/network/utils/uqmi/Makefile b/package/network/utils/uqmi/Makefile index 54e1b4fc7b16a2..1be3fcd9a2e5c8 100644 --- a/package/network/utils/uqmi/Makefile +++ b/package/network/utils/uqmi/Makefile @@ -1,13 +1,13 @@ include $(TOPDIR)/rules.mk PKG_NAME:=uqmi -PKG_RELEASE:=2 +PKG_RELEASE:=1 PKG_SOURCE_PROTO:=git PKG_SOURCE_URL=$(PROJECT_GIT)/project/uqmi.git -PKG_SOURCE_DATE:=2024-08-25 -PKG_SOURCE_VERSION:=28b48a10dbcd1177095b73c6d8086d10114f49b8 -PKG_MIRROR_HASH:=ca4c07775185b873da572d973b9bbce86198d41d921a8d32b990da34e5ffd65d +PKG_SOURCE_DATE:=2025-07-30 +PKG_SOURCE_VERSION:=7914da43cddaaf6cfba116260c81e6e9adffd5ab +PKG_MIRROR_HASH:=5972a5f90bd60d34b5c7a8cec14ae98f13dbb6ea5b35d845ce5da7a8a3b0e59c PKG_MAINTAINER:=Matti Laakso PKG_LICENSE:=GPL-2.0 diff --git a/package/network/utils/uqmi/files/lib/netifd/proto/qmi.sh b/package/network/utils/uqmi/files/lib/netifd/proto/qmi.sh index 8ec577a90b7823..a6a3fdaa693297 100755 --- a/package/network/utils/uqmi/files/lib/netifd/proto/qmi.sh +++ b/package/network/utils/uqmi/files/lib/netifd/proto/qmi.sh @@ -34,17 +34,20 @@ proto_qmi_init_config() { proto_qmi_setup() { local interface="$1" - local dataformat connstat plmn_mode mcc mnc - local device apn v6apn auth username password pincode delay modes pdptype - local profile v6profile dhcp dhcpv6 autoconnect plmn timeout mtu $PROTO_DEFAULT_OPTIONS - local ip4table ip6table - local cid_4 pdh_4 cid_6 pdh_6 - local ip_6 ip_prefix_length gateway_6 dns1_6 dns2_6 + + local connstat dataformat mcc mnc plmn_mode + local cid_4 cid_6 pdh_4 pdh_6 + local dns1_6 dns2_6 gateway_6 ip_6 ip_prefix_length local profile_pdptype - json_get_vars device apn v6apn auth username password pincode delay modes - json_get_vars pdptype profile v6profile dhcp dhcpv6 sourcefilter delegate autoconnect plmn ip4table - json_get_vars ip6table timeout mtu $PROTO_DEFAULT_OPTIONS + local delegate ip4table ip6table mtu sourcefilter $PROTO_DEFAULT_OPTIONS + json_get_vars delegate ip4table ip6table mtu sourcefilter $PROTO_DEFAULT_OPTIONS + + local apn auth delay device modes password pdptype pincode username v6apn + json_get_vars apn auth delay device modes password pdptype pincode username v6apn + + local profile v6profile dhcp dhcpv6 autoconnect plmn timeout + json_get_vars profile v6profile dhcp dhcpv6 autoconnect plmn timeout [ "$timeout" = "" ] && timeout="10" @@ -104,7 +107,7 @@ proto_qmi_setup() { # Check if UIM application is stuck in illegal state local uim_state_timeout=0 while true; do - json_load "$(uqmi -s -d "$device" -t 1000 --uim-get-sim-state)" + json_load "$(uqmi -s -d "$device" -t 2000 --uim-get-sim-state)" json_get_var card_application_state card_application_state # SIM card is either completely absent or state is labeled as illegal @@ -119,7 +122,7 @@ proto_qmi_setup() { if [ "$uim_state_timeout" -lt "$timeout" ] || [ "$timeout" = "0" ]; then let uim_state_timeout++ - sleep 1 + sleep 5 continue fi diff --git a/package/system/apk/Makefile b/package/system/apk/Makefile index 3e2066e2698f33..7176d64ef22b15 100644 --- a/package/system/apk/Makefile +++ b/package/system/apk/Makefile @@ -27,7 +27,7 @@ define Package/apk/default SECTION:=base CATEGORY:=Base system TITLE:=apk package manager - DEPENDS:=+zlib + DEPENDS:=@BROKEN +zlib URL:=$(PKG_SOURCE_URL) PROVIDES:=apk endef @@ -36,6 +36,7 @@ define Package/apk-mbedtls $(Package/apk/default) TITLE += (mbedtls) DEPENDS +=+libmbedtls + DEFAULT:=y if USE_APK VARIANT:=mbedtls DEFAULT_VARIANT:=1 CONFLICTS:=apk-openssl diff --git a/package/system/ca-certificates/Makefile b/package/system/ca-certificates/Makefile index 254d7b5178d89e..4febb647ac84ed 100644 --- a/package/system/ca-certificates/Makefile +++ b/package/system/ca-certificates/Makefile @@ -7,7 +7,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=ca-certificates -PKG_VERSION:=20240203 +PKG_VERSION:=20250419 PKG_RELEASE:=1 PKG_MAINTAINER:= @@ -16,7 +16,7 @@ PKG_LICENSE_FILES:=debian/copyright PKG_SOURCE:=$(PKG_NAME)_$(PKG_VERSION).tar.xz PKG_SOURCE_URL:=@DEBIAN/pool/main/c/ca-certificates -PKG_HASH:=3286d3fc42c4d11b7086711a85f865b44065ce05cf1fb5376b2abed07622a9c6 +PKG_HASH:=33b44ef78653ecd3f0f2f13e5bba6be466be2e7da72182f737912b81798ba5d2 PKG_INSTALL:=1 include $(INCLUDE_DIR)/package.mk diff --git a/package/system/gpio-cdev/nu801/Makefile b/package/system/gpio-cdev/nu801/Makefile index 82c04ccb415d1e..7724cd808bff66 100644 --- a/package/system/gpio-cdev/nu801/Makefile +++ b/package/system/gpio-cdev/nu801/Makefile @@ -3,6 +3,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=nu801 +PKG_FLAGS:=nonshared PKG_RELEASE:=1 PKG_SOURCE_PROTO:=git diff --git a/package/system/mtd/src/linksys_bootcount.c b/package/system/mtd/src/linksys_bootcount.c index bd06728696ce3f..3ec0b61718c3d8 100644 --- a/package/system/mtd/src/linksys_bootcount.c +++ b/package/system/mtd/src/linksys_bootcount.c @@ -69,12 +69,10 @@ struct bootcounter { uint32_t checksum; }; -static char page[2048]; - int mtd_resetbc(const char *mtd) { struct mtd_info_user mtd_info; - struct bootcounter *curr = (struct bootcounter *)page; + struct bootcounter *curr = NULL; unsigned int i; unsigned int bc_offset_increment; int last_count = 0; @@ -108,24 +106,37 @@ int mtd_resetbc(const char *mtd) } num_bc = mtd_info.size / bc_offset_increment; + curr = malloc(bc_offset_increment); - for (i = 0; i < num_bc; i++) { - pread(fd, curr, sizeof(*curr), i * bc_offset_increment); + if(curr == NULL) { + DLOG_ERR("Failed to allocate %u bytes from memory.", bc_offset_increment); - /* Existing code assumes erase is to 0xff; left as-is (2019) */ + retval = -6; + goto out; + } + + for (i = 0; i < num_bc; i++) { + ret = pread(fd, curr, sizeof(struct bootcounter), i * bc_offset_increment); - if (curr->magic != BOOTCOUNT_MAGIC && - curr->magic != 0xffffffff) { - DLOG_ERR("Unexpected magic %08x at offset %08x; aborting.", - curr->magic, i * bc_offset_increment); + if(ret != sizeof(struct bootcounter)) { + DLOG_ERR("Failed to read boot-count log at offset 0x%08x.", i * bc_offset_increment); - retval = -2; + retval = -5; goto out; } + /* Existing code assumes erase is to 0xff; left as-is (2019) */ if (curr->magic == 0xffffffff) break; + if (curr->magic != BOOTCOUNT_MAGIC || curr->checksum != curr->magic + curr->count) { + DLOG_ERR("Unexpected boot-count log at offset 0x%08x: magic 0x%08x boot count 0x%08x checksum 0x%08x; aborting.", + i * bc_offset_increment, curr->magic, curr->count, curr->checksum); + + retval = -2; + goto out; + } + last_count = curr->count; } @@ -182,6 +193,9 @@ int mtd_resetbc(const char *mtd) } out: + if (curr != NULL) + free(curr); + close(fd); return retval; } diff --git a/package/system/openwrt-keyring/Makefile b/package/system/openwrt-keyring/Makefile index 9344ec321d93b3..6c2fa3d108b6da 100644 --- a/package/system/openwrt-keyring/Makefile +++ b/package/system/openwrt-keyring/Makefile @@ -3,13 +3,13 @@ include $(TOPDIR)/rules.mk PKG_NAME:=openwrt-keyring -PKG_RELEASE:=1 +PKG_RELEASE:=2 PKG_SOURCE_PROTO:=git PKG_SOURCE_URL=$(PROJECT_GIT)/keyring.git -PKG_SOURCE_DATE:=2024-09-28 -PKG_SOURCE_VERSION:=3c066ce24e80d8f537d582406930d60c7cafb251 -PKG_MIRROR_HASH:=27a52fd164d38cc57d052e0e04c95ac941ce90be6231c2eb85dcbbde9d3b916e +PKG_SOURCE_DATE:=2024-11-01 +PKG_SOURCE_VERSION:=fbae29d730f81c892f52e0ff00fe867444aeeae6 +PKG_MIRROR_HASH:=9a314756ddb61dde084f810ef056835addd9097ad26cb5e66efc6b38debc8aa0 PKG_MAINTAINER:=John Crispin PKG_LICENSE:=GPL-2.0 @@ -38,8 +38,8 @@ endef else define Package/openwrt-keyring/install $(INSTALL_DIR) $(1)/etc/opkg/keys/ - # Public usign key for unattended snapshot builds - $(INSTALL_DATA) $(PKG_BUILD_DIR)/usign/b5043e70f9a75cde $(1)/etc/opkg/keys/ + # Public usign key for 24.10 release builds + $(INSTALL_DATA) $(PKG_BUILD_DIR)/usign/d310c6f2833e97f7 $(1)/etc/opkg/keys/ endef endif diff --git a/package/system/opkg/Makefile b/package/system/opkg/Makefile index 9fea969ae96e0b..e7c45e3523135a 100644 --- a/package/system/opkg/Makefile +++ b/package/system/opkg/Makefile @@ -39,6 +39,7 @@ define Package/opkg CATEGORY:=Base system TITLE:=opkg package manager DEPENDS:=+uclient-fetch +libpthread +libubox + DEFAULT:=y if !USE_APK URL:=$(PKG_SOURCE_URL) MENU:=1 endef diff --git a/package/system/procd/Makefile b/package/system/procd/Makefile index e07f3ec81d7cc1..65cc0ad9f65f74 100644 --- a/package/system/procd/Makefile +++ b/package/system/procd/Makefile @@ -12,9 +12,9 @@ PKG_RELEASE:=1 PKG_SOURCE_PROTO:=git PKG_SOURCE_URL=$(PROJECT_GIT)/project/procd.git -PKG_MIRROR_HASH:=3d15a68fb614c4d7e129dc1bbe8a79adcb3115753c2fc95a36fd03855efc7a58 -PKG_SOURCE_DATE:=2024-10-20 -PKG_SOURCE_VERSION:=ef3ab8bc8fb18216793dd0c8106dd222c560453a +PKG_MIRROR_HASH:=41dbb5352eff931ecc78c4ce9a081645c26a7fb8dc57cdd6521a2f8d3a142567 +PKG_SOURCE_DATE:=2024-12-22 +PKG_SOURCE_VERSION:=42d3937654508b04da64969f9d764ac2ec411904 CMAKE_INSTALL:=1 PKG_LICENSE:=GPL-2.0 @@ -71,7 +71,7 @@ endef define Package/procd-seccomp SECTION:=base CATEGORY:=Base system - DEPENDS:=@SECCOMP +libubox +libblobmsg-json + DEPENDS:=@USE_SECCOMP +libubox +libblobmsg-json TITLE:=OpenWrt process seccomp helper + utrace endef diff --git a/package/system/procd/files/procd.sh b/package/system/procd/files/procd.sh index 5dc8ec42b7a4ef..0f9405a2220007 100644 --- a/package/system/procd/files/procd.sh +++ b/package/system/procd/files/procd.sh @@ -101,9 +101,11 @@ _procd_close_service() { _procd_open_trigger service_triggers _procd_close_trigger - _procd_open_data - service_data - _procd_close_data + type service_data >/dev/null 2>&1 && { + _procd_open_data + service_data + _procd_close_data + } _procd_ubus_call ${1:-set} } @@ -306,6 +308,36 @@ _procd_add_reload_interface_trigger() { _procd_close_trigger } +_procd_add_data_trigger() { + json_add_array + _procd_add_array_data "service.data.update" + + json_add_array + _procd_add_array_data "if" + + json_add_array + _procd_add_array_data "eq" "name" "$1" + shift + json_close_array + + json_add_array + _procd_add_array_data "run_script" "$@" + json_close_array + + json_close_array + _procd_add_timeout + json_close_array +} + +_procd_add_reload_data_trigger() { + local script=$(readlink "$initscript") + local name=$(basename ${script:-$initscript}) + + _procd_open_trigger + _procd_add_data_trigger $1 /etc/init.d/$name reload + _procd_close_trigger +} + _procd_add_config_trigger() { json_add_array _procd_add_array_data "$1" @@ -659,6 +691,7 @@ _procd_wrapper \ procd_add_interface_trigger \ procd_add_mount_trigger \ procd_add_reload_trigger \ + procd_add_reload_data_trigger \ procd_add_reload_interface_trigger \ procd_add_action_mount_trigger \ procd_add_reload_mount_trigger \ diff --git a/package/system/rpcd/Makefile b/package/system/rpcd/Makefile index da031db8498d0f..dd2d57f6e7af26 100644 --- a/package/system/rpcd/Makefile +++ b/package/system/rpcd/Makefile @@ -12,9 +12,9 @@ PKG_RELEASE:=1 PKG_SOURCE_PROTO:=git PKG_SOURCE_URL=$(PROJECT_GIT)/project/rpcd.git -PKG_MIRROR_HASH:=67b2cb985d8712a3e5a17ebf8c74fd35d553c8f9a4197616f9a3649a8740cc33 -PKG_SOURCE_DATE:=2024-09-17 -PKG_SOURCE_VERSION:=9f4b86e70352ab9ca6aa272d096419acc53e2390 +PKG_MIRROR_HASH:=6757b14e1b30acee50b64d70d5022ec9da6da71885df81d89b949d47790ba580 +PKG_SOURCE_DATE:=2025-09-01 +PKG_SOURCE_VERSION:=bba95191ff2f22c9118a1ba1355b83afaa277ae3 PKG_MAINTAINER:=Jo-Philipp Wich PKG_LICENSE:=ISC diff --git a/package/system/ubus/Makefile b/package/system/ubus/Makefile index bef5e622d7067f..7e23beb2325272 100644 --- a/package/system/ubus/Makefile +++ b/package/system/ubus/Makefile @@ -5,10 +5,11 @@ PKG_RELEASE:=1 PKG_SOURCE_PROTO:=git PKG_SOURCE_URL=$(PROJECT_GIT)/project/ubus.git -PKG_SOURCE_DATE:=2024-10-20 -PKG_SOURCE_VERSION:=252a9b0c1774790fb9c25735d5a09c27dba895db -PKG_MIRROR_HASH:=72c21f02710d2314447670f1f1ea1833d2961f65fea3f9f94c060dda7c9d5914 -PKG_ABI_VERSION:=$(call abi_version_str,$(PKG_SOURCE_DATE)) +PKG_SOURCE_DATE:=2025-07-02 +PKG_SOURCE_DATE_ABI:=2025-01-02 +PKG_SOURCE_VERSION:=5952b48e251c0ea76dfce97f129da6f18d889eda +PKG_MIRROR_HASH:=60edfc101eaa85976d243febc368fc419fe44283bd3a743851a6bc7975e881f0 +PKG_ABI_VERSION:=$(call abi_version_str,$(PKG_SOURCE_DATE_ABI)) CMAKE_INSTALL:=1 PKG_LICENSE:=LGPL-2.1 diff --git a/package/system/uci/Makefile b/package/system/uci/Makefile index c8f661c68434f8..6e4d8da97c755e 100644 --- a/package/system/uci/Makefile +++ b/package/system/uci/Makefile @@ -13,9 +13,10 @@ PKG_RELEASE:=1 PKG_SOURCE_URL=$(PROJECT_GIT)/project/uci.git PKG_SOURCE_PROTO:=git -PKG_SOURCE_DATE:=2023-08-10 -PKG_SOURCE_VERSION:=5781664d5087ccc4b5ab58505883231212dbedbc -PKG_MIRROR_HASH:=0ca4a29c077e85a7cfe69916c3ceb2bee98662b6268befc3c02519939647f984 +PKG_SOURCE_DATE:=2025-01-20 +PKG_SOURCE_VERSION:=16ff0badbde7e17ec3bd1f827ffe45922956cf86 +PKG_MIRROR_HASH:=e91ee4a2c0baaafe1d8ccd5321de70a8412a50323b0b27bbc7ad145e77018a22 +PKG_ABI_VERSION:=20250120 PKG_LICENSE:=LGPL-2.1 PKG_LICENSE_FILES:= @@ -33,7 +34,7 @@ define Package/libuci CATEGORY:=Libraries TITLE:=C library for the Unified Configuration Interface (UCI) DEPENDS:=+libubox - ABI_VERSION:=20130104 + ABI_VERSION:=$(PKG_ABI_VERSION) endef define Package/uci @@ -55,11 +56,12 @@ TARGET_LDFLAGS += -L$(STAGING_DIR)/usr/lib CMAKE_OPTIONS += \ -DLUAPATH=/usr/lib/lua \ + -DABIVERSION=$(PKG_ABI_VERSION) \ $(if $(DEBUG),-DUCI_DEBUG=ON) define Package/libuci/install $(INSTALL_DIR) $(1)/lib - $(CP) $(PKG_BUILD_DIR)/libuci.so* $(1)/lib/ + $(CP) $(PKG_BUILD_DIR)/libuci.so.* $(1)/lib/ endef define Package/libuci-lua/install diff --git a/package/utils/bcm27xx-utils/Makefile b/package/utils/bcm27xx-utils/Makefile index 8f5d91da8f1357..f1aafd666a673e 100644 --- a/package/utils/bcm27xx-utils/Makefile +++ b/package/utils/bcm27xx-utils/Makefile @@ -3,13 +3,13 @@ include $(TOPDIR)/rules.mk PKG_NAME:=bcm27xx-utils -PKG_VERSION:=2024.10.25 +PKG_VERSION:=2025.03.14 PKG_RELEASE:=1 PKG_SOURCE_PROTO:=git PKG_SOURCE_URL:=https://github.com/raspberrypi/utils.git -PKG_SOURCE_VERSION:=6a2a6becebbc38fde34a94386457ac8210f9119b -PKG_MIRROR_HASH:=a775c7ffb9fac2d798ec8e0a4c7707eb7133cbc9c4418a1cf9434f87c42c01bb +PKG_SOURCE_VERSION:=685afa8c0d6f2310eaefe1b528627a8bf3154ca0 +PKG_MIRROR_HASH:=04528742fc5b55ba31f448a27588a9df707cbcc27823c1d219b7f877dd4ac200 PKG_FLAGS:=nonshared PKG_BUILD_FLAGS:=no-lto diff --git a/package/utils/bcm27xx-utils/patches/0002-cmake-disable-piolib.patch b/package/utils/bcm27xx-utils/patches/0002-cmake-disable-piolib.patch new file mode 100644 index 00000000000000..37f8a3a7e7ba9c --- /dev/null +++ b/package/utils/bcm27xx-utils/patches/0002-cmake-disable-piolib.patch @@ -0,0 +1,24 @@ +From 5249e68da31d11e0beaf9fd76a6d17ac04198b26 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= +Date: Sat, 28 Dec 2024 09:42:00 +0100 +Subject: [PATCH] cmake: disable piolib +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Álvaro Fernández Rojas +--- + CMakeLists.txt | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -10,7 +10,7 @@ add_subdirectory(otpset) + add_subdirectory(overlaycheck) + add_subdirectory(ovmerge) + add_subdirectory(pinctrl) +-add_subdirectory(piolib) ++# add_subdirectory(piolib) + add_subdirectory(raspinfo) + add_subdirectory(vcgencmd) + add_subdirectory(vclog) diff --git a/package/utils/busybox/Makefile b/package/utils/busybox/Makefile index 4ef470df755890..e3b9f256e0c797 100644 --- a/package/utils/busybox/Makefile +++ b/package/utils/busybox/Makefile @@ -48,7 +48,7 @@ define Package/busybox/Default MAINTAINER:=Felix Fietkau TITLE:=Core utilities for embedded Linux URL:=http://busybox.net/ - DEPENDS:=+BUSYBOX_CONFIG_PAM:libpam +BUSYBOX_CONFIG_NTPD:jsonfilter + DEPENDS:=+BUSYBOX_CONFIG_PAM:libpam +BUSYBOX_CONFIG_NTPD:jsonfilter +(USE_GLIBC&&BUSYBOX_CONFIG_FEATURE_MOUNT_NFS)||(USE_GLIBC&&BUSYBOX_CONFIG_FEATURE_INETD_RPC):libtirpc USERID:=ntp=123:ntp=123 endef @@ -104,6 +104,13 @@ ifeq ($(CONFIG_USE_GLIBC),y) LDLIBS += $(call BUSYBOX_IF_ENABLED,NSLOOKUP,resolv) endif +ifneq ($(CONFIG_BUSYBOX_$(BUSYBOX_SYM)_FEATURE_MOUNT_NFS)$(CONFIG_BUSYBOX_$(BUSYBOX_SYM)_FEATURE_INETD_RPC),) +ifndef CONFIG_USE_MUSL + TARGET_CFLAGS += -I$(STAGING_DIR)/usr/include/tirpc + LDLIBS += tirpc +endif +endif + ifeq ($(BUILD_VARIANT),selinux) LDLIBS += selinux sepol endif @@ -111,7 +118,7 @@ endif MAKE_VARS := MAKE_FLAGS += \ EXTRA_CFLAGS="$(TARGET_CFLAGS) $(TARGET_CPPFLAGS)" \ - EXTRA_LDFLAGS="$(TARGET_LDFLAGS)" \ + EXTRA_LDFLAGS="$(TARGET_LDFLAGS) $(TARGET_CFLAGS)" \ LDLIBS="$(LDLIBS)" \ LD="$(TARGET_CC)" \ SKIP_STRIP=y diff --git a/package/utils/busybox/patches/600-loginutils-login.c-libselinux-get_default_context-ex.patch b/package/utils/busybox/patches/600-loginutils-login.c-libselinux-get_default_context-ex.patch new file mode 100644 index 00000000000000..8c26ee001bbe9b --- /dev/null +++ b/package/utils/busybox/patches/600-loginutils-login.c-libselinux-get_default_context-ex.patch @@ -0,0 +1,51 @@ +From 850a6d031039237b0b13d8fab9f10a7cd4752907 Mon Sep 17 00:00:00 2001 +From: Dominick Grift +Date: Sat, 5 Apr 2025 13:40:26 +0200 +Subject: [PATCH] loginutils/login.c: libselinux get_default_context() expects + seuser + +Use getseuserbyname() to get the seuser associated with username and use that +instead with get_default_context() + +>From get_default_context.3: +"These functions takes a SELinux user identity that must be defined in the SELinux policy as their input, not a Linux username." + +Fixes: #19075 +Upstream-Status: Submitted [https://lists.busybox.net/pipermail/busybox/2025-April/091407.html] +Signed-off-by: Dominick Grift +--- + loginutils/login.c | 11 ++++++++++- + 1 file changed, 10 insertions(+), 1 deletion(-) + +--- a/loginutils/login.c ++++ b/loginutils/login.c +@@ -183,12 +183,16 @@ static void die_if_nologin(void) + static void initselinux(char *username, char *full_tty, + security_context_t *user_sid) + { ++ char *seuser = NULL, *level = NULL; + security_context_t old_tty_sid, new_tty_sid; + + if (!is_selinux_enabled()) + return; + +- if (get_default_context(username, NULL, user_sid)) { ++ if (getseuserbyname(username, &seuser, &level)) { ++ bb_error_msg_and_die("can't get seuser for %s", username); ++ } ++ if (get_default_context(seuser, NULL, user_sid)) { + bb_error_msg_and_die("can't get SID for %s", username); + } + if (getfilecon(full_tty, &old_tty_sid) < 0) { +@@ -201,6 +205,11 @@ static void initselinux(char *username, + if (setfilecon(full_tty, new_tty_sid) != 0) { + bb_perror_msg_and_die("chsid(%s, %s) failed", full_tty, new_tty_sid); + } ++ ++ if (ENABLE_FEATURE_CLEAN_UP) { ++ free(seuser); ++ free(level); ++ } + } + #endif + diff --git a/package/utils/debugcc/Makefile b/package/utils/debugcc/Makefile index 3e26cea7e510c0..c3821cd8c6eb68 100644 --- a/package/utils/debugcc/Makefile +++ b/package/utils/debugcc/Makefile @@ -11,6 +11,7 @@ PKG_MIRROR_HASH:=4cd7a770a05db28f496a60eb9fe015a4af677bba05053b4d4be21adcf95e52e PKG_LICENSE:=BSD-3-Clause PKG_LICENSE_FILES:=LICENSE +PKG_FLAGS:=nonshared PKG_MAINTAINER:=Christian Marangi diff --git a/package/utils/fritz-tools/Makefile b/package/utils/fritz-tools/Makefile index 6e20b56ff8a7ca..b43fe20e9e7555 100644 --- a/package/utils/fritz-tools/Makefile +++ b/package/utils/fritz-tools/Makefile @@ -1,7 +1,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=fritz-tools -PKG_RELEASE:=2 +PKG_RELEASE:=3 CMAKE_INSTALL:=1 include $(INCLUDE_DIR)/package.mk diff --git a/package/utils/fritz-tools/src/fritz_cal_extract.c b/package/utils/fritz-tools/src/fritz_cal_extract.c index 2978d86e0cc48e..c4547bc7e05d26 100644 --- a/package/utils/fritz-tools/src/fritz_cal_extract.c +++ b/package/utils/fritz-tools/src/fritz_cal_extract.c @@ -8,6 +8,9 @@ * that is Not copyrighted -- provided to the public domain * Version 1.4 11 December 2005 Mark Adler * + * Modifications to also handle calibration data in reversed byte order + * (c) 2024 by . + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or @@ -28,106 +31,126 @@ #include #include #include +#include #include #include #include #include "zlib.h" #define CHUNK 1024 +#define DEFAULT_BUFFERSIZE (129 * 1024) + +#define MIN(a,b) (((a)<(b))?(a):(b)) -static inline size_t special_min(size_t a, size_t b) +/* Reverse byte order in data buffer. + * 'top' is position of last valid data byte = (datasize - 1) + */ +static void buffer_reverse(unsigned char *data, unsigned int top) { - return a == 0 ? b : (a < b ? a : b); + register unsigned char swapbyte; + const unsigned int center = top / 2; + + for (unsigned int bottom = 0; bottom < center; ++bottom, --top) { + swapbyte = data[bottom]; + data[bottom] = data[top]; + data[top] = swapbyte; + } } -/* Decompress from file source to file dest until stream ends or EOF. - inf() returns Z_OK on success, Z_MEM_ERROR if memory could not be - allocated for processing, Z_DATA_ERROR if the deflate data is - invalid or incomplete, Z_VERSION_ERROR if the version of zlib.h and - the version of the library linked do not match, or Z_ERRNO if there - is an error reading or writing the files. */ -static int inf(FILE *source, FILE *dest, size_t limit, size_t skip) +/* Decompress from file source to data buffer until stream ends + * or *limit bytes have been written to buffer. + * + * On call, 'limit' must reference a variable containing the intended + * number of bytes to retrieve (must be <= allocated buffer size). + * + * Return values (success): + * Z_END_STREAM if complete data was retrieved (*limit == size of complete data), + * or Z_OK if data was retrieved up to limit (*limit == original value). + * + * Return values (failure): + * Z_MEM_ERROR if memory could not be allocated for processing, + * Z_DATA_ERROR if the deflate data is invalid or incomplete, + * Z_VERSION_ERROR if the version of zlib.h and the version of the + * library linked do not match, or + * Z_ERRNO if there is an error reading or writing the files. + */ +static int inflate_to_buffer(FILE *source, unsigned char *buf, size_t *limit) { - int ret; - size_t have; - z_stream strm; - unsigned char in[CHUNK]; - unsigned char out[CHUNK]; - - /* allocate inflate state */ - strm.zalloc = Z_NULL; - strm.zfree = Z_NULL; - strm.opaque = Z_NULL; - strm.avail_in = 0; - strm.next_in = Z_NULL; - ret = inflateInit(&strm); - if (ret != Z_OK) - return ret; - - /* decompress until deflate stream ends or end of file */ - do { - strm.avail_in = fread(in, 1, CHUNK, source); - if (ferror(source)) { - (void)inflateEnd(&strm); - return Z_ERRNO; - } - if (strm.avail_in == 0) - break; - strm.next_in = in; - - /* run inflate() on input until output buffer not full */ - do { - strm.avail_out = CHUNK; - strm.next_out = out; - ret = inflate(&strm, Z_NO_FLUSH); - assert(ret != Z_STREAM_ERROR); /* state not clobbered */ - switch (ret) { - case Z_NEED_DICT: - ret = Z_DATA_ERROR; /* and fall through */ - case Z_DATA_ERROR: - case Z_MEM_ERROR: - (void)inflateEnd(&strm); - return ret; - } - have = special_min(limit, CHUNK - strm.avail_out) - skip; - if (fwrite(&out[skip], have, 1, dest) != 1 || ferror(dest)) { - (void)inflateEnd(&strm); - return Z_ERRNO; - } - skip = 0; - limit -= have; - } while (strm.avail_out == 0 && limit > 0); - - /* done when inflate() says it's done */ - } while (ret != Z_STREAM_END && limit > 0); - - /* clean up and return */ - (void)inflateEnd(&strm); - return (limit == 0 ? Z_OK : (ret == Z_STREAM_END ? Z_OK : Z_DATA_ERROR)); + int ret; + z_stream strm; + unsigned char in[CHUNK]; + + /* allocate inflate state */ + strm.zalloc = Z_NULL; + strm.zfree = Z_NULL; + strm.opaque = Z_NULL; + strm.avail_in = 0; + strm.next_in = Z_NULL; + ret = inflateInit(&strm); + if (ret != Z_OK) + return ret; + + /* set data buffer as stream output */ + strm.avail_out = *limit; + strm.next_out = buf; + + /* decompress until deflate stream ends or end of file */ + do { + strm.avail_in = fread(in, 1, CHUNK, source); + if (ferror(source)) { + (void)inflateEnd(&strm); + return Z_ERRNO; + } + if (strm.avail_in == 0) + break; + strm.next_in = in; + + /* run inflate(), fill data buffer with all available output */ + ret = inflate(&strm, Z_FINISH); + assert(ret != Z_STREAM_ERROR); /* state not clobbered */ + + switch (ret) { + case Z_NEED_DICT: + ret = Z_DATA_ERROR; /* and fall through */ + case Z_DATA_ERROR: + case Z_MEM_ERROR: + (void)inflateEnd(&strm); + return ret; + } + /* done when inflate() says it's done or limit reached */ + } while (ret != Z_STREAM_END && strm.avail_out > 0); + + /* set limit to end of retrieved data */ + assert(strm.total_out <= *limit); + *limit = strm.total_out; + + /* clean up and return */ + (void)inflateEnd(&strm); + return (ret == Z_STREAM_END ? Z_STREAM_END : (strm.avail_out == 0 ? Z_OK : Z_DATA_ERROR)); } /* report a zlib or i/o error */ static void zerr(int ret) { - switch (ret) { - case Z_ERRNO: - if (ferror(stdin)) - fputs("error reading stdin\n", stderr); - if (ferror(stdout)) - fputs("error writing stdout\n", stderr); - break; - case Z_STREAM_ERROR: - fputs("invalid compression level\n", stderr); - break; - case Z_DATA_ERROR: - fputs("invalid or incomplete deflate data\n", stderr); - break; - case Z_MEM_ERROR: - fputs("out of memory\n", stderr); - break; - case Z_VERSION_ERROR: - fputs("zlib version mismatch!\n", stderr); - } + switch (ret) { + case Z_ERRNO: + if (ferror(stdin)) + fputs("error reading stdin\n", stderr); + if (ferror(stdout)) + fputs("error writing stdout\n", stderr); + break; + case Z_STREAM_ERROR: + fputs("invalid compression level\n", stderr); + break; + case Z_DATA_ERROR: + fputs("invalid or incomplete deflate data\n", stderr); + break; + case Z_MEM_ERROR: + fputs("out of memory\n", stderr); + break; + case Z_VERSION_ERROR: + fputs("zlib version mismatch!\n", stderr); + } } static unsigned int get_num(char *str) @@ -140,7 +163,8 @@ static unsigned int get_num(char *str) static void usage(void) { - fprintf(stderr, "Usage: fritz_cal_extract [-s seek offset] [-i skip] [-o output file] [-l limit] [infile] -e entry_id\n" + fprintf(stderr, "Usage: fritz_cal_extract -e entry_id [-s seek offset] [-l limit]\n" + "\t[-r reverse extracted data] [-i skip n bytes] [-o output file] [infile]\n" "Finds and extracts zlib compressed calibration data in the EVA loader\n"); exit(EXIT_FAILURE); } @@ -154,15 +178,18 @@ struct cal_entry { int main(int argc, char **argv) { struct cal_entry cal = { .len = 0 }; + unsigned char *buf = NULL; FILE *in = stdin; FILE *out = stdout; + size_t datasize = DEFAULT_BUFFERSIZE; size_t limit = 0, skip = 0; int initial_offset = 0; int entry = -1; + bool reversed = false, limit_was_set = true; int ret; int opt; - while ((opt = getopt(argc, argv, "s:e:o:l:i:")) != -1) { + while ((opt = getopt(argc, argv, "s:e:o:l:i:r")) != -1) { switch (opt) { case 's': initial_offset = (int)get_num(optarg); @@ -199,6 +226,9 @@ int main(int argc, char **argv) goto out_bad; } break; + case 'r': + reversed = true; + break; default: /* '?' */ usage(); } @@ -243,11 +273,50 @@ int main(int argc, char **argv) goto out_bad; } - ret = inf(in, out, limit, skip); - if (ret == Z_OK) - goto out; + /* Set boundaries. Only keep default datasize if we need complete data + * for reversal and didn't set a higher limit. */ + if (!limit) { + limit_was_set = false; + limit = datasize - skip; + } + datasize = (reversed && datasize >= limit + skip) ? datasize : (limit + skip); + + /* Create data buffer. */ + buf = malloc(datasize); + assert(buf != NULL); + + ret = inflate_to_buffer(in, buf, &datasize); + + if ((reversed || !limit_was_set) && ret != Z_STREAM_END) { /* didn't read to stream end */ + fprintf(stderr, "Failed: Data exceeds buffer size of %u. Refusing to reverse" + " or store incomplete data." + " Use a higher limit [-l] to increase buffer size.\n", + (unsigned int) datasize); + goto out_bad; + } + + ret = (ret == Z_STREAM_END) ? Z_OK : ret; /* normalize return value */ + if (ret != Z_OK) { + zerr(ret); + goto out_bad; + } + + if (reversed) + buffer_reverse(buf, datasize - 1); + + if (datasize <= skip) { + fprintf(stderr, "Failed to skip %u bytes, total data size is %u!\n", + (unsigned int)skip, (unsigned int)datasize); + goto out_bad; + } + + limit = MIN(limit, datasize - skip); + if (fwrite(&buf[skip], limit, 1, out) != 1 || ferror(out)) { + fprintf(stderr, "Failed to write data buffer to output file"); + goto out_bad; + } - zerr(ret); + goto out; out_bad: ret = EXIT_FAILURE; @@ -257,5 +326,6 @@ int main(int argc, char **argv) fclose(in); if (out) fclose(out); + free(buf); return ret; } diff --git a/package/utils/jsonfilter/Makefile b/package/utils/jsonfilter/Makefile index d249ea1a369da7..928ba1207b314e 100644 --- a/package/utils/jsonfilter/Makefile +++ b/package/utils/jsonfilter/Makefile @@ -5,9 +5,9 @@ PKG_RELEASE:=1 PKG_SOURCE_PROTO:=git PKG_SOURCE_URL=$(PROJECT_GIT)/project/jsonpath.git -PKG_SOURCE_DATE:=2024-01-23 -PKG_SOURCE_VERSION:=594cfa86469c005972ba750614f5b3f1af84d0f6 -PKG_MIRROR_HASH:=2f455f04fbfcdb4c81cccd23475b47395f847db44aa4bd9a1007b9aa0ab7fd19 +PKG_SOURCE_DATE:=2025-04-18 +PKG_SOURCE_VERSION:=8a86fb78235b5d7925b762b7b0934517890cc034 +PKG_MIRROR_HASH:=06b763387d00faae0e62af68626588ff2b8f12e0e6821950ae5422033df32757 CMAKE_INSTALL:=1 PKG_MAINTAINER:=Jo-Philipp Wich diff --git a/package/utils/mdadm/Makefile b/package/utils/mdadm/Makefile index c2778fe351cb3a..b521daaefc92b2 100644 --- a/package/utils/mdadm/Makefile +++ b/package/utils/mdadm/Makefile @@ -9,7 +9,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=mdadm PKG_VERSION:=4.3 -PKG_RELEASE:=1 +PKG_RELEASE:=2 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz PKG_SOURCE_URL:=@KERNEL/linux/utils/raid/mdadm diff --git a/package/utils/mdadm/patches/060-gcc14.patch b/package/utils/mdadm/patches/060-gcc14.patch new file mode 100644 index 00000000000000..545a40ac0ac563 --- /dev/null +++ b/package/utils/mdadm/patches/060-gcc14.patch @@ -0,0 +1,24 @@ +From 8bda86099089b44129ef6206764f9de47a45f0db Mon Sep 17 00:00:00 2001 +From: Alexander Kanavin +Date: Tue, 12 Mar 2024 11:01:50 +0100 +Subject: [PATCH] util.c: add limits.h include for NAME_MAX definition + +Add limits.h include for NAME_MAX definition. + +Signed-off-by: Alexander Kanavin +Signed-off-by: Mariusz Tkaczyk +--- + util.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/util.c ++++ b/util.c +@@ -36,7 +36,7 @@ + #include + #include + #include +- ++#include + + /* + * following taken from linux/blkpg.h because they aren't diff --git a/package/utils/mtd-utils/Makefile b/package/utils/mtd-utils/Makefile index 046572e83b415b..0dc88312514641 100644 --- a/package/utils/mtd-utils/Makefile +++ b/package/utils/mtd-utils/Makefile @@ -65,12 +65,20 @@ CONFIGURE_ARGS += \ --without-lzo \ --without-zlib +define Package/ubi-utils/conffiles +/etc/config/ubihealthd +endef + define Package/ubi-utils/install $(INSTALL_DIR) $(1)/usr/sbin $(INSTALL_BIN) \ - $(PKG_INSTALL_DIR)/usr/sbin/{ubiattach,ubicrc32,ubiblock,ubidetach,ubiformat,ubimkvol} $(1)/usr/sbin/ + $(PKG_INSTALL_DIR)/usr/sbin/{ubiattach,ubicrc32,ubiblock,ubidetach,ubiformat,ubihealthd} $(1)/usr/sbin/ $(INSTALL_BIN) \ - $(PKG_INSTALL_DIR)/usr/sbin/{ubinfo,ubinize,ubirename,ubirmvol,ubirsvol,ubiupdatevol} $(1)/usr/sbin/ + $(PKG_INSTALL_DIR)/usr/sbin/{ubimkvol,ubinfo,ubinize,ubirename,ubirmvol,ubirsvol,ubiupdatevol} $(1)/usr/sbin/ + $(INSTALL_DIR) $(1)/etc/init.d + $(INSTALL_BIN) ./files/ubihealthd.init $(1)/etc/init.d/ubihealthd + $(INSTALL_DIR) $(1)/etc/uci-defaults + $(INSTALL_DATA) ./files/ubihealthd.defaults $(1)/etc/uci-defaults/ubihealthd endef define Package/nand-utils/install diff --git a/package/utils/mtd-utils/files/ubihealthd.defaults b/package/utils/mtd-utils/files/ubihealthd.defaults new file mode 100644 index 00000000000000..5222961bd48ddb --- /dev/null +++ b/package/utils/mtd-utils/files/ubihealthd.defaults @@ -0,0 +1,18 @@ +#!/bin/sh + +[ -e "/etc/config/ubihealthd" ] && exit 0 +[ ! -e "/sys/class/ubi" ] && exit 0 + +touch "/etc/config/ubihealthd" + +for ubidev in /sys/class/ubi/*/total_eraseblocks; do + ubidev="${ubidev%/*}" + ubidev="${ubidev##*/}" + uci batch < +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=omnia-eeprom +PKG_VERSION:=0.1 +PKG_RELEASE:=1 + +PKG_SOURCE_SUBDIR:=$(PKG_NAME)-v$(PKG_VERSION) +PKG_SOURCE:=$(PKG_NAME)-v$(PKG_VERSION).tar.bz2 +PKG_SOURCE_URL:=https://gitlab.nic.cz/turris/omnia-eeprom/-/archive/v$(PKG_VERSION)/ +PKG_HASH:=6f949d0b8080adca8bae088774ce615b563ba6ec2807cce97ee6769b4eee7bbf +PKG_FLAGS:=nonshared + +PKG_MAINTAINER:=Marek Behun +PKG_LICENSE:=GPL-2.0-or-later + +PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_SOURCE_SUBDIR) + +include $(INCLUDE_DIR)/package.mk + +define Package/omnia-eeprom + SECTION:=utils + CATEGORY:=Utilities + URL:=https://gitlab.nic.cz/turris/omnia-eeprom + TITLE:=CZ.NIC Turris Omnia EEPROM accessing utility + DEPENDS:=@TARGET_mvebu_cortexa9 +kmod-eeprom-at24 +endef + +define Package/omnia-eeprom/description +This package contains the omnia-eeprom utility, which allows you to display +and update EEPROM fields on the Turris Omnia router. +The EEPROM is normally not meant to be updated by users, but there are some +exceptions where it might be useful. +One such example is to change the DDR3 speed from the default 1600K mode to +1333H mode, in order to solve random crashes that occur on some boards with +newer versions of the U-Boot bootloader (because of bugs in newer versions of +the DDR training algorithm). +endef + +MAKE_VARS += OMNIA_EEPROM_VERSION="v$(PKG_VERSION)" + +TARGET_CFLAGS += -Wall + +Build/Compile = $(Build/Compile/Default) + +define Package/omnia-eeprom/install + $(INSTALL_DIR) $(1)/usr/bin + $(INSTALL_BIN) $(PKG_BUILD_DIR)/omnia-eeprom $(1)/usr/bin/ +endef + +$(eval $(call BuildPackage,omnia-eeprom)) diff --git a/package/utils/omnia-mcutool/Makefile b/package/utils/omnia-mcutool/Makefile index 2eca0cf1902474..66f8ffc6d4a86a 100644 --- a/package/utils/omnia-mcutool/Makefile +++ b/package/utils/omnia-mcutool/Makefile @@ -27,7 +27,7 @@ define Package/omnia-mcutool CATEGORY:=Utilities URL:=https://gitlab.nic.cz/turris/$(PKG_NAME) TITLE:=CZ.NIC Turris Omnia MCU utility - DEPENDS:=+libopenssl +omnia-mcu-firmware @TARGET_mvebu_cortexa9_DEVICE_cznic_turris-omnia + DEPENDS:=+libopenssl +omnia-mcu-firmware endef define Package/omnia-mcutool/description diff --git a/package/utils/ucode/Makefile b/package/utils/ucode/Makefile index 6ee0cf2a1d56b9..8ae1b91c1f213a 100644 --- a/package/utils/ucode/Makefile +++ b/package/utils/ucode/Makefile @@ -8,17 +8,18 @@ include $(TOPDIR)/rules.mk PKG_NAME:=ucode -PKG_RELEASE:=3 +PKG_RELEASE:=1 PKG_SOURCE_PROTO:=git PKG_SOURCE_URL=https://github.com/jow-/ucode.git -PKG_SOURCE_DATE:=2024-07-22 -PKG_SOURCE_VERSION:=b610860dd4a0591ff586dd71a50f556a0ddafced -PKG_MIRROR_HASH:=a5ec51dd989174422d3b19b022ff4f863d57eb559c9f08d54c0d10651f598357 +PKG_SOURCE_DATE:=2025-07-18 +PKG_SOURCE_VERSION:=3f64c8089bf3ea4847c96b91df09fbfcaec19e1d +PKG_MIRROR_HASH:=55fbff7c527e1fadbda2e038636f39419649841ee63a5f3cdb50b9714b13420c PKG_MAINTAINER:=Jo-Philipp Wich PKG_LICENSE:=ISC PKG_ABI_VERSION:=20230711 +PKG_BUILD_DEPENDS:=libmd HOST_BUILD_DEPENDS:=libjson-c/host include $(INCLUDE_DIR)/package.mk @@ -51,7 +52,8 @@ CMAKE_HOST_OPTIONS += \ -DUCI_SUPPORT=OFF \ -DULOOP_SUPPORT=OFF \ -DDEBUG_SUPPORT=ON \ - -DLOG_SUPPORT=OFF + -DLOG_SUPPORT=OFF \ + -DDIGEST_SUPPORT=OFF define Package/ucode/default @@ -178,6 +180,10 @@ $(eval $(call UcodeModule, \ uloop, ULOOP_SUPPORT, +libubox, \ The uloop module allows ucode scripts to interact with OpenWrt uloop event loop implementation.)) +$(eval $(call UcodeModule, \ + digest, DIGEST_SUPPORT, , \ + The digest module allows ucode scripts to use libmd digests.)) + $(eval $(call BuildPackage,libucode)) $(eval $(call BuildPackage,ucode)) diff --git a/package/utils/ucode/patches/100-nl80211_vif_radio_mask.patch b/package/utils/ucode/patches/100-nl80211_vif_radio_mask.patch deleted file mode 100644 index 22e05f7c620518..00000000000000 --- a/package/utils/ucode/patches/100-nl80211_vif_radio_mask.patch +++ /dev/null @@ -1,40 +0,0 @@ ---- a/include/linux/nl80211.h -+++ b/include/linux/nl80211.h -@@ -2868,6 +2868,9 @@ enum nl80211_commands { - * nested item, it contains attributes defined in - * &enum nl80211_if_combination_attrs. - * -+ * @NL80211_ATTR_VIF_RADIO_MASK: Bitmask of allowed radios (u32). -+ * A value of 0 means all radios. -+ * - * @NUM_NL80211_ATTR: total number of nl80211_attrs available - * @NL80211_ATTR_MAX: highest attribute number currently defined - * @__NL80211_ATTR_AFTER_LAST: internal use -@@ -3416,6 +3419,8 @@ enum nl80211_attrs { - NL80211_ATTR_WIPHY_RADIOS, - NL80211_ATTR_WIPHY_INTERFACE_COMBINATIONS, - -+ NL80211_ATTR_VIF_RADIO_MASK, -+ - /* add attributes here, update the policy in nl80211.c */ - - __NL80211_ATTR_AFTER_LAST, ---- a/lib/nl80211.c -+++ b/lib/nl80211.c -@@ -829,7 +829,7 @@ static const uc_nl_nested_spec_t nl80211 - - static const uc_nl_nested_spec_t nl80211_msg = { - .headsize = 0, -- .nattrs = 128, -+ .nattrs = 129, - .attrs = { - { NL80211_ATTR_4ADDR, "4addr", DT_U8, 0, NULL }, - { NL80211_ATTR_AIRTIME_WEIGHT, "airtime_weight", DT_U16, 0, NULL }, -@@ -959,6 +959,7 @@ static const uc_nl_nested_spec_t nl80211 - { NL80211_ATTR_MAX_AP_ASSOC_STA, "max_ap_assoc", DT_U16, 0, NULL }, - { NL80211_ATTR_SURVEY_INFO, "survey_info", DT_NESTED, 0, &nl80211_survey_info_nla }, - { NL80211_ATTR_WIPHY_RADIOS, "radios", DT_NESTED, DF_MULTIPLE|DF_AUTOIDX, &nl80211_wiphy_radio_nla }, -+ { NL80211_ATTR_VIF_RADIO_MASK, "vif_radio_mask", DT_U32, 0, NULL }, - } - }; - diff --git a/package/utils/ucode/patches/100-ucode-add-padding-to-uc_resource_ext_t.patch b/package/utils/ucode/patches/100-ucode-add-padding-to-uc_resource_ext_t.patch new file mode 100644 index 00000000000000..f8a8cf29ccd67d --- /dev/null +++ b/package/utils/ucode/patches/100-ucode-add-padding-to-uc_resource_ext_t.patch @@ -0,0 +1,21 @@ +From: Felix Fietkau +Date: Mon, 21 Jul 2025 21:07:17 +0200 +Subject: [PATCH] ucode: add padding to uc_resource_ext_t + +This ensures that user data structures tied to the ext resource are aligned +to 64 bit, as usually guaranteed by the memory allocator. + +Signed-off-by: Felix Fietkau +--- + +--- a/include/ucode/types.h ++++ b/include/ucode/types.h +@@ -213,6 +213,8 @@ typedef struct { + uint32_t persistent:1; + uint32_t uvcount:8; + uint32_t datasize:20; ++ ++ uint32_t _pad; + } uc_resource_ext_t; + + uc_declare_vector(uc_resource_types_t, uc_resource_type_t *); diff --git a/package/utils/yafut/Makefile b/package/utils/yafut/Makefile index 1e2ec7bc024d87..e3f240f75454df 100644 --- a/package/utils/yafut/Makefile +++ b/package/utils/yafut/Makefile @@ -11,6 +11,7 @@ PKG_SOURCE_VERSION:=38439f8a53d33b14744bc8f938662670b9d3e361 PKG_LICENSE:=GPL-2.0 PKG_LICENSE_FILES:=LICENSE +PKG_FLAGS:=nonshared include $(INCLUDE_DIR)/package.mk include $(INCLUDE_DIR)/cmake.mk diff --git a/rules.mk b/rules.mk index 973fd1cbb90ea3..54df407fca4b95 100644 --- a/rules.mk +++ b/rules.mk @@ -20,6 +20,11 @@ endif export TMP_DIR:=$(TOPDIR)/tmp export TMPDIR:=$(TMP_DIR) +##@ +# @brief Strip quotes `"` and pounds `#` from string. +# +# @param 1: String. +## qstrip=$(strip $(subst ",,$(1))) #")) @@ -27,8 +32,23 @@ empty:= space:= $(empty) $(empty) comma:=, pound:=\# +##@ +# @brief Merge strings by removing spaces. +# +# @param 1: String. +## merge=$(subst $(space),,$(1)) +##@ +# @brief Get hash sum of variable list. +# +# @param 1: List of variable names. +## confvar=$(shell echo '$(foreach v,$(1),$(v)=$(subst ','\'',$($(v))))' | $(MKHASH) md5) +##@ +# @brief Strip last extension from file name. +# +# @param 1: File name. +## strip_last=$(patsubst %.$(lastword $(subst .,$(space),$(1))),%,$(1)) paren_left = ( @@ -51,9 +71,18 @@ __tr_head = $(subst $(paren_left)subst,$(paren_left)subst$(space),$(__tr_head_st __tr_tail = $(subst $(space),,$(foreach cv,$(1),$(paren_right))) __tr_template = $(__tr_head)$$(1)$(__tr_tail) +##@ +# @brief Convert string characters to upper. +## $(eval toupper = $(call __tr_template,$(chars_lower),$(chars_upper))) +##@ +# @brief Convert string characters to lower. +## $(eval tolower = $(call __tr_template,$(chars_upper),$(chars_lower))) +##@ +# @brief Abbreviate version. Truncate to 8 characters. +## version_abbrev = $(if $(if $(CHECK),,$(DUMP)),$(1),$(shell printf '%.8s' $(1))) _SINGLE=export MAKEFLAGS=$(space); @@ -102,6 +131,13 @@ endif DEFAULT_SUBDIR_TARGETS:=clean download prepare compile update refresh prereq dist distcheck configure check check-depends +##@ +# @brief Create default targets. +# +# Targets are created from @DEFAULT_SUBDIR_TARGETS and input argument lists. +# +# @param 1: Additional targets list. +## define DefaultTargets $(foreach t,$(DEFAULT_SUBDIR_TARGETS) $(1), .$(t): @@ -371,16 +407,28 @@ export BISON_PKGDATADIR:=$(STAGING_DIR_HOST)/share/bison export HOST_GNULIB_SRCDIR:=$(STAGING_DIR_HOST)/share/gnulib export M4:=$(STAGING_DIR_HOST)/bin/m4 +##@ +# @brief Slugify variable name and prepend suffix. +## define shvar V_$(subst .,_,$(subst -,_,$(subst /,_,$(1)))) endef +##@ +# @brief Create and export variable, set to function result. +# +# @param 1: Function name. Used as variable name, prepended with `V_`. +## define shexport export $(call shvar,$(1))=$$(call $(1)) endef +##@ +# @brief Support 64 bit tine in C code. +# # Test support for 64-bit time with C code from largefile.m4 provided by GNU Gnulib -# the value is 'y' when successful and '' otherwise +# the value is `y` when successful and `` otherwise +## define YEAR_2038 $(shell \ mkdir -p $(TMP_DIR); \ @@ -392,9 +440,12 @@ $(shell \ ) endef -# Execute commands under flock -# $(1) => The shell expression. -# $(2) => The lock name. If not given, the global lock will be used. +##@ +# @brief Execute commands under flock +# +# @param 1: The shell expression. +# @param 2: The lock name. If not given, the global lock will be used. +## ifneq ($(wildcard $(STAGING_DIR_HOST)/bin/flock),) define locked SHELL= \ @@ -406,10 +457,14 @@ else locked=$(1) endif -# Recursively copy paths into another directory, purge dangling + +##@ +# @brief Recursively copy paths into another directory, purge dangling # symlinks before. -# $(1) => File glob expression -# $(2) => Destination directory +# +# @param 1: File glob expression. +# @param 1: Destination directory. +## define file_copy for src_dir in $(sort $(foreach d,$(wildcard $(1)),$(dir $(d)))); do \ ( cd $$src_dir; find -type f -or -type d ) | \ @@ -424,19 +479,30 @@ define file_copy $(CP) $(1) $(2) endef -# Calculate sha256sum of any plain file within a given directory -# $(1) => Input directory -# $(2) => If set, recurse into subdirectories +##@ +# @brief Calculate sha256sum of any plain file within a given directory. +# +# @param 1: Input directory. +# @param 2: If set, recurse into subdirectories. +## define sha256sums (cd $(1); find . $(if $(2),,-maxdepth 1) -type f -not -name 'sha256sums' -printf "%P\n" | sort | \ xargs -r $(MKHASH) -n sha256 | sed -ne 's!^\(.*\) \(.*\)$$!\1 *\2!p' > sha256sums) endef -# file extension +##@ +# @brief Retrieve file extension. +# +# @param 1: File name. +## ext=$(word $(words $(subst ., ,$(1))),$(subst ., ,$(1))) -# Count Git commits of a package -# $(1) => if non-empty: count commits since last ": [uU]pdate to " or ": [bB]ump to " in commit message +##@ +# @brief Count Git commits of a package. +# +# @param 1: if non-empty: count commits since last ": [uU]pdate to " +# or ": [bB]ump to " in commit message. +## define commitcount $(shell \ if git log -1 >/dev/null 2>/dev/null; then \ @@ -458,6 +524,11 @@ $(shell \ ) endef +##@ +# @brief Get ABI version string, stripping `-`, `_` and `.`. +# +# @param 1: Version string. +## abi_version_str = $(subst -,,$(subst _,,$(subst .,,$(1)))) COMMITCOUNT = $(if $(DUMP),0,$(call commitcount)) diff --git a/scripts/download-check-artifact.sh b/scripts/download-check-artifact.sh new file mode 100755 index 00000000000000..bc0918b2146388 --- /dev/null +++ b/scripts/download-check-artifact.sh @@ -0,0 +1,159 @@ +#!/usr/bin/env bash +# Script to perform verified file downloads. +# Exit codes: +# 0 - File downloaded successfully and verified +# 1 - Failed to download requested file +# 2 - Failed to download sha256sums file +# 3 - Failed to download sha256sums.gpg file +# 4 - GnuPG is available but fails to verify the signature (missing pubkey, file integrity error, ...) +# 5 - The checksums do not match +# 6 - Unable to copy the requested file to its final destination +# 254 - The script got interrupted by a signal +# 255 - A suitable download or checksum utility is missing + +[ -n "$1" ] || { + echo "$0 - Download and verify build artifacts" + echo "Usage: $0 " >&2 + exit 1 +} + +finish() { + [ -e "/tmp/verify.$$" ] && { + echo "Cleaning up." + rm -r "/tmp/verify.$$" + } + exit "$1" +} + +trap "finish 254" INT TERM + +destdir="$(pwd)" +image_url="$1" +image_file="${image_url##*/}" +sha256_url="${image_url%/*}/sha256sums" +gpgsig_url="${image_url%/*}/sha256sums.asc" +keyserver_url="hkp://keyserver.ubuntu.com" + +# Find a suitable download utility +if which curl >/dev/null; then + download() { curl --progress-bar -o "$1" "$2"; } +elif which wget >/dev/null; then + download() { wget -O "$1" "$2"; } +elif which fetch >/dev/null; then + download() { fetch -o "$1" "$2"; } +else + echo "No suitable download utility found, cannot download files!" >&2 + finish 255 +fi + +# Find a suitable checksum utility +if which sha256sum >/dev/null; then + checksum() { sha256sum -c --ignore-missing "sha256sums"; } +elif which shasum >/dev/null; then + checksum() { + local sum + sum="$(shasum -a 256 "$image_file")"; + grep -xF "${sum%% *} *$image_file" "sha256sums"; + } +else + echo "No SHA256 checksum executable installed, cannot verify checksums!" >&2 + finish 255 +fi + +# Check for gpg availability +if which gpg >/dev/null; then + runpgp() { gpg "$@"; } +else + runpgp() { + echo "WARNING: No GnuPG installed, cannot verify digital signature!" >&2 + return 0 + } +fi + +tmpdir="$(mktemp -d)" +cd "$tmpdir" || { + echo "Failed to create temporary directory!" >&2 + finish 255 +} + +echo "" +echo "1) Downloading artifact file" +echo "=========================" +download "$image_file" "$image_url" || { + echo "Failed to download image file!" >&2 + finish 1 +} + +echo "" +echo "2) Downloading checksum file" +echo "============================" +download "sha256sums" "$sha256_url" || { + echo "Failed to download checksum file!" >&2 + finish 2 +} + +echo "" +echo "3) Downloading the GPG signature" +echo "================================" +download "sha256sums.gpg" "$gpgsig_url" || { + echo "Failed to download GPG signature!" >&2 + finish 3 +} + +echo "" +echo "4) Verifying GPG signature" +echo "==========================" +missing_key=$(runpgp --status-fd 1 --with-fingerprint --verify \ + "sha256sums.gpg" "sha256sums" 2>/dev/null | sed -ne 's!^.* NO_PUBKEY !!p') + +if [ -n "$missing_key" ]; then + echo "The signature was signed by a public key with the id $missing_key" >&2 + echo "which is not present on this system." >&2 + echo "" >&2 + + echo "Provide a public keyserver url below or press enter to accept the" >&2 + echo "default suggestion. Hit Ctrl-C to abort the operation." >&2 + echo "" >&2 + + while true; do + printf 'Keyserver to use? [%s] > ' "$keyserver_url" + read -r url; case "${url:-$keyserver_url}" in + hkp://*) + gpg --keyserver "${url:-$keyserver_url}" --recv-keys "$missing_key" || { + echo "Failed to download public key." >&2 + finish 7 + } + break + ;; + *) + echo "Expecting a key server url in the form 'hkp://hostname'." >&2 + ;; + esac + done +fi + +runpgp --with-fingerprint --verify "sha256sums.gpg" "sha256sums" || { + echo "Failed to verify checksum file with GPG signature!" >&2 + finish 4 +} + +echo "" +echo "5) Verifying SHA256 checksum" +echo "============================" +checksum || { + echo "Checksums do not match!" >&2 + finish 5 +} + +cp "$image_file" "$destdir/$image_file" || { + echo "Failed to write '$destdir/$image_file'" >&2 + finish 6 +} + +echo "" +echo "Verification done!" +echo "==================" +echo "Downloaded artifact placed in '$destdir/$image_file'." +echo "" + +finish 0 diff --git a/scripts/feeds b/scripts/feeds index d07c28bc50f8bd..959995c7afa171 100755 --- a/scripts/feeds +++ b/scripts/feeds @@ -157,12 +157,12 @@ my %update_method = ( 'src-git' => { 'init' => "git clone --depth 1 '%s' '%s'", 'init_branch' => "git clone --depth 1 --branch '%s' '%s' '%s'", - 'init_commit' => "git clone '%s' '%s' && cd '%s' && git checkout -b '%s' '%s' && cd -", + 'init_commit' => "git clone --depth 1 '%s' '%s' && cd '%s' && git fetch --depth=1 origin '%s' && git -c advice.detachedHead=false checkout '%s' && cd -", 'update' => "git pull --ff-only", 'update_rebase' => "git pull --rebase=merges", 'update_stash' => "git pull --rebase=merges --autostash", 'update_force' => "git pull --ff-only || (git reset --hard HEAD; git pull --ff-only; exit 1)", - 'post_update' => "git submodule update --init --recursive", + 'post_update' => "git submodule update --init --recursive --depth 1", 'controldir' => ".git", 'revision' => "git rev-parse HEAD | tr -d '\n'"}, 'src-git-full' => { diff --git a/scripts/ipkg-remove b/scripts/ipkg-remove index f4957004c0ebca..19d7148e83c5a4 100755 --- a/scripts/ipkg-remove +++ b/scripts/ipkg-remove @@ -3,17 +3,24 @@ sourcename="$1"; shift for pkg in "$@"; do - tar -Ozxf "$pkg" ./control.tar.gz 2>/dev/null | tar -Ozxf - ./control 2>/dev/null | \ - while read field value; do - if [ "$field" = "SourceName:" ] && [ "$value" = "$sourcename" ]; then - rm -vf "$pkg" - break - fi - done case "$pkg" in */"${sourcename}_"*.ipk) rm -vf "$pkg" ;; + *) + tar -Ozxf "$pkg" ./control.tar.gz 2>/dev/null | tar -Ozxf - ./control 2>/dev/null | { + packagename= + abiversion= + while read field value; do + case "$field" in + Package:) packagename="$value";; + ABIVersion:) abiversion="$value";; + esac + done + [ -n "$abiversion" ] && packagename="${packagename%%$abiversion}" + [ "$packagename" = "$sourcename" ] && rm -vf "$pkg" + } + ;; esac done diff --git a/scripts/json_overview_image_info.py b/scripts/json_overview_image_info.py index 0d2cf7f1ef5134..96921c27430a86 100755 --- a/scripts/json_overview_image_info.py +++ b/scripts/json_overview_image_info.py @@ -47,7 +47,13 @@ def get_initial_output(image_info): if output: - default_packages, output["arch_packages"] = run( + ( + default_packages, + output["arch_packages"], + linux_version, + linux_release, + linux_vermagic, + ) = run( [ "make", "--no-print-directory", @@ -55,6 +61,9 @@ def get_initial_output(image_info): "target/linux/", "val.DEFAULT_PACKAGES", "val.ARCH_PACKAGES", + "val.LINUX_VERSION", + "val.LINUX_RELEASE", + "val.LINUX_VERMAGIC", "V=s", ], stdout=PIPE, @@ -64,7 +73,11 @@ def get_initial_output(image_info): ).stdout.splitlines() output["default_packages"] = sorted(default_packages.split()) - + output["linux_kernel"] = { + "version": linux_version, + "release": linux_release, + "vermagic": linux_vermagic, + } output_path.write_text(json.dumps(output, sort_keys=True, separators=(",", ":"))) else: print("JSON info file script could not find any JSON files for target") diff --git a/scripts/kernel_bump.sh b/scripts/kernel_bump.sh index b1c17d6c3970e8..03e809eedcb65b 100755 --- a/scripts/kernel_bump.sh +++ b/scripts/kernel_bump.sh @@ -2,6 +2,9 @@ # SPDX-License-Identifier: GPL-2.0-or-later # # Copyright (C) 2024 Olliver Schinagl +# +# This script was implemented from scratch -- inspired by ideas shared +# with the OpenWrt project by Elliott Mitchell set -eu if [ -n "${DEBUG_TRACE_SH:-}" ] && \ diff --git a/scripts/make-index-json.py b/scripts/make-index-json.py new file mode 100755 index 00000000000000..af5c6cf0735d4d --- /dev/null +++ b/scripts/make-index-json.py @@ -0,0 +1,84 @@ +#!/usr/bin/env python3 +""" +Parse the native package index files into a json file for use by downstream +tools. See: + + https://github.com/openwrt/openwrt/commit/218ce40cd738f3373438aab82467807a8707fb9c + +The "version 1" index.json contained ABI-versioned package names, making the +unusable by the ASU server. The version 2 format contains package names that +have been stripped of their ABI version. +""" + +import email.parser +import json + + +def parse_args(): + from argparse import ArgumentParser + + source_format = "apk", "opkg" + + parser = ArgumentParser() + # fmt: off + parser.add_argument("-a", "--architecture", required=True, + help="Required device architecture: like 'x86_64' or 'aarch64_generic'") + parser.add_argument("-f", "--source-format", required=True, choices=source_format, + help="Required source format of input: 'apk' or 'opkg'") + parser.add_argument(dest="source", + help="File name for input, '-' for stdin") + # fmt: on + args = parser.parse_args() + return args + + +def parse_apk(text: str) -> dict: + packages: dict = {} + + data = json.loads(text) + for package in data.get("packages", []): + package_name: str = package["name"] + + for tag in package.get("tags", []): + if tag.startswith("openwrt:abiversion="): + package_abi: str = tag.split("=")[-1] + package_name = package_name.removesuffix(package_abi) + break + + packages[package_name] = package["version"] + + return packages + + +def parse_opkg(text: str) -> dict: + packages: dict = {} + + parser: email.parser.Parser = email.parser.Parser() + chunks: list[str] = text.strip().split("\n\n") + for chunk in chunks: + package: dict = parser.parsestr(chunk, headersonly=True) + package_name: str = package["Package"] + if package_abi := package.get("ABIVersion"): + package_name = package_name.removesuffix(package_abi) + + packages[package_name] = package["Version"] + + return packages + + +if __name__ == "__main__": + import sys + + args = parse_args() + + input = sys.stdin if args.source == "-" else open(args.source, "r") + with input: + text: str = input.read() + + packages = parse_apk(text) if args.source_format == "apk" else parse_opkg(text) + index = { + "version": 2, + "architecture": args.architecture, + "packages": packages, + } + print(json.dumps(index, indent=2)) diff --git a/scripts/target-metadata.pl b/scripts/target-metadata.pl index 0c17e2e3273df6..3cca361374efca 100755 --- a/scripts/target-metadata.pl +++ b/scripts/target-metadata.pl @@ -433,7 +433,7 @@ () my @targets = parse_target_metadata($file); foreach my $cur (@targets) { next unless $cur->{id} eq $target; - my @profile_ids_unique = do { my %seen; grep { !$seen{$_}++} map { $_->{id} } @{$cur->{profiles}}}; + my @profile_ids_unique = do { my %seen; grep { !$seen{$_}++} map { $_->{id} } grep { $_->{default} !~ /^n/ } @{$cur->{profiles}}}; print "PROFILE_NAMES = ".join(" ", @profile_ids_unique)."\n"; foreach my $profile (@{$cur->{profiles}}) { print $profile->{id}.'_NAME:='.$profile->{name}."\n"; diff --git a/target/imagebuilder/files/Makefile b/target/imagebuilder/files/Makefile index f46b61b7870670..e9e08fb2765b0e 100644 --- a/target/imagebuilder/files/Makefile +++ b/target/imagebuilder/files/Makefile @@ -26,6 +26,7 @@ include $(INCLUDE_DIR)/debug.mk include $(INCLUDE_DIR)/depends.mk include $(INCLUDE_DIR)/rootfs.mk +include $(INCLUDE_DIR)/default-packages.mk include $(INCLUDE_DIR)/version.mk export REVISION export SOURCE_DATE_EPOCH @@ -138,6 +139,11 @@ _call_info: FORCE echo 'Available Profiles:' echo; $(PROFILE_LIST) +ifneq ($(CONFIG_USE_APK),) + DEFAULT_PACKAGES += apk-mbedtls +else + DEFAULT_PACKAGES += opkg +endif BUILD_PACKAGES:=$(sort $(DEFAULT_PACKAGES) $($(USER_PROFILE)_PACKAGES) kernel) # "-pkgname" in the package list means remove "pkgname" from the package list BUILD_PACKAGES:=$(filter-out $(filter -%,$(BUILD_PACKAGES)) $(patsubst -%,%,$(filter -%,$(BUILD_PACKAGES))),$(BUILD_PACKAGES)) @@ -352,7 +358,7 @@ ifeq ($(PACKAGE),) endif @$(MAKE) -s package_reload ifeq ($(CONFIG_USE_APK),) - @$(OPKG) list --depends $(PACKAGE) + @$(OPKG) whatdepends -A $(PACKAGE) else @$(APK) list --depends $(PACKAGE) endif diff --git a/target/linux/Makefile b/target/linux/Makefile index eaf31982229677..f1e20abf046b03 100644 --- a/target/linux/Makefile +++ b/target/linux/Makefile @@ -4,6 +4,7 @@ include $(TOPDIR)/rules.mk include $(INCLUDE_DIR)/target.mk +include $(INCLUDE_DIR)/default-packages.mk export TARGET_BUILD=1 diff --git a/target/linux/airoha/an7581/config-6.6 b/target/linux/airoha/an7581/config-6.6 index 5001de9b199472..44f86a3b39433f 100644 --- a/target/linux/airoha/an7581/config-6.6 +++ b/target/linux/airoha/an7581/config-6.6 @@ -1,4 +1,5 @@ CONFIG_64BIT=y +CONFIG_AIROHA_CPU_PM_DOMAIN=y CONFIG_AIROHA_THERMAL=y CONFIG_AIROHA_WATCHDOG=y CONFIG_AMPERE_ERRATUM_AC03_CPU_38=y @@ -111,8 +112,6 @@ CONFIG_CAVIUM_ERRATUM_30115=y CONFIG_CAVIUM_TX2_ERRATUM_219=y CONFIG_CC_HAVE_SHADOW_CALL_STACK=y CONFIG_CC_HAVE_STACKPROTECTOR_SYSREG=y -CONFIG_CC_IMPLICIT_FALLTHROUGH="-Wimplicit-fallthrough=5" -CONFIG_CC_NO_ARRAY_BOUNDS=y # CONFIG_CFS_BANDWIDTH is not set CONFIG_CGROUPS=y CONFIG_CGROUP_CPUACCT=y @@ -133,6 +132,8 @@ CONFIG_COMPAT_32BIT_TIME=y CONFIG_CONTEXT_TRACKING=y CONFIG_CONTEXT_TRACKING_IDLE=y CONFIG_COREDUMP=y +CONFIG_CPUFREQ_DT=y +CONFIG_CPUFREQ_DT_PLATDEV=y CONFIG_CPUSETS=y CONFIG_CPU_FREQ=y CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y @@ -192,8 +193,6 @@ CONFIG_CRYPTO_SHA512=y CONFIG_CRYPTO_ZSTD=y CONFIG_DCACHE_WORD_ACCESS=y CONFIG_DEBUG_BUGVERBOSE=y -# CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT is not set -CONFIG_DEBUG_INFO_NONE=y CONFIG_DEBUG_MISC=y CONFIG_DEVMEM=y CONFIG_DMADEVICES=y @@ -232,7 +231,6 @@ CONFIG_FUNCTION_ALIGNMENT_4B=y CONFIG_FWNODE_MDIO=y CONFIG_FW_CACHE=y # CONFIG_FW_LOADER_USER_HELPER is not set -CONFIG_GCC10_NO_ARRAY_BOUNDS=y CONFIG_GCC_SUPPORTS_DYNAMIC_FTRACE_WITH_ARGS=y CONFIG_GENERIC_ALLOCATOR=y CONFIG_GENERIC_ARCH_TOPOLOGY=y @@ -354,6 +352,10 @@ CONFIG_MDIO_DEVRES=y # CONFIG_MEMCG is not set CONFIG_MFD_SYSCON=y CONFIG_MIGRATION=y +CONFIG_MMC=y +CONFIG_MMC_BLOCK=y +CONFIG_MMC_CQHCI=y +CONFIG_MMC_MTK=y CONFIG_MMU_LAZY_TLB_REFCOUNT=y CONFIG_MODULES_TREE_LOOKUP=y CONFIG_MODULES_USE_ELF_RELA=y @@ -401,7 +403,8 @@ CONFIG_NET_NS=y CONFIG_NET_SELFTESTS=y CONFIG_NET_SWITCHDEV=y # CONFIG_NET_VENDOR_3COM is not set -CONFIG_NET_VENDOR_MEDIATEK=y +CONFIG_NET_VENDOR_AIROHA=y +# CONFIG_NET_VENDOR_MEDIATEK is not set CONFIG_NLS=y CONFIG_NLS_DEFAULT="utf8" CONFIG_NO_HZ_COMMON=y @@ -436,7 +439,8 @@ CONFIG_PCIEASPM_PERFORMANCE=y # CONFIG_PCIEASPM_POWERSAVE is not set # CONFIG_PCIEASPM_POWER_SUPERSAVE is not set CONFIG_PCIEPORTBUS=y -# CONFIG_PCIE_MEDIATEK is not set +CONFIG_PCIE_MEDIATEK=y +CONFIG_PCIE_MEDIATEK_GEN3=y CONFIG_PCIE_PME=y CONFIG_PCI_DOMAINS=y CONFIG_PCI_DOMAINS_GENERIC=y @@ -493,6 +497,8 @@ CONFIG_RATIONAL=y CONFIG_RCU_CPU_STALL_TIMEOUT=21 CONFIG_REGMAP=y CONFIG_REGMAP_MMIO=y +CONFIG_REGULATOR=y +CONFIG_REGULATOR_FIXED_VOLTAGE=y CONFIG_RELOCATABLE=y CONFIG_RESET_CONTROLLER=y CONFIG_RFS_ACCEL=y diff --git a/target/linux/airoha/dts/an7581-evb-emmc.dts b/target/linux/airoha/dts/an7581-evb-emmc.dts index 91d797779562ba..26d446e2a1efbd 100644 --- a/target/linux/airoha/dts/an7581-evb-emmc.dts +++ b/target/linux/airoha/dts/an7581-evb-emmc.dts @@ -100,8 +100,9 @@ }; &mmc0 { - pinctrl-names = "default"; + pinctrl-names = "default", "state_uhs"; pinctrl-0 = <&mmc_pins>; + pinctrl-1 = <&mmc_pins>; status = "okay"; #address-cells = <1>; diff --git a/target/linux/airoha/dts/an7581-evb.dts b/target/linux/airoha/dts/an7581-evb.dts index 3cf531a29c4401..9e88bc8a77b3ea 100644 --- a/target/linux/airoha/dts/an7581-evb.dts +++ b/target/linux/airoha/dts/an7581-evb.dts @@ -150,35 +150,40 @@ &spi_nand { partitions { - compatible = "airoha,fixed-partitions"; + compatible = "fixed-partitions"; #address-cells = <1>; #size-cells = <1>; bootloader@0 { label = "bootloader"; reg = <0x00000000 0x00080000>; + read-only; }; - tclinux@80000 { + art@200000 { + label = "art"; + reg = <0x00200000 0x00400000>; + }; + + tclinux@600000 { label = "tclinux"; - compatible = "denx,fit"; - reg = <0x00080000 0x02800000>; + reg = <0x00600000 0x03200000>; }; - tclinux_slave@2880000 { - label = "tclinux_slave"; - reg = <0x02880000 0x02800000>; + tclinux_slave@3800000 { + label = "tclinux_alt"; + reg = <0x03800000 0x03200000>; }; - rootfs_data@5080000 { + rootfs_data@6a00000 { label = "rootfs_data"; - reg = <0x5080000 0x00800000>; + reg = <0x06a00000 0x01400000>; }; - art@ffffffff { - compatible = "airoha,dynamic-art"; - label = "art"; - reg = <0xffffffff 0x00300000>; + reserved_bmt@7e00000 { + label = "reserved_bmt"; + reg = <0x07e00000 0x00200000>; + read-only; }; }; }; diff --git a/target/linux/airoha/dts/an7581.dtsi b/target/linux/airoha/dts/an7581.dtsi index 8abd736875c585..3b9f0c6d653fb9 100644 --- a/target/linux/airoha/dts/an7581.dtsi +++ b/target/linux/airoha/dts/an7581.dtsi @@ -78,7 +78,10 @@ reg = <0x0>; operating-points-v2 = <&cpu_opp_table>; enable-method = "psci"; - clock-frequency = <80000000>; + clocks = <&cpufreq>; + clock-names = "cpu"; + power-domains = <&cpufreq>; + power-domain-names = "perf"; next-level-cache = <&l2>; #cooling-cells = <2>; }; @@ -89,7 +92,10 @@ reg = <0x1>; operating-points-v2 = <&cpu_opp_table>; enable-method = "psci"; - clock-frequency = <80000000>; + clocks = <&cpufreq>; + clock-names = "cpu"; + power-domains = <&cpufreq>; + power-domain-names = "perf"; next-level-cache = <&l2>; #cooling-cells = <2>; }; @@ -100,7 +106,10 @@ reg = <0x2>; operating-points-v2 = <&cpu_opp_table>; enable-method = "psci"; - clock-frequency = <80000000>; + clocks = <&cpufreq>; + clock-names = "cpu"; + power-domains = <&cpufreq>; + power-domain-names = "perf"; next-level-cache = <&l2>; #cooling-cells = <2>; }; @@ -111,7 +120,10 @@ reg = <0x3>; operating-points-v2 = <&cpu_opp_table>; enable-method = "psci"; - clock-frequency = <80000000>; + clocks = <&cpufreq>; + clock-names = "cpu"; + power-domains = <&cpufreq>; + power-domain-names = "perf"; next-level-cache = <&l2>; #cooling-cells = <2>; }; @@ -125,68 +137,156 @@ }; }; + cpufreq: cpufreq { + compatible = "airoha,en7581-cpufreq"; + + operating-points-v2 = <&cpu_smcc_opp_table>; + + #power-domain-cells = <0>; + #clock-cells = <0>; + }; + cpu_opp_table: opp-table { compatible = "operating-points-v2"; opp-shared; opp-500000000 { opp-hz = /bits/ 64 <500000000>; + required-opps = <&smcc_opp0>; }; opp-550000000 { opp-hz = /bits/ 64 <550000000>; + required-opps = <&smcc_opp1>; }; opp-600000000 { opp-hz = /bits/ 64 <600000000>; + required-opps = <&smcc_opp2>; }; opp-650000000 { opp-hz = /bits/ 64 <650000000>; + required-opps = <&smcc_opp3>; }; opp-7000000000 { opp-hz = /bits/ 64 <700000000>; + required-opps = <&smcc_opp4>; }; opp-7500000000 { opp-hz = /bits/ 64 <750000000>; + required-opps = <&smcc_opp5>; }; opp-8000000000 { opp-hz = /bits/ 64 <800000000>; + required-opps = <&smcc_opp6>; }; opp-8500000000 { opp-hz = /bits/ 64 <850000000>; + required-opps = <&smcc_opp7>; }; opp-9000000000 { opp-hz = /bits/ 64 <900000000>; + required-opps = <&smcc_opp8>; }; opp-9500000000 { opp-hz = /bits/ 64 <950000000>; + required-opps = <&smcc_opp9>; }; opp-10000000000 { opp-hz = /bits/ 64 <1000000000>; + required-opps = <&smcc_opp10>; }; opp-10500000000 { opp-hz = /bits/ 64 <1050000000>; + required-opps = <&smcc_opp11>; }; opp-11000000000 { opp-hz = /bits/ 64 <1100000000>; + required-opps = <&smcc_opp12>; }; opp-11500000000 { opp-hz = /bits/ 64 <1150000000>; + required-opps = <&smcc_opp13>; }; opp-12000000000 { opp-hz = /bits/ 64 <1200000000>; + required-opps = <&smcc_opp14>; + }; + }; + + cpu_smcc_opp_table: opp-table-cpu-smcc { + compatible = "operating-points-v2"; + + smcc_opp0: opp0 { + opp-level = <0>; + }; + + smcc_opp1: opp1 { + opp-level = <1>; + }; + + smcc_opp2: opp2 { + opp-level = <2>; + }; + + smcc_opp3: opp3 { + opp-level = <3>; + }; + + smcc_opp4: opp4 { + opp-level = <4>; + }; + + smcc_opp5: opp5 { + opp-level = <5>; + }; + + smcc_opp6: opp6 { + opp-level = <6>; + }; + + smcc_opp7: opp7 { + opp-level = <7>; + }; + + smcc_opp8: opp8 { + opp-level = <8>; + }; + + smcc_opp9: opp9 { + opp-level = <9>; + }; + + smcc_opp10: opp10 { + opp-level = <10>; + }; + + smcc_opp11: opp11 { + opp-level = <11>; + }; + + smcc_opp12: opp12 { + opp-level = <12>; + }; + + smcc_opp13: opp13 { + opp-level = <13>; + }; + + smcc_opp14: opp14 { + opp-level = <14>; }; }; @@ -232,6 +332,21 @@ }; }; + clk25m: oscillator { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <25000000>; + clock-output-names = "clkxtal"; + }; + + vmmc_3v3: regulator-vmmc-3v3 { + compatible = "regulator-fixed"; + regulator-name = "vmmc"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + soc { compatible = "simple-bus"; #address-cells = <2>; @@ -318,7 +433,7 @@ reg = <0x0 0x1fa20000 0x0 0x388>; }; - syscon@1fbe3400 { + pbus_csr: syscon@1fbe3400 { compatible = "airoha,en7581-pbus-csr", "syscon"; reg = <0x0 0x1fbe3400 0x0 0xff>; }; @@ -431,7 +546,6 @@ spi-max-frequency = <50000000>; spi-tx-bus-width = <1>; spi-rx-bus-width = <2>; - airoha,bmt; }; }; @@ -440,8 +554,11 @@ reg = <0x0 0x1fa0e000 0x0 0x1000>, <0x0 0x1fa0c000 0x0 0x60>; interrupts = ; + clocks = <&scuclk EN7581_CLK_EMMC>, <&clk25m>; + clock-names = "source", "hclk"; bus-width = <4>; max-frequency = <52000000>; + vmmc-supply = <&vmmc_3v3>; disable-wp; cap-mmc-highspeed; non-removable; @@ -486,6 +603,8 @@ <&scuclk EN7581_PCIE2_RST>; reset-names = "phy-lane0", "phy-lane1", "phy-lane2"; + mediatek,pbus-csr = <&pbus_csr 0x0 0x4>; + interrupts = ; bus-range = <0x00 0xff>; #interrupt-cells = <1>; @@ -527,6 +646,8 @@ <&scuclk EN7581_PCIE2_RST>; reset-names = "phy-lane0", "phy-lane1", "phy-lane2"; + mediatek,pbus-csr = <&pbus_csr 0x8 0xc>; + interrupts = ; bus-range = <0x00 0xff>; #interrupt-cells = <1>; @@ -587,7 +708,7 @@ status = "disabled"; fixed-link { - speed = <1000>; + speed = <10000>; full-duplex; pause; }; @@ -648,7 +769,7 @@ phy-mode = "internal"; fixed-link { - speed = <1000>; + speed = <10000>; full-duplex; pause; }; diff --git a/target/linux/airoha/en7523/config-6.6 b/target/linux/airoha/en7523/config-6.6 index ce93f7d9ff6f57..a40b61696a11af 100644 --- a/target/linux/airoha/en7523/config-6.6 +++ b/target/linux/airoha/en7523/config-6.6 @@ -45,8 +45,6 @@ CONFIG_BSD_PROCESS_ACCT=y CONFIG_BSD_PROCESS_ACCT_V3=y CONFIG_CACHE_L2X0=y CONFIG_CC_HAVE_STACKPROTECTOR_TLS=y -CONFIG_CC_IMPLICIT_FALLTHROUGH="-Wimplicit-fallthrough=5" -CONFIG_CC_NO_ARRAY_BOUNDS=y CONFIG_CLONE_BACKWARDS=y CONFIG_CMDLINE="rootfstype=squashfs,jffs2" CONFIG_CMDLINE_FROM_BOOTLOADER=y @@ -102,7 +100,6 @@ CONFIG_FUNCTION_ALIGNMENT=0 CONFIG_FWNODE_MDIO=y CONFIG_FW_LOADER_PAGED_BUF=y CONFIG_FW_LOADER_SYSFS=y -CONFIG_GCC10_NO_ARRAY_BOUNDS=y CONFIG_GCC_ASM_GOTO_OUTPUT_WORKAROUND=y CONFIG_GENERIC_ALLOCATOR=y CONFIG_GENERIC_ARCH_TOPOLOGY=y diff --git a/target/linux/airoha/patches-6.6/002-v6.11-i2c-mt7621-Add-Airoha-EN7581-i2c-support.patch b/target/linux/airoha/patches-6.6/002-v6.11-i2c-mt7621-Add-Airoha-EN7581-i2c-support.patch index 25eb475e214187..46c376e343d1b7 100644 --- a/target/linux/airoha/patches-6.6/002-v6.11-i2c-mt7621-Add-Airoha-EN7581-i2c-support.patch +++ b/target/linux/airoha/patches-6.6/002-v6.11-i2c-mt7621-Add-Airoha-EN7581-i2c-support.patch @@ -16,7 +16,7 @@ Signed-off-by: Andi Shyti --- a/drivers/i2c/busses/Kconfig +++ b/drivers/i2c/busses/Kconfig -@@ -839,7 +839,7 @@ config I2C_MT65XX +@@ -841,7 +841,7 @@ config I2C_MT65XX config I2C_MT7621 tristate "MT7621/MT7628 I2C Controller" diff --git a/target/linux/airoha/patches-6.6/019-01-v6.11-clk-en7523-Add-reset-controller-support-for-EN7581-S.patch b/target/linux/airoha/patches-6.6/019-01-v6.11-clk-en7523-Add-reset-controller-support-for-EN7581-S.patch index f7cc5159eaf5a6..4d9ff9ef9de3e3 100644 --- a/target/linux/airoha/patches-6.6/019-01-v6.11-clk-en7523-Add-reset-controller-support-for-EN7581-S.patch +++ b/target/linux/airoha/patches-6.6/019-01-v6.11-clk-en7523-Add-reset-controller-support-for-EN7581-S.patch @@ -139,7 +139,7 @@ Signed-off-by: Stephen Boyd return PTR_ERR(pb_base); @@ -428,6 +510,95 @@ static void en7523_register_clocks(struc - clk_data->num = EN7523_NUM_CLOCKS; + clk_data->hws[EN7523_CLK_PCIE] = hw; } +static int en7523_reset_update(struct reset_controller_dev *rcdev, diff --git a/target/linux/airoha/patches-6.6/029-v6.12-net-dsa-mt7530-Add-EN7581-support.patch b/target/linux/airoha/patches-6.6/029-v6.12-net-dsa-mt7530-Add-EN7581-support.patch index 55e4ae9d404e64..d07163902d98ce 100644 --- a/target/linux/airoha/patches-6.6/029-v6.12-net-dsa-mt7530-Add-EN7581-support.patch +++ b/target/linux/airoha/patches-6.6/029-v6.12-net-dsa-mt7530-Add-EN7581-support.patch @@ -66,7 +66,7 @@ Signed-off-by: David S. Miller /* Disable forwarding by default on all ports */ mt7530_rmw(priv, MT7530_PCR_P(i), PCR_MATRIX_MASK, -@@ -2550,8 +2553,10 @@ mt7531_setup_common(struct dsa_switch *d +@@ -2553,8 +2556,10 @@ mt7531_setup_common(struct dsa_switch *d /* Clear link settings and enable force mode to force link down * on all ports until they're enabled later. */ @@ -79,7 +79,7 @@ Signed-off-by: David S. Miller /* Disable forwarding by default on all ports */ mt7530_rmw(priv, MT7530_PCR_P(i), PCR_MATRIX_MASK, -@@ -2783,6 +2788,28 @@ static void mt7988_mac_port_get_caps(str +@@ -2779,6 +2784,28 @@ static void mt7988_mac_port_get_caps(str } } @@ -108,7 +108,7 @@ Signed-off-by: David S. Miller static void mt7530_mac_config(struct dsa_switch *ds, int port, unsigned int mode, phy_interface_t interface) -@@ -3220,6 +3247,16 @@ const struct mt753x_info mt753x_table[] +@@ -3216,6 +3243,16 @@ const struct mt753x_info mt753x_table[] .phy_write_c45 = mt7531_ind_c45_phy_write, .mac_port_get_caps = mt7988_mac_port_get_caps, }, diff --git a/target/linux/airoha/patches-6.6/031-01-v6.13-net-airoha-Read-completion-queue-data-in-airoha_qdma.patch b/target/linux/airoha/patches-6.6/031-01-v6.13-net-airoha-Read-completion-queue-data-in-airoha_qdma.patch new file mode 100644 index 00000000000000..306ce6588396bf --- /dev/null +++ b/target/linux/airoha/patches-6.6/031-01-v6.13-net-airoha-Read-completion-queue-data-in-airoha_qdma.patch @@ -0,0 +1,92 @@ +From 3affa310de523d63e52ea8e2efb3c476df29e414 Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Tue, 29 Oct 2024 13:17:09 +0100 +Subject: [PATCH 1/2] net: airoha: Read completion queue data in + airoha_qdma_tx_napi_poll() + +In order to avoid any possible race, read completion queue head and +pending entry in airoha_qdma_tx_napi_poll routine instead of doing it in +airoha_irq_handler. Remove unused airoha_tx_irq_queue unused fields. +This is a preliminary patch to add Qdisc offload for airoha_eth driver. + +Signed-off-by: Lorenzo Bianconi +Link: https://patch.msgid.link/20241029-airoha-en7581-tx-napi-work-v1-1-96ad1686b946@kernel.org +Signed-off-by: Jakub Kicinski +--- + drivers/net/ethernet/mediatek/airoha_eth.c | 31 +++++++++------------- + 1 file changed, 13 insertions(+), 18 deletions(-) + +--- a/drivers/net/ethernet/mediatek/airoha_eth.c ++++ b/drivers/net/ethernet/mediatek/airoha_eth.c +@@ -752,11 +752,9 @@ struct airoha_tx_irq_queue { + struct airoha_qdma *qdma; + + struct napi_struct napi; +- u32 *q; + + int size; +- int queued; +- u16 head; ++ u32 *q; + }; + + struct airoha_hw_stats { +@@ -1656,25 +1654,31 @@ static int airoha_qdma_init_rx(struct ai + static int airoha_qdma_tx_napi_poll(struct napi_struct *napi, int budget) + { + struct airoha_tx_irq_queue *irq_q; ++ int id, done = 0, irq_queued; + struct airoha_qdma *qdma; + struct airoha_eth *eth; +- int id, done = 0; ++ u32 status, head; + + irq_q = container_of(napi, struct airoha_tx_irq_queue, napi); + qdma = irq_q->qdma; + id = irq_q - &qdma->q_tx_irq[0]; + eth = qdma->eth; + +- while (irq_q->queued > 0 && done < budget) { +- u32 qid, last, val = irq_q->q[irq_q->head]; ++ status = airoha_qdma_rr(qdma, REG_IRQ_STATUS(id)); ++ head = FIELD_GET(IRQ_HEAD_IDX_MASK, status); ++ head = head % irq_q->size; ++ irq_queued = FIELD_GET(IRQ_ENTRY_LEN_MASK, status); ++ ++ while (irq_queued > 0 && done < budget) { ++ u32 qid, last, val = irq_q->q[head]; + struct airoha_queue *q; + + if (val == 0xff) + break; + +- irq_q->q[irq_q->head] = 0xff; /* mark as done */ +- irq_q->head = (irq_q->head + 1) % irq_q->size; +- irq_q->queued--; ++ irq_q->q[head] = 0xff; /* mark as done */ ++ head = (head + 1) % irq_q->size; ++ irq_queued--; + done++; + + last = FIELD_GET(IRQ_DESC_IDX_MASK, val); +@@ -2026,20 +2030,11 @@ static irqreturn_t airoha_irq_handler(in + + if (intr[0] & INT_TX_MASK) { + for (i = 0; i < ARRAY_SIZE(qdma->q_tx_irq); i++) { +- struct airoha_tx_irq_queue *irq_q = &qdma->q_tx_irq[i]; +- u32 status, head; +- + if (!(intr[0] & TX_DONE_INT_MASK(i))) + continue; + + airoha_qdma_irq_disable(qdma, QDMA_INT_REG_IDX0, + TX_DONE_INT_MASK(i)); +- +- status = airoha_qdma_rr(qdma, REG_IRQ_STATUS(i)); +- head = FIELD_GET(IRQ_HEAD_IDX_MASK, status); +- irq_q->head = head % irq_q->size; +- irq_q->queued = FIELD_GET(IRQ_ENTRY_LEN_MASK, status); +- + napi_schedule(&qdma->q_tx_irq[i].napi); + } + } diff --git a/target/linux/airoha/patches-6.6/031-02-v6.13-net-airoha-Simplify-Tx-napi-logic.patch b/target/linux/airoha/patches-6.6/031-02-v6.13-net-airoha-Simplify-Tx-napi-logic.patch new file mode 100644 index 00000000000000..b35f828f118d9e --- /dev/null +++ b/target/linux/airoha/patches-6.6/031-02-v6.13-net-airoha-Simplify-Tx-napi-logic.patch @@ -0,0 +1,130 @@ +From 0c729f53b8c33b9e5eadc2d5e673759e3510501e Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Tue, 29 Oct 2024 13:17:10 +0100 +Subject: [PATCH 2/2] net: airoha: Simplify Tx napi logic + +Simplify Tx napi logic relying just on the packet index provided by +completion queue indicating the completed packet that can be removed +from the Tx DMA ring. +This is a preliminary patch to add Qdisc offload for airoha_eth driver. + +Signed-off-by: Lorenzo Bianconi +Link: https://patch.msgid.link/20241029-airoha-en7581-tx-napi-work-v1-2-96ad1686b946@kernel.org +Signed-off-by: Jakub Kicinski +--- + drivers/net/ethernet/mediatek/airoha_eth.c | 73 ++++++++++++---------- + 1 file changed, 41 insertions(+), 32 deletions(-) + +--- a/drivers/net/ethernet/mediatek/airoha_eth.c ++++ b/drivers/net/ethernet/mediatek/airoha_eth.c +@@ -1670,8 +1670,12 @@ static int airoha_qdma_tx_napi_poll(stru + irq_queued = FIELD_GET(IRQ_ENTRY_LEN_MASK, status); + + while (irq_queued > 0 && done < budget) { +- u32 qid, last, val = irq_q->q[head]; ++ u32 qid, val = irq_q->q[head]; ++ struct airoha_qdma_desc *desc; ++ struct airoha_queue_entry *e; + struct airoha_queue *q; ++ u32 index, desc_ctrl; ++ struct sk_buff *skb; + + if (val == 0xff) + break; +@@ -1681,9 +1685,7 @@ static int airoha_qdma_tx_napi_poll(stru + irq_queued--; + done++; + +- last = FIELD_GET(IRQ_DESC_IDX_MASK, val); + qid = FIELD_GET(IRQ_RING_IDX_MASK, val); +- + if (qid >= ARRAY_SIZE(qdma->q_tx)) + continue; + +@@ -1691,46 +1693,53 @@ static int airoha_qdma_tx_napi_poll(stru + if (!q->ndesc) + continue; + ++ index = FIELD_GET(IRQ_DESC_IDX_MASK, val); ++ if (index >= q->ndesc) ++ continue; ++ + spin_lock_bh(&q->lock); + +- while (q->queued > 0) { +- struct airoha_qdma_desc *desc = &q->desc[q->tail]; +- struct airoha_queue_entry *e = &q->entry[q->tail]; +- u32 desc_ctrl = le32_to_cpu(desc->ctrl); +- struct sk_buff *skb = e->skb; +- u16 index = q->tail; +- +- if (!(desc_ctrl & QDMA_DESC_DONE_MASK) && +- !(desc_ctrl & QDMA_DESC_DROP_MASK)) +- break; ++ if (!q->queued) ++ goto unlock; + +- q->tail = (q->tail + 1) % q->ndesc; +- q->queued--; ++ desc = &q->desc[index]; ++ desc_ctrl = le32_to_cpu(desc->ctrl); + +- dma_unmap_single(eth->dev, e->dma_addr, e->dma_len, +- DMA_TO_DEVICE); +- +- WRITE_ONCE(desc->msg0, 0); +- WRITE_ONCE(desc->msg1, 0); ++ if (!(desc_ctrl & QDMA_DESC_DONE_MASK) && ++ !(desc_ctrl & QDMA_DESC_DROP_MASK)) ++ goto unlock; ++ ++ e = &q->entry[index]; ++ skb = e->skb; ++ ++ dma_unmap_single(eth->dev, e->dma_addr, e->dma_len, ++ DMA_TO_DEVICE); ++ memset(e, 0, sizeof(*e)); ++ WRITE_ONCE(desc->msg0, 0); ++ WRITE_ONCE(desc->msg1, 0); ++ q->queued--; ++ ++ /* completion ring can report out-of-order indexes if hw QoS ++ * is enabled and packets with different priority are queued ++ * to same DMA ring. Take into account possible out-of-order ++ * reports incrementing DMA ring tail pointer ++ */ ++ while (q->tail != q->head && !q->entry[q->tail].dma_addr) ++ q->tail = (q->tail + 1) % q->ndesc; + +- if (skb) { +- u16 queue = skb_get_queue_mapping(skb); +- struct netdev_queue *txq; +- +- txq = netdev_get_tx_queue(skb->dev, queue); +- netdev_tx_completed_queue(txq, 1, skb->len); +- if (netif_tx_queue_stopped(txq) && +- q->ndesc - q->queued >= q->free_thr) +- netif_tx_wake_queue(txq); +- +- dev_kfree_skb_any(skb); +- e->skb = NULL; +- } ++ if (skb) { ++ u16 queue = skb_get_queue_mapping(skb); ++ struct netdev_queue *txq; ++ ++ txq = netdev_get_tx_queue(skb->dev, queue); ++ netdev_tx_completed_queue(txq, 1, skb->len); ++ if (netif_tx_queue_stopped(txq) && ++ q->ndesc - q->queued >= q->free_thr) ++ netif_tx_wake_queue(txq); + +- if (index == last) +- break; ++ dev_kfree_skb_any(skb); + } +- ++unlock: + spin_unlock_bh(&q->lock); + } + diff --git a/target/linux/airoha/patches-6.6/103-watchdog-Add-support-for-Airoha-EN7851-watchdog.patch b/target/linux/airoha/patches-6.6/032-v6.13-watchdog-Add-support-for-Airoha-EN7851-watchdog.patch similarity index 94% rename from target/linux/airoha/patches-6.6/103-watchdog-Add-support-for-Airoha-EN7851-watchdog.patch rename to target/linux/airoha/patches-6.6/032-v6.13-watchdog-Add-support-for-Airoha-EN7851-watchdog.patch index e58ee546094250..02dbadff4e8704 100644 --- a/target/linux/airoha/patches-6.6/103-watchdog-Add-support-for-Airoha-EN7851-watchdog.patch +++ b/target/linux/airoha/patches-6.6/032-v6.13-watchdog-Add-support-for-Airoha-EN7851-watchdog.patch @@ -1,19 +1,18 @@ -From 4019d58ca5b249e4cf79169cc0c6a4ff5275c155 Mon Sep 17 00:00:00 2001 +From 3cf67f3769b8227ca75ca7102180a2e270ee01aa Mon Sep 17 00:00:00 2001 From: Christian Marangi -Date: Fri, 5 Jul 2024 19:12:12 +0200 -Subject: [PATCH v2 2/2] watchdog: Add support for Airoha EN7851 watchdog +Date: Fri, 11 Oct 2024 12:43:53 +0200 +Subject: [PATCH] watchdog: Add support for Airoha EN7851 watchdog Add support for Airoha EN7851 watchdog. This is a very basic watchdog with no pretimeout support, max timeout is 28 seconds and it ticks based on half the SoC BUS clock. Signed-off-by: Christian Marangi +Reviewed-by: Guenter Roeck +Link: https://lore.kernel.org/r/20241011104411.28659-2-ansuelsmth@gmail.com +Signed-off-by: Guenter Roeck +Signed-off-by: Wim Van Sebroeck --- -Changes v2: -- Drop clock-frequency implementation -- Add missing bitfield.h header -- Attach BUS clock - drivers/watchdog/Kconfig | 8 ++ drivers/watchdog/Makefile | 1 + drivers/watchdog/airoha_wdt.c | 216 ++++++++++++++++++++++++++++++++++ diff --git a/target/linux/airoha/patches-6.6/106-01-clk-en7523-remove-REG_PCIE-_-MEM-MEM_MASK-configurat.patch b/target/linux/airoha/patches-6.6/033-01-v6.13-clk-en7523-remove-REG_PCIE-_-MEM-MEM_MASK-configurat.patch similarity index 89% rename from target/linux/airoha/patches-6.6/106-01-clk-en7523-remove-REG_PCIE-_-MEM-MEM_MASK-configurat.patch rename to target/linux/airoha/patches-6.6/033-01-v6.13-clk-en7523-remove-REG_PCIE-_-MEM-MEM_MASK-configurat.patch index d2e0c6d5417ec9..59aefbb66e96d0 100644 --- a/target/linux/airoha/patches-6.6/106-01-clk-en7523-remove-REG_PCIE-_-MEM-MEM_MASK-configurat.patch +++ b/target/linux/airoha/patches-6.6/033-01-v6.13-clk-en7523-remove-REG_PCIE-_-MEM-MEM_MASK-configurat.patch @@ -1,6 +1,6 @@ -From 64e497f372dfca3e6be9fe05a0f9b874ea8604d2 Mon Sep 17 00:00:00 2001 +From c31d1cdd7bff1d2c13d435bb9d0c76bfaa332097 Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi -Date: Tue, 3 Sep 2024 23:39:46 +0200 +Date: Tue, 12 Nov 2024 01:08:49 +0100 Subject: [PATCH 1/6] clk: en7523: remove REG_PCIE*_{MEM,MEM_MASK} configuration @@ -12,6 +12,8 @@ This patch does not introduce any backward incompatibility since the dts for EN7581 SoC is not upstream yet. Signed-off-by: Lorenzo Bianconi +Link: https://lore.kernel.org/r/20241112-clk-en7581-syscon-v2-2-8ada5e394ae4@kernel.org +Signed-off-by: Stephen Boyd --- drivers/clk/clk-en7523.c | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/target/linux/airoha/patches-6.6/106-02-clk-en7523-move-clock_register-in-hw_init-callback.patch b/target/linux/airoha/patches-6.6/033-02-v6.13-clk-en7523-move-clock_register-in-hw_init-callback.patch similarity index 93% rename from target/linux/airoha/patches-6.6/106-02-clk-en7523-move-clock_register-in-hw_init-callback.patch rename to target/linux/airoha/patches-6.6/033-02-v6.13-clk-en7523-move-clock_register-in-hw_init-callback.patch index 44bfc4404bb52d..6a76886c1b4856 100644 --- a/target/linux/airoha/patches-6.6/106-02-clk-en7523-move-clock_register-in-hw_init-callback.patch +++ b/target/linux/airoha/patches-6.6/033-02-v6.13-clk-en7523-move-clock_register-in-hw_init-callback.patch @@ -1,6 +1,6 @@ -From 0dd8a6df58a4a8cf1f341249e7358b3bb51f52ad Mon Sep 17 00:00:00 2001 +From b8bdfc666bc5f58caf46e67b615132fccbaca3d4 Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi -Date: Tue, 3 Sep 2024 23:39:47 +0200 +Date: Tue, 12 Nov 2024 01:08:50 +0100 Subject: [PATCH 2/6] clk: en7523: move clock_register in hw_init callback Move en7523_register_clocks routine in hw_init callback. @@ -11,6 +11,8 @@ EN7523 and EN7581 SoCs in order to access chip-scu IO region miscellaneous registers needed by multiple devices (clock, pinctrl ..). Signed-off-by: Lorenzo Bianconi +Link: https://lore.kernel.org/r/20241112-clk-en7581-syscon-v2-3-8ada5e394ae4@kernel.org +Signed-off-by: Stephen Boyd --- drivers/clk/clk-en7523.c | 82 ++++++++++++++++++++++++---------------- 1 file changed, 50 insertions(+), 32 deletions(-) @@ -49,7 +51,7 @@ Signed-off-by: Lorenzo Bianconi void __iomem *base, void __iomem *np_base) { @@ -449,6 +436,49 @@ static void en7523_register_clocks(struc - clk_data->num = EN7523_NUM_CLOCKS; + clk_data->hws[EN7523_CLK_PCIE] = hw; } +static int en7523_clk_hw_init(struct platform_device *pdev, diff --git a/target/linux/airoha/patches-6.6/106-03-clk-en7523-introduce-chip_scu-regmap.patch b/target/linux/airoha/patches-6.6/033-03-v6.13-clk-en7523-introduce-chip_scu-regmap.patch similarity index 94% rename from target/linux/airoha/patches-6.6/106-03-clk-en7523-introduce-chip_scu-regmap.patch rename to target/linux/airoha/patches-6.6/033-03-v6.13-clk-en7523-introduce-chip_scu-regmap.patch index 4f8211c564658c..31966273f0238d 100644 --- a/target/linux/airoha/patches-6.6/106-03-clk-en7523-introduce-chip_scu-regmap.patch +++ b/target/linux/airoha/patches-6.6/033-03-v6.13-clk-en7523-introduce-chip_scu-regmap.patch @@ -1,6 +1,6 @@ -From f849bcb746abeaafa63b4f02f1d8bb22703fc645 Mon Sep 17 00:00:00 2001 +From f72fc22038dd544fa4d39c06e8c81c09c0041ed4 Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi -Date: Tue, 3 Sep 2024 23:39:48 +0200 +Date: Tue, 12 Nov 2024 01:08:51 +0100 Subject: [PATCH 3/6] clk: en7523: introduce chip_scu regmap Introduce chip_scu regmap pointer since EN7581 SoC will access chip-scu @@ -9,6 +9,8 @@ for EN7581 SoC. This patch does not introduce any backward incompatibility since the dts for EN7581 SoC is not upstream yet. Signed-off-by: Lorenzo Bianconi +Link: https://lore.kernel.org/r/20241112-clk-en7581-syscon-v2-4-8ada5e394ae4@kernel.org +Signed-off-by: Stephen Boyd --- drivers/clk/clk-en7523.c | 81 ++++++++++++++++++++++++++++++---------- 1 file changed, 61 insertions(+), 20 deletions(-) @@ -61,7 +63,7 @@ Signed-off-by: Lorenzo Bianconi val >>= desc->div_shift; val &= (1 << desc->div_bits) - 1; -@@ -416,9 +409,12 @@ static void en7523_register_clocks(struc +@@ -418,9 +411,12 @@ static void en7523_register_clocks(struc for (i = 0; i < ARRAY_SIZE(en7523_base_clks); i++) { const struct en_clk_desc *desc = &en7523_base_clks[i]; diff --git a/target/linux/airoha/patches-6.6/106-04-clk-en7523-fix-estimation-of-fixed-rate-for-EN7581.patch b/target/linux/airoha/patches-6.6/033-04-v6.13-clk-en7523-fix-estimation-of-fixed-rate-for-EN7581.patch similarity index 94% rename from target/linux/airoha/patches-6.6/106-04-clk-en7523-fix-estimation-of-fixed-rate-for-EN7581.patch rename to target/linux/airoha/patches-6.6/033-04-v6.13-clk-en7523-fix-estimation-of-fixed-rate-for-EN7581.patch index c311375a8b780d..79c9ab2ee1c486 100644 --- a/target/linux/airoha/patches-6.6/106-04-clk-en7523-fix-estimation-of-fixed-rate-for-EN7581.patch +++ b/target/linux/airoha/patches-6.6/033-04-v6.13-clk-en7523-fix-estimation-of-fixed-rate-for-EN7581.patch @@ -1,6 +1,6 @@ -From b9ea4918216ca0c2511446c531d3f8163ac1466d Mon Sep 17 00:00:00 2001 +From f98eded9e9ab048c88ff59c5523e703a6ced5523 Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi -Date: Tue, 3 Sep 2024 23:39:49 +0200 +Date: Tue, 12 Nov 2024 01:08:52 +0100 Subject: [PATCH 4/6] clk: en7523: fix estimation of fixed rate for EN7581 Introduce en7581_base_clks array in order to define per-SoC fixed-rate @@ -9,6 +9,8 @@ clocks Fixes: 66bc47326ce2 ("clk: en7523: Add EN7581 support") Signed-off-by: Lorenzo Bianconi +Link: https://lore.kernel.org/r/20241112-clk-en7581-syscon-v2-5-8ada5e394ae4@kernel.org +Signed-off-by: Stephen Boyd --- drivers/clk/clk-en7523.c | 105 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 103 insertions(+), 2 deletions(-) diff --git a/target/linux/airoha/patches-6.6/106-05-clk-en7523-move-en7581_reset_register-in-en7581_clk_.patch b/target/linux/airoha/patches-6.6/033-05-v6.13-clk-en7523-move-en7581_reset_register-in-en7581_clk_.patch similarity index 95% rename from target/linux/airoha/patches-6.6/106-05-clk-en7523-move-en7581_reset_register-in-en7581_clk_.patch rename to target/linux/airoha/patches-6.6/033-05-v6.13-clk-en7523-move-en7581_reset_register-in-en7581_clk_.patch index 3869a58a83ac57..36b9d9f3dc6ed2 100644 --- a/target/linux/airoha/patches-6.6/106-05-clk-en7523-move-en7581_reset_register-in-en7581_clk_.patch +++ b/target/linux/airoha/patches-6.6/033-05-v6.13-clk-en7523-move-en7581_reset_register-in-en7581_clk_.patch @@ -1,6 +1,6 @@ -From 2c5b1a5b68973947a6919d9c951f9b3e0d84f347 Mon Sep 17 00:00:00 2001 +From 82e6bf912d5846646892becea659b39d178d79e3 Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi -Date: Tue, 3 Sep 2024 23:39:50 +0200 +Date: Tue, 12 Nov 2024 01:08:53 +0100 Subject: [PATCH 5/6] clk: en7523: move en7581_reset_register() in en7581_clk_hw_init() @@ -9,6 +9,8 @@ feature is supported just by EN7581 SoC. Get rid of reset struct in en_clk_soc_data data struct. Signed-off-by: Lorenzo Bianconi +Link: https://lore.kernel.org/r/20241112-clk-en7581-syscon-v2-6-8ada5e394ae4@kernel.org +Signed-off-by: Stephen Boyd --- drivers/clk/clk-en7523.c | 93 ++++++++++++++-------------------------- 1 file changed, 33 insertions(+), 60 deletions(-) diff --git a/target/linux/airoha/patches-6.6/106-06-clk-en7523-map-io-region-in-a-single-block.patch b/target/linux/airoha/patches-6.6/033-06-v6.13-clk-en7523-map-io-region-in-a-single-block.patch similarity index 91% rename from target/linux/airoha/patches-6.6/106-06-clk-en7523-map-io-region-in-a-single-block.patch rename to target/linux/airoha/patches-6.6/033-06-v6.13-clk-en7523-map-io-region-in-a-single-block.patch index db04d602f33299..dec7b81e5b2012 100644 --- a/target/linux/airoha/patches-6.6/106-06-clk-en7523-map-io-region-in-a-single-block.patch +++ b/target/linux/airoha/patches-6.6/033-06-v6.13-clk-en7523-map-io-region-in-a-single-block.patch @@ -1,6 +1,6 @@ -From 665a59f4836c3d7813a9d8bfb9680d93adb4626e Mon Sep 17 00:00:00 2001 +From a9eaf305017a5ebe73ab34e85bd5414055a88f29 Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi -Date: Tue, 3 Sep 2024 23:39:51 +0200 +Date: Tue, 12 Nov 2024 01:08:54 +0100 Subject: [PATCH 6/6] clk: en7523: map io region in a single block Map all clock-controller memory region in a single block. @@ -8,6 +8,8 @@ This patch does not introduce any backward incompatibility since the dts for EN7581 SoC is not upstream yet. Signed-off-by: Lorenzo Bianconi +Link: https://lore.kernel.org/r/20241112-clk-en7581-syscon-v2-7-8ada5e394ae4@kernel.org +Signed-off-by: Stephen Boyd --- drivers/clk/clk-en7523.c | 32 +++++++++++++------------------- 1 file changed, 13 insertions(+), 19 deletions(-) diff --git a/target/linux/airoha/patches-6.6/107-pinctrl-airoha-Add-support-for-EN7581-SoC.patch b/target/linux/airoha/patches-6.6/034-v6.13-pinctrl-airoha-Add-support-for-EN7581-SoC.patch similarity index 99% rename from target/linux/airoha/patches-6.6/107-pinctrl-airoha-Add-support-for-EN7581-SoC.patch rename to target/linux/airoha/patches-6.6/034-v6.13-pinctrl-airoha-Add-support-for-EN7581-SoC.patch index 8e299512c36a40..502f89f26d7a76 100644 --- a/target/linux/airoha/patches-6.6/107-pinctrl-airoha-Add-support-for-EN7581-SoC.patch +++ b/target/linux/airoha/patches-6.6/034-v6.13-pinctrl-airoha-Add-support-for-EN7581-SoC.patch @@ -1,7 +1,7 @@ -From 21cb14f3e6d12d666a9ec0fd7cc01d722b04e514 Mon Sep 17 00:00:00 2001 +From 1c8ace2d0725c1c8d5012f8a56c5fb31805aad27 Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi -Date: Wed, 16 Oct 2024 12:07:33 +0200 -Subject: [PATCH 1/2] pinctrl: airoha: Add support for EN7581 SoC +Date: Wed, 23 Oct 2024 01:20:05 +0200 +Subject: [PATCH] pinctrl: airoha: Add support for EN7581 SoC Introduce pinctrl driver for EN7581 SoC. Current EN7581 pinctrl driver supports the following functionalities: @@ -15,8 +15,10 @@ Tested-by: Benjamin Larsson Co-developed-by: Benjamin Larsson Signed-off-by: Benjamin Larsson Reviewed-by: Linus Walleij -Signed-off-by: Lorenzo Bianconi Reviewed-by: AngeloGioacchino Del Regno +Signed-off-by: Lorenzo Bianconi +Link: https://lore.kernel.org/20241023-en7581-pinctrl-v9-5-afb0cbcab0ec@kernel.org +Signed-off-by: Linus Walleij --- MAINTAINERS | 7 + drivers/pinctrl/mediatek/Kconfig | 17 +- @@ -25,24 +27,22 @@ Reviewed-by: AngeloGioacchino Del Regno -# +L: linux-mediatek@lists.infradead.org (moderated for non-subscribers) -# +S: Maintained -# +F: Documentation/devicetree/bindings/pinctrl/airoha,en7581-pinctrl.yaml -# +F: drivers/pinctrl/mediatek/pinctrl-airoha.c -# + -# PIN CONTROLLER - AMD -# M: Basavaraj Natikar -# M: Shyam Sundar S K ++PIN CONTROLLER - AIROHA ++M: Lorenzo Bianconi ++L: linux-mediatek@lists.infradead.org (moderated for non-subscribers) ++S: Maintained ++F: Documentation/devicetree/bindings/pinctrl/airoha,en7581-pinctrl.yaml ++F: drivers/pinctrl/mediatek/pinctrl-airoha.c ++ + PIN CONTROLLER - AMD + M: Basavaraj Natikar + M: Shyam Sundar S K --- a/drivers/pinctrl/mediatek/Kconfig +++ b/drivers/pinctrl/mediatek/Kconfig @@ -1,6 +1,6 @@ diff --git a/target/linux/airoha/patches-6.6/109-clk-en7523-Fix-wrong-BUS-clock-for-EN7581.patch b/target/linux/airoha/patches-6.6/035-v6.13-clk-en7523-Fix-wrong-BUS-clock-for-EN7581.patch similarity index 82% rename from target/linux/airoha/patches-6.6/109-clk-en7523-Fix-wrong-BUS-clock-for-EN7581.patch rename to target/linux/airoha/patches-6.6/035-v6.13-clk-en7523-Fix-wrong-BUS-clock-for-EN7581.patch index 01a5fd0c876075..89b970f8bb6ba6 100644 --- a/target/linux/airoha/patches-6.6/109-clk-en7523-Fix-wrong-BUS-clock-for-EN7581.patch +++ b/target/linux/airoha/patches-6.6/035-v6.13-clk-en7523-Fix-wrong-BUS-clock-for-EN7581.patch @@ -1,12 +1,12 @@ -From 6d74b9e6d3bb07f50b22b9ea047b84a83aba185c Mon Sep 17 00:00:00 2001 +From 2eb75f86d52565367211c51334d15fe672633085 Mon Sep 17 00:00:00 2001 From: Christian Marangi -Date: Thu, 17 Oct 2024 19:26:24 +0200 +Date: Sat, 16 Nov 2024 11:56:53 +0100 Subject: [PATCH] clk: en7523: Fix wrong BUS clock for EN7581 The Documentation for EN7581 had a typo and still referenced the EN7523 BUS base source frequency. This was in conflict with a different page in -the Documentration that state that the BUS runs at 300MHz (600MHz source with -divisor set to 2) and the actual watchdog that tick at half the BUS +the Documentration that state that the BUS runs at 300MHz (600MHz source +with divisor set to 2) and the actual watchdog that tick at half the BUS clock (150MHz). This was verified with the watchdog by timing the seconds that the system takes to reboot (due too watchdog) and by operating on different values of the BUS divisor. @@ -18,6 +18,9 @@ This was also confirmed by Airoha. Cc: stable@vger.kernel.org Fixes: 66bc47326ce2 ("clk: en7523: Add EN7581 support") Signed-off-by: Christian Marangi +Link: https://lore.kernel.org/r/20241116105710.19748-1-ansuelsmth@gmail.com +Acked-by: Lorenzo Bianconi +Signed-off-by: Stephen Boyd --- drivers/clk/clk-en7523.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/target/linux/airoha/patches-6.6/036-v6.13-net-airoha-Fix-typo-in-REG_CDM2_FWD_CFG-configuratio.patch b/target/linux/airoha/patches-6.6/036-v6.13-net-airoha-Fix-typo-in-REG_CDM2_FWD_CFG-configuratio.patch new file mode 100644 index 00000000000000..a71197150f4807 --- /dev/null +++ b/target/linux/airoha/patches-6.6/036-v6.13-net-airoha-Fix-typo-in-REG_CDM2_FWD_CFG-configuratio.patch @@ -0,0 +1,35 @@ +From 30d9d8f6a2d7e44a9f91737dd409dbc87ac6f6b7 Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Tue, 15 Oct 2024 09:58:09 +0200 +Subject: [PATCH] net: airoha: Fix typo in REG_CDM2_FWD_CFG configuration + +Fix typo in airoha_fe_init routine configuring CDM2_OAM_QSEL_MASK field +of REG_CDM2_FWD_CFG register. +This bug is not introducing any user visible problem since Frame Engine +CDM2 port is used just by the second QDMA block and we currently enable +just QDMA1 block connected to the MT7530 dsa switch via CDM1 port. + +Introduced by commit 23020f049327 ("net: airoha: Introduce ethernet +support for EN7581 SoC") + +Reported-by: ChihWei Cheng +Signed-off-by: Lorenzo Bianconi +Reviewed-by: Simon Horman +Message-ID: <20241015-airoha-eth-cdm2-fixes-v1-1-9dc6993286c3@kernel.org> +Signed-off-by: Andrew Lunn +--- + drivers/net/ethernet/mediatek/airoha_eth.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/net/ethernet/mediatek/airoha_eth.c ++++ b/drivers/net/ethernet/mediatek/airoha_eth.c +@@ -1369,7 +1369,8 @@ static int airoha_fe_init(struct airoha_ + airoha_fe_set(eth, REG_GDM_MISC_CFG, + GDM2_RDM_ACK_WAIT_PREF_MASK | + GDM2_CHN_VLD_MODE_MASK); +- airoha_fe_rmw(eth, REG_CDM2_FWD_CFG, CDM2_OAM_QSEL_MASK, 15); ++ airoha_fe_rmw(eth, REG_CDM2_FWD_CFG, CDM2_OAM_QSEL_MASK, ++ FIELD_PREP(CDM2_OAM_QSEL_MASK, 15)); + + /* init fragment and assemble Force Port */ + /* NPU Core-3, NPU Bridge Channel-3 */ diff --git a/target/linux/airoha/patches-6.6/037-v6.14-net-airoha-Fix-error-path-in-airoha_probe.patch b/target/linux/airoha/patches-6.6/037-v6.14-net-airoha-Fix-error-path-in-airoha_probe.patch new file mode 100644 index 00000000000000..9499c1541a1302 --- /dev/null +++ b/target/linux/airoha/patches-6.6/037-v6.14-net-airoha-Fix-error-path-in-airoha_probe.patch @@ -0,0 +1,102 @@ +From 0c7469ee718e1dd929f52bfb142a7f6fb68f0765 Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Mon, 16 Dec 2024 18:47:33 +0100 +Subject: [PATCH] net: airoha: Fix error path in airoha_probe() + +Do not run napi_disable() if airoha_hw_init() fails since Tx/Rx napi +has not been started yet. In order to fix the issue, introduce +airoha_qdma_stop_napi routine and remove napi_disable in +airoha_hw_cleanup(). + +Fixes: 23020f049327 ("net: airoha: Introduce ethernet support for EN7581 SoC") +Reviewed-by: Michal Swiatkowski +Signed-off-by: Lorenzo Bianconi +Link: https://patch.msgid.link/20241216-airoha_probe-error-path-fix-v2-1-6b10e04e9a5c@kernel.org +Signed-off-by: Jakub Kicinski +--- + drivers/net/ethernet/mediatek/airoha_eth.c | 33 ++++++++++++++++------ + 1 file changed, 25 insertions(+), 8 deletions(-) + +--- a/drivers/net/ethernet/mediatek/airoha_eth.c ++++ b/drivers/net/ethernet/mediatek/airoha_eth.c +@@ -2139,17 +2139,14 @@ static void airoha_hw_cleanup(struct air + if (!qdma->q_rx[i].ndesc) + continue; + +- napi_disable(&qdma->q_rx[i].napi); + netif_napi_del(&qdma->q_rx[i].napi); + airoha_qdma_cleanup_rx_queue(&qdma->q_rx[i]); + if (qdma->q_rx[i].page_pool) + page_pool_destroy(qdma->q_rx[i].page_pool); + } + +- for (i = 0; i < ARRAY_SIZE(qdma->q_tx_irq); i++) { +- napi_disable(&qdma->q_tx_irq[i].napi); ++ for (i = 0; i < ARRAY_SIZE(qdma->q_tx_irq); i++) + netif_napi_del(&qdma->q_tx_irq[i].napi); +- } + + for (i = 0; i < ARRAY_SIZE(qdma->q_tx); i++) { + if (!qdma->q_tx[i].ndesc) +@@ -2174,6 +2171,21 @@ static void airoha_qdma_start_napi(struc + } + } + ++static void airoha_qdma_stop_napi(struct airoha_qdma *qdma) ++{ ++ int i; ++ ++ for (i = 0; i < ARRAY_SIZE(qdma->q_tx_irq); i++) ++ napi_disable(&qdma->q_tx_irq[i].napi); ++ ++ for (i = 0; i < ARRAY_SIZE(qdma->q_rx); i++) { ++ if (!qdma->q_rx[i].ndesc) ++ continue; ++ ++ napi_disable(&qdma->q_rx[i].napi); ++ } ++} ++ + static void airoha_update_hw_stats(struct airoha_gdm_port *port) + { + struct airoha_eth *eth = port->qdma->eth; +@@ -2731,7 +2743,7 @@ static int airoha_probe(struct platform_ + + err = airoha_hw_init(pdev, eth); + if (err) +- goto error; ++ goto error_hw_cleanup; + + for (i = 0; i < ARRAY_SIZE(eth->qdma); i++) + airoha_qdma_start_napi(ð->qdma[i]); +@@ -2746,13 +2758,16 @@ static int airoha_probe(struct platform_ + err = airoha_alloc_gdm_port(eth, np); + if (err) { + of_node_put(np); +- goto error; ++ goto error_napi_stop; + } + } + + return 0; + +-error: ++error_napi_stop: ++ for (i = 0; i < ARRAY_SIZE(eth->qdma); i++) ++ airoha_qdma_stop_napi(ð->qdma[i]); ++error_hw_cleanup: + for (i = 0; i < ARRAY_SIZE(eth->qdma); i++) + airoha_hw_cleanup(ð->qdma[i]); + +@@ -2773,8 +2788,10 @@ static void airoha_remove(struct platfor + struct airoha_eth *eth = platform_get_drvdata(pdev); + int i; + +- for (i = 0; i < ARRAY_SIZE(eth->qdma); i++) ++ for (i = 0; i < ARRAY_SIZE(eth->qdma); i++) { ++ airoha_qdma_stop_napi(ð->qdma[i]); + airoha_hw_cleanup(ð->qdma[i]); ++ } + + for (i = 0; i < ARRAY_SIZE(eth->ports); i++) { + struct airoha_gdm_port *port = eth->ports[i]; diff --git a/target/linux/airoha/patches-6.6/038-01-v6.14-net-airoha-Enable-Tx-drop-capability-for-each-Tx-DMA.patch b/target/linux/airoha/patches-6.6/038-01-v6.14-net-airoha-Enable-Tx-drop-capability-for-each-Tx-DMA.patch new file mode 100644 index 00000000000000..c8681aace5b556 --- /dev/null +++ b/target/linux/airoha/patches-6.6/038-01-v6.14-net-airoha-Enable-Tx-drop-capability-for-each-Tx-DMA.patch @@ -0,0 +1,27 @@ +From 5f795590380476f1c9b7ed0ac945c9b0269dc23a Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Fri, 3 Jan 2025 13:17:02 +0100 +Subject: [PATCH 1/4] net: airoha: Enable Tx drop capability for each Tx DMA + ring + +This is a preliminary patch in order to enable hw Qdisc offloading. + +Signed-off-by: Lorenzo Bianconi +Signed-off-by: Paolo Abeni +--- + drivers/net/ethernet/mediatek/airoha_eth.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/drivers/net/ethernet/mediatek/airoha_eth.c ++++ b/drivers/net/ethernet/mediatek/airoha_eth.c +@@ -1790,6 +1790,10 @@ static int airoha_qdma_init_tx_queue(str + WRITE_ONCE(q->desc[i].ctrl, cpu_to_le32(val)); + } + ++ /* xmit ring drop default setting */ ++ airoha_qdma_set(qdma, REG_TX_RING_BLOCKING(qid), ++ TX_RING_IRQ_BLOCKING_TX_DROP_EN_MASK); ++ + airoha_qdma_wr(qdma, REG_TX_RING_BASE(qid), dma_addr); + airoha_qdma_rmw(qdma, REG_TX_CPU_IDX(qid), TX_RING_CPU_IDX_MASK, + FIELD_PREP(TX_RING_CPU_IDX_MASK, q->head)); diff --git a/target/linux/airoha/patches-6.6/038-02-v6.14-net-airoha-Introduce-ndo_select_queue-callback.patch b/target/linux/airoha/patches-6.6/038-02-v6.14-net-airoha-Introduce-ndo_select_queue-callback.patch new file mode 100644 index 00000000000000..75743bdd347b26 --- /dev/null +++ b/target/linux/airoha/patches-6.6/038-02-v6.14-net-airoha-Introduce-ndo_select_queue-callback.patch @@ -0,0 +1,86 @@ +From 2b288b81560b94958cd68bbe54673e55a1730c95 Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Fri, 3 Jan 2025 13:17:03 +0100 +Subject: [PATCH 2/4] net: airoha: Introduce ndo_select_queue callback + +Airoha EN7581 SoC supports 32 Tx DMA rings used to feed packets to QoS +channels. Each channels supports 8 QoS queues where the user can apply +QoS scheduling policies. In a similar way, the user can configure hw +rate shaping for each QoS channel. +Introduce ndo_select_queue callback in order to select the tx queue +based on QoS channel and QoS queue. In particular, for dsa device select +QoS channel according to the dsa user port index, rely on port id +otherwise. Select QoS queue based on the skb priority. + +Signed-off-by: Lorenzo Bianconi +Signed-off-by: Paolo Abeni +--- + drivers/net/ethernet/mediatek/airoha_eth.c | 30 ++++++++++++++++++++-- + 1 file changed, 28 insertions(+), 2 deletions(-) + +--- a/drivers/net/ethernet/mediatek/airoha_eth.c ++++ b/drivers/net/ethernet/mediatek/airoha_eth.c +@@ -23,6 +23,8 @@ + #define AIROHA_MAX_NUM_XSI_RSTS 5 + #define AIROHA_MAX_MTU 2000 + #define AIROHA_MAX_PACKET_SIZE 2048 ++#define AIROHA_NUM_QOS_CHANNELS 4 ++#define AIROHA_NUM_QOS_QUEUES 8 + #define AIROHA_NUM_TX_RING 32 + #define AIROHA_NUM_RX_RING 32 + #define AIROHA_FE_MC_MAX_VLAN_TABLE 64 +@@ -2422,21 +2424,44 @@ static void airoha_dev_get_stats64(struc + } while (u64_stats_fetch_retry(&port->stats.syncp, start)); + } + ++static u16 airoha_dev_select_queue(struct net_device *dev, struct sk_buff *skb, ++ struct net_device *sb_dev) ++{ ++ struct airoha_gdm_port *port = netdev_priv(dev); ++ int queue, channel; ++ ++ /* For dsa device select QoS channel according to the dsa user port ++ * index, rely on port id otherwise. Select QoS queue based on the ++ * skb priority. ++ */ ++ channel = netdev_uses_dsa(dev) ? skb_get_queue_mapping(skb) : port->id; ++ channel = channel % AIROHA_NUM_QOS_CHANNELS; ++ queue = (skb->priority - 1) % AIROHA_NUM_QOS_QUEUES; /* QoS queue */ ++ queue = channel * AIROHA_NUM_QOS_QUEUES + queue; ++ ++ return queue < dev->num_tx_queues ? queue : 0; ++} ++ + static netdev_tx_t airoha_dev_xmit(struct sk_buff *skb, + struct net_device *dev) + { + struct skb_shared_info *sinfo = skb_shinfo(skb); + struct airoha_gdm_port *port = netdev_priv(dev); +- u32 msg0 = 0, msg1, len = skb_headlen(skb); +- int i, qid = skb_get_queue_mapping(skb); ++ u32 msg0, msg1, len = skb_headlen(skb); + struct airoha_qdma *qdma = port->qdma; + u32 nr_frags = 1 + sinfo->nr_frags; + struct netdev_queue *txq; + struct airoha_queue *q; + void *data = skb->data; ++ int i, qid; + u16 index; + u8 fport; + ++ qid = skb_get_queue_mapping(skb) % ARRAY_SIZE(qdma->q_tx); ++ msg0 = FIELD_PREP(QDMA_ETH_TXMSG_CHAN_MASK, ++ qid / AIROHA_NUM_QOS_QUEUES) | ++ FIELD_PREP(QDMA_ETH_TXMSG_QUEUE_MASK, ++ qid % AIROHA_NUM_QOS_QUEUES); + if (skb->ip_summed == CHECKSUM_PARTIAL) + msg0 |= FIELD_PREP(QDMA_ETH_TXMSG_TCO_MASK, 1) | + FIELD_PREP(QDMA_ETH_TXMSG_UCO_MASK, 1) | +@@ -2610,6 +2635,7 @@ static const struct net_device_ops airoh + .ndo_init = airoha_dev_init, + .ndo_open = airoha_dev_open, + .ndo_stop = airoha_dev_stop, ++ .ndo_select_queue = airoha_dev_select_queue, + .ndo_start_xmit = airoha_dev_xmit, + .ndo_get_stats64 = airoha_dev_get_stats64, + .ndo_set_mac_address = airoha_dev_set_macaddr, diff --git a/target/linux/airoha/patches-6.6/038-03-v6.14-net-airoha-Add-sched-ETS-offload-support.patch b/target/linux/airoha/patches-6.6/038-03-v6.14-net-airoha-Add-sched-ETS-offload-support.patch new file mode 100644 index 00000000000000..ad5e0e5c2a63b1 --- /dev/null +++ b/target/linux/airoha/patches-6.6/038-03-v6.14-net-airoha-Add-sched-ETS-offload-support.patch @@ -0,0 +1,292 @@ +From 20bf7d07c956e5c7a22d3076c599cbb7a6054917 Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Fri, 3 Jan 2025 13:17:04 +0100 +Subject: [PATCH 3/4] net: airoha: Add sched ETS offload support + +Introduce support for ETS Qdisc offload available on the Airoha EN7581 +ethernet controller. In order to be effective, ETS Qdisc must configured +as leaf of a HTB Qdisc (HTB Qdisc offload will be added in the following +patch). ETS Qdisc available on EN7581 ethernet controller supports at +most 8 concurrent bands (QoS queues). We can enable an ETS Qdisc for +each available QoS channel. + +Signed-off-by: Lorenzo Bianconi +Signed-off-by: Paolo Abeni +--- + drivers/net/ethernet/mediatek/airoha_eth.c | 196 ++++++++++++++++++++- + 1 file changed, 195 insertions(+), 1 deletion(-) + +--- a/drivers/net/ethernet/mediatek/airoha_eth.c ++++ b/drivers/net/ethernet/mediatek/airoha_eth.c +@@ -15,6 +15,7 @@ + #include + #include + #include ++#include + #include + + #define AIROHA_MAX_NUM_GDM_PORTS 1 +@@ -543,9 +544,24 @@ + #define INGRESS_SLOW_TICK_RATIO_MASK GENMASK(29, 16) + #define INGRESS_FAST_TICK_MASK GENMASK(15, 0) + ++#define REG_QUEUE_CLOSE_CFG(_n) (0x00a0 + ((_n) & 0xfc)) ++#define TXQ_DISABLE_CHAN_QUEUE_MASK(_n, _m) BIT((_m) + (((_n) & 0x3) << 3)) ++ + #define REG_TXQ_DIS_CFG_BASE(_n) ((_n) ? 0x20a0 : 0x00a0) + #define REG_TXQ_DIS_CFG(_n, _m) (REG_TXQ_DIS_CFG_BASE((_n)) + (_m) << 2) + ++#define REG_CNTR_CFG(_n) (0x0400 + ((_n) << 3)) ++#define CNTR_EN_MASK BIT(31) ++#define CNTR_ALL_CHAN_EN_MASK BIT(30) ++#define CNTR_ALL_QUEUE_EN_MASK BIT(29) ++#define CNTR_ALL_DSCP_RING_EN_MASK BIT(28) ++#define CNTR_SRC_MASK GENMASK(27, 24) ++#define CNTR_DSCP_RING_MASK GENMASK(20, 16) ++#define CNTR_CHAN_MASK GENMASK(7, 3) ++#define CNTR_QUEUE_MASK GENMASK(2, 0) ++ ++#define REG_CNTR_VAL(_n) (0x0404 + ((_n) << 3)) ++ + #define REG_LMGR_INIT_CFG 0x1000 + #define LMGR_INIT_START BIT(31) + #define LMGR_SRAM_MODE_MASK BIT(30) +@@ -571,9 +587,19 @@ + #define TWRR_WEIGHT_SCALE_MASK BIT(31) + #define TWRR_WEIGHT_BASE_MASK BIT(3) + ++#define REG_TXWRR_WEIGHT_CFG 0x1024 ++#define TWRR_RW_CMD_MASK BIT(31) ++#define TWRR_RW_CMD_DONE BIT(30) ++#define TWRR_CHAN_IDX_MASK GENMASK(23, 19) ++#define TWRR_QUEUE_IDX_MASK GENMASK(18, 16) ++#define TWRR_VALUE_MASK GENMASK(15, 0) ++ + #define REG_PSE_BUF_USAGE_CFG 0x1028 + #define PSE_BUF_ESTIMATE_EN_MASK BIT(29) + ++#define REG_CHAN_QOS_MODE(_n) (0x1040 + ((_n) << 2)) ++#define CHAN_QOS_MODE_MASK(_n) GENMASK(2 + ((_n) << 2), (_n) << 2) ++ + #define REG_GLB_TRTCM_CFG 0x1080 + #define GLB_TRTCM_EN_MASK BIT(31) + #define GLB_TRTCM_MODE_MASK BIT(30) +@@ -722,6 +748,17 @@ enum { + FE_PSE_PORT_DROP = 0xf, + }; + ++enum tx_sched_mode { ++ TC_SCH_WRR8, ++ TC_SCH_SP, ++ TC_SCH_WRR7, ++ TC_SCH_WRR6, ++ TC_SCH_WRR5, ++ TC_SCH_WRR4, ++ TC_SCH_WRR3, ++ TC_SCH_WRR2, ++}; ++ + struct airoha_queue_entry { + union { + void *buf; +@@ -812,6 +849,10 @@ struct airoha_gdm_port { + int id; + + struct airoha_hw_stats stats; ++ ++ /* qos stats counters */ ++ u64 cpu_tx_packets; ++ u64 fwd_tx_packets; + }; + + struct airoha_eth { +@@ -1962,6 +2003,27 @@ static void airoha_qdma_init_qos(struct + FIELD_PREP(SLA_SLOW_TICK_RATIO_MASK, 40)); + } + ++static void airoha_qdma_init_qos_stats(struct airoha_qdma *qdma) ++{ ++ int i; ++ ++ for (i = 0; i < AIROHA_NUM_QOS_CHANNELS; i++) { ++ /* Tx-cpu transferred count */ ++ airoha_qdma_wr(qdma, REG_CNTR_VAL(i << 1), 0); ++ airoha_qdma_wr(qdma, REG_CNTR_CFG(i << 1), ++ CNTR_EN_MASK | CNTR_ALL_QUEUE_EN_MASK | ++ CNTR_ALL_DSCP_RING_EN_MASK | ++ FIELD_PREP(CNTR_CHAN_MASK, i)); ++ /* Tx-fwd transferred count */ ++ airoha_qdma_wr(qdma, REG_CNTR_VAL((i << 1) + 1), 0); ++ airoha_qdma_wr(qdma, REG_CNTR_CFG(i << 1), ++ CNTR_EN_MASK | CNTR_ALL_QUEUE_EN_MASK | ++ CNTR_ALL_DSCP_RING_EN_MASK | ++ FIELD_PREP(CNTR_SRC_MASK, 1) | ++ FIELD_PREP(CNTR_CHAN_MASK, i)); ++ } ++} ++ + static int airoha_qdma_hw_init(struct airoha_qdma *qdma) + { + int i; +@@ -2012,6 +2074,7 @@ static int airoha_qdma_hw_init(struct ai + + airoha_qdma_set(qdma, REG_TXQ_CNGST_CFG, + TXQ_CNGST_DROP_EN | TXQ_CNGST_DEI_DROP_EN); ++ airoha_qdma_init_qos_stats(qdma); + + return 0; + } +@@ -2631,6 +2694,135 @@ airoha_ethtool_get_rmon_stats(struct net + } while (u64_stats_fetch_retry(&port->stats.syncp, start)); + } + ++static int airoha_qdma_set_chan_tx_sched(struct airoha_gdm_port *port, ++ int channel, enum tx_sched_mode mode, ++ const u16 *weights, u8 n_weights) ++{ ++ int i; ++ ++ for (i = 0; i < AIROHA_NUM_TX_RING; i++) ++ airoha_qdma_clear(port->qdma, REG_QUEUE_CLOSE_CFG(channel), ++ TXQ_DISABLE_CHAN_QUEUE_MASK(channel, i)); ++ ++ for (i = 0; i < n_weights; i++) { ++ u32 status; ++ int err; ++ ++ airoha_qdma_wr(port->qdma, REG_TXWRR_WEIGHT_CFG, ++ TWRR_RW_CMD_MASK | ++ FIELD_PREP(TWRR_CHAN_IDX_MASK, channel) | ++ FIELD_PREP(TWRR_QUEUE_IDX_MASK, i) | ++ FIELD_PREP(TWRR_VALUE_MASK, weights[i])); ++ err = read_poll_timeout(airoha_qdma_rr, status, ++ status & TWRR_RW_CMD_DONE, ++ USEC_PER_MSEC, 10 * USEC_PER_MSEC, ++ true, port->qdma, ++ REG_TXWRR_WEIGHT_CFG); ++ if (err) ++ return err; ++ } ++ ++ airoha_qdma_rmw(port->qdma, REG_CHAN_QOS_MODE(channel >> 3), ++ CHAN_QOS_MODE_MASK(channel), ++ mode << __ffs(CHAN_QOS_MODE_MASK(channel))); ++ ++ return 0; ++} ++ ++static int airoha_qdma_set_tx_prio_sched(struct airoha_gdm_port *port, ++ int channel) ++{ ++ static const u16 w[AIROHA_NUM_QOS_QUEUES] = {}; ++ ++ return airoha_qdma_set_chan_tx_sched(port, channel, TC_SCH_SP, w, ++ ARRAY_SIZE(w)); ++} ++ ++static int airoha_qdma_set_tx_ets_sched(struct airoha_gdm_port *port, ++ int channel, ++ struct tc_ets_qopt_offload *opt) ++{ ++ struct tc_ets_qopt_offload_replace_params *p = &opt->replace_params; ++ enum tx_sched_mode mode = TC_SCH_SP; ++ u16 w[AIROHA_NUM_QOS_QUEUES] = {}; ++ int i, nstrict = 0; ++ ++ if (p->bands > AIROHA_NUM_QOS_QUEUES) ++ return -EINVAL; ++ ++ for (i = 0; i < p->bands; i++) { ++ if (!p->quanta[i]) ++ nstrict++; ++ } ++ ++ /* this configuration is not supported by the hw */ ++ if (nstrict == AIROHA_NUM_QOS_QUEUES - 1) ++ return -EINVAL; ++ ++ for (i = 0; i < p->bands - nstrict; i++) ++ w[i] = p->weights[nstrict + i]; ++ ++ if (!nstrict) ++ mode = TC_SCH_WRR8; ++ else if (nstrict < AIROHA_NUM_QOS_QUEUES - 1) ++ mode = nstrict + 1; ++ ++ return airoha_qdma_set_chan_tx_sched(port, channel, mode, w, ++ ARRAY_SIZE(w)); ++} ++ ++static int airoha_qdma_get_tx_ets_stats(struct airoha_gdm_port *port, ++ int channel, ++ struct tc_ets_qopt_offload *opt) ++{ ++ u64 cpu_tx_packets = airoha_qdma_rr(port->qdma, ++ REG_CNTR_VAL(channel << 1)); ++ u64 fwd_tx_packets = airoha_qdma_rr(port->qdma, ++ REG_CNTR_VAL((channel << 1) + 1)); ++ u64 tx_packets = (cpu_tx_packets - port->cpu_tx_packets) + ++ (fwd_tx_packets - port->fwd_tx_packets); ++ _bstats_update(opt->stats.bstats, 0, tx_packets); ++ ++ port->cpu_tx_packets = cpu_tx_packets; ++ port->fwd_tx_packets = fwd_tx_packets; ++ ++ return 0; ++} ++ ++static int airoha_tc_setup_qdisc_ets(struct airoha_gdm_port *port, ++ struct tc_ets_qopt_offload *opt) ++{ ++ int channel = TC_H_MAJ(opt->handle) >> 16; ++ ++ if (opt->parent == TC_H_ROOT) ++ return -EINVAL; ++ ++ switch (opt->command) { ++ case TC_ETS_REPLACE: ++ return airoha_qdma_set_tx_ets_sched(port, channel, opt); ++ case TC_ETS_DESTROY: ++ /* PRIO is default qdisc scheduler */ ++ return airoha_qdma_set_tx_prio_sched(port, channel); ++ case TC_ETS_STATS: ++ return airoha_qdma_get_tx_ets_stats(port, channel, opt); ++ default: ++ return -EOPNOTSUPP; ++ } ++} ++ ++static int airoha_dev_tc_setup(struct net_device *dev, enum tc_setup_type type, ++ void *type_data) ++{ ++ struct airoha_gdm_port *port = netdev_priv(dev); ++ ++ switch (type) { ++ case TC_SETUP_QDISC_ETS: ++ return airoha_tc_setup_qdisc_ets(port, type_data); ++ default: ++ return -EOPNOTSUPP; ++ } ++} ++ + static const struct net_device_ops airoha_netdev_ops = { + .ndo_init = airoha_dev_init, + .ndo_open = airoha_dev_open, +@@ -2639,6 +2831,7 @@ static const struct net_device_ops airoh + .ndo_start_xmit = airoha_dev_xmit, + .ndo_get_stats64 = airoha_dev_get_stats64, + .ndo_set_mac_address = airoha_dev_set_macaddr, ++ .ndo_setup_tc = airoha_dev_tc_setup, + }; + + static const struct ethtool_ops airoha_ethtool_ops = { +@@ -2688,7 +2881,8 @@ static int airoha_alloc_gdm_port(struct + dev->watchdog_timeo = 5 * HZ; + dev->hw_features = NETIF_F_IP_CSUM | NETIF_F_RXCSUM | + NETIF_F_TSO6 | NETIF_F_IPV6_CSUM | +- NETIF_F_SG | NETIF_F_TSO; ++ NETIF_F_SG | NETIF_F_TSO | ++ NETIF_F_HW_TC; + dev->features |= dev->hw_features; + dev->dev.of_node = np; + dev->irq = qdma->irq; diff --git a/target/linux/airoha/patches-6.6/038-04-v6.14-net-airoha-Add-sched-HTB-offload-support.patch b/target/linux/airoha/patches-6.6/038-04-v6.14-net-airoha-Add-sched-HTB-offload-support.patch new file mode 100644 index 00000000000000..1239b174e51c1a --- /dev/null +++ b/target/linux/airoha/patches-6.6/038-04-v6.14-net-airoha-Add-sched-HTB-offload-support.patch @@ -0,0 +1,371 @@ +From ef1ca9271313b4ea7b03de69576aacef1e78f381 Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Fri, 3 Jan 2025 13:17:05 +0100 +Subject: [PATCH 4/4] net: airoha: Add sched HTB offload support + +Introduce support for HTB Qdisc offload available in the Airoha EN7581 +ethernet controller. EN7581 can offload only one level of HTB leafs. +Each HTB leaf represents a QoS channel supported by EN7581 SoC. +The typical use-case is creating a HTB leaf for QoS channel to rate +limit the egress traffic and attach an ETS Qdisc to each HTB leaf in +order to enforce traffic prioritization. + +Signed-off-by: Lorenzo Bianconi +Signed-off-by: Paolo Abeni +--- + drivers/net/ethernet/mediatek/airoha_eth.c | 288 ++++++++++++++++++++- + 1 file changed, 287 insertions(+), 1 deletion(-) + +--- a/drivers/net/ethernet/mediatek/airoha_eth.c ++++ b/drivers/net/ethernet/mediatek/airoha_eth.c +@@ -28,6 +28,8 @@ + #define AIROHA_NUM_QOS_QUEUES 8 + #define AIROHA_NUM_TX_RING 32 + #define AIROHA_NUM_RX_RING 32 ++#define AIROHA_NUM_NETDEV_TX_RINGS (AIROHA_NUM_TX_RING + \ ++ AIROHA_NUM_QOS_CHANNELS) + #define AIROHA_FE_MC_MAX_VLAN_TABLE 64 + #define AIROHA_FE_MC_MAX_VLAN_PORT 16 + #define AIROHA_NUM_TX_IRQ 2 +@@ -43,6 +45,9 @@ + #define PSE_RSV_PAGES 128 + #define PSE_QUEUE_RSV_PAGES 64 + ++#define QDMA_METER_IDX(_n) ((_n) & 0xff) ++#define QDMA_METER_GROUP(_n) (((_n) >> 8) & 0x3) ++ + /* FE */ + #define PSE_BASE 0x0100 + #define CSR_IFC_BASE 0x0200 +@@ -583,6 +588,17 @@ + #define EGRESS_SLOW_TICK_RATIO_MASK GENMASK(29, 16) + #define EGRESS_FAST_TICK_MASK GENMASK(15, 0) + ++#define TRTCM_PARAM_RW_MASK BIT(31) ++#define TRTCM_PARAM_RW_DONE_MASK BIT(30) ++#define TRTCM_PARAM_TYPE_MASK GENMASK(29, 28) ++#define TRTCM_METER_GROUP_MASK GENMASK(27, 26) ++#define TRTCM_PARAM_INDEX_MASK GENMASK(23, 17) ++#define TRTCM_PARAM_RATE_TYPE_MASK BIT(16) ++ ++#define REG_TRTCM_CFG_PARAM(_n) ((_n) + 0x4) ++#define REG_TRTCM_DATA_LOW(_n) ((_n) + 0x8) ++#define REG_TRTCM_DATA_HIGH(_n) ((_n) + 0xc) ++ + #define REG_TXWRR_MODE_CFG 0x1020 + #define TWRR_WEIGHT_SCALE_MASK BIT(31) + #define TWRR_WEIGHT_BASE_MASK BIT(3) +@@ -759,6 +775,29 @@ enum tx_sched_mode { + TC_SCH_WRR2, + }; + ++enum trtcm_param_type { ++ TRTCM_MISC_MODE, /* meter_en, pps_mode, tick_sel */ ++ TRTCM_TOKEN_RATE_MODE, ++ TRTCM_BUCKETSIZE_SHIFT_MODE, ++ TRTCM_BUCKET_COUNTER_MODE, ++}; ++ ++enum trtcm_mode_type { ++ TRTCM_COMMIT_MODE, ++ TRTCM_PEAK_MODE, ++}; ++ ++enum trtcm_param { ++ TRTCM_TICK_SEL = BIT(0), ++ TRTCM_PKT_MODE = BIT(1), ++ TRTCM_METER_MODE = BIT(2), ++}; ++ ++#define MIN_TOKEN_SIZE 4096 ++#define MAX_TOKEN_SIZE_OFFSET 17 ++#define TRTCM_TOKEN_RATE_MASK GENMASK(23, 6) ++#define TRTCM_TOKEN_RATE_FRACTION_MASK GENMASK(5, 0) ++ + struct airoha_queue_entry { + union { + void *buf; +@@ -850,6 +889,8 @@ struct airoha_gdm_port { + + struct airoha_hw_stats stats; + ++ DECLARE_BITMAP(qos_sq_bmap, AIROHA_NUM_QOS_CHANNELS); ++ + /* qos stats counters */ + u64 cpu_tx_packets; + u64 fwd_tx_packets; +@@ -2810,6 +2851,243 @@ static int airoha_tc_setup_qdisc_ets(str + } + } + ++static int airoha_qdma_get_trtcm_param(struct airoha_qdma *qdma, int channel, ++ u32 addr, enum trtcm_param_type param, ++ enum trtcm_mode_type mode, ++ u32 *val_low, u32 *val_high) ++{ ++ u32 idx = QDMA_METER_IDX(channel), group = QDMA_METER_GROUP(channel); ++ u32 val, config = FIELD_PREP(TRTCM_PARAM_TYPE_MASK, param) | ++ FIELD_PREP(TRTCM_METER_GROUP_MASK, group) | ++ FIELD_PREP(TRTCM_PARAM_INDEX_MASK, idx) | ++ FIELD_PREP(TRTCM_PARAM_RATE_TYPE_MASK, mode); ++ ++ airoha_qdma_wr(qdma, REG_TRTCM_CFG_PARAM(addr), config); ++ if (read_poll_timeout(airoha_qdma_rr, val, ++ val & TRTCM_PARAM_RW_DONE_MASK, ++ USEC_PER_MSEC, 10 * USEC_PER_MSEC, true, ++ qdma, REG_TRTCM_CFG_PARAM(addr))) ++ return -ETIMEDOUT; ++ ++ *val_low = airoha_qdma_rr(qdma, REG_TRTCM_DATA_LOW(addr)); ++ if (val_high) ++ *val_high = airoha_qdma_rr(qdma, REG_TRTCM_DATA_HIGH(addr)); ++ ++ return 0; ++} ++ ++static int airoha_qdma_set_trtcm_param(struct airoha_qdma *qdma, int channel, ++ u32 addr, enum trtcm_param_type param, ++ enum trtcm_mode_type mode, u32 val) ++{ ++ u32 idx = QDMA_METER_IDX(channel), group = QDMA_METER_GROUP(channel); ++ u32 config = TRTCM_PARAM_RW_MASK | ++ FIELD_PREP(TRTCM_PARAM_TYPE_MASK, param) | ++ FIELD_PREP(TRTCM_METER_GROUP_MASK, group) | ++ FIELD_PREP(TRTCM_PARAM_INDEX_MASK, idx) | ++ FIELD_PREP(TRTCM_PARAM_RATE_TYPE_MASK, mode); ++ ++ airoha_qdma_wr(qdma, REG_TRTCM_DATA_LOW(addr), val); ++ airoha_qdma_wr(qdma, REG_TRTCM_CFG_PARAM(addr), config); ++ ++ return read_poll_timeout(airoha_qdma_rr, val, ++ val & TRTCM_PARAM_RW_DONE_MASK, ++ USEC_PER_MSEC, 10 * USEC_PER_MSEC, true, ++ qdma, REG_TRTCM_CFG_PARAM(addr)); ++} ++ ++static int airoha_qdma_set_trtcm_config(struct airoha_qdma *qdma, int channel, ++ u32 addr, enum trtcm_mode_type mode, ++ bool enable, u32 enable_mask) ++{ ++ u32 val; ++ ++ if (airoha_qdma_get_trtcm_param(qdma, channel, addr, TRTCM_MISC_MODE, ++ mode, &val, NULL)) ++ return -EINVAL; ++ ++ val = enable ? val | enable_mask : val & ~enable_mask; ++ ++ return airoha_qdma_set_trtcm_param(qdma, channel, addr, TRTCM_MISC_MODE, ++ mode, val); ++} ++ ++static int airoha_qdma_set_trtcm_token_bucket(struct airoha_qdma *qdma, ++ int channel, u32 addr, ++ enum trtcm_mode_type mode, ++ u32 rate_val, u32 bucket_size) ++{ ++ u32 val, config, tick, unit, rate, rate_frac; ++ int err; ++ ++ if (airoha_qdma_get_trtcm_param(qdma, channel, addr, TRTCM_MISC_MODE, ++ mode, &config, NULL)) ++ return -EINVAL; ++ ++ val = airoha_qdma_rr(qdma, addr); ++ tick = FIELD_GET(INGRESS_FAST_TICK_MASK, val); ++ if (config & TRTCM_TICK_SEL) ++ tick *= FIELD_GET(INGRESS_SLOW_TICK_RATIO_MASK, val); ++ if (!tick) ++ return -EINVAL; ++ ++ unit = (config & TRTCM_PKT_MODE) ? 1000000 / tick : 8000 / tick; ++ if (!unit) ++ return -EINVAL; ++ ++ rate = rate_val / unit; ++ rate_frac = rate_val % unit; ++ rate_frac = FIELD_PREP(TRTCM_TOKEN_RATE_MASK, rate_frac) / unit; ++ rate = FIELD_PREP(TRTCM_TOKEN_RATE_MASK, rate) | ++ FIELD_PREP(TRTCM_TOKEN_RATE_FRACTION_MASK, rate_frac); ++ ++ err = airoha_qdma_set_trtcm_param(qdma, channel, addr, ++ TRTCM_TOKEN_RATE_MODE, mode, rate); ++ if (err) ++ return err; ++ ++ val = max_t(u32, bucket_size, MIN_TOKEN_SIZE); ++ val = min_t(u32, __fls(val), MAX_TOKEN_SIZE_OFFSET); ++ ++ return airoha_qdma_set_trtcm_param(qdma, channel, addr, ++ TRTCM_BUCKETSIZE_SHIFT_MODE, ++ mode, val); ++} ++ ++static int airoha_qdma_set_tx_rate_limit(struct airoha_gdm_port *port, ++ int channel, u32 rate, ++ u32 bucket_size) ++{ ++ int i, err; ++ ++ for (i = 0; i <= TRTCM_PEAK_MODE; i++) { ++ err = airoha_qdma_set_trtcm_config(port->qdma, channel, ++ REG_EGRESS_TRTCM_CFG, i, ++ !!rate, TRTCM_METER_MODE); ++ if (err) ++ return err; ++ ++ err = airoha_qdma_set_trtcm_token_bucket(port->qdma, channel, ++ REG_EGRESS_TRTCM_CFG, ++ i, rate, bucket_size); ++ if (err) ++ return err; ++ } ++ ++ return 0; ++} ++ ++static int airoha_tc_htb_alloc_leaf_queue(struct airoha_gdm_port *port, ++ struct tc_htb_qopt_offload *opt) ++{ ++ u32 channel = TC_H_MIN(opt->classid) % AIROHA_NUM_QOS_CHANNELS; ++ u32 rate = div_u64(opt->rate, 1000) << 3; /* kbps */ ++ struct net_device *dev = port->dev; ++ int num_tx_queues = dev->real_num_tx_queues; ++ int err; ++ ++ if (opt->parent_classid != TC_HTB_CLASSID_ROOT) { ++ NL_SET_ERR_MSG_MOD(opt->extack, "invalid parent classid"); ++ return -EINVAL; ++ } ++ ++ err = airoha_qdma_set_tx_rate_limit(port, channel, rate, opt->quantum); ++ if (err) { ++ NL_SET_ERR_MSG_MOD(opt->extack, ++ "failed configuring htb offload"); ++ return err; ++ } ++ ++ if (opt->command == TC_HTB_NODE_MODIFY) ++ return 0; ++ ++ err = netif_set_real_num_tx_queues(dev, num_tx_queues + 1); ++ if (err) { ++ airoha_qdma_set_tx_rate_limit(port, channel, 0, opt->quantum); ++ NL_SET_ERR_MSG_MOD(opt->extack, ++ "failed setting real_num_tx_queues"); ++ return err; ++ } ++ ++ set_bit(channel, port->qos_sq_bmap); ++ opt->qid = AIROHA_NUM_TX_RING + channel; ++ ++ return 0; ++} ++ ++static void airoha_tc_remove_htb_queue(struct airoha_gdm_port *port, int queue) ++{ ++ struct net_device *dev = port->dev; ++ ++ netif_set_real_num_tx_queues(dev, dev->real_num_tx_queues - 1); ++ airoha_qdma_set_tx_rate_limit(port, queue + 1, 0, 0); ++ clear_bit(queue, port->qos_sq_bmap); ++} ++ ++static int airoha_tc_htb_delete_leaf_queue(struct airoha_gdm_port *port, ++ struct tc_htb_qopt_offload *opt) ++{ ++ u32 channel = TC_H_MIN(opt->classid) % AIROHA_NUM_QOS_CHANNELS; ++ ++ if (!test_bit(channel, port->qos_sq_bmap)) { ++ NL_SET_ERR_MSG_MOD(opt->extack, "invalid queue id"); ++ return -EINVAL; ++ } ++ ++ airoha_tc_remove_htb_queue(port, channel); ++ ++ return 0; ++} ++ ++static int airoha_tc_htb_destroy(struct airoha_gdm_port *port) ++{ ++ int q; ++ ++ for_each_set_bit(q, port->qos_sq_bmap, AIROHA_NUM_QOS_CHANNELS) ++ airoha_tc_remove_htb_queue(port, q); ++ ++ return 0; ++} ++ ++static int airoha_tc_get_htb_get_leaf_queue(struct airoha_gdm_port *port, ++ struct tc_htb_qopt_offload *opt) ++{ ++ u32 channel = TC_H_MIN(opt->classid) % AIROHA_NUM_QOS_CHANNELS; ++ ++ if (!test_bit(channel, port->qos_sq_bmap)) { ++ NL_SET_ERR_MSG_MOD(opt->extack, "invalid queue id"); ++ return -EINVAL; ++ } ++ ++ opt->qid = channel; ++ ++ return 0; ++} ++ ++static int airoha_tc_setup_qdisc_htb(struct airoha_gdm_port *port, ++ struct tc_htb_qopt_offload *opt) ++{ ++ switch (opt->command) { ++ case TC_HTB_CREATE: ++ break; ++ case TC_HTB_DESTROY: ++ return airoha_tc_htb_destroy(port); ++ case TC_HTB_NODE_MODIFY: ++ case TC_HTB_LEAF_ALLOC_QUEUE: ++ return airoha_tc_htb_alloc_leaf_queue(port, opt); ++ case TC_HTB_LEAF_DEL: ++ case TC_HTB_LEAF_DEL_LAST: ++ case TC_HTB_LEAF_DEL_LAST_FORCE: ++ return airoha_tc_htb_delete_leaf_queue(port, opt); ++ case TC_HTB_LEAF_QUERY_QUEUE: ++ return airoha_tc_get_htb_get_leaf_queue(port, opt); ++ default: ++ return -EOPNOTSUPP; ++ } ++ ++ return 0; ++} ++ + static int airoha_dev_tc_setup(struct net_device *dev, enum tc_setup_type type, + void *type_data) + { +@@ -2818,6 +3096,8 @@ static int airoha_dev_tc_setup(struct ne + switch (type) { + case TC_SETUP_QDISC_ETS: + return airoha_tc_setup_qdisc_ets(port, type_data); ++ case TC_SETUP_QDISC_HTB: ++ return airoha_tc_setup_qdisc_htb(port, type_data); + default: + return -EOPNOTSUPP; + } +@@ -2868,7 +3148,8 @@ static int airoha_alloc_gdm_port(struct + } + + dev = devm_alloc_etherdev_mqs(eth->dev, sizeof(*port), +- AIROHA_NUM_TX_RING, AIROHA_NUM_RX_RING); ++ AIROHA_NUM_NETDEV_TX_RINGS, ++ AIROHA_NUM_RX_RING); + if (!dev) { + dev_err(eth->dev, "alloc_etherdev failed\n"); + return -ENOMEM; +@@ -2888,6 +3169,11 @@ static int airoha_alloc_gdm_port(struct + dev->irq = qdma->irq; + SET_NETDEV_DEV(dev, eth->dev); + ++ /* reserve hw queues for HTB offloading */ ++ err = netif_set_real_num_tx_queues(dev, AIROHA_NUM_TX_RING); ++ if (err) ++ return err; ++ + err = of_get_ethdev_address(np, dev); + if (err) { + if (err == -EPROBE_DEFER) diff --git a/target/linux/airoha/patches-6.6/039-v6.14-cpufreq-airoha-Add-EN7581-CPUFreq-SMCCC-driver.patch b/target/linux/airoha/patches-6.6/039-v6.14-cpufreq-airoha-Add-EN7581-CPUFreq-SMCCC-driver.patch new file mode 100644 index 00000000000000..0db82d55e14451 --- /dev/null +++ b/target/linux/airoha/patches-6.6/039-v6.14-cpufreq-airoha-Add-EN7581-CPUFreq-SMCCC-driver.patch @@ -0,0 +1,232 @@ +From 84cf9e541cccb8cb698518a9897942e8c78f1d83 Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Thu, 9 Jan 2025 14:12:58 +0100 +Subject: [PATCH] cpufreq: airoha: Add EN7581 CPUFreq SMCCC driver + +Add simple CPU Freq driver for Airoha EN7581 SoC that control CPU +frequency scaling with SMC APIs and register a generic "cpufreq-dt" +device. + +All CPU share the same frequency and can't be controlled independently. +CPU frequency is controlled by the attached PM domain. + +Add SoC compatible to cpufreq-dt-plat block list as a dedicated cpufreq +driver is needed with OPP v2 nodes declared in DTS. + +Signed-off-by: Christian Marangi +Signed-off-by: Viresh Kumar +--- + drivers/cpufreq/Kconfig.arm | 8 ++ + drivers/cpufreq/Makefile | 1 + + drivers/cpufreq/airoha-cpufreq.c | 152 +++++++++++++++++++++++++++ + drivers/cpufreq/cpufreq-dt-platdev.c | 2 + + 4 files changed, 163 insertions(+) + create mode 100644 drivers/cpufreq/airoha-cpufreq.c + +--- a/drivers/cpufreq/Kconfig.arm ++++ b/drivers/cpufreq/Kconfig.arm +@@ -41,6 +41,14 @@ config ARM_ALLWINNER_SUN50I_CPUFREQ_NVME + To compile this driver as a module, choose M here: the + module will be called sun50i-cpufreq-nvmem. + ++config ARM_AIROHA_SOC_CPUFREQ ++ tristate "Airoha EN7581 SoC CPUFreq support" ++ depends on ARCH_AIROHA || COMPILE_TEST ++ select PM_OPP ++ default ARCH_AIROHA ++ help ++ This adds the CPUFreq driver for Airoha EN7581 SoCs. ++ + config ARM_APPLE_SOC_CPUFREQ + tristate "Apple Silicon SoC CPUFreq support" + depends on ARCH_APPLE || (COMPILE_TEST && 64BIT) +--- a/drivers/cpufreq/Makefile ++++ b/drivers/cpufreq/Makefile +@@ -52,6 +52,7 @@ obj-$(CONFIG_X86_AMD_FREQ_SENSITIVITY) + + + ################################################################################## + # ARM SoC drivers ++obj-$(CONFIG_ARM_AIROHA_SOC_CPUFREQ) += airoha-cpufreq.o + obj-$(CONFIG_ARM_APPLE_SOC_CPUFREQ) += apple-soc-cpufreq.o + obj-$(CONFIG_ARM_ARMADA_37XX_CPUFREQ) += armada-37xx-cpufreq.o + obj-$(CONFIG_ARM_ARMADA_8K_CPUFREQ) += armada-8k-cpufreq.o +--- /dev/null ++++ b/drivers/cpufreq/airoha-cpufreq.c +@@ -0,0 +1,166 @@ ++// SPDX-License-Identifier: GPL-2.0 ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "cpufreq-dt.h" ++ ++struct airoha_cpufreq_priv { ++ int opp_token; ++ struct device **virt_devs; ++ struct platform_device *cpufreq_dt; ++}; ++ ++static struct platform_device *cpufreq_pdev; ++ ++/* NOP function to disable OPP from setting clock */ ++static int airoha_cpufreq_config_clks_nop(struct device *dev, ++ struct opp_table *opp_table, ++ struct dev_pm_opp *old_opp, ++ struct dev_pm_opp *opp, ++ void *data, bool scaling_down) ++{ ++ return 0; ++} ++ ++static const char * const airoha_cpufreq_clk_names[] = { "cpu", NULL }; ++static const char * const airoha_cpufreq_pd_names[] = { "perf", NULL }; ++ ++static int airoha_cpufreq_probe(struct platform_device *pdev) ++{ ++ struct dev_pm_opp_config config = { ++ .clk_names = airoha_cpufreq_clk_names, ++ .config_clks = airoha_cpufreq_config_clks_nop, ++ .genpd_names = airoha_cpufreq_pd_names, ++ }; ++ struct platform_device *cpufreq_dt; ++ struct airoha_cpufreq_priv *priv; ++ struct device *dev = &pdev->dev; ++ struct device **virt_devs = NULL; ++ struct device *cpu_dev; ++ int ret; ++ ++ /* CPUs refer to the same OPP table */ ++ cpu_dev = get_cpu_device(0); ++ if (!cpu_dev) ++ return -ENODEV; ++ ++ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); ++ if (!priv) ++ return -ENOMEM; ++ ++ /* Set OPP table conf with NOP config_clks */ ++ priv->opp_token = dev_pm_opp_set_config(cpu_dev, &config); ++ if (priv->opp_token < 0) ++ return dev_err_probe(dev, priv->opp_token, "Failed to set OPP config\n"); ++ ++ /* Set Attached PM for OPP ACTIVE */ ++ if (virt_devs) { ++ const char * const *name = airoha_cpufreq_pd_names; ++ int i, j; ++ ++ for (i = 0; *name; i++, name++) { ++ ret = pm_runtime_resume_and_get(virt_devs[i]); ++ if (ret) { ++ dev_err(cpu_dev, "failed to resume %s: %d\n", ++ *name, ret); ++ ++ /* Rollback previous PM runtime calls */ ++ name = config.genpd_names; ++ for (j = 0; *name && j < i; j++, name++) ++ pm_runtime_put(virt_devs[j]); ++ ++ goto err_register_cpufreq; ++ } ++ } ++ priv->virt_devs = virt_devs; ++ } ++ ++ cpufreq_dt = platform_device_register_simple("cpufreq-dt", -1, NULL, 0); ++ ret = PTR_ERR_OR_ZERO(cpufreq_dt); ++ if (ret) { ++ dev_err(dev, "failed to create cpufreq-dt device: %d\n", ret); ++ goto err_register_cpufreq; ++ } ++ ++ priv->cpufreq_dt = cpufreq_dt; ++ platform_set_drvdata(pdev, priv); ++ ++ return 0; ++ ++err_register_cpufreq: ++ dev_pm_opp_clear_config(priv->opp_token); ++ ++ return ret; ++} ++ ++static void airoha_cpufreq_remove(struct platform_device *pdev) ++{ ++ struct airoha_cpufreq_priv *priv = platform_get_drvdata(pdev); ++ const char * const *name = airoha_cpufreq_pd_names; ++ int i; ++ ++ platform_device_unregister(priv->cpufreq_dt); ++ ++ dev_pm_opp_clear_config(priv->opp_token); ++ ++ for (i = 0; *name; i++, name++) ++ pm_runtime_put(priv->virt_devs[i]); ++} ++ ++static struct platform_driver airoha_cpufreq_driver = { ++ .probe = airoha_cpufreq_probe, ++ .remove_new = airoha_cpufreq_remove, ++ .driver = { ++ .name = "airoha-cpufreq", ++ }, ++}; ++ ++static const struct of_device_id airoha_cpufreq_match_list[] __initconst = { ++ { .compatible = "airoha,en7581" }, ++ {}, ++}; ++MODULE_DEVICE_TABLE(of, airoha_cpufreq_match_list); ++ ++static int __init airoha_cpufreq_init(void) ++{ ++ struct device_node *np = of_find_node_by_path("/"); ++ const struct of_device_id *match; ++ int ret; ++ ++ if (!np) ++ return -ENODEV; ++ ++ match = of_match_node(airoha_cpufreq_match_list, np); ++ of_node_put(np); ++ if (!match) ++ return -ENODEV; ++ ++ ret = platform_driver_register(&airoha_cpufreq_driver); ++ if (unlikely(ret < 0)) ++ return ret; ++ ++ cpufreq_pdev = platform_device_register_data(NULL, "airoha-cpufreq", ++ -1, match, sizeof(*match)); ++ ret = PTR_ERR_OR_ZERO(cpufreq_pdev); ++ if (ret) ++ platform_driver_unregister(&airoha_cpufreq_driver); ++ ++ return ret; ++} ++module_init(airoha_cpufreq_init); ++ ++static void __exit airoha_cpufreq_exit(void) ++{ ++ platform_device_unregister(cpufreq_pdev); ++ platform_driver_unregister(&airoha_cpufreq_driver); ++} ++module_exit(airoha_cpufreq_exit); ++ ++MODULE_AUTHOR("Christian Marangi "); ++MODULE_DESCRIPTION("CPUfreq driver for Airoha SoCs"); ++MODULE_LICENSE("GPL"); +--- a/drivers/cpufreq/cpufreq-dt-platdev.c ++++ b/drivers/cpufreq/cpufreq-dt-platdev.c +@@ -103,6 +103,8 @@ static const struct of_device_id allowli + * platforms using "operating-points-v2" property. + */ + static const struct of_device_id blocklist[] __initconst = { ++ { .compatible = "airoha,en7581", }, ++ + { .compatible = "allwinner,sun50i-h6", }, + + { .compatible = "apple,arm-platform", }, diff --git a/target/linux/airoha/patches-6.6/039-v6.14-net-airoha-Enforce-ETS-Qdisc-priomap.patch b/target/linux/airoha/patches-6.6/039-v6.14-net-airoha-Enforce-ETS-Qdisc-priomap.patch new file mode 100644 index 00000000000000..2753972070227a --- /dev/null +++ b/target/linux/airoha/patches-6.6/039-v6.14-net-airoha-Enforce-ETS-Qdisc-priomap.patch @@ -0,0 +1,53 @@ +From b56e4d660a9688ff83f5cbdc6e3ea063352d0d79 Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Sun, 12 Jan 2025 19:32:45 +0100 +Subject: [PATCH] net: airoha: Enforce ETS Qdisc priomap + +EN7581 SoC supports fixed QoS band priority where WRR queues have lowest +priorities with respect to SP ones. +E.g: WRR0, WRR1, .., WRRm, SP0, SP1, .., SPn + +Enforce ETS Qdisc priomap according to the hw capabilities. + +Suggested-by: Davide Caratti +Signed-off-by: Lorenzo Bianconi +Reviewed-by: Davide Caratti +Link: https://patch.msgid.link/20250112-airoha_ets_priomap-v1-1-fb616de159ba@kernel.org +Signed-off-by: Jakub Kicinski +--- + drivers/net/ethernet/mediatek/airoha_eth.c | 17 +++++++++++++++-- + 1 file changed, 15 insertions(+), 2 deletions(-) + +--- a/drivers/net/ethernet/mediatek/airoha_eth.c ++++ b/drivers/net/ethernet/mediatek/airoha_eth.c +@@ -2786,7 +2786,7 @@ static int airoha_qdma_set_tx_ets_sched( + struct tc_ets_qopt_offload_replace_params *p = &opt->replace_params; + enum tx_sched_mode mode = TC_SCH_SP; + u16 w[AIROHA_NUM_QOS_QUEUES] = {}; +- int i, nstrict = 0; ++ int i, nstrict = 0, nwrr, qidx; + + if (p->bands > AIROHA_NUM_QOS_QUEUES) + return -EINVAL; +@@ -2800,7 +2800,20 @@ static int airoha_qdma_set_tx_ets_sched( + if (nstrict == AIROHA_NUM_QOS_QUEUES - 1) + return -EINVAL; + +- for (i = 0; i < p->bands - nstrict; i++) ++ /* EN7581 SoC supports fixed QoS band priority where WRR queues have ++ * lowest priorities with respect to SP ones. ++ * e.g: WRR0, WRR1, .., WRRm, SP0, SP1, .., SPn ++ */ ++ nwrr = p->bands - nstrict; ++ qidx = nstrict && nwrr ? nstrict : 0; ++ for (i = 1; i <= p->bands; i++) { ++ if (p->priomap[i % AIROHA_NUM_QOS_QUEUES] != qidx) ++ return -EINVAL; ++ ++ qidx = i == nwrr ? 0 : qidx + 1; ++ } ++ ++ for (i = 0; i < nwrr; i++) + w[i] = p->weights[nstrict + i]; + + if (!nstrict) diff --git a/target/linux/airoha/patches-6.6/040-v6.14-pmdomain-airoha-Add-Airoha-CPU-PM-Domain-support.patch b/target/linux/airoha/patches-6.6/040-v6.14-pmdomain-airoha-Add-Airoha-CPU-PM-Domain-support.patch new file mode 100644 index 00000000000000..8dc8a3d304a4c1 --- /dev/null +++ b/target/linux/airoha/patches-6.6/040-v6.14-pmdomain-airoha-Add-Airoha-CPU-PM-Domain-support.patch @@ -0,0 +1,196 @@ +From 82e703dd438b71432cc0ccbb90925d1e32dd014a Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Thu, 9 Jan 2025 14:12:57 +0100 +Subject: [PATCH] pmdomain: airoha: Add Airoha CPU PM Domain support + +Add Airoha CPU PM Domain support to control frequency and power of CPU +present on Airoha EN7581 SoC. + +Frequency and power can be controlled with the use of the SMC command by +passing the performance state. The driver also expose a read-only clock +that expose the current CPU frequency with SMC command. + +Signed-off-by: Christian Marangi +Link: https://lore.kernel.org/r/20250109131313.32317-1-ansuelsmth@gmail.com +Signed-off-by: Ulf Hansson +--- + drivers/pmdomain/mediatek/Kconfig | 12 ++ + drivers/pmdomain/mediatek/Makefile | 1 + + .../pmdomain/mediatek/airoha-cpu-pmdomain.c | 144 ++++++++++++++++++ + 3 files changed, 157 insertions(+) + create mode 100644 drivers/pmdomain/mediatek/airoha-cpu-pmdomain.c + +--- a/drivers/soc/mediatek/Kconfig ++++ b/drivers/soc/mediatek/Kconfig +@@ -2,6 +2,17 @@ + # + # MediaTek SoC drivers + # ++config AIROHA_CPU_PM_DOMAIN ++ tristate "Airoha CPU power domain" ++ default ARCH_AIROHA ++ depends on PM ++ select PM_GENERIC_DOMAINS ++ help ++ Say y here to enable CPU power domain support for Airoha SoC. ++ ++ CPU frequency and power is controlled by ATF with SMC command to ++ set performance states. ++ + menu "MediaTek SoC drivers" + depends on ARCH_MEDIATEK || COMPILE_TEST + +--- a/drivers/pmdomain/mediatek/Makefile ++++ b/drivers/pmdomain/mediatek/Makefile +@@ -1,3 +1,4 @@ + # SPDX-License-Identifier: GPL-2.0-only + obj-$(CONFIG_MTK_SCPSYS) += mtk-scpsys.o + obj-$(CONFIG_MTK_SCPSYS_PM_DOMAINS) += mtk-pm-domains.o ++obj-$(CONFIG_AIROHA_CPU_PM_DOMAIN) += airoha-cpu-pmdomain.o +--- /dev/null ++++ b/drivers/pmdomain/mediatek/airoha-cpu-pmdomain.c +@@ -0,0 +1,144 @@ ++// SPDX-License-Identifier: GPL-2.0 ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define AIROHA_SIP_AVS_HANDLE 0x82000301 ++#define AIROHA_AVS_OP_BASE 0xddddddd0 ++#define AIROHA_AVS_OP_MASK GENMASK(1, 0) ++#define AIROHA_AVS_OP_FREQ_DYN_ADJ (AIROHA_AVS_OP_BASE | \ ++ FIELD_PREP(AIROHA_AVS_OP_MASK, 0x1)) ++#define AIROHA_AVS_OP_GET_FREQ (AIROHA_AVS_OP_BASE | \ ++ FIELD_PREP(AIROHA_AVS_OP_MASK, 0x2)) ++ ++struct airoha_cpu_pmdomain_priv { ++ struct clk_hw hw; ++ struct generic_pm_domain pd; ++}; ++ ++static long airoha_cpu_pmdomain_clk_round(struct clk_hw *hw, unsigned long rate, ++ unsigned long *parent_rate) ++{ ++ return rate; ++} ++ ++static unsigned long airoha_cpu_pmdomain_clk_get(struct clk_hw *hw, ++ unsigned long parent_rate) ++{ ++ struct arm_smccc_res res; ++ ++ arm_smccc_1_1_invoke(AIROHA_SIP_AVS_HANDLE, AIROHA_AVS_OP_GET_FREQ, ++ 0, 0, 0, 0, 0, 0, &res); ++ ++ /* SMCCC returns freq in MHz */ ++ return (int)(res.a0 * 1000 * 1000); ++} ++ ++/* Airoha CPU clk SMCC is always enabled */ ++static int airoha_cpu_pmdomain_clk_is_enabled(struct clk_hw *hw) ++{ ++ return true; ++} ++ ++static const struct clk_ops airoha_cpu_pmdomain_clk_ops = { ++ .recalc_rate = airoha_cpu_pmdomain_clk_get, ++ .is_enabled = airoha_cpu_pmdomain_clk_is_enabled, ++ .round_rate = airoha_cpu_pmdomain_clk_round, ++}; ++ ++static int airoha_cpu_pmdomain_set_performance_state(struct generic_pm_domain *domain, ++ unsigned int state) ++{ ++ struct arm_smccc_res res; ++ ++ arm_smccc_1_1_invoke(AIROHA_SIP_AVS_HANDLE, AIROHA_AVS_OP_FREQ_DYN_ADJ, ++ 0, state, 0, 0, 0, 0, &res); ++ ++ /* SMC signal correct apply by unsetting BIT 0 */ ++ return res.a0 & BIT(0) ? -EINVAL : 0; ++} ++ ++static int airoha_cpu_pmdomain_probe(struct platform_device *pdev) ++{ ++ struct airoha_cpu_pmdomain_priv *priv; ++ struct device *dev = &pdev->dev; ++ const struct clk_init_data init = { ++ .name = "cpu", ++ .ops = &airoha_cpu_pmdomain_clk_ops, ++ /* Clock with no set_rate, can't cache */ ++ .flags = CLK_GET_RATE_NOCACHE, ++ }; ++ struct generic_pm_domain *pd; ++ int ret; ++ ++ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); ++ if (!priv) ++ return -ENOMEM; ++ ++ /* Init and register a get-only clk for Cpufreq */ ++ priv->hw.init = &init; ++ ret = devm_clk_hw_register(dev, &priv->hw); ++ if (ret) ++ return ret; ++ ++ ret = devm_of_clk_add_hw_provider(dev, of_clk_hw_simple_get, ++ &priv->hw); ++ if (ret) ++ return ret; ++ ++ /* Init and register a PD for CPU */ ++ pd = &priv->pd; ++ pd->name = "cpu_pd"; ++ pd->flags = GENPD_FLAG_ALWAYS_ON; ++ pd->set_performance_state = airoha_cpu_pmdomain_set_performance_state; ++ ++ ret = pm_genpd_init(pd, NULL, false); ++ if (ret) ++ return ret; ++ ++ ret = of_genpd_add_provider_simple(dev->of_node, pd); ++ if (ret) ++ goto err_add_provider; ++ ++ platform_set_drvdata(pdev, priv); ++ ++ return 0; ++ ++err_add_provider: ++ pm_genpd_remove(pd); ++ ++ return ret; ++} ++ ++static void airoha_cpu_pmdomain_remove(struct platform_device *pdev) ++{ ++ struct airoha_cpu_pmdomain_priv *priv = platform_get_drvdata(pdev); ++ ++ of_genpd_del_provider(pdev->dev.of_node); ++ pm_genpd_remove(&priv->pd); ++} ++ ++static const struct of_device_id airoha_cpu_pmdomain_of_match[] = { ++ { .compatible = "airoha,en7581-cpufreq" }, ++ { }, ++}; ++MODULE_DEVICE_TABLE(of, airoha_cpu_pmdomain_of_match); ++ ++static struct platform_driver airoha_cpu_pmdomain_driver = { ++ .probe = airoha_cpu_pmdomain_probe, ++ .remove_new = airoha_cpu_pmdomain_remove, ++ .driver = { ++ .name = "airoha-cpu-pmdomain", ++ .of_match_table = airoha_cpu_pmdomain_of_match, ++ }, ++}; ++module_platform_driver(airoha_cpu_pmdomain_driver); ++ ++MODULE_AUTHOR("Christian Marangi "); ++MODULE_DESCRIPTION("CPU PM domain driver for Airoha SoCs"); ++MODULE_LICENSE("GPL"); diff --git a/target/linux/airoha/patches-6.6/041-01-v6.14-clk-en7523-Rework-clock-handling-for-different-clock.patch b/target/linux/airoha/patches-6.6/041-01-v6.14-clk-en7523-Rework-clock-handling-for-different-clock.patch new file mode 100644 index 00000000000000..96d2bbf28ef81f --- /dev/null +++ b/target/linux/airoha/patches-6.6/041-01-v6.14-clk-en7523-Rework-clock-handling-for-different-clock.patch @@ -0,0 +1,83 @@ +From e4a9748e7103c47e575459db2b6a77d14f34da2b Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Tue, 14 Jan 2025 00:10:02 +0100 +Subject: [PATCH 1/4] clk: en7523: Rework clock handling for different clock + numbers + +Airoha EN7581 SoC have additional clock compared to EN7523 but current +driver permits to only support up to EN7523 clock numbers. + +To handle this, rework the clock handling and permit to declare the +clocks number in match_data and alloca clk_data based on the compatible +match_data. + +Signed-off-by: Christian Marangi +Link: https://lore.kernel.org/r/20250113231030.6735-2-ansuelsmth@gmail.com +Signed-off-by: Stephen Boyd +--- + drivers/clk/clk-en7523.c | 14 ++++++++------ + 1 file changed, 8 insertions(+), 6 deletions(-) + +--- a/drivers/clk/clk-en7523.c ++++ b/drivers/clk/clk-en7523.c +@@ -75,6 +75,7 @@ struct en_rst_data { + }; + + struct en_clk_soc_data { ++ u32 num_clocks; + const struct clk_ops pcie_ops; + int (*hw_init)(struct platform_device *pdev, + struct clk_hw_onecell_data *clk_data); +@@ -504,8 +505,6 @@ static void en7523_register_clocks(struc + u32 rate; + int i; + +- clk_data->num = EN7523_NUM_CLOCKS; +- + for (i = 0; i < ARRAY_SIZE(en7523_base_clks); i++) { + const struct en_clk_desc *desc = &en7523_base_clks[i]; + u32 reg = desc->div_reg ? desc->div_reg : desc->base_reg; +@@ -587,8 +586,6 @@ static void en7581_register_clocks(struc + + hw = en7523_register_pcie_clk(dev, base); + clk_data->hws[EN7523_CLK_PCIE] = hw; +- +- clk_data->num = EN7523_NUM_CLOCKS; + } + + static int en7523_reset_update(struct reset_controller_dev *rcdev, +@@ -702,13 +699,15 @@ static int en7523_clk_probe(struct platf + struct clk_hw_onecell_data *clk_data; + int r; + ++ soc_data = device_get_match_data(&pdev->dev); ++ + clk_data = devm_kzalloc(&pdev->dev, +- struct_size(clk_data, hws, EN7523_NUM_CLOCKS), ++ struct_size(clk_data, hws, soc_data->num_clocks), + GFP_KERNEL); + if (!clk_data) + return -ENOMEM; + +- soc_data = device_get_match_data(&pdev->dev); ++ clk_data->num = soc_data->num_clocks; + r = soc_data->hw_init(pdev, clk_data); + if (r) + return r; +@@ -717,6 +716,7 @@ static int en7523_clk_probe(struct platf + } + + static const struct en_clk_soc_data en7523_data = { ++ .num_clocks = ARRAY_SIZE(en7523_base_clks) + 1, + .pcie_ops = { + .is_enabled = en7523_pci_is_enabled, + .prepare = en7523_pci_prepare, +@@ -726,6 +726,8 @@ static const struct en_clk_soc_data en75 + }; + + static const struct en_clk_soc_data en7581_data = { ++ /* We increment num_clocks by 1 to account for additional PCIe clock */ ++ .num_clocks = ARRAY_SIZE(en7581_base_clks) + 1, + .pcie_ops = { + .is_enabled = en7581_pci_is_enabled, + .enable = en7581_pci_enable, diff --git a/target/linux/airoha/patches-6.6/041-02-v6.14-dt-bindings-clock-drop-NUM_CLOCKS-define-for-EN7581.patch b/target/linux/airoha/patches-6.6/041-02-v6.14-dt-bindings-clock-drop-NUM_CLOCKS-define-for-EN7581.patch new file mode 100644 index 00000000000000..5db79a47488f91 --- /dev/null +++ b/target/linux/airoha/patches-6.6/041-02-v6.14-dt-bindings-clock-drop-NUM_CLOCKS-define-for-EN7581.patch @@ -0,0 +1,26 @@ +From 02d3b7557ce28c373ea1e925ae16ab5988284313 Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Tue, 14 Jan 2025 00:10:03 +0100 +Subject: [PATCH 2/4] dt-bindings: clock: drop NUM_CLOCKS define for EN7581 + +Drop NUM_CLOCKS define for EN7581 include. This is not a binding and +should not be placed here. Value is derived internally in the user +driver. + +Signed-off-by: Christian Marangi +Acked-by: Krzysztof Kozlowski +Link: https://lore.kernel.org/r/20250113231030.6735-3-ansuelsmth@gmail.com +Signed-off-by: Stephen Boyd +--- + include/dt-bindings/clock/en7523-clk.h | 2 -- + 1 file changed, 2 deletions(-) + +--- a/include/dt-bindings/clock/en7523-clk.h ++++ b/include/dt-bindings/clock/en7523-clk.h +@@ -12,6 +12,4 @@ + #define EN7523_CLK_CRYPTO 6 + #define EN7523_CLK_PCIE 7 + +-#define EN7523_NUM_CLOCKS 8 +- + #endif /* _DT_BINDINGS_CLOCK_AIROHA_EN7523_H_ */ diff --git a/target/linux/airoha/patches-6.6/041-03-v6.14-dt-bindings-clock-add-ID-for-eMMC-for-EN7581.patch b/target/linux/airoha/patches-6.6/041-03-v6.14-dt-bindings-clock-add-ID-for-eMMC-for-EN7581.patch new file mode 100644 index 00000000000000..a3f0c9e6fea76e --- /dev/null +++ b/target/linux/airoha/patches-6.6/041-03-v6.14-dt-bindings-clock-add-ID-for-eMMC-for-EN7581.patch @@ -0,0 +1,25 @@ +From 82108ad3285f58f314ad41398f44017c7dbe44de Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Tue, 14 Jan 2025 00:10:04 +0100 +Subject: [PATCH 3/4] dt-bindings: clock: add ID for eMMC for EN7581 + +Add ID for eMMC for EN7581. This is to control clock selection of eMMC +between 200MHz and 150MHz. + +Signed-off-by: Christian Marangi +Acked-by: Conor Dooley +Link: https://lore.kernel.org/r/20250113231030.6735-4-ansuelsmth@gmail.com +Signed-off-by: Stephen Boyd +--- + include/dt-bindings/clock/en7523-clk.h | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/include/dt-bindings/clock/en7523-clk.h ++++ b/include/dt-bindings/clock/en7523-clk.h +@@ -12,4 +12,6 @@ + #define EN7523_CLK_CRYPTO 6 + #define EN7523_CLK_PCIE 7 + ++#define EN7581_CLK_EMMC 8 ++ + #endif /* _DT_BINDINGS_CLOCK_AIROHA_EN7523_H_ */ diff --git a/target/linux/airoha/patches-6.6/041-04-v6.14-clk-en7523-Add-clock-for-eMMC-for-EN7581.patch b/target/linux/airoha/patches-6.6/041-04-v6.14-clk-en7523-Add-clock-for-eMMC-for-EN7581.patch new file mode 100644 index 00000000000000..6c8a3300bee185 --- /dev/null +++ b/target/linux/airoha/patches-6.6/041-04-v6.14-clk-en7523-Add-clock-for-eMMC-for-EN7581.patch @@ -0,0 +1,41 @@ +From bfe257f9780d8f77045a7da6ec959ee0659d2f98 Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Tue, 14 Jan 2025 00:10:05 +0100 +Subject: [PATCH 4/4] clk: en7523: Add clock for eMMC for EN7581 + +Add clock for eMMC for EN7581. This is used to give info of the current +eMMC source clock and to switch it from 200MHz or 150MHz. + +Signed-off-by: Christian Marangi +Link: https://lore.kernel.org/r/20250113231030.6735-5-ansuelsmth@gmail.com +Signed-off-by: Stephen Boyd +--- + drivers/clk/clk-en7523.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +--- a/drivers/clk/clk-en7523.c ++++ b/drivers/clk/clk-en7523.c +@@ -91,6 +91,7 @@ static const u32 emi7581_base[] = { 5400 + static const u32 bus7581_base[] = { 600000000, 540000000 }; + static const u32 npu7581_base[] = { 800000000, 750000000, 720000000, 600000000 }; + static const u32 crypto_base[] = { 540000000, 480000000 }; ++static const u32 emmc7581_base[] = { 200000000, 150000000 }; + + static const struct en_clk_desc en7523_base_clks[] = { + { +@@ -281,6 +282,15 @@ static const struct en_clk_desc en7581_b + .base_shift = 0, + .base_values = crypto_base, + .n_base_values = ARRAY_SIZE(crypto_base), ++ }, { ++ .id = EN7581_CLK_EMMC, ++ .name = "emmc", ++ ++ .base_reg = REG_CRYPTO_CLKSRC2, ++ .base_bits = 1, ++ .base_shift = 12, ++ .base_values = emmc7581_base, ++ .n_base_values = ARRAY_SIZE(emmc7581_base), + } + }; + diff --git a/target/linux/airoha/patches-6.6/042-01-v6.14-PCI-mediatek-gen3-Rely-on-clk_bulk_prepare_enable-in.patch b/target/linux/airoha/patches-6.6/042-01-v6.14-PCI-mediatek-gen3-Rely-on-clk_bulk_prepare_enable-in.patch new file mode 100644 index 00000000000000..9e353f7926dc77 --- /dev/null +++ b/target/linux/airoha/patches-6.6/042-01-v6.14-PCI-mediatek-gen3-Rely-on-clk_bulk_prepare_enable-in.patch @@ -0,0 +1,57 @@ +From 0e7a622da17da0042294860cdb7a2fac091d25b1 Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Wed, 8 Jan 2025 10:50:40 +0100 +Subject: [PATCH 1/6] PCI: mediatek-gen3: Rely on clk_bulk_prepare_enable() in + mtk_pcie_en7581_power_up() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Replace clk_bulk_prepare() and clk_bulk_enable() with +clk_bulk_prepare_enable() in mtk_pcie_en7581_power_up() routine. + +Link: https://lore.kernel.org/r/20250108-pcie-en7581-fixes-v6-1-21ac939a3b9b@kernel.org +Signed-off-by: Lorenzo Bianconi +Signed-off-by: Krzysztof Wilczyński +Reviewed-by: AngeloGioacchino Del Regno +Reviewed-by: Manivannan Sadhasivam +--- + drivers/pci/controller/pcie-mediatek-gen3.c | 14 +++----------- + 1 file changed, 3 insertions(+), 11 deletions(-) + +--- a/drivers/pci/controller/pcie-mediatek-gen3.c ++++ b/drivers/pci/controller/pcie-mediatek-gen3.c +@@ -907,12 +907,6 @@ static int mtk_pcie_en7581_power_up(stru + pm_runtime_enable(dev); + pm_runtime_get_sync(dev); + +- err = clk_bulk_prepare(pcie->num_clks, pcie->clks); +- if (err) { +- dev_err(dev, "failed to prepare clock\n"); +- goto err_clk_prepare; +- } +- + val = FIELD_PREP(PCIE_VAL_LN0_DOWNSTREAM, 0x47) | + FIELD_PREP(PCIE_VAL_LN1_DOWNSTREAM, 0x47) | + FIELD_PREP(PCIE_VAL_LN0_UPSTREAM, 0x41) | +@@ -925,17 +919,15 @@ static int mtk_pcie_en7581_power_up(stru + FIELD_PREP(PCIE_K_FINETUNE_MAX, 0xf); + writel_relaxed(val, pcie->base + PCIE_PIPE4_PIE8_REG); + +- err = clk_bulk_enable(pcie->num_clks, pcie->clks); ++ err = clk_bulk_prepare_enable(pcie->num_clks, pcie->clks); + if (err) { + dev_err(dev, "failed to prepare clock\n"); +- goto err_clk_enable; ++ goto err_clk_prepare_enable; + } + + return 0; + +-err_clk_enable: +- clk_bulk_unprepare(pcie->num_clks, pcie->clks); +-err_clk_prepare: ++err_clk_prepare_enable: + pm_runtime_put_sync(dev); + pm_runtime_disable(dev); + reset_control_bulk_assert(pcie->soc->phy_resets.num_resets, pcie->phy_resets); diff --git a/target/linux/airoha/patches-6.6/042-02-v6.14-PCI-mediatek-gen3-Move-reset-assert-callbacks-in-.po.patch b/target/linux/airoha/patches-6.6/042-02-v6.14-PCI-mediatek-gen3-Move-reset-assert-callbacks-in-.po.patch new file mode 100644 index 00000000000000..ed5636d4fda56c --- /dev/null +++ b/target/linux/airoha/patches-6.6/042-02-v6.14-PCI-mediatek-gen3-Move-reset-assert-callbacks-in-.po.patch @@ -0,0 +1,86 @@ +From e4c7dfd953f7618f0ccb70d87c1629634f306fab Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Wed, 8 Jan 2025 10:50:41 +0100 +Subject: [PATCH 2/6] PCI: mediatek-gen3: Move reset/assert callbacks in + .power_up() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +In order to make the code more readable, the reset_control_bulk_assert() +function for PHY reset lines is moved to make it pair with +reset_control_bulk_deassert() in mtk_pcie_power_up() and +mtk_pcie_en7581_power_up(). The same change is done for +reset_control_assert() used to assert MAC reset line. + +Introduce PCIE_MTK_RESET_TIME_US macro for the time needed to +complete PCIe reset on MediaTek controller. + +Link: https://lore.kernel.org/r/20250108-pcie-en7581-fixes-v6-2-21ac939a3b9b@kernel.org +Signed-off-by: Lorenzo Bianconi +Signed-off-by: Krzysztof Wilczyński +Reviewed-by: AngeloGioacchino Del Regno +Reviewed-by: Manivannan Sadhasivam +--- + drivers/pci/controller/pcie-mediatek-gen3.c | 28 +++++++++++++-------- + 1 file changed, 18 insertions(+), 10 deletions(-) + +--- a/drivers/pci/controller/pcie-mediatek-gen3.c ++++ b/drivers/pci/controller/pcie-mediatek-gen3.c +@@ -120,6 +120,8 @@ + + #define MAX_NUM_PHY_RESETS 3 + ++#define PCIE_MTK_RESET_TIME_US 10 ++ + /* Time in ms needed to complete PCIe reset on EN7581 SoC */ + #define PCIE_EN7581_RESET_TIME_MS 100 + +@@ -875,9 +877,14 @@ static int mtk_pcie_en7581_power_up(stru + u32 val; + + /* +- * Wait for the time needed to complete the bulk assert in +- * mtk_pcie_setup for EN7581 SoC. ++ * The controller may have been left out of reset by the bootloader ++ * so make sure that we get a clean start by asserting resets here. + */ ++ reset_control_bulk_assert(pcie->soc->phy_resets.num_resets, ++ pcie->phy_resets); ++ reset_control_assert(pcie->mac_reset); ++ ++ /* Wait for the time needed to complete the reset lines assert. */ + mdelay(PCIE_EN7581_RESET_TIME_MS); + + err = phy_init(pcie->phy); +@@ -944,6 +951,15 @@ static int mtk_pcie_power_up(struct mtk_ + struct device *dev = pcie->dev; + int err; + ++ /* ++ * The controller may have been left out of reset by the bootloader ++ * so make sure that we get a clean start by asserting resets here. ++ */ ++ reset_control_bulk_assert(pcie->soc->phy_resets.num_resets, ++ pcie->phy_resets); ++ reset_control_assert(pcie->mac_reset); ++ usleep_range(PCIE_MTK_RESET_TIME_US, 2 * PCIE_MTK_RESET_TIME_US); ++ + /* PHY power on and enable pipe clock */ + err = reset_control_bulk_deassert(pcie->soc->phy_resets.num_resets, pcie->phy_resets); + if (err) { +@@ -1016,14 +1032,6 @@ static int mtk_pcie_setup(struct mtk_gen + * counter since the bulk is shared. + */ + reset_control_bulk_deassert(pcie->soc->phy_resets.num_resets, pcie->phy_resets); +- /* +- * The controller may have been left out of reset by the bootloader +- * so make sure that we get a clean start by asserting resets here. +- */ +- reset_control_bulk_assert(pcie->soc->phy_resets.num_resets, pcie->phy_resets); +- +- reset_control_assert(pcie->mac_reset); +- usleep_range(10, 20); + + /* Don't touch the hardware registers before power up */ + err = pcie->soc->power_up(pcie); diff --git a/target/linux/airoha/patches-6.6/042-03-v6.14-PCI-mediatek-gen3-Add-comment-about-initialization-o.patch b/target/linux/airoha/patches-6.6/042-03-v6.14-PCI-mediatek-gen3-Add-comment-about-initialization-o.patch new file mode 100644 index 00000000000000..785e5bd7617830 --- /dev/null +++ b/target/linux/airoha/patches-6.6/042-03-v6.14-PCI-mediatek-gen3-Add-comment-about-initialization-o.patch @@ -0,0 +1,35 @@ +From 0c9d2d2ef0d916b490a9222ed20ff4616fca876d Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Wed, 8 Jan 2025 10:50:42 +0100 +Subject: [PATCH 3/6] PCI: mediatek-gen3: Add comment about initialization + order in mtk_pcie_en7581_power_up() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Add a comment in mtk_pcie_en7581_power_up() to clarify, unlike the other +MediaTek Gen3 controllers, the Airoha EN7581 requires PHY initialization +and power-on before PHY reset deassert. + +Link: https://lore.kernel.org/r/20250108-pcie-en7581-fixes-v6-3-21ac939a3b9b@kernel.org +Signed-off-by: Lorenzo Bianconi +Signed-off-by: Krzysztof Wilczyński +Reviewed-by: Manivannan Sadhasivam +Reviewed-by: AngeloGioacchino Del Regno +--- + drivers/pci/controller/pcie-mediatek-gen3.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/drivers/pci/controller/pcie-mediatek-gen3.c ++++ b/drivers/pci/controller/pcie-mediatek-gen3.c +@@ -887,6 +887,10 @@ static int mtk_pcie_en7581_power_up(stru + /* Wait for the time needed to complete the reset lines assert. */ + mdelay(PCIE_EN7581_RESET_TIME_MS); + ++ /* ++ * Unlike the other MediaTek Gen3 controllers, the Airoha EN7581 ++ * requires PHY initialization and power-on before PHY reset deassert. ++ */ + err = phy_init(pcie->phy); + if (err) { + dev_err(dev, "failed to initialize PHY\n"); diff --git a/target/linux/airoha/patches-6.6/042-04-v6.14-PCI-mediatek-gen3-Move-reset-delay-in-mtk_pcie_en758.patch b/target/linux/airoha/patches-6.6/042-04-v6.14-PCI-mediatek-gen3-Move-reset-delay-in-mtk_pcie_en758.patch new file mode 100644 index 00000000000000..1e6d4cd0922ce1 --- /dev/null +++ b/target/linux/airoha/patches-6.6/042-04-v6.14-PCI-mediatek-gen3-Move-reset-delay-in-mtk_pcie_en758.patch @@ -0,0 +1,59 @@ +From 90d4e466c9ea2010f33880a36317a8486ccbe082 Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Wed, 8 Jan 2025 10:50:43 +0100 +Subject: [PATCH 4/6] PCI: mediatek-gen3: Move reset delay in + mtk_pcie_en7581_power_up() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Airoha EN7581 has a hw bug asserting/releasing PCIE_PE_RSTB signal +causing occasional PCIe link down issues. In order to overcome the +problem, PCIe block is reset using REG_PCI_CONTROL (0x88) and +REG_RESET_CONTROL (0x834) registers available in the clock module +running clk_bulk_prepare_enable() in mtk_pcie_en7581_power_up(). + +In order to make the code more readable, move the wait for the time +needed to complete the PCIe reset from en7581_pci_enable() to +mtk_pcie_en7581_power_up(). + +Reduce reset timeout from 250ms to the standard PCIE_T_PVPERL_MS value +(100ms) since it has no impact on the driver behavior. + +Link: https://lore.kernel.org/r/20250108-pcie-en7581-fixes-v6-4-21ac939a3b9b@kernel.org +Signed-off-by: Lorenzo Bianconi +Signed-off-by: Krzysztof Wilczyński +Reviewed-by: AngeloGioacchino Del Regno +Reviewed-by: Manivannan Sadhasivam +Acked-by: Stephen Boyd +--- + drivers/clk/clk-en7523.c | 1 - + drivers/pci/controller/pcie-mediatek-gen3.c | 7 +++++++ + 2 files changed, 7 insertions(+), 1 deletion(-) + +--- a/drivers/clk/clk-en7523.c ++++ b/drivers/clk/clk-en7523.c +@@ -489,7 +489,6 @@ static int en7581_pci_enable(struct clk_ + REG_PCI_CONTROL_PERSTOUT; + val = readl(np_base + REG_PCI_CONTROL); + writel(val | mask, np_base + REG_PCI_CONTROL); +- msleep(250); + + return 0; + } +--- a/drivers/pci/controller/pcie-mediatek-gen3.c ++++ b/drivers/pci/controller/pcie-mediatek-gen3.c +@@ -936,6 +936,13 @@ static int mtk_pcie_en7581_power_up(stru + goto err_clk_prepare_enable; + } + ++ /* ++ * Airoha EN7581 performs PCIe reset via clk callbacks since it has a ++ * hw issue with PCIE_PE_RSTB signal. Add wait for the time needed to ++ * complete the PCIe reset. ++ */ ++ msleep(PCIE_T_PVPERL_MS); ++ + return 0; + + err_clk_prepare_enable: diff --git a/target/linux/airoha/patches-6.6/042-05-v6.14-PCI-mediatek-gen3-Rely-on-msleep-in-mtk_pcie_en7581_.patch b/target/linux/airoha/patches-6.6/042-05-v6.14-PCI-mediatek-gen3-Rely-on-msleep-in-mtk_pcie_en7581_.patch new file mode 100644 index 00000000000000..eb89411d5944bf --- /dev/null +++ b/target/linux/airoha/patches-6.6/042-05-v6.14-PCI-mediatek-gen3-Rely-on-msleep-in-mtk_pcie_en7581_.patch @@ -0,0 +1,41 @@ +From c98bee18d0a094e37100c85effe5e161418f8644 Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Wed, 8 Jan 2025 10:50:44 +0100 +Subject: [PATCH 5/6] PCI: mediatek-gen3: Rely on msleep() in + mtk_pcie_en7581_power_up() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Since mtk_pcie_en7581_power_up() runs in non-atomic context, rely on +msleep() routine instead of mdelay(). + +Link: https://lore.kernel.org/r/20250108-pcie-en7581-fixes-v6-5-21ac939a3b9b@kernel.org +Signed-off-by: Lorenzo Bianconi +Signed-off-by: Krzysztof Wilczyński +Reviewed-by: AngeloGioacchino Del Regno +Reviewed-by: Manivannan Sadhasivam +--- + drivers/pci/controller/pcie-mediatek-gen3.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/pci/controller/pcie-mediatek-gen3.c ++++ b/drivers/pci/controller/pcie-mediatek-gen3.c +@@ -885,7 +885,7 @@ static int mtk_pcie_en7581_power_up(stru + reset_control_assert(pcie->mac_reset); + + /* Wait for the time needed to complete the reset lines assert. */ +- mdelay(PCIE_EN7581_RESET_TIME_MS); ++ msleep(PCIE_EN7581_RESET_TIME_MS); + + /* + * Unlike the other MediaTek Gen3 controllers, the Airoha EN7581 +@@ -913,7 +913,7 @@ static int mtk_pcie_en7581_power_up(stru + * Wait for the time needed to complete the bulk de-assert above. + * This time is specific for EN7581 SoC. + */ +- mdelay(PCIE_EN7581_RESET_TIME_MS); ++ msleep(PCIE_EN7581_RESET_TIME_MS); + + pm_runtime_enable(dev); + pm_runtime_get_sync(dev); diff --git a/target/linux/airoha/patches-6.6/042-06-v6.14-PCI-mediatek-gen3-Avoid-PCIe-resetting-via-PERST-for.patch b/target/linux/airoha/patches-6.6/042-06-v6.14-PCI-mediatek-gen3-Avoid-PCIe-resetting-via-PERST-for.patch new file mode 100644 index 00000000000000..d18d6f6b5a8117 --- /dev/null +++ b/target/linux/airoha/patches-6.6/042-06-v6.14-PCI-mediatek-gen3-Avoid-PCIe-resetting-via-PERST-for.patch @@ -0,0 +1,128 @@ +From 491cb9c5084790aafa02e843349492c284373231 Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Thu, 9 Jan 2025 00:30:45 +0100 +Subject: [PATCH 6/6] PCI: mediatek-gen3: Avoid PCIe resetting via PERST# for + Airoha EN7581 SoC +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Airoha EN7581 has a hw bug asserting/releasing PERST# signal causing +occasional PCIe link down issues. In order to overcome the problem, +PERST# signal is not asserted/released during device probe or +suspend/resume phase and the PCIe block is reset using +en7523_reset_assert() and en7581_pci_enable(). + +Introduce flags field in the mtk_gen3_pcie_pdata struct in order to +specify per-SoC capabilities. + +Link: https://lore.kernel.org/r/20250109-pcie-en7581-rst-fix-v4-1-4a45c89fb143@kernel.org +Tested-by: Hui Ma +Signed-off-by: Lorenzo Bianconi +Signed-off-by: Krzysztof Wilczyński +--- + drivers/pci/controller/pcie-mediatek-gen3.c | 59 ++++++++++++++------- + 1 file changed, 41 insertions(+), 18 deletions(-) + +--- a/drivers/pci/controller/pcie-mediatek-gen3.c ++++ b/drivers/pci/controller/pcie-mediatek-gen3.c +@@ -127,10 +127,18 @@ + + struct mtk_gen3_pcie; + ++enum mtk_gen3_pcie_flags { ++ SKIP_PCIE_RSTB = BIT(0), /* Skip PERST# assertion during device ++ * probing or suspend/resume phase to ++ * avoid hw bugs/issues. ++ */ ++}; ++ + /** + * struct mtk_gen3_pcie_pdata - differentiate between host generations + * @power_up: pcie power_up callback + * @phy_resets: phy reset lines SoC data. ++ * @flags: pcie device flags. + */ + struct mtk_gen3_pcie_pdata { + int (*power_up)(struct mtk_gen3_pcie *pcie); +@@ -138,6 +146,7 @@ struct mtk_gen3_pcie_pdata { + const char *id[MAX_NUM_PHY_RESETS]; + int num_resets; + } phy_resets; ++ u32 flags; + }; + + /** +@@ -404,22 +413,33 @@ static int mtk_pcie_startup_port(struct + val |= PCIE_DISABLE_DVFSRC_VLT_REQ; + writel_relaxed(val, pcie->base + PCIE_MISC_CTRL_REG); + +- /* Assert all reset signals */ +- val = readl_relaxed(pcie->base + PCIE_RST_CTRL_REG); +- val |= PCIE_MAC_RSTB | PCIE_PHY_RSTB | PCIE_BRG_RSTB | PCIE_PE_RSTB; +- writel_relaxed(val, pcie->base + PCIE_RST_CTRL_REG); +- + /* +- * Described in PCIe CEM specification sections 2.2 (PERST# Signal) +- * and 2.2.1 (Initial Power-Up (G3 to S0)). +- * The deassertion of PERST# should be delayed 100ms (TPVPERL) +- * for the power and clock to become stable. ++ * Airoha EN7581 has a hw bug asserting/releasing PCIE_PE_RSTB signal ++ * causing occasional PCIe link down. In order to overcome the issue, ++ * PCIE_RSTB signals are not asserted/released at this stage and the ++ * PCIe block is reset using en7523_reset_assert() and ++ * en7581_pci_enable(). + */ +- msleep(100); +- +- /* De-assert reset signals */ +- val &= ~(PCIE_MAC_RSTB | PCIE_PHY_RSTB | PCIE_BRG_RSTB | PCIE_PE_RSTB); +- writel_relaxed(val, pcie->base + PCIE_RST_CTRL_REG); ++ if (!(pcie->soc->flags & SKIP_PCIE_RSTB)) { ++ /* Assert all reset signals */ ++ val = readl_relaxed(pcie->base + PCIE_RST_CTRL_REG); ++ val |= PCIE_MAC_RSTB | PCIE_PHY_RSTB | PCIE_BRG_RSTB | ++ PCIE_PE_RSTB; ++ writel_relaxed(val, pcie->base + PCIE_RST_CTRL_REG); ++ ++ /* ++ * Described in PCIe CEM specification revision 6.0. ++ * ++ * The deassertion of PERST# should be delayed 100ms (TPVPERL) ++ * for the power and clock to become stable. ++ */ ++ msleep(PCIE_T_PVPERL_MS); ++ ++ /* De-assert reset signals */ ++ val &= ~(PCIE_MAC_RSTB | PCIE_PHY_RSTB | PCIE_BRG_RSTB | ++ PCIE_PE_RSTB); ++ writel_relaxed(val, pcie->base + PCIE_RST_CTRL_REG); ++ } + + /* Check if the link is up or not */ + err = readl_poll_timeout(pcie->base + PCIE_LINK_STATUS_REG, val, +@@ -1178,10 +1198,12 @@ static int mtk_pcie_suspend_noirq(struct + return err; + } + +- /* Pull down the PERST# pin */ +- val = readl_relaxed(pcie->base + PCIE_RST_CTRL_REG); +- val |= PCIE_PE_RSTB; +- writel_relaxed(val, pcie->base + PCIE_RST_CTRL_REG); ++ if (!(pcie->soc->flags & SKIP_PCIE_RSTB)) { ++ /* Assert the PERST# pin */ ++ val = readl_relaxed(pcie->base + PCIE_RST_CTRL_REG); ++ val |= PCIE_PE_RSTB; ++ writel_relaxed(val, pcie->base + PCIE_RST_CTRL_REG); ++ } + + dev_dbg(pcie->dev, "entered L2 states successfully"); + +@@ -1232,6 +1254,7 @@ static const struct mtk_gen3_pcie_pdata + .id[2] = "phy-lane2", + .num_resets = 3, + }, ++ .flags = SKIP_PCIE_RSTB, + }; + + static const struct of_device_id mtk_pcie_of_match[] = { diff --git a/target/linux/airoha/patches-6.6/043-v6.15-PCI-mediatek-gen3-Remove-leftover-mac_reset-assert-f.patch b/target/linux/airoha/patches-6.6/043-v6.15-PCI-mediatek-gen3-Remove-leftover-mac_reset-assert-f.patch new file mode 100644 index 00000000000000..b4a69eb684f6ae --- /dev/null +++ b/target/linux/airoha/patches-6.6/043-v6.15-PCI-mediatek-gen3-Remove-leftover-mac_reset-assert-f.patch @@ -0,0 +1,34 @@ +From b6d7bb0d3bd74b491e2e6fd59c4d5110d06fd63b Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Sat, 1 Feb 2025 12:00:18 +0100 +Subject: [PATCH] PCI: mediatek-gen3: Remove leftover mac_reset assert for + Airoha EN7581 SoC +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Remove a leftover assert for mac_reset line in mtk_pcie_en7581_power_up(). + +This is not harmful since EN7581 does not requires mac_reset and +mac_reset is not defined in EN7581 device tree. + +Signed-off-by: Lorenzo Bianconi +Reviewed-by: Manivannan Sadhasivam +Reviewed-by: Philipp Zabel +Link: https://lore.kernel.org/r/20250201-pcie-en7581-remove-mac_reset-v2-1-a06786cdc683@kernel.org +[kwilczynski: commit log] +Signed-off-by: Krzysztof Wilczyński +--- + drivers/pci/controller/pcie-mediatek-gen3.c | 1 - + 1 file changed, 1 deletion(-) + +--- a/drivers/pci/controller/pcie-mediatek-gen3.c ++++ b/drivers/pci/controller/pcie-mediatek-gen3.c +@@ -902,7 +902,6 @@ static int mtk_pcie_en7581_power_up(stru + */ + reset_control_bulk_assert(pcie->soc->phy_resets.num_resets, + pcie->phy_resets); +- reset_control_assert(pcie->mac_reset); + + /* Wait for the time needed to complete the reset lines assert. */ + msleep(PCIE_EN7581_RESET_TIME_MS); diff --git a/target/linux/airoha/patches-6.6/044-v6.15-PCI-mediatek-gen3-Configure-PBUS_CSR-registers-for-E.patch b/target/linux/airoha/patches-6.6/044-v6.15-PCI-mediatek-gen3-Configure-PBUS_CSR-registers-for-E.patch new file mode 100644 index 00000000000000..6470e03bb56b6e --- /dev/null +++ b/target/linux/airoha/patches-6.6/044-v6.15-PCI-mediatek-gen3-Configure-PBUS_CSR-registers-for-E.patch @@ -0,0 +1,81 @@ +From 249b78298078448a699c39356d27d8183af4b281 Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Tue, 25 Feb 2025 09:04:07 +0100 +Subject: [PATCH] PCI: mediatek-gen3: Configure PBUS_CSR registers for EN7581 + SoC +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Configure PBus base address and address mask to allow the hw +to detect if a given address is accessible on PCIe controller. + +Fixes: f6ab898356dd ("PCI: mediatek-gen3: Add Airoha EN7581 support") +Reviewed-by: Manivannan Sadhasivam +Signed-off-by: Lorenzo Bianconi +Link: https://lore.kernel.org/r/20250225-en7581-pcie-pbus-csr-v4-2-24324382424a@kernel.org +Signed-off-by: Krzysztof Wilczyński +--- + drivers/pci/controller/pcie-mediatek-gen3.c | 28 ++++++++++++++++++++- + 1 file changed, 27 insertions(+), 1 deletion(-) + +--- a/drivers/pci/controller/pcie-mediatek-gen3.c ++++ b/drivers/pci/controller/pcie-mediatek-gen3.c +@@ -15,6 +15,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -24,6 +25,7 @@ + #include + #include + #include ++#include + #include + + #include "../pci.h" +@@ -892,9 +894,13 @@ static int mtk_pcie_parse_port(struct mt + + static int mtk_pcie_en7581_power_up(struct mtk_gen3_pcie *pcie) + { ++ struct pci_host_bridge *host = pci_host_bridge_from_priv(pcie); + struct device *dev = pcie->dev; ++ struct resource_entry *entry; ++ struct regmap *pbus_regmap; ++ u32 val, args[2], size; ++ resource_size_t addr; + int err; +- u32 val; + + /* + * The controller may have been left out of reset by the bootloader +@@ -907,6 +913,26 @@ static int mtk_pcie_en7581_power_up(stru + msleep(PCIE_EN7581_RESET_TIME_MS); + + /* ++ * Configure PBus base address and base address mask to allow the ++ * hw to detect if a given address is accessible on PCIe controller. ++ */ ++ pbus_regmap = syscon_regmap_lookup_by_phandle_args(dev->of_node, ++ "mediatek,pbus-csr", ++ ARRAY_SIZE(args), ++ args); ++ if (IS_ERR(pbus_regmap)) ++ return PTR_ERR(pbus_regmap); ++ ++ entry = resource_list_first_type(&host->windows, IORESOURCE_MEM); ++ if (!entry) ++ return -ENODEV; ++ ++ addr = entry->res->start - entry->offset; ++ regmap_write(pbus_regmap, args[0], lower_32_bits(addr)); ++ size = lower_32_bits(resource_size(entry->res)); ++ regmap_write(pbus_regmap, args[1], GENMASK(31, __fls(size))); ++ ++ /* + * Unlike the other MediaTek Gen3 controllers, the Airoha EN7581 + * requires PHY initialization and power-on before PHY reset deassert. + */ diff --git a/target/linux/airoha/patches-6.6/045-v6.14-net-airoha-Fix-wrong-GDM4-register-definition.patch b/target/linux/airoha/patches-6.6/045-v6.14-net-airoha-Fix-wrong-GDM4-register-definition.patch new file mode 100644 index 00000000000000..f17242a6c5c7fd --- /dev/null +++ b/target/linux/airoha/patches-6.6/045-v6.14-net-airoha-Fix-wrong-GDM4-register-definition.patch @@ -0,0 +1,41 @@ +From d31a49d37cb132b31cc6683eef2122f8609d6229 Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Mon, 20 Jan 2025 16:41:40 +0100 +Subject: [PATCH] net: airoha: Fix wrong GDM4 register definition + +Fix wrong GDM4 register definition, in Airoha SDK GDM4 is defined at +offset 0x2400 but this doesn't make sense as it does conflict with the +CDM4 that is in the same location. + +Following the pattern where each GDM base is at the FWD_CFG, currently +GDM4 base offset is set to 0x2500. This is correct but REG_GDM4_FWD_CFG +and REG_GDM4_SRC_PORT_SET are still using the SDK reference with the +0x2400 offset. Fix these 2 define by subtracting 0x100 to each register +to reflect the real address location. + +Fixes: 23020f049327 ("net: airoha: Introduce ethernet support for EN7581 SoC") +Signed-off-by: Christian Marangi +Acked-by: Lorenzo Bianconi +Reviewed-by: Jacob Keller +Link: https://patch.msgid.link/20250120154148.13424-1-ansuelsmth@gmail.com +Signed-off-by: Jakub Kicinski +--- + drivers/net/ethernet/mediatek/airoha_eth.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/net/ethernet/mediatek/airoha_eth.c ++++ b/drivers/net/ethernet/mediatek/airoha_eth.c +@@ -266,11 +266,11 @@ + #define REG_GDM3_FWD_CFG GDM3_BASE + #define GDM3_PAD_EN_MASK BIT(28) + +-#define REG_GDM4_FWD_CFG (GDM4_BASE + 0x100) ++#define REG_GDM4_FWD_CFG GDM4_BASE + #define GDM4_PAD_EN_MASK BIT(28) + #define GDM4_SPORT_OFFSET0_MASK GENMASK(11, 8) + +-#define REG_GDM4_SRC_PORT_SET (GDM4_BASE + 0x33c) ++#define REG_GDM4_SRC_PORT_SET (GDM4_BASE + 0x23c) + #define GDM4_SPORT_OFF2_MASK GENMASK(19, 16) + #define GDM4_SPORT_OFF1_MASK GENMASK(15, 12) + #define GDM4_SPORT_OFF0_MASK GENMASK(11, 8) diff --git a/target/linux/airoha/patches-6.6/046-v6.15-net-airoha-Fix-TSO-support-for-header-cloned-skbs.patch b/target/linux/airoha/patches-6.6/046-v6.15-net-airoha-Fix-TSO-support-for-header-cloned-skbs.patch new file mode 100644 index 00000000000000..9c2443ce698603 --- /dev/null +++ b/target/linux/airoha/patches-6.6/046-v6.15-net-airoha-Fix-TSO-support-for-header-cloned-skbs.patch @@ -0,0 +1,60 @@ +From c6287e1a858e336cc202b484c6138a0fe252c6b3 Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Thu, 13 Feb 2025 16:34:20 +0100 +Subject: [PATCH] net: airoha: Fix TSO support for header cloned skbs + +For GSO packets, skb_cow_head() will reallocate the skb for TSO header +cloned skbs in airoha_dev_xmit(). For this reason, sinfo pointer can be +no more valid. Fix the issue relying on skb_shinfo() macro directly in +airoha_dev_xmit(). + +The problem exists since +commit 23020f049327 ("net: airoha: Introduce ethernet support for EN7581 SoC") +but it is not a user visible, since we can't currently enable TSO +for DSA user ports since we are missing to initialize net_device +vlan_features field. + +Reviewed-by: Mateusz Polchlopek +Signed-off-by: Lorenzo Bianconi +Link: https://patch.msgid.link/20250213-airoha-en7581-flowtable-offload-v4-1-b69ca16d74db@kernel.org +Signed-off-by: Jakub Kicinski +--- + drivers/net/ethernet/mediatek/airoha_eth.c | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +--- a/drivers/net/ethernet/mediatek/airoha_eth.c ++++ b/drivers/net/ethernet/mediatek/airoha_eth.c +@@ -2549,11 +2549,10 @@ static u16 airoha_dev_select_queue(struc + static netdev_tx_t airoha_dev_xmit(struct sk_buff *skb, + struct net_device *dev) + { +- struct skb_shared_info *sinfo = skb_shinfo(skb); + struct airoha_gdm_port *port = netdev_priv(dev); ++ u32 nr_frags = 1 + skb_shinfo(skb)->nr_frags; + u32 msg0, msg1, len = skb_headlen(skb); + struct airoha_qdma *qdma = port->qdma; +- u32 nr_frags = 1 + sinfo->nr_frags; + struct netdev_queue *txq; + struct airoha_queue *q; + void *data = skb->data; +@@ -2576,8 +2575,9 @@ static netdev_tx_t airoha_dev_xmit(struc + if (skb_cow_head(skb, 0)) + goto error; + +- if (sinfo->gso_type & (SKB_GSO_TCPV4 | SKB_GSO_TCPV6)) { +- __be16 csum = cpu_to_be16(sinfo->gso_size); ++ if (skb_shinfo(skb)->gso_type & (SKB_GSO_TCPV4 | ++ SKB_GSO_TCPV6)) { ++ __be16 csum = cpu_to_be16(skb_shinfo(skb)->gso_size); + + tcp_hdr(skb)->check = (__force __sum16)csum; + msg0 |= FIELD_PREP(QDMA_ETH_TXMSG_TSO_MASK, 1); +@@ -2606,7 +2606,7 @@ static netdev_tx_t airoha_dev_xmit(struc + for (i = 0; i < nr_frags; i++) { + struct airoha_qdma_desc *desc = &q->desc[index]; + struct airoha_queue_entry *e = &q->entry[index]; +- skb_frag_t *frag = &sinfo->frags[i]; ++ skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; + dma_addr_t addr; + u32 val; + diff --git a/target/linux/airoha/patches-6.6/047-v6.13-net-airoha-Reset-BQL-stopping-the-netdevice.patch b/target/linux/airoha/patches-6.6/047-v6.13-net-airoha-Reset-BQL-stopping-the-netdevice.patch new file mode 100644 index 00000000000000..f20e2034c22c97 --- /dev/null +++ b/target/linux/airoha/patches-6.6/047-v6.13-net-airoha-Reset-BQL-stopping-the-netdevice.patch @@ -0,0 +1,42 @@ +From c9f947769b77c8e8f318bfc8a0777e5d20c44d8d Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Thu, 17 Oct 2024 16:01:41 +0200 +Subject: [PATCH] net: airoha: Reset BQL stopping the netdevice + +Run airoha_qdma_cleanup_tx_queue() in ndo_stop callback in order to +unmap pending skbs. Moreover, reset BQL txq state stopping the netdevice, + +Signed-off-by: Lorenzo Bianconi +Reviewed-by: Hariprasad Kelam +Message-ID: <20241017-airoha-en7581-reset-bql-v1-1-08c0c9888de5@kernel.org> +Signed-off-by: Andrew Lunn +--- + drivers/net/ethernet/mediatek/airoha_eth.c | 10 +++++++++- + 1 file changed, 9 insertions(+), 1 deletion(-) + +--- a/drivers/net/ethernet/mediatek/airoha_eth.c ++++ b/drivers/net/ethernet/mediatek/airoha_eth.c +@@ -2469,7 +2469,7 @@ static int airoha_dev_stop(struct net_de + { + struct airoha_gdm_port *port = netdev_priv(dev); + struct airoha_qdma *qdma = port->qdma; +- int err; ++ int i, err; + + netif_tx_disable(dev); + err = airoha_set_gdm_ports(qdma->eth, false); +@@ -2480,6 +2480,14 @@ static int airoha_dev_stop(struct net_de + GLOBAL_CFG_TX_DMA_EN_MASK | + GLOBAL_CFG_RX_DMA_EN_MASK); + ++ for (i = 0; i < ARRAY_SIZE(qdma->q_tx); i++) { ++ if (!qdma->q_tx[i].ndesc) ++ continue; ++ ++ airoha_qdma_cleanup_tx_queue(&qdma->q_tx[i]); ++ netdev_tx_reset_subqueue(dev, i); ++ } ++ + return 0; + } + diff --git a/target/linux/airoha/patches-6.6/048-01-v6.15-net-airoha-Move-airoha_eth-driver-in-a-dedicated-fol.patch b/target/linux/airoha/patches-6.6/048-01-v6.15-net-airoha-Move-airoha_eth-driver-in-a-dedicated-fol.patch new file mode 100644 index 00000000000000..255bbd2ed9d837 --- /dev/null +++ b/target/linux/airoha/patches-6.6/048-01-v6.15-net-airoha-Move-airoha_eth-driver-in-a-dedicated-fol.patch @@ -0,0 +1,6825 @@ +From fb3dda82fd38ca42140f29b3082324dcdc128293 Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Fri, 28 Feb 2025 11:54:09 +0100 +Subject: [PATCH 01/15] net: airoha: Move airoha_eth driver in a dedicated + folder + +The airoha_eth driver has no codebase shared with mtk_eth_soc one. +Moreover, the upcoming features (flowtable hw offloading, PCS, ..) will +not reuse any code from MediaTek driver. Move the Airoha driver in a +dedicated folder. + +Signed-off-by: Lorenzo Bianconi +Signed-off-by: Paolo Abeni +--- + drivers/net/ethernet/Kconfig | 2 ++ + drivers/net/ethernet/Makefile | 1 + + drivers/net/ethernet/airoha/Kconfig | 18 ++++++++++++++++++ + drivers/net/ethernet/airoha/Makefile | 6 ++++++ + .../ethernet/{mediatek => airoha}/airoha_eth.c | 0 + drivers/net/ethernet/mediatek/Kconfig | 8 -------- + drivers/net/ethernet/mediatek/Makefile | 1 - + 7 files changed, 27 insertions(+), 9 deletions(-) + create mode 100644 drivers/net/ethernet/airoha/Kconfig + create mode 100644 drivers/net/ethernet/airoha/Makefile + rename drivers/net/ethernet/{mediatek => airoha}/airoha_eth.c (100%) + +--- a/drivers/net/ethernet/Kconfig ++++ b/drivers/net/ethernet/Kconfig +@@ -23,6 +23,8 @@ source "drivers/net/ethernet/actions/Kco + source "drivers/net/ethernet/adaptec/Kconfig" + source "drivers/net/ethernet/aeroflex/Kconfig" + source "drivers/net/ethernet/agere/Kconfig" ++source "drivers/net/ethernet/airoha/Kconfig" ++source "drivers/net/ethernet/mellanox/Kconfig" + source "drivers/net/ethernet/alacritech/Kconfig" + source "drivers/net/ethernet/allwinner/Kconfig" + source "drivers/net/ethernet/alteon/Kconfig" +--- a/drivers/net/ethernet/Makefile ++++ b/drivers/net/ethernet/Makefile +@@ -10,6 +10,7 @@ obj-$(CONFIG_NET_VENDOR_ADAPTEC) += adap + obj-$(CONFIG_GRETH) += aeroflex/ + obj-$(CONFIG_NET_VENDOR_ADI) += adi/ + obj-$(CONFIG_NET_VENDOR_AGERE) += agere/ ++obj-$(CONFIG_NET_VENDOR_AIROHA) += airoha/ + obj-$(CONFIG_NET_VENDOR_ALACRITECH) += alacritech/ + obj-$(CONFIG_NET_VENDOR_ALLWINNER) += allwinner/ + obj-$(CONFIG_NET_VENDOR_ALTEON) += alteon/ +--- /dev/null ++++ b/drivers/net/ethernet/airoha/Kconfig +@@ -0,0 +1,18 @@ ++# SPDX-License-Identifier: GPL-2.0-only ++config NET_VENDOR_AIROHA ++ bool "Airoha devices" ++ depends on ARCH_AIROHA || COMPILE_TEST ++ help ++ If you have a Airoha SoC with ethernet, say Y. ++ ++if NET_VENDOR_AIROHA ++ ++config NET_AIROHA ++ tristate "Airoha SoC Gigabit Ethernet support" ++ depends on NET_DSA || !NET_DSA ++ select PAGE_POOL ++ help ++ This driver supports the gigabit ethernet MACs in the ++ Airoha SoC family. ++ ++endif #NET_VENDOR_AIROHA +--- /dev/null ++++ b/drivers/net/ethernet/airoha/Makefile +@@ -0,0 +1,6 @@ ++# SPDX-License-Identifier: GPL-2.0-only ++# ++# Airoha for the Mediatek SoCs built-in ethernet macs ++# ++ ++obj-$(CONFIG_NET_AIROHA) += airoha_eth.o +--- a/drivers/net/ethernet/mediatek/Kconfig ++++ b/drivers/net/ethernet/mediatek/Kconfig +@@ -7,14 +7,6 @@ config NET_VENDOR_MEDIATEK + + if NET_VENDOR_MEDIATEK + +-config NET_AIROHA +- tristate "Airoha SoC Gigabit Ethernet support" +- depends on NET_DSA || !NET_DSA +- select PAGE_POOL +- help +- This driver supports the gigabit ethernet MACs in the +- Airoha SoC family. +- + config NET_MEDIATEK_SOC_WED + depends on ARCH_MEDIATEK || COMPILE_TEST + def_bool NET_MEDIATEK_SOC != n +--- a/drivers/net/ethernet/mediatek/Makefile ++++ b/drivers/net/ethernet/mediatek/Makefile +@@ -11,4 +11,3 @@ mtk_eth-$(CONFIG_NET_MEDIATEK_SOC_WED) + + endif + obj-$(CONFIG_NET_MEDIATEK_SOC_WED) += mtk_wed_ops.o + obj-$(CONFIG_NET_MEDIATEK_STAR_EMAC) += mtk_star_emac.o +-obj-$(CONFIG_NET_AIROHA) += airoha_eth.o +--- /dev/null ++++ b/drivers/net/ethernet/airoha/airoha_eth.c +@@ -0,0 +1,3359 @@ ++// SPDX-License-Identifier: GPL-2.0-only ++/* ++ * Copyright (c) 2024 AIROHA Inc ++ * Author: Lorenzo Bianconi ++ */ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define AIROHA_MAX_NUM_GDM_PORTS 1 ++#define AIROHA_MAX_NUM_QDMA 2 ++#define AIROHA_MAX_NUM_RSTS 3 ++#define AIROHA_MAX_NUM_XSI_RSTS 5 ++#define AIROHA_MAX_MTU 2000 ++#define AIROHA_MAX_PACKET_SIZE 2048 ++#define AIROHA_NUM_QOS_CHANNELS 4 ++#define AIROHA_NUM_QOS_QUEUES 8 ++#define AIROHA_NUM_TX_RING 32 ++#define AIROHA_NUM_RX_RING 32 ++#define AIROHA_NUM_NETDEV_TX_RINGS (AIROHA_NUM_TX_RING + \ ++ AIROHA_NUM_QOS_CHANNELS) ++#define AIROHA_FE_MC_MAX_VLAN_TABLE 64 ++#define AIROHA_FE_MC_MAX_VLAN_PORT 16 ++#define AIROHA_NUM_TX_IRQ 2 ++#define HW_DSCP_NUM 2048 ++#define IRQ_QUEUE_LEN(_n) ((_n) ? 1024 : 2048) ++#define TX_DSCP_NUM 1024 ++#define RX_DSCP_NUM(_n) \ ++ ((_n) == 2 ? 128 : \ ++ (_n) == 11 ? 128 : \ ++ (_n) == 15 ? 128 : \ ++ (_n) == 0 ? 1024 : 16) ++ ++#define PSE_RSV_PAGES 128 ++#define PSE_QUEUE_RSV_PAGES 64 ++ ++#define QDMA_METER_IDX(_n) ((_n) & 0xff) ++#define QDMA_METER_GROUP(_n) (((_n) >> 8) & 0x3) ++ ++/* FE */ ++#define PSE_BASE 0x0100 ++#define CSR_IFC_BASE 0x0200 ++#define CDM1_BASE 0x0400 ++#define GDM1_BASE 0x0500 ++#define PPE1_BASE 0x0c00 ++ ++#define CDM2_BASE 0x1400 ++#define GDM2_BASE 0x1500 ++ ++#define GDM3_BASE 0x1100 ++#define GDM4_BASE 0x2500 ++ ++#define GDM_BASE(_n) \ ++ ((_n) == 4 ? GDM4_BASE : \ ++ (_n) == 3 ? GDM3_BASE : \ ++ (_n) == 2 ? GDM2_BASE : GDM1_BASE) ++ ++#define REG_FE_DMA_GLO_CFG 0x0000 ++#define FE_DMA_GLO_L2_SPACE_MASK GENMASK(7, 4) ++#define FE_DMA_GLO_PG_SZ_MASK BIT(3) ++ ++#define REG_FE_RST_GLO_CFG 0x0004 ++#define FE_RST_GDM4_MBI_ARB_MASK BIT(3) ++#define FE_RST_GDM3_MBI_ARB_MASK BIT(2) ++#define FE_RST_CORE_MASK BIT(0) ++ ++#define REG_FE_WAN_MAC_H 0x0030 ++#define REG_FE_LAN_MAC_H 0x0040 ++ ++#define REG_FE_MAC_LMIN(_n) ((_n) + 0x04) ++#define REG_FE_MAC_LMAX(_n) ((_n) + 0x08) ++ ++#define REG_FE_CDM1_OQ_MAP0 0x0050 ++#define REG_FE_CDM1_OQ_MAP1 0x0054 ++#define REG_FE_CDM1_OQ_MAP2 0x0058 ++#define REG_FE_CDM1_OQ_MAP3 0x005c ++ ++#define REG_FE_PCE_CFG 0x0070 ++#define PCE_DPI_EN_MASK BIT(2) ++#define PCE_KA_EN_MASK BIT(1) ++#define PCE_MC_EN_MASK BIT(0) ++ ++#define REG_FE_PSE_QUEUE_CFG_WR 0x0080 ++#define PSE_CFG_PORT_ID_MASK GENMASK(27, 24) ++#define PSE_CFG_QUEUE_ID_MASK GENMASK(20, 16) ++#define PSE_CFG_WR_EN_MASK BIT(8) ++#define PSE_CFG_OQRSV_SEL_MASK BIT(0) ++ ++#define REG_FE_PSE_QUEUE_CFG_VAL 0x0084 ++#define PSE_CFG_OQ_RSV_MASK GENMASK(13, 0) ++ ++#define PSE_FQ_CFG 0x008c ++#define PSE_FQ_LIMIT_MASK GENMASK(14, 0) ++ ++#define REG_FE_PSE_BUF_SET 0x0090 ++#define PSE_SHARE_USED_LTHD_MASK GENMASK(31, 16) ++#define PSE_ALLRSV_MASK GENMASK(14, 0) ++ ++#define REG_PSE_SHARE_USED_THD 0x0094 ++#define PSE_SHARE_USED_MTHD_MASK GENMASK(31, 16) ++#define PSE_SHARE_USED_HTHD_MASK GENMASK(15, 0) ++ ++#define REG_GDM_MISC_CFG 0x0148 ++#define GDM2_RDM_ACK_WAIT_PREF_MASK BIT(9) ++#define GDM2_CHN_VLD_MODE_MASK BIT(5) ++ ++#define REG_FE_CSR_IFC_CFG CSR_IFC_BASE ++#define FE_IFC_EN_MASK BIT(0) ++ ++#define REG_FE_VIP_PORT_EN 0x01f0 ++#define REG_FE_IFC_PORT_EN 0x01f4 ++ ++#define REG_PSE_IQ_REV1 (PSE_BASE + 0x08) ++#define PSE_IQ_RES1_P2_MASK GENMASK(23, 16) ++ ++#define REG_PSE_IQ_REV2 (PSE_BASE + 0x0c) ++#define PSE_IQ_RES2_P5_MASK GENMASK(15, 8) ++#define PSE_IQ_RES2_P4_MASK GENMASK(7, 0) ++ ++#define REG_FE_VIP_EN(_n) (0x0300 + ((_n) << 3)) ++#define PATN_FCPU_EN_MASK BIT(7) ++#define PATN_SWP_EN_MASK BIT(6) ++#define PATN_DP_EN_MASK BIT(5) ++#define PATN_SP_EN_MASK BIT(4) ++#define PATN_TYPE_MASK GENMASK(3, 1) ++#define PATN_EN_MASK BIT(0) ++ ++#define REG_FE_VIP_PATN(_n) (0x0304 + ((_n) << 3)) ++#define PATN_DP_MASK GENMASK(31, 16) ++#define PATN_SP_MASK GENMASK(15, 0) ++ ++#define REG_CDM1_VLAN_CTRL CDM1_BASE ++#define CDM1_VLAN_MASK GENMASK(31, 16) ++ ++#define REG_CDM1_FWD_CFG (CDM1_BASE + 0x08) ++#define CDM1_VIP_QSEL_MASK GENMASK(24, 20) ++ ++#define REG_CDM1_CRSN_QSEL(_n) (CDM1_BASE + 0x10 + ((_n) << 2)) ++#define CDM1_CRSN_QSEL_REASON_MASK(_n) \ ++ GENMASK(4 + (((_n) % 4) << 3), (((_n) % 4) << 3)) ++ ++#define REG_CDM2_FWD_CFG (CDM2_BASE + 0x08) ++#define CDM2_OAM_QSEL_MASK GENMASK(31, 27) ++#define CDM2_VIP_QSEL_MASK GENMASK(24, 20) ++ ++#define REG_CDM2_CRSN_QSEL(_n) (CDM2_BASE + 0x10 + ((_n) << 2)) ++#define CDM2_CRSN_QSEL_REASON_MASK(_n) \ ++ GENMASK(4 + (((_n) % 4) << 3), (((_n) % 4) << 3)) ++ ++#define REG_GDM_FWD_CFG(_n) GDM_BASE(_n) ++#define GDM_DROP_CRC_ERR BIT(23) ++#define GDM_IP4_CKSUM BIT(22) ++#define GDM_TCP_CKSUM BIT(21) ++#define GDM_UDP_CKSUM BIT(20) ++#define GDM_UCFQ_MASK GENMASK(15, 12) ++#define GDM_BCFQ_MASK GENMASK(11, 8) ++#define GDM_MCFQ_MASK GENMASK(7, 4) ++#define GDM_OCFQ_MASK GENMASK(3, 0) ++ ++#define REG_GDM_INGRESS_CFG(_n) (GDM_BASE(_n) + 0x10) ++#define GDM_INGRESS_FC_EN_MASK BIT(1) ++#define GDM_STAG_EN_MASK BIT(0) ++ ++#define REG_GDM_LEN_CFG(_n) (GDM_BASE(_n) + 0x14) ++#define GDM_SHORT_LEN_MASK GENMASK(13, 0) ++#define GDM_LONG_LEN_MASK GENMASK(29, 16) ++ ++#define REG_FE_CPORT_CFG (GDM1_BASE + 0x40) ++#define FE_CPORT_PAD BIT(26) ++#define FE_CPORT_PORT_XFC_MASK BIT(25) ++#define FE_CPORT_QUEUE_XFC_MASK BIT(24) ++ ++#define REG_FE_GDM_MIB_CLEAR(_n) (GDM_BASE(_n) + 0xf0) ++#define FE_GDM_MIB_RX_CLEAR_MASK BIT(1) ++#define FE_GDM_MIB_TX_CLEAR_MASK BIT(0) ++ ++#define REG_FE_GDM1_MIB_CFG (GDM1_BASE + 0xf4) ++#define FE_STRICT_RFC2819_MODE_MASK BIT(31) ++#define FE_GDM1_TX_MIB_SPLIT_EN_MASK BIT(17) ++#define FE_GDM1_RX_MIB_SPLIT_EN_MASK BIT(16) ++#define FE_TX_MIB_ID_MASK GENMASK(15, 8) ++#define FE_RX_MIB_ID_MASK GENMASK(7, 0) ++ ++#define REG_FE_GDM_TX_OK_PKT_CNT_L(_n) (GDM_BASE(_n) + 0x104) ++#define REG_FE_GDM_TX_OK_BYTE_CNT_L(_n) (GDM_BASE(_n) + 0x10c) ++#define REG_FE_GDM_TX_ETH_PKT_CNT_L(_n) (GDM_BASE(_n) + 0x110) ++#define REG_FE_GDM_TX_ETH_BYTE_CNT_L(_n) (GDM_BASE(_n) + 0x114) ++#define REG_FE_GDM_TX_ETH_DROP_CNT(_n) (GDM_BASE(_n) + 0x118) ++#define REG_FE_GDM_TX_ETH_BC_CNT(_n) (GDM_BASE(_n) + 0x11c) ++#define REG_FE_GDM_TX_ETH_MC_CNT(_n) (GDM_BASE(_n) + 0x120) ++#define REG_FE_GDM_TX_ETH_RUNT_CNT(_n) (GDM_BASE(_n) + 0x124) ++#define REG_FE_GDM_TX_ETH_LONG_CNT(_n) (GDM_BASE(_n) + 0x128) ++#define REG_FE_GDM_TX_ETH_E64_CNT_L(_n) (GDM_BASE(_n) + 0x12c) ++#define REG_FE_GDM_TX_ETH_L64_CNT_L(_n) (GDM_BASE(_n) + 0x130) ++#define REG_FE_GDM_TX_ETH_L127_CNT_L(_n) (GDM_BASE(_n) + 0x134) ++#define REG_FE_GDM_TX_ETH_L255_CNT_L(_n) (GDM_BASE(_n) + 0x138) ++#define REG_FE_GDM_TX_ETH_L511_CNT_L(_n) (GDM_BASE(_n) + 0x13c) ++#define REG_FE_GDM_TX_ETH_L1023_CNT_L(_n) (GDM_BASE(_n) + 0x140) ++ ++#define REG_FE_GDM_RX_OK_PKT_CNT_L(_n) (GDM_BASE(_n) + 0x148) ++#define REG_FE_GDM_RX_FC_DROP_CNT(_n) (GDM_BASE(_n) + 0x14c) ++#define REG_FE_GDM_RX_RC_DROP_CNT(_n) (GDM_BASE(_n) + 0x150) ++#define REG_FE_GDM_RX_OVERFLOW_DROP_CNT(_n) (GDM_BASE(_n) + 0x154) ++#define REG_FE_GDM_RX_ERROR_DROP_CNT(_n) (GDM_BASE(_n) + 0x158) ++#define REG_FE_GDM_RX_OK_BYTE_CNT_L(_n) (GDM_BASE(_n) + 0x15c) ++#define REG_FE_GDM_RX_ETH_PKT_CNT_L(_n) (GDM_BASE(_n) + 0x160) ++#define REG_FE_GDM_RX_ETH_BYTE_CNT_L(_n) (GDM_BASE(_n) + 0x164) ++#define REG_FE_GDM_RX_ETH_DROP_CNT(_n) (GDM_BASE(_n) + 0x168) ++#define REG_FE_GDM_RX_ETH_BC_CNT(_n) (GDM_BASE(_n) + 0x16c) ++#define REG_FE_GDM_RX_ETH_MC_CNT(_n) (GDM_BASE(_n) + 0x170) ++#define REG_FE_GDM_RX_ETH_CRC_ERR_CNT(_n) (GDM_BASE(_n) + 0x174) ++#define REG_FE_GDM_RX_ETH_FRAG_CNT(_n) (GDM_BASE(_n) + 0x178) ++#define REG_FE_GDM_RX_ETH_JABBER_CNT(_n) (GDM_BASE(_n) + 0x17c) ++#define REG_FE_GDM_RX_ETH_RUNT_CNT(_n) (GDM_BASE(_n) + 0x180) ++#define REG_FE_GDM_RX_ETH_LONG_CNT(_n) (GDM_BASE(_n) + 0x184) ++#define REG_FE_GDM_RX_ETH_E64_CNT_L(_n) (GDM_BASE(_n) + 0x188) ++#define REG_FE_GDM_RX_ETH_L64_CNT_L(_n) (GDM_BASE(_n) + 0x18c) ++#define REG_FE_GDM_RX_ETH_L127_CNT_L(_n) (GDM_BASE(_n) + 0x190) ++#define REG_FE_GDM_RX_ETH_L255_CNT_L(_n) (GDM_BASE(_n) + 0x194) ++#define REG_FE_GDM_RX_ETH_L511_CNT_L(_n) (GDM_BASE(_n) + 0x198) ++#define REG_FE_GDM_RX_ETH_L1023_CNT_L(_n) (GDM_BASE(_n) + 0x19c) ++ ++#define REG_PPE1_TB_HASH_CFG (PPE1_BASE + 0x250) ++#define PPE1_SRAM_TABLE_EN_MASK BIT(0) ++#define PPE1_SRAM_HASH1_EN_MASK BIT(8) ++#define PPE1_DRAM_TABLE_EN_MASK BIT(16) ++#define PPE1_DRAM_HASH1_EN_MASK BIT(24) ++ ++#define REG_FE_GDM_TX_OK_PKT_CNT_H(_n) (GDM_BASE(_n) + 0x280) ++#define REG_FE_GDM_TX_OK_BYTE_CNT_H(_n) (GDM_BASE(_n) + 0x284) ++#define REG_FE_GDM_TX_ETH_PKT_CNT_H(_n) (GDM_BASE(_n) + 0x288) ++#define REG_FE_GDM_TX_ETH_BYTE_CNT_H(_n) (GDM_BASE(_n) + 0x28c) ++ ++#define REG_FE_GDM_RX_OK_PKT_CNT_H(_n) (GDM_BASE(_n) + 0x290) ++#define REG_FE_GDM_RX_OK_BYTE_CNT_H(_n) (GDM_BASE(_n) + 0x294) ++#define REG_FE_GDM_RX_ETH_PKT_CNT_H(_n) (GDM_BASE(_n) + 0x298) ++#define REG_FE_GDM_RX_ETH_BYTE_CNT_H(_n) (GDM_BASE(_n) + 0x29c) ++#define REG_FE_GDM_TX_ETH_E64_CNT_H(_n) (GDM_BASE(_n) + 0x2b8) ++#define REG_FE_GDM_TX_ETH_L64_CNT_H(_n) (GDM_BASE(_n) + 0x2bc) ++#define REG_FE_GDM_TX_ETH_L127_CNT_H(_n) (GDM_BASE(_n) + 0x2c0) ++#define REG_FE_GDM_TX_ETH_L255_CNT_H(_n) (GDM_BASE(_n) + 0x2c4) ++#define REG_FE_GDM_TX_ETH_L511_CNT_H(_n) (GDM_BASE(_n) + 0x2c8) ++#define REG_FE_GDM_TX_ETH_L1023_CNT_H(_n) (GDM_BASE(_n) + 0x2cc) ++#define REG_FE_GDM_RX_ETH_E64_CNT_H(_n) (GDM_BASE(_n) + 0x2e8) ++#define REG_FE_GDM_RX_ETH_L64_CNT_H(_n) (GDM_BASE(_n) + 0x2ec) ++#define REG_FE_GDM_RX_ETH_L127_CNT_H(_n) (GDM_BASE(_n) + 0x2f0) ++#define REG_FE_GDM_RX_ETH_L255_CNT_H(_n) (GDM_BASE(_n) + 0x2f4) ++#define REG_FE_GDM_RX_ETH_L511_CNT_H(_n) (GDM_BASE(_n) + 0x2f8) ++#define REG_FE_GDM_RX_ETH_L1023_CNT_H(_n) (GDM_BASE(_n) + 0x2fc) ++ ++#define REG_GDM2_CHN_RLS (GDM2_BASE + 0x20) ++#define MBI_RX_AGE_SEL_MASK GENMASK(26, 25) ++#define MBI_TX_AGE_SEL_MASK GENMASK(18, 17) ++ ++#define REG_GDM3_FWD_CFG GDM3_BASE ++#define GDM3_PAD_EN_MASK BIT(28) ++ ++#define REG_GDM4_FWD_CFG GDM4_BASE ++#define GDM4_PAD_EN_MASK BIT(28) ++#define GDM4_SPORT_OFFSET0_MASK GENMASK(11, 8) ++ ++#define REG_GDM4_SRC_PORT_SET (GDM4_BASE + 0x23c) ++#define GDM4_SPORT_OFF2_MASK GENMASK(19, 16) ++#define GDM4_SPORT_OFF1_MASK GENMASK(15, 12) ++#define GDM4_SPORT_OFF0_MASK GENMASK(11, 8) ++ ++#define REG_IP_FRAG_FP 0x2010 ++#define IP_ASSEMBLE_PORT_MASK GENMASK(24, 21) ++#define IP_ASSEMBLE_NBQ_MASK GENMASK(20, 16) ++#define IP_FRAGMENT_PORT_MASK GENMASK(8, 5) ++#define IP_FRAGMENT_NBQ_MASK GENMASK(4, 0) ++ ++#define REG_MC_VLAN_EN 0x2100 ++#define MC_VLAN_EN_MASK BIT(0) ++ ++#define REG_MC_VLAN_CFG 0x2104 ++#define MC_VLAN_CFG_CMD_DONE_MASK BIT(31) ++#define MC_VLAN_CFG_TABLE_ID_MASK GENMASK(21, 16) ++#define MC_VLAN_CFG_PORT_ID_MASK GENMASK(11, 8) ++#define MC_VLAN_CFG_TABLE_SEL_MASK BIT(4) ++#define MC_VLAN_CFG_RW_MASK BIT(0) ++ ++#define REG_MC_VLAN_DATA 0x2108 ++ ++#define REG_CDM5_RX_OQ1_DROP_CNT 0x29d4 ++ ++/* QDMA */ ++#define REG_QDMA_GLOBAL_CFG 0x0004 ++#define GLOBAL_CFG_RX_2B_OFFSET_MASK BIT(31) ++#define GLOBAL_CFG_DMA_PREFERENCE_MASK GENMASK(30, 29) ++#define GLOBAL_CFG_CPU_TXR_RR_MASK BIT(28) ++#define GLOBAL_CFG_DSCP_BYTE_SWAP_MASK BIT(27) ++#define GLOBAL_CFG_PAYLOAD_BYTE_SWAP_MASK BIT(26) ++#define GLOBAL_CFG_MULTICAST_MODIFY_FP_MASK BIT(25) ++#define GLOBAL_CFG_OAM_MODIFY_MASK BIT(24) ++#define GLOBAL_CFG_RESET_MASK BIT(23) ++#define GLOBAL_CFG_RESET_DONE_MASK BIT(22) ++#define GLOBAL_CFG_MULTICAST_EN_MASK BIT(21) ++#define GLOBAL_CFG_IRQ1_EN_MASK BIT(20) ++#define GLOBAL_CFG_IRQ0_EN_MASK BIT(19) ++#define GLOBAL_CFG_LOOPCNT_EN_MASK BIT(18) ++#define GLOBAL_CFG_RD_BYPASS_WR_MASK BIT(17) ++#define GLOBAL_CFG_QDMA_LOOPBACK_MASK BIT(16) ++#define GLOBAL_CFG_LPBK_RXQ_SEL_MASK GENMASK(13, 8) ++#define GLOBAL_CFG_CHECK_DONE_MASK BIT(7) ++#define GLOBAL_CFG_TX_WB_DONE_MASK BIT(6) ++#define GLOBAL_CFG_MAX_ISSUE_NUM_MASK GENMASK(5, 4) ++#define GLOBAL_CFG_RX_DMA_BUSY_MASK BIT(3) ++#define GLOBAL_CFG_RX_DMA_EN_MASK BIT(2) ++#define GLOBAL_CFG_TX_DMA_BUSY_MASK BIT(1) ++#define GLOBAL_CFG_TX_DMA_EN_MASK BIT(0) ++ ++#define REG_FWD_DSCP_BASE 0x0010 ++#define REG_FWD_BUF_BASE 0x0014 ++ ++#define REG_HW_FWD_DSCP_CFG 0x0018 ++#define HW_FWD_DSCP_PAYLOAD_SIZE_MASK GENMASK(29, 28) ++#define HW_FWD_DSCP_SCATTER_LEN_MASK GENMASK(17, 16) ++#define HW_FWD_DSCP_MIN_SCATTER_LEN_MASK GENMASK(15, 0) ++ ++#define REG_INT_STATUS(_n) \ ++ (((_n) == 4) ? 0x0730 : \ ++ ((_n) == 3) ? 0x0724 : \ ++ ((_n) == 2) ? 0x0720 : \ ++ ((_n) == 1) ? 0x0024 : 0x0020) ++ ++#define REG_INT_ENABLE(_n) \ ++ (((_n) == 4) ? 0x0750 : \ ++ ((_n) == 3) ? 0x0744 : \ ++ ((_n) == 2) ? 0x0740 : \ ++ ((_n) == 1) ? 0x002c : 0x0028) ++ ++/* QDMA_CSR_INT_ENABLE1 */ ++#define RX15_COHERENT_INT_MASK BIT(31) ++#define RX14_COHERENT_INT_MASK BIT(30) ++#define RX13_COHERENT_INT_MASK BIT(29) ++#define RX12_COHERENT_INT_MASK BIT(28) ++#define RX11_COHERENT_INT_MASK BIT(27) ++#define RX10_COHERENT_INT_MASK BIT(26) ++#define RX9_COHERENT_INT_MASK BIT(25) ++#define RX8_COHERENT_INT_MASK BIT(24) ++#define RX7_COHERENT_INT_MASK BIT(23) ++#define RX6_COHERENT_INT_MASK BIT(22) ++#define RX5_COHERENT_INT_MASK BIT(21) ++#define RX4_COHERENT_INT_MASK BIT(20) ++#define RX3_COHERENT_INT_MASK BIT(19) ++#define RX2_COHERENT_INT_MASK BIT(18) ++#define RX1_COHERENT_INT_MASK BIT(17) ++#define RX0_COHERENT_INT_MASK BIT(16) ++#define TX7_COHERENT_INT_MASK BIT(15) ++#define TX6_COHERENT_INT_MASK BIT(14) ++#define TX5_COHERENT_INT_MASK BIT(13) ++#define TX4_COHERENT_INT_MASK BIT(12) ++#define TX3_COHERENT_INT_MASK BIT(11) ++#define TX2_COHERENT_INT_MASK BIT(10) ++#define TX1_COHERENT_INT_MASK BIT(9) ++#define TX0_COHERENT_INT_MASK BIT(8) ++#define CNT_OVER_FLOW_INT_MASK BIT(7) ++#define IRQ1_FULL_INT_MASK BIT(5) ++#define IRQ1_INT_MASK BIT(4) ++#define HWFWD_DSCP_LOW_INT_MASK BIT(3) ++#define HWFWD_DSCP_EMPTY_INT_MASK BIT(2) ++#define IRQ0_FULL_INT_MASK BIT(1) ++#define IRQ0_INT_MASK BIT(0) ++ ++#define TX_DONE_INT_MASK(_n) \ ++ ((_n) ? IRQ1_INT_MASK | IRQ1_FULL_INT_MASK \ ++ : IRQ0_INT_MASK | IRQ0_FULL_INT_MASK) ++ ++#define INT_TX_MASK \ ++ (IRQ1_INT_MASK | IRQ1_FULL_INT_MASK | \ ++ IRQ0_INT_MASK | IRQ0_FULL_INT_MASK) ++ ++#define INT_IDX0_MASK \ ++ (TX0_COHERENT_INT_MASK | TX1_COHERENT_INT_MASK | \ ++ TX2_COHERENT_INT_MASK | TX3_COHERENT_INT_MASK | \ ++ TX4_COHERENT_INT_MASK | TX5_COHERENT_INT_MASK | \ ++ TX6_COHERENT_INT_MASK | TX7_COHERENT_INT_MASK | \ ++ RX0_COHERENT_INT_MASK | RX1_COHERENT_INT_MASK | \ ++ RX2_COHERENT_INT_MASK | RX3_COHERENT_INT_MASK | \ ++ RX4_COHERENT_INT_MASK | RX7_COHERENT_INT_MASK | \ ++ RX8_COHERENT_INT_MASK | RX9_COHERENT_INT_MASK | \ ++ RX15_COHERENT_INT_MASK | INT_TX_MASK) ++ ++/* QDMA_CSR_INT_ENABLE2 */ ++#define RX15_NO_CPU_DSCP_INT_MASK BIT(31) ++#define RX14_NO_CPU_DSCP_INT_MASK BIT(30) ++#define RX13_NO_CPU_DSCP_INT_MASK BIT(29) ++#define RX12_NO_CPU_DSCP_INT_MASK BIT(28) ++#define RX11_NO_CPU_DSCP_INT_MASK BIT(27) ++#define RX10_NO_CPU_DSCP_INT_MASK BIT(26) ++#define RX9_NO_CPU_DSCP_INT_MASK BIT(25) ++#define RX8_NO_CPU_DSCP_INT_MASK BIT(24) ++#define RX7_NO_CPU_DSCP_INT_MASK BIT(23) ++#define RX6_NO_CPU_DSCP_INT_MASK BIT(22) ++#define RX5_NO_CPU_DSCP_INT_MASK BIT(21) ++#define RX4_NO_CPU_DSCP_INT_MASK BIT(20) ++#define RX3_NO_CPU_DSCP_INT_MASK BIT(19) ++#define RX2_NO_CPU_DSCP_INT_MASK BIT(18) ++#define RX1_NO_CPU_DSCP_INT_MASK BIT(17) ++#define RX0_NO_CPU_DSCP_INT_MASK BIT(16) ++#define RX15_DONE_INT_MASK BIT(15) ++#define RX14_DONE_INT_MASK BIT(14) ++#define RX13_DONE_INT_MASK BIT(13) ++#define RX12_DONE_INT_MASK BIT(12) ++#define RX11_DONE_INT_MASK BIT(11) ++#define RX10_DONE_INT_MASK BIT(10) ++#define RX9_DONE_INT_MASK BIT(9) ++#define RX8_DONE_INT_MASK BIT(8) ++#define RX7_DONE_INT_MASK BIT(7) ++#define RX6_DONE_INT_MASK BIT(6) ++#define RX5_DONE_INT_MASK BIT(5) ++#define RX4_DONE_INT_MASK BIT(4) ++#define RX3_DONE_INT_MASK BIT(3) ++#define RX2_DONE_INT_MASK BIT(2) ++#define RX1_DONE_INT_MASK BIT(1) ++#define RX0_DONE_INT_MASK BIT(0) ++ ++#define RX_DONE_INT_MASK \ ++ (RX0_DONE_INT_MASK | RX1_DONE_INT_MASK | \ ++ RX2_DONE_INT_MASK | RX3_DONE_INT_MASK | \ ++ RX4_DONE_INT_MASK | RX7_DONE_INT_MASK | \ ++ RX8_DONE_INT_MASK | RX9_DONE_INT_MASK | \ ++ RX15_DONE_INT_MASK) ++#define INT_IDX1_MASK \ ++ (RX_DONE_INT_MASK | \ ++ RX0_NO_CPU_DSCP_INT_MASK | RX1_NO_CPU_DSCP_INT_MASK | \ ++ RX2_NO_CPU_DSCP_INT_MASK | RX3_NO_CPU_DSCP_INT_MASK | \ ++ RX4_NO_CPU_DSCP_INT_MASK | RX7_NO_CPU_DSCP_INT_MASK | \ ++ RX8_NO_CPU_DSCP_INT_MASK | RX9_NO_CPU_DSCP_INT_MASK | \ ++ RX15_NO_CPU_DSCP_INT_MASK) ++ ++/* QDMA_CSR_INT_ENABLE5 */ ++#define TX31_COHERENT_INT_MASK BIT(31) ++#define TX30_COHERENT_INT_MASK BIT(30) ++#define TX29_COHERENT_INT_MASK BIT(29) ++#define TX28_COHERENT_INT_MASK BIT(28) ++#define TX27_COHERENT_INT_MASK BIT(27) ++#define TX26_COHERENT_INT_MASK BIT(26) ++#define TX25_COHERENT_INT_MASK BIT(25) ++#define TX24_COHERENT_INT_MASK BIT(24) ++#define TX23_COHERENT_INT_MASK BIT(23) ++#define TX22_COHERENT_INT_MASK BIT(22) ++#define TX21_COHERENT_INT_MASK BIT(21) ++#define TX20_COHERENT_INT_MASK BIT(20) ++#define TX19_COHERENT_INT_MASK BIT(19) ++#define TX18_COHERENT_INT_MASK BIT(18) ++#define TX17_COHERENT_INT_MASK BIT(17) ++#define TX16_COHERENT_INT_MASK BIT(16) ++#define TX15_COHERENT_INT_MASK BIT(15) ++#define TX14_COHERENT_INT_MASK BIT(14) ++#define TX13_COHERENT_INT_MASK BIT(13) ++#define TX12_COHERENT_INT_MASK BIT(12) ++#define TX11_COHERENT_INT_MASK BIT(11) ++#define TX10_COHERENT_INT_MASK BIT(10) ++#define TX9_COHERENT_INT_MASK BIT(9) ++#define TX8_COHERENT_INT_MASK BIT(8) ++ ++#define INT_IDX4_MASK \ ++ (TX8_COHERENT_INT_MASK | TX9_COHERENT_INT_MASK | \ ++ TX10_COHERENT_INT_MASK | TX11_COHERENT_INT_MASK | \ ++ TX12_COHERENT_INT_MASK | TX13_COHERENT_INT_MASK | \ ++ TX14_COHERENT_INT_MASK | TX15_COHERENT_INT_MASK | \ ++ TX16_COHERENT_INT_MASK | TX17_COHERENT_INT_MASK | \ ++ TX18_COHERENT_INT_MASK | TX19_COHERENT_INT_MASK | \ ++ TX20_COHERENT_INT_MASK | TX21_COHERENT_INT_MASK | \ ++ TX22_COHERENT_INT_MASK | TX23_COHERENT_INT_MASK | \ ++ TX24_COHERENT_INT_MASK | TX25_COHERENT_INT_MASK | \ ++ TX26_COHERENT_INT_MASK | TX27_COHERENT_INT_MASK | \ ++ TX28_COHERENT_INT_MASK | TX29_COHERENT_INT_MASK | \ ++ TX30_COHERENT_INT_MASK | TX31_COHERENT_INT_MASK) ++ ++#define REG_TX_IRQ_BASE(_n) ((_n) ? 0x0048 : 0x0050) ++ ++#define REG_TX_IRQ_CFG(_n) ((_n) ? 0x004c : 0x0054) ++#define TX_IRQ_THR_MASK GENMASK(27, 16) ++#define TX_IRQ_DEPTH_MASK GENMASK(11, 0) ++ ++#define REG_IRQ_CLEAR_LEN(_n) ((_n) ? 0x0064 : 0x0058) ++#define IRQ_CLEAR_LEN_MASK GENMASK(7, 0) ++ ++#define REG_IRQ_STATUS(_n) ((_n) ? 0x0068 : 0x005c) ++#define IRQ_ENTRY_LEN_MASK GENMASK(27, 16) ++#define IRQ_HEAD_IDX_MASK GENMASK(11, 0) ++ ++#define REG_TX_RING_BASE(_n) \ ++ (((_n) < 8) ? 0x0100 + ((_n) << 5) : 0x0b00 + (((_n) - 8) << 5)) ++ ++#define REG_TX_RING_BLOCKING(_n) \ ++ (((_n) < 8) ? 0x0104 + ((_n) << 5) : 0x0b04 + (((_n) - 8) << 5)) ++ ++#define TX_RING_IRQ_BLOCKING_MAP_MASK BIT(6) ++#define TX_RING_IRQ_BLOCKING_CFG_MASK BIT(4) ++#define TX_RING_IRQ_BLOCKING_TX_DROP_EN_MASK BIT(2) ++#define TX_RING_IRQ_BLOCKING_MAX_TH_TXRING_EN_MASK BIT(1) ++#define TX_RING_IRQ_BLOCKING_MIN_TH_TXRING_EN_MASK BIT(0) ++ ++#define REG_TX_CPU_IDX(_n) \ ++ (((_n) < 8) ? 0x0108 + ((_n) << 5) : 0x0b08 + (((_n) - 8) << 5)) ++ ++#define TX_RING_CPU_IDX_MASK GENMASK(15, 0) ++ ++#define REG_TX_DMA_IDX(_n) \ ++ (((_n) < 8) ? 0x010c + ((_n) << 5) : 0x0b0c + (((_n) - 8) << 5)) ++ ++#define TX_RING_DMA_IDX_MASK GENMASK(15, 0) ++ ++#define IRQ_RING_IDX_MASK GENMASK(20, 16) ++#define IRQ_DESC_IDX_MASK GENMASK(15, 0) ++ ++#define REG_RX_RING_BASE(_n) \ ++ (((_n) < 16) ? 0x0200 + ((_n) << 5) : 0x0e00 + (((_n) - 16) << 5)) ++ ++#define REG_RX_RING_SIZE(_n) \ ++ (((_n) < 16) ? 0x0204 + ((_n) << 5) : 0x0e04 + (((_n) - 16) << 5)) ++ ++#define RX_RING_THR_MASK GENMASK(31, 16) ++#define RX_RING_SIZE_MASK GENMASK(15, 0) ++ ++#define REG_RX_CPU_IDX(_n) \ ++ (((_n) < 16) ? 0x0208 + ((_n) << 5) : 0x0e08 + (((_n) - 16) << 5)) ++ ++#define RX_RING_CPU_IDX_MASK GENMASK(15, 0) ++ ++#define REG_RX_DMA_IDX(_n) \ ++ (((_n) < 16) ? 0x020c + ((_n) << 5) : 0x0e0c + (((_n) - 16) << 5)) ++ ++#define REG_RX_DELAY_INT_IDX(_n) \ ++ (((_n) < 16) ? 0x0210 + ((_n) << 5) : 0x0e10 + (((_n) - 16) << 5)) ++ ++#define RX_DELAY_INT_MASK GENMASK(15, 0) ++ ++#define RX_RING_DMA_IDX_MASK GENMASK(15, 0) ++ ++#define REG_INGRESS_TRTCM_CFG 0x0070 ++#define INGRESS_TRTCM_EN_MASK BIT(31) ++#define INGRESS_TRTCM_MODE_MASK BIT(30) ++#define INGRESS_SLOW_TICK_RATIO_MASK GENMASK(29, 16) ++#define INGRESS_FAST_TICK_MASK GENMASK(15, 0) ++ ++#define REG_QUEUE_CLOSE_CFG(_n) (0x00a0 + ((_n) & 0xfc)) ++#define TXQ_DISABLE_CHAN_QUEUE_MASK(_n, _m) BIT((_m) + (((_n) & 0x3) << 3)) ++ ++#define REG_TXQ_DIS_CFG_BASE(_n) ((_n) ? 0x20a0 : 0x00a0) ++#define REG_TXQ_DIS_CFG(_n, _m) (REG_TXQ_DIS_CFG_BASE((_n)) + (_m) << 2) ++ ++#define REG_CNTR_CFG(_n) (0x0400 + ((_n) << 3)) ++#define CNTR_EN_MASK BIT(31) ++#define CNTR_ALL_CHAN_EN_MASK BIT(30) ++#define CNTR_ALL_QUEUE_EN_MASK BIT(29) ++#define CNTR_ALL_DSCP_RING_EN_MASK BIT(28) ++#define CNTR_SRC_MASK GENMASK(27, 24) ++#define CNTR_DSCP_RING_MASK GENMASK(20, 16) ++#define CNTR_CHAN_MASK GENMASK(7, 3) ++#define CNTR_QUEUE_MASK GENMASK(2, 0) ++ ++#define REG_CNTR_VAL(_n) (0x0404 + ((_n) << 3)) ++ ++#define REG_LMGR_INIT_CFG 0x1000 ++#define LMGR_INIT_START BIT(31) ++#define LMGR_SRAM_MODE_MASK BIT(30) ++#define HW_FWD_PKTSIZE_OVERHEAD_MASK GENMASK(27, 20) ++#define HW_FWD_DESC_NUM_MASK GENMASK(16, 0) ++ ++#define REG_FWD_DSCP_LOW_THR 0x1004 ++#define FWD_DSCP_LOW_THR_MASK GENMASK(17, 0) ++ ++#define REG_EGRESS_RATE_METER_CFG 0x100c ++#define EGRESS_RATE_METER_EN_MASK BIT(31) ++#define EGRESS_RATE_METER_EQ_RATE_EN_MASK BIT(17) ++#define EGRESS_RATE_METER_WINDOW_SZ_MASK GENMASK(16, 12) ++#define EGRESS_RATE_METER_TIMESLICE_MASK GENMASK(10, 0) ++ ++#define REG_EGRESS_TRTCM_CFG 0x1010 ++#define EGRESS_TRTCM_EN_MASK BIT(31) ++#define EGRESS_TRTCM_MODE_MASK BIT(30) ++#define EGRESS_SLOW_TICK_RATIO_MASK GENMASK(29, 16) ++#define EGRESS_FAST_TICK_MASK GENMASK(15, 0) ++ ++#define TRTCM_PARAM_RW_MASK BIT(31) ++#define TRTCM_PARAM_RW_DONE_MASK BIT(30) ++#define TRTCM_PARAM_TYPE_MASK GENMASK(29, 28) ++#define TRTCM_METER_GROUP_MASK GENMASK(27, 26) ++#define TRTCM_PARAM_INDEX_MASK GENMASK(23, 17) ++#define TRTCM_PARAM_RATE_TYPE_MASK BIT(16) ++ ++#define REG_TRTCM_CFG_PARAM(_n) ((_n) + 0x4) ++#define REG_TRTCM_DATA_LOW(_n) ((_n) + 0x8) ++#define REG_TRTCM_DATA_HIGH(_n) ((_n) + 0xc) ++ ++#define REG_TXWRR_MODE_CFG 0x1020 ++#define TWRR_WEIGHT_SCALE_MASK BIT(31) ++#define TWRR_WEIGHT_BASE_MASK BIT(3) ++ ++#define REG_TXWRR_WEIGHT_CFG 0x1024 ++#define TWRR_RW_CMD_MASK BIT(31) ++#define TWRR_RW_CMD_DONE BIT(30) ++#define TWRR_CHAN_IDX_MASK GENMASK(23, 19) ++#define TWRR_QUEUE_IDX_MASK GENMASK(18, 16) ++#define TWRR_VALUE_MASK GENMASK(15, 0) ++ ++#define REG_PSE_BUF_USAGE_CFG 0x1028 ++#define PSE_BUF_ESTIMATE_EN_MASK BIT(29) ++ ++#define REG_CHAN_QOS_MODE(_n) (0x1040 + ((_n) << 2)) ++#define CHAN_QOS_MODE_MASK(_n) GENMASK(2 + ((_n) << 2), (_n) << 2) ++ ++#define REG_GLB_TRTCM_CFG 0x1080 ++#define GLB_TRTCM_EN_MASK BIT(31) ++#define GLB_TRTCM_MODE_MASK BIT(30) ++#define GLB_SLOW_TICK_RATIO_MASK GENMASK(29, 16) ++#define GLB_FAST_TICK_MASK GENMASK(15, 0) ++ ++#define REG_TXQ_CNGST_CFG 0x10a0 ++#define TXQ_CNGST_DROP_EN BIT(31) ++#define TXQ_CNGST_DEI_DROP_EN BIT(30) ++ ++#define REG_SLA_TRTCM_CFG 0x1150 ++#define SLA_TRTCM_EN_MASK BIT(31) ++#define SLA_TRTCM_MODE_MASK BIT(30) ++#define SLA_SLOW_TICK_RATIO_MASK GENMASK(29, 16) ++#define SLA_FAST_TICK_MASK GENMASK(15, 0) ++ ++/* CTRL */ ++#define QDMA_DESC_DONE_MASK BIT(31) ++#define QDMA_DESC_DROP_MASK BIT(30) /* tx: drop - rx: overflow */ ++#define QDMA_DESC_MORE_MASK BIT(29) /* more SG elements */ ++#define QDMA_DESC_DEI_MASK BIT(25) ++#define QDMA_DESC_NO_DROP_MASK BIT(24) ++#define QDMA_DESC_LEN_MASK GENMASK(15, 0) ++/* DATA */ ++#define QDMA_DESC_NEXT_ID_MASK GENMASK(15, 0) ++/* TX MSG0 */ ++#define QDMA_ETH_TXMSG_MIC_IDX_MASK BIT(30) ++#define QDMA_ETH_TXMSG_SP_TAG_MASK GENMASK(29, 14) ++#define QDMA_ETH_TXMSG_ICO_MASK BIT(13) ++#define QDMA_ETH_TXMSG_UCO_MASK BIT(12) ++#define QDMA_ETH_TXMSG_TCO_MASK BIT(11) ++#define QDMA_ETH_TXMSG_TSO_MASK BIT(10) ++#define QDMA_ETH_TXMSG_FAST_MASK BIT(9) ++#define QDMA_ETH_TXMSG_OAM_MASK BIT(8) ++#define QDMA_ETH_TXMSG_CHAN_MASK GENMASK(7, 3) ++#define QDMA_ETH_TXMSG_QUEUE_MASK GENMASK(2, 0) ++/* TX MSG1 */ ++#define QDMA_ETH_TXMSG_NO_DROP BIT(31) ++#define QDMA_ETH_TXMSG_METER_MASK GENMASK(30, 24) /* 0x7f no meters */ ++#define QDMA_ETH_TXMSG_FPORT_MASK GENMASK(23, 20) ++#define QDMA_ETH_TXMSG_NBOQ_MASK GENMASK(19, 15) ++#define QDMA_ETH_TXMSG_HWF_MASK BIT(14) ++#define QDMA_ETH_TXMSG_HOP_MASK BIT(13) ++#define QDMA_ETH_TXMSG_PTP_MASK BIT(12) ++#define QDMA_ETH_TXMSG_ACNT_G1_MASK GENMASK(10, 6) /* 0x1f do not count */ ++#define QDMA_ETH_TXMSG_ACNT_G0_MASK GENMASK(5, 0) /* 0x3f do not count */ ++ ++/* RX MSG1 */ ++#define QDMA_ETH_RXMSG_DEI_MASK BIT(31) ++#define QDMA_ETH_RXMSG_IP6_MASK BIT(30) ++#define QDMA_ETH_RXMSG_IP4_MASK BIT(29) ++#define QDMA_ETH_RXMSG_IP4F_MASK BIT(28) ++#define QDMA_ETH_RXMSG_L4_VALID_MASK BIT(27) ++#define QDMA_ETH_RXMSG_L4F_MASK BIT(26) ++#define QDMA_ETH_RXMSG_SPORT_MASK GENMASK(25, 21) ++#define QDMA_ETH_RXMSG_CRSN_MASK GENMASK(20, 16) ++#define QDMA_ETH_RXMSG_PPE_ENTRY_MASK GENMASK(15, 0) ++ ++struct airoha_qdma_desc { ++ __le32 rsv; ++ __le32 ctrl; ++ __le32 addr; ++ __le32 data; ++ __le32 msg0; ++ __le32 msg1; ++ __le32 msg2; ++ __le32 msg3; ++}; ++ ++/* CTRL0 */ ++#define QDMA_FWD_DESC_CTX_MASK BIT(31) ++#define QDMA_FWD_DESC_RING_MASK GENMASK(30, 28) ++#define QDMA_FWD_DESC_IDX_MASK GENMASK(27, 16) ++#define QDMA_FWD_DESC_LEN_MASK GENMASK(15, 0) ++/* CTRL1 */ ++#define QDMA_FWD_DESC_FIRST_IDX_MASK GENMASK(15, 0) ++/* CTRL2 */ ++#define QDMA_FWD_DESC_MORE_PKT_NUM_MASK GENMASK(2, 0) ++ ++struct airoha_qdma_fwd_desc { ++ __le32 addr; ++ __le32 ctrl0; ++ __le32 ctrl1; ++ __le32 ctrl2; ++ __le32 msg0; ++ __le32 msg1; ++ __le32 rsv0; ++ __le32 rsv1; ++}; ++ ++enum { ++ QDMA_INT_REG_IDX0, ++ QDMA_INT_REG_IDX1, ++ QDMA_INT_REG_IDX2, ++ QDMA_INT_REG_IDX3, ++ QDMA_INT_REG_IDX4, ++ QDMA_INT_REG_MAX ++}; ++ ++enum { ++ XSI_PCIE0_PORT, ++ XSI_PCIE1_PORT, ++ XSI_USB_PORT, ++ XSI_AE_PORT, ++ XSI_ETH_PORT, ++}; ++ ++enum { ++ XSI_PCIE0_VIP_PORT_MASK = BIT(22), ++ XSI_PCIE1_VIP_PORT_MASK = BIT(23), ++ XSI_USB_VIP_PORT_MASK = BIT(25), ++ XSI_ETH_VIP_PORT_MASK = BIT(24), ++}; ++ ++enum { ++ DEV_STATE_INITIALIZED, ++}; ++ ++enum { ++ CDM_CRSN_QSEL_Q1 = 1, ++ CDM_CRSN_QSEL_Q5 = 5, ++ CDM_CRSN_QSEL_Q6 = 6, ++ CDM_CRSN_QSEL_Q15 = 15, ++}; ++ ++enum { ++ CRSN_08 = 0x8, ++ CRSN_21 = 0x15, /* KA */ ++ CRSN_22 = 0x16, /* hit bind and force route to CPU */ ++ CRSN_24 = 0x18, ++ CRSN_25 = 0x19, ++}; ++ ++enum { ++ FE_PSE_PORT_CDM1, ++ FE_PSE_PORT_GDM1, ++ FE_PSE_PORT_GDM2, ++ FE_PSE_PORT_GDM3, ++ FE_PSE_PORT_PPE1, ++ FE_PSE_PORT_CDM2, ++ FE_PSE_PORT_CDM3, ++ FE_PSE_PORT_CDM4, ++ FE_PSE_PORT_PPE2, ++ FE_PSE_PORT_GDM4, ++ FE_PSE_PORT_CDM5, ++ FE_PSE_PORT_DROP = 0xf, ++}; ++ ++enum tx_sched_mode { ++ TC_SCH_WRR8, ++ TC_SCH_SP, ++ TC_SCH_WRR7, ++ TC_SCH_WRR6, ++ TC_SCH_WRR5, ++ TC_SCH_WRR4, ++ TC_SCH_WRR3, ++ TC_SCH_WRR2, ++}; ++ ++enum trtcm_param_type { ++ TRTCM_MISC_MODE, /* meter_en, pps_mode, tick_sel */ ++ TRTCM_TOKEN_RATE_MODE, ++ TRTCM_BUCKETSIZE_SHIFT_MODE, ++ TRTCM_BUCKET_COUNTER_MODE, ++}; ++ ++enum trtcm_mode_type { ++ TRTCM_COMMIT_MODE, ++ TRTCM_PEAK_MODE, ++}; ++ ++enum trtcm_param { ++ TRTCM_TICK_SEL = BIT(0), ++ TRTCM_PKT_MODE = BIT(1), ++ TRTCM_METER_MODE = BIT(2), ++}; ++ ++#define MIN_TOKEN_SIZE 4096 ++#define MAX_TOKEN_SIZE_OFFSET 17 ++#define TRTCM_TOKEN_RATE_MASK GENMASK(23, 6) ++#define TRTCM_TOKEN_RATE_FRACTION_MASK GENMASK(5, 0) ++ ++struct airoha_queue_entry { ++ union { ++ void *buf; ++ struct sk_buff *skb; ++ }; ++ dma_addr_t dma_addr; ++ u16 dma_len; ++}; ++ ++struct airoha_queue { ++ struct airoha_qdma *qdma; ++ ++ /* protect concurrent queue accesses */ ++ spinlock_t lock; ++ struct airoha_queue_entry *entry; ++ struct airoha_qdma_desc *desc; ++ u16 head; ++ u16 tail; ++ ++ int queued; ++ int ndesc; ++ int free_thr; ++ int buf_size; ++ ++ struct napi_struct napi; ++ struct page_pool *page_pool; ++}; ++ ++struct airoha_tx_irq_queue { ++ struct airoha_qdma *qdma; ++ ++ struct napi_struct napi; ++ ++ int size; ++ u32 *q; ++}; ++ ++struct airoha_hw_stats { ++ /* protect concurrent hw_stats accesses */ ++ spinlock_t lock; ++ struct u64_stats_sync syncp; ++ ++ /* get_stats64 */ ++ u64 rx_ok_pkts; ++ u64 tx_ok_pkts; ++ u64 rx_ok_bytes; ++ u64 tx_ok_bytes; ++ u64 rx_multicast; ++ u64 rx_errors; ++ u64 rx_drops; ++ u64 tx_drops; ++ u64 rx_crc_error; ++ u64 rx_over_errors; ++ /* ethtool stats */ ++ u64 tx_broadcast; ++ u64 tx_multicast; ++ u64 tx_len[7]; ++ u64 rx_broadcast; ++ u64 rx_fragment; ++ u64 rx_jabber; ++ u64 rx_len[7]; ++}; ++ ++struct airoha_qdma { ++ struct airoha_eth *eth; ++ void __iomem *regs; ++ ++ /* protect concurrent irqmask accesses */ ++ spinlock_t irq_lock; ++ u32 irqmask[QDMA_INT_REG_MAX]; ++ int irq; ++ ++ struct airoha_tx_irq_queue q_tx_irq[AIROHA_NUM_TX_IRQ]; ++ ++ struct airoha_queue q_tx[AIROHA_NUM_TX_RING]; ++ struct airoha_queue q_rx[AIROHA_NUM_RX_RING]; ++ ++ /* descriptor and packet buffers for qdma hw forward */ ++ struct { ++ void *desc; ++ void *q; ++ } hfwd; ++}; ++ ++struct airoha_gdm_port { ++ struct airoha_qdma *qdma; ++ struct net_device *dev; ++ int id; ++ ++ struct airoha_hw_stats stats; ++ ++ DECLARE_BITMAP(qos_sq_bmap, AIROHA_NUM_QOS_CHANNELS); ++ ++ /* qos stats counters */ ++ u64 cpu_tx_packets; ++ u64 fwd_tx_packets; ++}; ++ ++struct airoha_eth { ++ struct device *dev; ++ ++ unsigned long state; ++ void __iomem *fe_regs; ++ ++ struct reset_control_bulk_data rsts[AIROHA_MAX_NUM_RSTS]; ++ struct reset_control_bulk_data xsi_rsts[AIROHA_MAX_NUM_XSI_RSTS]; ++ ++ struct net_device *napi_dev; ++ ++ struct airoha_qdma qdma[AIROHA_MAX_NUM_QDMA]; ++ struct airoha_gdm_port *ports[AIROHA_MAX_NUM_GDM_PORTS]; ++}; ++ ++static u32 airoha_rr(void __iomem *base, u32 offset) ++{ ++ return readl(base + offset); ++} ++ ++static void airoha_wr(void __iomem *base, u32 offset, u32 val) ++{ ++ writel(val, base + offset); ++} ++ ++static u32 airoha_rmw(void __iomem *base, u32 offset, u32 mask, u32 val) ++{ ++ val |= (airoha_rr(base, offset) & ~mask); ++ airoha_wr(base, offset, val); ++ ++ return val; ++} ++ ++#define airoha_fe_rr(eth, offset) \ ++ airoha_rr((eth)->fe_regs, (offset)) ++#define airoha_fe_wr(eth, offset, val) \ ++ airoha_wr((eth)->fe_regs, (offset), (val)) ++#define airoha_fe_rmw(eth, offset, mask, val) \ ++ airoha_rmw((eth)->fe_regs, (offset), (mask), (val)) ++#define airoha_fe_set(eth, offset, val) \ ++ airoha_rmw((eth)->fe_regs, (offset), 0, (val)) ++#define airoha_fe_clear(eth, offset, val) \ ++ airoha_rmw((eth)->fe_regs, (offset), (val), 0) ++ ++#define airoha_qdma_rr(qdma, offset) \ ++ airoha_rr((qdma)->regs, (offset)) ++#define airoha_qdma_wr(qdma, offset, val) \ ++ airoha_wr((qdma)->regs, (offset), (val)) ++#define airoha_qdma_rmw(qdma, offset, mask, val) \ ++ airoha_rmw((qdma)->regs, (offset), (mask), (val)) ++#define airoha_qdma_set(qdma, offset, val) \ ++ airoha_rmw((qdma)->regs, (offset), 0, (val)) ++#define airoha_qdma_clear(qdma, offset, val) \ ++ airoha_rmw((qdma)->regs, (offset), (val), 0) ++ ++static void airoha_qdma_set_irqmask(struct airoha_qdma *qdma, int index, ++ u32 clear, u32 set) ++{ ++ unsigned long flags; ++ ++ if (WARN_ON_ONCE(index >= ARRAY_SIZE(qdma->irqmask))) ++ return; ++ ++ spin_lock_irqsave(&qdma->irq_lock, flags); ++ ++ qdma->irqmask[index] &= ~clear; ++ qdma->irqmask[index] |= set; ++ airoha_qdma_wr(qdma, REG_INT_ENABLE(index), qdma->irqmask[index]); ++ /* Read irq_enable register in order to guarantee the update above ++ * completes in the spinlock critical section. ++ */ ++ airoha_qdma_rr(qdma, REG_INT_ENABLE(index)); ++ ++ spin_unlock_irqrestore(&qdma->irq_lock, flags); ++} ++ ++static void airoha_qdma_irq_enable(struct airoha_qdma *qdma, int index, ++ u32 mask) ++{ ++ airoha_qdma_set_irqmask(qdma, index, 0, mask); ++} ++ ++static void airoha_qdma_irq_disable(struct airoha_qdma *qdma, int index, ++ u32 mask) ++{ ++ airoha_qdma_set_irqmask(qdma, index, mask, 0); ++} ++ ++static bool airhoa_is_lan_gdm_port(struct airoha_gdm_port *port) ++{ ++ /* GDM1 port on EN7581 SoC is connected to the lan dsa switch. ++ * GDM{2,3,4} can be used as wan port connected to an external ++ * phy module. ++ */ ++ return port->id == 1; ++} ++ ++static void airoha_set_macaddr(struct airoha_gdm_port *port, const u8 *addr) ++{ ++ struct airoha_eth *eth = port->qdma->eth; ++ u32 val, reg; ++ ++ reg = airhoa_is_lan_gdm_port(port) ? REG_FE_LAN_MAC_H ++ : REG_FE_WAN_MAC_H; ++ val = (addr[0] << 16) | (addr[1] << 8) | addr[2]; ++ airoha_fe_wr(eth, reg, val); ++ ++ val = (addr[3] << 16) | (addr[4] << 8) | addr[5]; ++ airoha_fe_wr(eth, REG_FE_MAC_LMIN(reg), val); ++ airoha_fe_wr(eth, REG_FE_MAC_LMAX(reg), val); ++} ++ ++static void airoha_set_gdm_port_fwd_cfg(struct airoha_eth *eth, u32 addr, ++ u32 val) ++{ ++ airoha_fe_rmw(eth, addr, GDM_OCFQ_MASK, ++ FIELD_PREP(GDM_OCFQ_MASK, val)); ++ airoha_fe_rmw(eth, addr, GDM_MCFQ_MASK, ++ FIELD_PREP(GDM_MCFQ_MASK, val)); ++ airoha_fe_rmw(eth, addr, GDM_BCFQ_MASK, ++ FIELD_PREP(GDM_BCFQ_MASK, val)); ++ airoha_fe_rmw(eth, addr, GDM_UCFQ_MASK, ++ FIELD_PREP(GDM_UCFQ_MASK, val)); ++} ++ ++static int airoha_set_gdm_port(struct airoha_eth *eth, int port, bool enable) ++{ ++ u32 val = enable ? FE_PSE_PORT_PPE1 : FE_PSE_PORT_DROP; ++ u32 vip_port, cfg_addr; ++ ++ switch (port) { ++ case XSI_PCIE0_PORT: ++ vip_port = XSI_PCIE0_VIP_PORT_MASK; ++ cfg_addr = REG_GDM_FWD_CFG(3); ++ break; ++ case XSI_PCIE1_PORT: ++ vip_port = XSI_PCIE1_VIP_PORT_MASK; ++ cfg_addr = REG_GDM_FWD_CFG(3); ++ break; ++ case XSI_USB_PORT: ++ vip_port = XSI_USB_VIP_PORT_MASK; ++ cfg_addr = REG_GDM_FWD_CFG(4); ++ break; ++ case XSI_ETH_PORT: ++ vip_port = XSI_ETH_VIP_PORT_MASK; ++ cfg_addr = REG_GDM_FWD_CFG(4); ++ break; ++ default: ++ return -EINVAL; ++ } ++ ++ if (enable) { ++ airoha_fe_set(eth, REG_FE_VIP_PORT_EN, vip_port); ++ airoha_fe_set(eth, REG_FE_IFC_PORT_EN, vip_port); ++ } else { ++ airoha_fe_clear(eth, REG_FE_VIP_PORT_EN, vip_port); ++ airoha_fe_clear(eth, REG_FE_IFC_PORT_EN, vip_port); ++ } ++ ++ airoha_set_gdm_port_fwd_cfg(eth, cfg_addr, val); ++ ++ return 0; ++} ++ ++static int airoha_set_gdm_ports(struct airoha_eth *eth, bool enable) ++{ ++ const int port_list[] = { ++ XSI_PCIE0_PORT, ++ XSI_PCIE1_PORT, ++ XSI_USB_PORT, ++ XSI_ETH_PORT ++ }; ++ int i, err; ++ ++ for (i = 0; i < ARRAY_SIZE(port_list); i++) { ++ err = airoha_set_gdm_port(eth, port_list[i], enable); ++ if (err) ++ goto error; ++ } ++ ++ return 0; ++ ++error: ++ for (i--; i >= 0; i--) ++ airoha_set_gdm_port(eth, port_list[i], false); ++ ++ return err; ++} ++ ++static void airoha_fe_maccr_init(struct airoha_eth *eth) ++{ ++ int p; ++ ++ for (p = 1; p <= ARRAY_SIZE(eth->ports); p++) { ++ airoha_fe_set(eth, REG_GDM_FWD_CFG(p), ++ GDM_TCP_CKSUM | GDM_UDP_CKSUM | GDM_IP4_CKSUM | ++ GDM_DROP_CRC_ERR); ++ airoha_set_gdm_port_fwd_cfg(eth, REG_GDM_FWD_CFG(p), ++ FE_PSE_PORT_CDM1); ++ airoha_fe_rmw(eth, REG_GDM_LEN_CFG(p), ++ GDM_SHORT_LEN_MASK | GDM_LONG_LEN_MASK, ++ FIELD_PREP(GDM_SHORT_LEN_MASK, 60) | ++ FIELD_PREP(GDM_LONG_LEN_MASK, 4004)); ++ } ++ ++ airoha_fe_rmw(eth, REG_CDM1_VLAN_CTRL, CDM1_VLAN_MASK, ++ FIELD_PREP(CDM1_VLAN_MASK, 0x8100)); ++ ++ airoha_fe_set(eth, REG_FE_CPORT_CFG, FE_CPORT_PAD); ++} ++ ++static void airoha_fe_vip_setup(struct airoha_eth *eth) ++{ ++ airoha_fe_wr(eth, REG_FE_VIP_PATN(3), ETH_P_PPP_DISC); ++ airoha_fe_wr(eth, REG_FE_VIP_EN(3), PATN_FCPU_EN_MASK | PATN_EN_MASK); ++ ++ airoha_fe_wr(eth, REG_FE_VIP_PATN(4), PPP_LCP); ++ airoha_fe_wr(eth, REG_FE_VIP_EN(4), ++ PATN_FCPU_EN_MASK | FIELD_PREP(PATN_TYPE_MASK, 1) | ++ PATN_EN_MASK); ++ ++ airoha_fe_wr(eth, REG_FE_VIP_PATN(6), PPP_IPCP); ++ airoha_fe_wr(eth, REG_FE_VIP_EN(6), ++ PATN_FCPU_EN_MASK | FIELD_PREP(PATN_TYPE_MASK, 1) | ++ PATN_EN_MASK); ++ ++ airoha_fe_wr(eth, REG_FE_VIP_PATN(7), PPP_CHAP); ++ airoha_fe_wr(eth, REG_FE_VIP_EN(7), ++ PATN_FCPU_EN_MASK | FIELD_PREP(PATN_TYPE_MASK, 1) | ++ PATN_EN_MASK); ++ ++ /* BOOTP (0x43) */ ++ airoha_fe_wr(eth, REG_FE_VIP_PATN(8), 0x43); ++ airoha_fe_wr(eth, REG_FE_VIP_EN(8), ++ PATN_FCPU_EN_MASK | PATN_SP_EN_MASK | ++ FIELD_PREP(PATN_TYPE_MASK, 4) | PATN_EN_MASK); ++ ++ /* BOOTP (0x44) */ ++ airoha_fe_wr(eth, REG_FE_VIP_PATN(9), 0x44); ++ airoha_fe_wr(eth, REG_FE_VIP_EN(9), ++ PATN_FCPU_EN_MASK | PATN_SP_EN_MASK | ++ FIELD_PREP(PATN_TYPE_MASK, 4) | PATN_EN_MASK); ++ ++ /* ISAKMP */ ++ airoha_fe_wr(eth, REG_FE_VIP_PATN(10), 0x1f401f4); ++ airoha_fe_wr(eth, REG_FE_VIP_EN(10), ++ PATN_FCPU_EN_MASK | PATN_DP_EN_MASK | PATN_SP_EN_MASK | ++ FIELD_PREP(PATN_TYPE_MASK, 4) | PATN_EN_MASK); ++ ++ airoha_fe_wr(eth, REG_FE_VIP_PATN(11), PPP_IPV6CP); ++ airoha_fe_wr(eth, REG_FE_VIP_EN(11), ++ PATN_FCPU_EN_MASK | FIELD_PREP(PATN_TYPE_MASK, 1) | ++ PATN_EN_MASK); ++ ++ /* DHCPv6 */ ++ airoha_fe_wr(eth, REG_FE_VIP_PATN(12), 0x2220223); ++ airoha_fe_wr(eth, REG_FE_VIP_EN(12), ++ PATN_FCPU_EN_MASK | PATN_DP_EN_MASK | PATN_SP_EN_MASK | ++ FIELD_PREP(PATN_TYPE_MASK, 4) | PATN_EN_MASK); ++ ++ airoha_fe_wr(eth, REG_FE_VIP_PATN(19), PPP_PAP); ++ airoha_fe_wr(eth, REG_FE_VIP_EN(19), ++ PATN_FCPU_EN_MASK | FIELD_PREP(PATN_TYPE_MASK, 1) | ++ PATN_EN_MASK); ++ ++ /* ETH->ETH_P_1905 (0x893a) */ ++ airoha_fe_wr(eth, REG_FE_VIP_PATN(20), 0x893a); ++ airoha_fe_wr(eth, REG_FE_VIP_EN(20), ++ PATN_FCPU_EN_MASK | PATN_EN_MASK); ++ ++ airoha_fe_wr(eth, REG_FE_VIP_PATN(21), ETH_P_LLDP); ++ airoha_fe_wr(eth, REG_FE_VIP_EN(21), ++ PATN_FCPU_EN_MASK | PATN_EN_MASK); ++} ++ ++static u32 airoha_fe_get_pse_queue_rsv_pages(struct airoha_eth *eth, ++ u32 port, u32 queue) ++{ ++ u32 val; ++ ++ airoha_fe_rmw(eth, REG_FE_PSE_QUEUE_CFG_WR, ++ PSE_CFG_PORT_ID_MASK | PSE_CFG_QUEUE_ID_MASK, ++ FIELD_PREP(PSE_CFG_PORT_ID_MASK, port) | ++ FIELD_PREP(PSE_CFG_QUEUE_ID_MASK, queue)); ++ val = airoha_fe_rr(eth, REG_FE_PSE_QUEUE_CFG_VAL); ++ ++ return FIELD_GET(PSE_CFG_OQ_RSV_MASK, val); ++} ++ ++static void airoha_fe_set_pse_queue_rsv_pages(struct airoha_eth *eth, ++ u32 port, u32 queue, u32 val) ++{ ++ airoha_fe_rmw(eth, REG_FE_PSE_QUEUE_CFG_VAL, PSE_CFG_OQ_RSV_MASK, ++ FIELD_PREP(PSE_CFG_OQ_RSV_MASK, val)); ++ airoha_fe_rmw(eth, REG_FE_PSE_QUEUE_CFG_WR, ++ PSE_CFG_PORT_ID_MASK | PSE_CFG_QUEUE_ID_MASK | ++ PSE_CFG_WR_EN_MASK | PSE_CFG_OQRSV_SEL_MASK, ++ FIELD_PREP(PSE_CFG_PORT_ID_MASK, port) | ++ FIELD_PREP(PSE_CFG_QUEUE_ID_MASK, queue) | ++ PSE_CFG_WR_EN_MASK | PSE_CFG_OQRSV_SEL_MASK); ++} ++ ++static u32 airoha_fe_get_pse_all_rsv(struct airoha_eth *eth) ++{ ++ u32 val = airoha_fe_rr(eth, REG_FE_PSE_BUF_SET); ++ ++ return FIELD_GET(PSE_ALLRSV_MASK, val); ++} ++ ++static int airoha_fe_set_pse_oq_rsv(struct airoha_eth *eth, ++ u32 port, u32 queue, u32 val) ++{ ++ u32 orig_val = airoha_fe_get_pse_queue_rsv_pages(eth, port, queue); ++ u32 tmp, all_rsv, fq_limit; ++ ++ airoha_fe_set_pse_queue_rsv_pages(eth, port, queue, val); ++ ++ /* modify all rsv */ ++ all_rsv = airoha_fe_get_pse_all_rsv(eth); ++ all_rsv += (val - orig_val); ++ airoha_fe_rmw(eth, REG_FE_PSE_BUF_SET, PSE_ALLRSV_MASK, ++ FIELD_PREP(PSE_ALLRSV_MASK, all_rsv)); ++ ++ /* modify hthd */ ++ tmp = airoha_fe_rr(eth, PSE_FQ_CFG); ++ fq_limit = FIELD_GET(PSE_FQ_LIMIT_MASK, tmp); ++ tmp = fq_limit - all_rsv - 0x20; ++ airoha_fe_rmw(eth, REG_PSE_SHARE_USED_THD, ++ PSE_SHARE_USED_HTHD_MASK, ++ FIELD_PREP(PSE_SHARE_USED_HTHD_MASK, tmp)); ++ ++ tmp = fq_limit - all_rsv - 0x100; ++ airoha_fe_rmw(eth, REG_PSE_SHARE_USED_THD, ++ PSE_SHARE_USED_MTHD_MASK, ++ FIELD_PREP(PSE_SHARE_USED_MTHD_MASK, tmp)); ++ tmp = (3 * tmp) >> 2; ++ airoha_fe_rmw(eth, REG_FE_PSE_BUF_SET, ++ PSE_SHARE_USED_LTHD_MASK, ++ FIELD_PREP(PSE_SHARE_USED_LTHD_MASK, tmp)); ++ ++ return 0; ++} ++ ++static void airoha_fe_pse_ports_init(struct airoha_eth *eth) ++{ ++ const u32 pse_port_num_queues[] = { ++ [FE_PSE_PORT_CDM1] = 6, ++ [FE_PSE_PORT_GDM1] = 6, ++ [FE_PSE_PORT_GDM2] = 32, ++ [FE_PSE_PORT_GDM3] = 6, ++ [FE_PSE_PORT_PPE1] = 4, ++ [FE_PSE_PORT_CDM2] = 6, ++ [FE_PSE_PORT_CDM3] = 8, ++ [FE_PSE_PORT_CDM4] = 10, ++ [FE_PSE_PORT_PPE2] = 4, ++ [FE_PSE_PORT_GDM4] = 2, ++ [FE_PSE_PORT_CDM5] = 2, ++ }; ++ u32 all_rsv; ++ int q; ++ ++ all_rsv = airoha_fe_get_pse_all_rsv(eth); ++ /* hw misses PPE2 oq rsv */ ++ all_rsv += PSE_RSV_PAGES * pse_port_num_queues[FE_PSE_PORT_PPE2]; ++ airoha_fe_set(eth, REG_FE_PSE_BUF_SET, all_rsv); ++ ++ /* CMD1 */ ++ for (q = 0; q < pse_port_num_queues[FE_PSE_PORT_CDM1]; q++) ++ airoha_fe_set_pse_oq_rsv(eth, FE_PSE_PORT_CDM1, q, ++ PSE_QUEUE_RSV_PAGES); ++ /* GMD1 */ ++ for (q = 0; q < pse_port_num_queues[FE_PSE_PORT_GDM1]; q++) ++ airoha_fe_set_pse_oq_rsv(eth, FE_PSE_PORT_GDM1, q, ++ PSE_QUEUE_RSV_PAGES); ++ /* GMD2 */ ++ for (q = 6; q < pse_port_num_queues[FE_PSE_PORT_GDM2]; q++) ++ airoha_fe_set_pse_oq_rsv(eth, FE_PSE_PORT_GDM2, q, 0); ++ /* GMD3 */ ++ for (q = 0; q < pse_port_num_queues[FE_PSE_PORT_GDM3]; q++) ++ airoha_fe_set_pse_oq_rsv(eth, FE_PSE_PORT_GDM3, q, ++ PSE_QUEUE_RSV_PAGES); ++ /* PPE1 */ ++ for (q = 0; q < pse_port_num_queues[FE_PSE_PORT_PPE1]; q++) { ++ if (q < pse_port_num_queues[FE_PSE_PORT_PPE1]) ++ airoha_fe_set_pse_oq_rsv(eth, FE_PSE_PORT_PPE1, q, ++ PSE_QUEUE_RSV_PAGES); ++ else ++ airoha_fe_set_pse_oq_rsv(eth, FE_PSE_PORT_PPE1, q, 0); ++ } ++ /* CDM2 */ ++ for (q = 0; q < pse_port_num_queues[FE_PSE_PORT_CDM2]; q++) ++ airoha_fe_set_pse_oq_rsv(eth, FE_PSE_PORT_CDM2, q, ++ PSE_QUEUE_RSV_PAGES); ++ /* CDM3 */ ++ for (q = 0; q < pse_port_num_queues[FE_PSE_PORT_CDM3] - 1; q++) ++ airoha_fe_set_pse_oq_rsv(eth, FE_PSE_PORT_CDM3, q, 0); ++ /* CDM4 */ ++ for (q = 4; q < pse_port_num_queues[FE_PSE_PORT_CDM4]; q++) ++ airoha_fe_set_pse_oq_rsv(eth, FE_PSE_PORT_CDM4, q, ++ PSE_QUEUE_RSV_PAGES); ++ /* PPE2 */ ++ for (q = 0; q < pse_port_num_queues[FE_PSE_PORT_PPE2]; q++) { ++ if (q < pse_port_num_queues[FE_PSE_PORT_PPE2] / 2) ++ airoha_fe_set_pse_oq_rsv(eth, FE_PSE_PORT_PPE2, q, ++ PSE_QUEUE_RSV_PAGES); ++ else ++ airoha_fe_set_pse_oq_rsv(eth, FE_PSE_PORT_PPE2, q, 0); ++ } ++ /* GMD4 */ ++ for (q = 0; q < pse_port_num_queues[FE_PSE_PORT_GDM4]; q++) ++ airoha_fe_set_pse_oq_rsv(eth, FE_PSE_PORT_GDM4, q, ++ PSE_QUEUE_RSV_PAGES); ++ /* CDM5 */ ++ for (q = 0; q < pse_port_num_queues[FE_PSE_PORT_CDM5]; q++) ++ airoha_fe_set_pse_oq_rsv(eth, FE_PSE_PORT_CDM5, q, ++ PSE_QUEUE_RSV_PAGES); ++} ++ ++static int airoha_fe_mc_vlan_clear(struct airoha_eth *eth) ++{ ++ int i; ++ ++ for (i = 0; i < AIROHA_FE_MC_MAX_VLAN_TABLE; i++) { ++ int err, j; ++ u32 val; ++ ++ airoha_fe_wr(eth, REG_MC_VLAN_DATA, 0x0); ++ ++ val = FIELD_PREP(MC_VLAN_CFG_TABLE_ID_MASK, i) | ++ MC_VLAN_CFG_TABLE_SEL_MASK | MC_VLAN_CFG_RW_MASK; ++ airoha_fe_wr(eth, REG_MC_VLAN_CFG, val); ++ err = read_poll_timeout(airoha_fe_rr, val, ++ val & MC_VLAN_CFG_CMD_DONE_MASK, ++ USEC_PER_MSEC, 5 * USEC_PER_MSEC, ++ false, eth, REG_MC_VLAN_CFG); ++ if (err) ++ return err; ++ ++ for (j = 0; j < AIROHA_FE_MC_MAX_VLAN_PORT; j++) { ++ airoha_fe_wr(eth, REG_MC_VLAN_DATA, 0x0); ++ ++ val = FIELD_PREP(MC_VLAN_CFG_TABLE_ID_MASK, i) | ++ FIELD_PREP(MC_VLAN_CFG_PORT_ID_MASK, j) | ++ MC_VLAN_CFG_RW_MASK; ++ airoha_fe_wr(eth, REG_MC_VLAN_CFG, val); ++ err = read_poll_timeout(airoha_fe_rr, val, ++ val & MC_VLAN_CFG_CMD_DONE_MASK, ++ USEC_PER_MSEC, ++ 5 * USEC_PER_MSEC, false, eth, ++ REG_MC_VLAN_CFG); ++ if (err) ++ return err; ++ } ++ } ++ ++ return 0; ++} ++ ++static void airoha_fe_crsn_qsel_init(struct airoha_eth *eth) ++{ ++ /* CDM1_CRSN_QSEL */ ++ airoha_fe_rmw(eth, REG_CDM1_CRSN_QSEL(CRSN_22 >> 2), ++ CDM1_CRSN_QSEL_REASON_MASK(CRSN_22), ++ FIELD_PREP(CDM1_CRSN_QSEL_REASON_MASK(CRSN_22), ++ CDM_CRSN_QSEL_Q1)); ++ airoha_fe_rmw(eth, REG_CDM1_CRSN_QSEL(CRSN_08 >> 2), ++ CDM1_CRSN_QSEL_REASON_MASK(CRSN_08), ++ FIELD_PREP(CDM1_CRSN_QSEL_REASON_MASK(CRSN_08), ++ CDM_CRSN_QSEL_Q1)); ++ airoha_fe_rmw(eth, REG_CDM1_CRSN_QSEL(CRSN_21 >> 2), ++ CDM1_CRSN_QSEL_REASON_MASK(CRSN_21), ++ FIELD_PREP(CDM1_CRSN_QSEL_REASON_MASK(CRSN_21), ++ CDM_CRSN_QSEL_Q1)); ++ airoha_fe_rmw(eth, REG_CDM1_CRSN_QSEL(CRSN_24 >> 2), ++ CDM1_CRSN_QSEL_REASON_MASK(CRSN_24), ++ FIELD_PREP(CDM1_CRSN_QSEL_REASON_MASK(CRSN_24), ++ CDM_CRSN_QSEL_Q6)); ++ airoha_fe_rmw(eth, REG_CDM1_CRSN_QSEL(CRSN_25 >> 2), ++ CDM1_CRSN_QSEL_REASON_MASK(CRSN_25), ++ FIELD_PREP(CDM1_CRSN_QSEL_REASON_MASK(CRSN_25), ++ CDM_CRSN_QSEL_Q1)); ++ /* CDM2_CRSN_QSEL */ ++ airoha_fe_rmw(eth, REG_CDM2_CRSN_QSEL(CRSN_08 >> 2), ++ CDM2_CRSN_QSEL_REASON_MASK(CRSN_08), ++ FIELD_PREP(CDM2_CRSN_QSEL_REASON_MASK(CRSN_08), ++ CDM_CRSN_QSEL_Q1)); ++ airoha_fe_rmw(eth, REG_CDM2_CRSN_QSEL(CRSN_21 >> 2), ++ CDM2_CRSN_QSEL_REASON_MASK(CRSN_21), ++ FIELD_PREP(CDM2_CRSN_QSEL_REASON_MASK(CRSN_21), ++ CDM_CRSN_QSEL_Q1)); ++ airoha_fe_rmw(eth, REG_CDM2_CRSN_QSEL(CRSN_22 >> 2), ++ CDM2_CRSN_QSEL_REASON_MASK(CRSN_22), ++ FIELD_PREP(CDM2_CRSN_QSEL_REASON_MASK(CRSN_22), ++ CDM_CRSN_QSEL_Q1)); ++ airoha_fe_rmw(eth, REG_CDM2_CRSN_QSEL(CRSN_24 >> 2), ++ CDM2_CRSN_QSEL_REASON_MASK(CRSN_24), ++ FIELD_PREP(CDM2_CRSN_QSEL_REASON_MASK(CRSN_24), ++ CDM_CRSN_QSEL_Q6)); ++ airoha_fe_rmw(eth, REG_CDM2_CRSN_QSEL(CRSN_25 >> 2), ++ CDM2_CRSN_QSEL_REASON_MASK(CRSN_25), ++ FIELD_PREP(CDM2_CRSN_QSEL_REASON_MASK(CRSN_25), ++ CDM_CRSN_QSEL_Q1)); ++} ++ ++static int airoha_fe_init(struct airoha_eth *eth) ++{ ++ airoha_fe_maccr_init(eth); ++ ++ /* PSE IQ reserve */ ++ airoha_fe_rmw(eth, REG_PSE_IQ_REV1, PSE_IQ_RES1_P2_MASK, ++ FIELD_PREP(PSE_IQ_RES1_P2_MASK, 0x10)); ++ airoha_fe_rmw(eth, REG_PSE_IQ_REV2, ++ PSE_IQ_RES2_P5_MASK | PSE_IQ_RES2_P4_MASK, ++ FIELD_PREP(PSE_IQ_RES2_P5_MASK, 0x40) | ++ FIELD_PREP(PSE_IQ_RES2_P4_MASK, 0x34)); ++ ++ /* enable FE copy engine for MC/KA/DPI */ ++ airoha_fe_wr(eth, REG_FE_PCE_CFG, ++ PCE_DPI_EN_MASK | PCE_KA_EN_MASK | PCE_MC_EN_MASK); ++ /* set vip queue selection to ring 1 */ ++ airoha_fe_rmw(eth, REG_CDM1_FWD_CFG, CDM1_VIP_QSEL_MASK, ++ FIELD_PREP(CDM1_VIP_QSEL_MASK, 0x4)); ++ airoha_fe_rmw(eth, REG_CDM2_FWD_CFG, CDM2_VIP_QSEL_MASK, ++ FIELD_PREP(CDM2_VIP_QSEL_MASK, 0x4)); ++ /* set GDM4 source interface offset to 8 */ ++ airoha_fe_rmw(eth, REG_GDM4_SRC_PORT_SET, ++ GDM4_SPORT_OFF2_MASK | ++ GDM4_SPORT_OFF1_MASK | ++ GDM4_SPORT_OFF0_MASK, ++ FIELD_PREP(GDM4_SPORT_OFF2_MASK, 8) | ++ FIELD_PREP(GDM4_SPORT_OFF1_MASK, 8) | ++ FIELD_PREP(GDM4_SPORT_OFF0_MASK, 8)); ++ ++ /* set PSE Page as 128B */ ++ airoha_fe_rmw(eth, REG_FE_DMA_GLO_CFG, ++ FE_DMA_GLO_L2_SPACE_MASK | FE_DMA_GLO_PG_SZ_MASK, ++ FIELD_PREP(FE_DMA_GLO_L2_SPACE_MASK, 2) | ++ FE_DMA_GLO_PG_SZ_MASK); ++ airoha_fe_wr(eth, REG_FE_RST_GLO_CFG, ++ FE_RST_CORE_MASK | FE_RST_GDM3_MBI_ARB_MASK | ++ FE_RST_GDM4_MBI_ARB_MASK); ++ usleep_range(1000, 2000); ++ ++ /* connect RxRing1 and RxRing15 to PSE Port0 OQ-1 ++ * connect other rings to PSE Port0 OQ-0 ++ */ ++ airoha_fe_wr(eth, REG_FE_CDM1_OQ_MAP0, BIT(4)); ++ airoha_fe_wr(eth, REG_FE_CDM1_OQ_MAP1, BIT(28)); ++ airoha_fe_wr(eth, REG_FE_CDM1_OQ_MAP2, BIT(4)); ++ airoha_fe_wr(eth, REG_FE_CDM1_OQ_MAP3, BIT(28)); ++ ++ airoha_fe_vip_setup(eth); ++ airoha_fe_pse_ports_init(eth); ++ ++ airoha_fe_set(eth, REG_GDM_MISC_CFG, ++ GDM2_RDM_ACK_WAIT_PREF_MASK | ++ GDM2_CHN_VLD_MODE_MASK); ++ airoha_fe_rmw(eth, REG_CDM2_FWD_CFG, CDM2_OAM_QSEL_MASK, ++ FIELD_PREP(CDM2_OAM_QSEL_MASK, 15)); ++ ++ /* init fragment and assemble Force Port */ ++ /* NPU Core-3, NPU Bridge Channel-3 */ ++ airoha_fe_rmw(eth, REG_IP_FRAG_FP, ++ IP_FRAGMENT_PORT_MASK | IP_FRAGMENT_NBQ_MASK, ++ FIELD_PREP(IP_FRAGMENT_PORT_MASK, 6) | ++ FIELD_PREP(IP_FRAGMENT_NBQ_MASK, 3)); ++ /* QDMA LAN, RX Ring-22 */ ++ airoha_fe_rmw(eth, REG_IP_FRAG_FP, ++ IP_ASSEMBLE_PORT_MASK | IP_ASSEMBLE_NBQ_MASK, ++ FIELD_PREP(IP_ASSEMBLE_PORT_MASK, 0) | ++ FIELD_PREP(IP_ASSEMBLE_NBQ_MASK, 22)); ++ ++ airoha_fe_set(eth, REG_GDM3_FWD_CFG, GDM3_PAD_EN_MASK); ++ airoha_fe_set(eth, REG_GDM4_FWD_CFG, GDM4_PAD_EN_MASK); ++ ++ airoha_fe_crsn_qsel_init(eth); ++ ++ airoha_fe_clear(eth, REG_FE_CPORT_CFG, FE_CPORT_QUEUE_XFC_MASK); ++ airoha_fe_set(eth, REG_FE_CPORT_CFG, FE_CPORT_PORT_XFC_MASK); ++ ++ /* default aging mode for mbi unlock issue */ ++ airoha_fe_rmw(eth, REG_GDM2_CHN_RLS, ++ MBI_RX_AGE_SEL_MASK | MBI_TX_AGE_SEL_MASK, ++ FIELD_PREP(MBI_RX_AGE_SEL_MASK, 3) | ++ FIELD_PREP(MBI_TX_AGE_SEL_MASK, 3)); ++ ++ /* disable IFC by default */ ++ airoha_fe_clear(eth, REG_FE_CSR_IFC_CFG, FE_IFC_EN_MASK); ++ ++ /* enable 1:N vlan action, init vlan table */ ++ airoha_fe_set(eth, REG_MC_VLAN_EN, MC_VLAN_EN_MASK); ++ ++ return airoha_fe_mc_vlan_clear(eth); ++} ++ ++static int airoha_qdma_fill_rx_queue(struct airoha_queue *q) ++{ ++ enum dma_data_direction dir = page_pool_get_dma_dir(q->page_pool); ++ struct airoha_qdma *qdma = q->qdma; ++ struct airoha_eth *eth = qdma->eth; ++ int qid = q - &qdma->q_rx[0]; ++ int nframes = 0; ++ ++ while (q->queued < q->ndesc - 1) { ++ struct airoha_queue_entry *e = &q->entry[q->head]; ++ struct airoha_qdma_desc *desc = &q->desc[q->head]; ++ struct page *page; ++ int offset; ++ u32 val; ++ ++ page = page_pool_dev_alloc_frag(q->page_pool, &offset, ++ q->buf_size); ++ if (!page) ++ break; ++ ++ q->head = (q->head + 1) % q->ndesc; ++ q->queued++; ++ nframes++; ++ ++ e->buf = page_address(page) + offset; ++ e->dma_addr = page_pool_get_dma_addr(page) + offset; ++ e->dma_len = SKB_WITH_OVERHEAD(q->buf_size); ++ ++ dma_sync_single_for_device(eth->dev, e->dma_addr, e->dma_len, ++ dir); ++ ++ val = FIELD_PREP(QDMA_DESC_LEN_MASK, e->dma_len); ++ WRITE_ONCE(desc->ctrl, cpu_to_le32(val)); ++ WRITE_ONCE(desc->addr, cpu_to_le32(e->dma_addr)); ++ val = FIELD_PREP(QDMA_DESC_NEXT_ID_MASK, q->head); ++ WRITE_ONCE(desc->data, cpu_to_le32(val)); ++ WRITE_ONCE(desc->msg0, 0); ++ WRITE_ONCE(desc->msg1, 0); ++ WRITE_ONCE(desc->msg2, 0); ++ WRITE_ONCE(desc->msg3, 0); ++ ++ airoha_qdma_rmw(qdma, REG_RX_CPU_IDX(qid), ++ RX_RING_CPU_IDX_MASK, ++ FIELD_PREP(RX_RING_CPU_IDX_MASK, q->head)); ++ } ++ ++ return nframes; ++} ++ ++static int airoha_qdma_get_gdm_port(struct airoha_eth *eth, ++ struct airoha_qdma_desc *desc) ++{ ++ u32 port, sport, msg1 = le32_to_cpu(desc->msg1); ++ ++ sport = FIELD_GET(QDMA_ETH_RXMSG_SPORT_MASK, msg1); ++ switch (sport) { ++ case 0x10 ... 0x13: ++ port = 0; ++ break; ++ case 0x2 ... 0x4: ++ port = sport - 1; ++ break; ++ default: ++ return -EINVAL; ++ } ++ ++ return port >= ARRAY_SIZE(eth->ports) ? -EINVAL : port; ++} ++ ++static int airoha_qdma_rx_process(struct airoha_queue *q, int budget) ++{ ++ enum dma_data_direction dir = page_pool_get_dma_dir(q->page_pool); ++ struct airoha_qdma *qdma = q->qdma; ++ struct airoha_eth *eth = qdma->eth; ++ int qid = q - &qdma->q_rx[0]; ++ int done = 0; ++ ++ while (done < budget) { ++ struct airoha_queue_entry *e = &q->entry[q->tail]; ++ struct airoha_qdma_desc *desc = &q->desc[q->tail]; ++ dma_addr_t dma_addr = le32_to_cpu(desc->addr); ++ u32 desc_ctrl = le32_to_cpu(desc->ctrl); ++ struct sk_buff *skb; ++ int len, p; ++ ++ if (!(desc_ctrl & QDMA_DESC_DONE_MASK)) ++ break; ++ ++ if (!dma_addr) ++ break; ++ ++ len = FIELD_GET(QDMA_DESC_LEN_MASK, desc_ctrl); ++ if (!len) ++ break; ++ ++ q->tail = (q->tail + 1) % q->ndesc; ++ q->queued--; ++ ++ dma_sync_single_for_cpu(eth->dev, dma_addr, ++ SKB_WITH_OVERHEAD(q->buf_size), dir); ++ ++ p = airoha_qdma_get_gdm_port(eth, desc); ++ if (p < 0 || !eth->ports[p]) { ++ page_pool_put_full_page(q->page_pool, ++ virt_to_head_page(e->buf), ++ true); ++ continue; ++ } ++ ++ skb = napi_build_skb(e->buf, q->buf_size); ++ if (!skb) { ++ page_pool_put_full_page(q->page_pool, ++ virt_to_head_page(e->buf), ++ true); ++ break; ++ } ++ ++ skb_reserve(skb, 2); ++ __skb_put(skb, len); ++ skb_mark_for_recycle(skb); ++ skb->dev = eth->ports[p]->dev; ++ skb->protocol = eth_type_trans(skb, skb->dev); ++ skb->ip_summed = CHECKSUM_UNNECESSARY; ++ skb_record_rx_queue(skb, qid); ++ napi_gro_receive(&q->napi, skb); ++ ++ done++; ++ } ++ airoha_qdma_fill_rx_queue(q); ++ ++ return done; ++} ++ ++static int airoha_qdma_rx_napi_poll(struct napi_struct *napi, int budget) ++{ ++ struct airoha_queue *q = container_of(napi, struct airoha_queue, napi); ++ int cur, done = 0; ++ ++ do { ++ cur = airoha_qdma_rx_process(q, budget - done); ++ done += cur; ++ } while (cur && done < budget); ++ ++ if (done < budget && napi_complete(napi)) ++ airoha_qdma_irq_enable(q->qdma, QDMA_INT_REG_IDX1, ++ RX_DONE_INT_MASK); ++ ++ return done; ++} ++ ++static int airoha_qdma_init_rx_queue(struct airoha_queue *q, ++ struct airoha_qdma *qdma, int ndesc) ++{ ++ const struct page_pool_params pp_params = { ++ .order = 0, ++ .pool_size = 256, ++ .flags = PP_FLAG_DMA_MAP | PP_FLAG_DMA_SYNC_DEV | ++ PP_FLAG_PAGE_FRAG, ++ .dma_dir = DMA_FROM_DEVICE, ++ .max_len = PAGE_SIZE, ++ .nid = NUMA_NO_NODE, ++ .dev = qdma->eth->dev, ++ .napi = &q->napi, ++ }; ++ struct airoha_eth *eth = qdma->eth; ++ int qid = q - &qdma->q_rx[0], thr; ++ dma_addr_t dma_addr; ++ ++ q->buf_size = PAGE_SIZE / 2; ++ q->ndesc = ndesc; ++ q->qdma = qdma; ++ ++ q->entry = devm_kzalloc(eth->dev, q->ndesc * sizeof(*q->entry), ++ GFP_KERNEL); ++ if (!q->entry) ++ return -ENOMEM; ++ ++ q->page_pool = page_pool_create(&pp_params); ++ if (IS_ERR(q->page_pool)) { ++ int err = PTR_ERR(q->page_pool); ++ ++ q->page_pool = NULL; ++ return err; ++ } ++ ++ q->desc = dmam_alloc_coherent(eth->dev, q->ndesc * sizeof(*q->desc), ++ &dma_addr, GFP_KERNEL); ++ if (!q->desc) ++ return -ENOMEM; ++ ++ netif_napi_add(eth->napi_dev, &q->napi, airoha_qdma_rx_napi_poll); ++ ++ airoha_qdma_wr(qdma, REG_RX_RING_BASE(qid), dma_addr); ++ airoha_qdma_rmw(qdma, REG_RX_RING_SIZE(qid), ++ RX_RING_SIZE_MASK, ++ FIELD_PREP(RX_RING_SIZE_MASK, ndesc)); ++ ++ thr = clamp(ndesc >> 3, 1, 32); ++ airoha_qdma_rmw(qdma, REG_RX_RING_SIZE(qid), RX_RING_THR_MASK, ++ FIELD_PREP(RX_RING_THR_MASK, thr)); ++ airoha_qdma_rmw(qdma, REG_RX_DMA_IDX(qid), RX_RING_DMA_IDX_MASK, ++ FIELD_PREP(RX_RING_DMA_IDX_MASK, q->head)); ++ ++ airoha_qdma_fill_rx_queue(q); ++ ++ return 0; ++} ++ ++static void airoha_qdma_cleanup_rx_queue(struct airoha_queue *q) ++{ ++ struct airoha_eth *eth = q->qdma->eth; ++ ++ while (q->queued) { ++ struct airoha_queue_entry *e = &q->entry[q->tail]; ++ struct page *page = virt_to_head_page(e->buf); ++ ++ dma_sync_single_for_cpu(eth->dev, e->dma_addr, e->dma_len, ++ page_pool_get_dma_dir(q->page_pool)); ++ page_pool_put_full_page(q->page_pool, page, false); ++ q->tail = (q->tail + 1) % q->ndesc; ++ q->queued--; ++ } ++} ++ ++static int airoha_qdma_init_rx(struct airoha_qdma *qdma) ++{ ++ int i; ++ ++ for (i = 0; i < ARRAY_SIZE(qdma->q_rx); i++) { ++ int err; ++ ++ if (!(RX_DONE_INT_MASK & BIT(i))) { ++ /* rx-queue not binded to irq */ ++ continue; ++ } ++ ++ err = airoha_qdma_init_rx_queue(&qdma->q_rx[i], qdma, ++ RX_DSCP_NUM(i)); ++ if (err) ++ return err; ++ } ++ ++ return 0; ++} ++ ++static int airoha_qdma_tx_napi_poll(struct napi_struct *napi, int budget) ++{ ++ struct airoha_tx_irq_queue *irq_q; ++ int id, done = 0, irq_queued; ++ struct airoha_qdma *qdma; ++ struct airoha_eth *eth; ++ u32 status, head; ++ ++ irq_q = container_of(napi, struct airoha_tx_irq_queue, napi); ++ qdma = irq_q->qdma; ++ id = irq_q - &qdma->q_tx_irq[0]; ++ eth = qdma->eth; ++ ++ status = airoha_qdma_rr(qdma, REG_IRQ_STATUS(id)); ++ head = FIELD_GET(IRQ_HEAD_IDX_MASK, status); ++ head = head % irq_q->size; ++ irq_queued = FIELD_GET(IRQ_ENTRY_LEN_MASK, status); ++ ++ while (irq_queued > 0 && done < budget) { ++ u32 qid, val = irq_q->q[head]; ++ struct airoha_qdma_desc *desc; ++ struct airoha_queue_entry *e; ++ struct airoha_queue *q; ++ u32 index, desc_ctrl; ++ struct sk_buff *skb; ++ ++ if (val == 0xff) ++ break; ++ ++ irq_q->q[head] = 0xff; /* mark as done */ ++ head = (head + 1) % irq_q->size; ++ irq_queued--; ++ done++; ++ ++ qid = FIELD_GET(IRQ_RING_IDX_MASK, val); ++ if (qid >= ARRAY_SIZE(qdma->q_tx)) ++ continue; ++ ++ q = &qdma->q_tx[qid]; ++ if (!q->ndesc) ++ continue; ++ ++ index = FIELD_GET(IRQ_DESC_IDX_MASK, val); ++ if (index >= q->ndesc) ++ continue; ++ ++ spin_lock_bh(&q->lock); ++ ++ if (!q->queued) ++ goto unlock; ++ ++ desc = &q->desc[index]; ++ desc_ctrl = le32_to_cpu(desc->ctrl); ++ ++ if (!(desc_ctrl & QDMA_DESC_DONE_MASK) && ++ !(desc_ctrl & QDMA_DESC_DROP_MASK)) ++ goto unlock; ++ ++ e = &q->entry[index]; ++ skb = e->skb; ++ ++ dma_unmap_single(eth->dev, e->dma_addr, e->dma_len, ++ DMA_TO_DEVICE); ++ memset(e, 0, sizeof(*e)); ++ WRITE_ONCE(desc->msg0, 0); ++ WRITE_ONCE(desc->msg1, 0); ++ q->queued--; ++ ++ /* completion ring can report out-of-order indexes if hw QoS ++ * is enabled and packets with different priority are queued ++ * to same DMA ring. Take into account possible out-of-order ++ * reports incrementing DMA ring tail pointer ++ */ ++ while (q->tail != q->head && !q->entry[q->tail].dma_addr) ++ q->tail = (q->tail + 1) % q->ndesc; ++ ++ if (skb) { ++ u16 queue = skb_get_queue_mapping(skb); ++ struct netdev_queue *txq; ++ ++ txq = netdev_get_tx_queue(skb->dev, queue); ++ netdev_tx_completed_queue(txq, 1, skb->len); ++ if (netif_tx_queue_stopped(txq) && ++ q->ndesc - q->queued >= q->free_thr) ++ netif_tx_wake_queue(txq); ++ ++ dev_kfree_skb_any(skb); ++ } ++unlock: ++ spin_unlock_bh(&q->lock); ++ } ++ ++ if (done) { ++ int i, len = done >> 7; ++ ++ for (i = 0; i < len; i++) ++ airoha_qdma_rmw(qdma, REG_IRQ_CLEAR_LEN(id), ++ IRQ_CLEAR_LEN_MASK, 0x80); ++ airoha_qdma_rmw(qdma, REG_IRQ_CLEAR_LEN(id), ++ IRQ_CLEAR_LEN_MASK, (done & 0x7f)); ++ } ++ ++ if (done < budget && napi_complete(napi)) ++ airoha_qdma_irq_enable(qdma, QDMA_INT_REG_IDX0, ++ TX_DONE_INT_MASK(id)); ++ ++ return done; ++} ++ ++static int airoha_qdma_init_tx_queue(struct airoha_queue *q, ++ struct airoha_qdma *qdma, int size) ++{ ++ struct airoha_eth *eth = qdma->eth; ++ int i, qid = q - &qdma->q_tx[0]; ++ dma_addr_t dma_addr; ++ ++ spin_lock_init(&q->lock); ++ q->ndesc = size; ++ q->qdma = qdma; ++ q->free_thr = 1 + MAX_SKB_FRAGS; ++ ++ q->entry = devm_kzalloc(eth->dev, q->ndesc * sizeof(*q->entry), ++ GFP_KERNEL); ++ if (!q->entry) ++ return -ENOMEM; ++ ++ q->desc = dmam_alloc_coherent(eth->dev, q->ndesc * sizeof(*q->desc), ++ &dma_addr, GFP_KERNEL); ++ if (!q->desc) ++ return -ENOMEM; ++ ++ for (i = 0; i < q->ndesc; i++) { ++ u32 val; ++ ++ val = FIELD_PREP(QDMA_DESC_DONE_MASK, 1); ++ WRITE_ONCE(q->desc[i].ctrl, cpu_to_le32(val)); ++ } ++ ++ /* xmit ring drop default setting */ ++ airoha_qdma_set(qdma, REG_TX_RING_BLOCKING(qid), ++ TX_RING_IRQ_BLOCKING_TX_DROP_EN_MASK); ++ ++ airoha_qdma_wr(qdma, REG_TX_RING_BASE(qid), dma_addr); ++ airoha_qdma_rmw(qdma, REG_TX_CPU_IDX(qid), TX_RING_CPU_IDX_MASK, ++ FIELD_PREP(TX_RING_CPU_IDX_MASK, q->head)); ++ airoha_qdma_rmw(qdma, REG_TX_DMA_IDX(qid), TX_RING_DMA_IDX_MASK, ++ FIELD_PREP(TX_RING_DMA_IDX_MASK, q->head)); ++ ++ return 0; ++} ++ ++static int airoha_qdma_tx_irq_init(struct airoha_tx_irq_queue *irq_q, ++ struct airoha_qdma *qdma, int size) ++{ ++ int id = irq_q - &qdma->q_tx_irq[0]; ++ struct airoha_eth *eth = qdma->eth; ++ dma_addr_t dma_addr; ++ ++ netif_napi_add_tx(eth->napi_dev, &irq_q->napi, ++ airoha_qdma_tx_napi_poll); ++ irq_q->q = dmam_alloc_coherent(eth->dev, size * sizeof(u32), ++ &dma_addr, GFP_KERNEL); ++ if (!irq_q->q) ++ return -ENOMEM; ++ ++ memset(irq_q->q, 0xff, size * sizeof(u32)); ++ irq_q->size = size; ++ irq_q->qdma = qdma; ++ ++ airoha_qdma_wr(qdma, REG_TX_IRQ_BASE(id), dma_addr); ++ airoha_qdma_rmw(qdma, REG_TX_IRQ_CFG(id), TX_IRQ_DEPTH_MASK, ++ FIELD_PREP(TX_IRQ_DEPTH_MASK, size)); ++ airoha_qdma_rmw(qdma, REG_TX_IRQ_CFG(id), TX_IRQ_THR_MASK, ++ FIELD_PREP(TX_IRQ_THR_MASK, 1)); ++ ++ return 0; ++} ++ ++static int airoha_qdma_init_tx(struct airoha_qdma *qdma) ++{ ++ int i, err; ++ ++ for (i = 0; i < ARRAY_SIZE(qdma->q_tx_irq); i++) { ++ err = airoha_qdma_tx_irq_init(&qdma->q_tx_irq[i], qdma, ++ IRQ_QUEUE_LEN(i)); ++ if (err) ++ return err; ++ } ++ ++ for (i = 0; i < ARRAY_SIZE(qdma->q_tx); i++) { ++ err = airoha_qdma_init_tx_queue(&qdma->q_tx[i], qdma, ++ TX_DSCP_NUM); ++ if (err) ++ return err; ++ } ++ ++ return 0; ++} ++ ++static void airoha_qdma_cleanup_tx_queue(struct airoha_queue *q) ++{ ++ struct airoha_eth *eth = q->qdma->eth; ++ ++ spin_lock_bh(&q->lock); ++ while (q->queued) { ++ struct airoha_queue_entry *e = &q->entry[q->tail]; ++ ++ dma_unmap_single(eth->dev, e->dma_addr, e->dma_len, ++ DMA_TO_DEVICE); ++ dev_kfree_skb_any(e->skb); ++ e->skb = NULL; ++ ++ q->tail = (q->tail + 1) % q->ndesc; ++ q->queued--; ++ } ++ spin_unlock_bh(&q->lock); ++} ++ ++static int airoha_qdma_init_hfwd_queues(struct airoha_qdma *qdma) ++{ ++ struct airoha_eth *eth = qdma->eth; ++ dma_addr_t dma_addr; ++ u32 status; ++ int size; ++ ++ size = HW_DSCP_NUM * sizeof(struct airoha_qdma_fwd_desc); ++ qdma->hfwd.desc = dmam_alloc_coherent(eth->dev, size, &dma_addr, ++ GFP_KERNEL); ++ if (!qdma->hfwd.desc) ++ return -ENOMEM; ++ ++ airoha_qdma_wr(qdma, REG_FWD_DSCP_BASE, dma_addr); ++ ++ size = AIROHA_MAX_PACKET_SIZE * HW_DSCP_NUM; ++ qdma->hfwd.q = dmam_alloc_coherent(eth->dev, size, &dma_addr, ++ GFP_KERNEL); ++ if (!qdma->hfwd.q) ++ return -ENOMEM; ++ ++ airoha_qdma_wr(qdma, REG_FWD_BUF_BASE, dma_addr); ++ ++ airoha_qdma_rmw(qdma, REG_HW_FWD_DSCP_CFG, ++ HW_FWD_DSCP_PAYLOAD_SIZE_MASK, ++ FIELD_PREP(HW_FWD_DSCP_PAYLOAD_SIZE_MASK, 0)); ++ airoha_qdma_rmw(qdma, REG_FWD_DSCP_LOW_THR, FWD_DSCP_LOW_THR_MASK, ++ FIELD_PREP(FWD_DSCP_LOW_THR_MASK, 128)); ++ airoha_qdma_rmw(qdma, REG_LMGR_INIT_CFG, ++ LMGR_INIT_START | LMGR_SRAM_MODE_MASK | ++ HW_FWD_DESC_NUM_MASK, ++ FIELD_PREP(HW_FWD_DESC_NUM_MASK, HW_DSCP_NUM) | ++ LMGR_INIT_START); ++ ++ return read_poll_timeout(airoha_qdma_rr, status, ++ !(status & LMGR_INIT_START), USEC_PER_MSEC, ++ 30 * USEC_PER_MSEC, true, qdma, ++ REG_LMGR_INIT_CFG); ++} ++ ++static void airoha_qdma_init_qos(struct airoha_qdma *qdma) ++{ ++ airoha_qdma_clear(qdma, REG_TXWRR_MODE_CFG, TWRR_WEIGHT_SCALE_MASK); ++ airoha_qdma_set(qdma, REG_TXWRR_MODE_CFG, TWRR_WEIGHT_BASE_MASK); ++ ++ airoha_qdma_clear(qdma, REG_PSE_BUF_USAGE_CFG, ++ PSE_BUF_ESTIMATE_EN_MASK); ++ ++ airoha_qdma_set(qdma, REG_EGRESS_RATE_METER_CFG, ++ EGRESS_RATE_METER_EN_MASK | ++ EGRESS_RATE_METER_EQ_RATE_EN_MASK); ++ /* 2047us x 31 = 63.457ms */ ++ airoha_qdma_rmw(qdma, REG_EGRESS_RATE_METER_CFG, ++ EGRESS_RATE_METER_WINDOW_SZ_MASK, ++ FIELD_PREP(EGRESS_RATE_METER_WINDOW_SZ_MASK, 0x1f)); ++ airoha_qdma_rmw(qdma, REG_EGRESS_RATE_METER_CFG, ++ EGRESS_RATE_METER_TIMESLICE_MASK, ++ FIELD_PREP(EGRESS_RATE_METER_TIMESLICE_MASK, 0x7ff)); ++ ++ /* ratelimit init */ ++ airoha_qdma_set(qdma, REG_GLB_TRTCM_CFG, GLB_TRTCM_EN_MASK); ++ /* fast-tick 25us */ ++ airoha_qdma_rmw(qdma, REG_GLB_TRTCM_CFG, GLB_FAST_TICK_MASK, ++ FIELD_PREP(GLB_FAST_TICK_MASK, 25)); ++ airoha_qdma_rmw(qdma, REG_GLB_TRTCM_CFG, GLB_SLOW_TICK_RATIO_MASK, ++ FIELD_PREP(GLB_SLOW_TICK_RATIO_MASK, 40)); ++ ++ airoha_qdma_set(qdma, REG_EGRESS_TRTCM_CFG, EGRESS_TRTCM_EN_MASK); ++ airoha_qdma_rmw(qdma, REG_EGRESS_TRTCM_CFG, EGRESS_FAST_TICK_MASK, ++ FIELD_PREP(EGRESS_FAST_TICK_MASK, 25)); ++ airoha_qdma_rmw(qdma, REG_EGRESS_TRTCM_CFG, ++ EGRESS_SLOW_TICK_RATIO_MASK, ++ FIELD_PREP(EGRESS_SLOW_TICK_RATIO_MASK, 40)); ++ ++ airoha_qdma_set(qdma, REG_INGRESS_TRTCM_CFG, INGRESS_TRTCM_EN_MASK); ++ airoha_qdma_clear(qdma, REG_INGRESS_TRTCM_CFG, ++ INGRESS_TRTCM_MODE_MASK); ++ airoha_qdma_rmw(qdma, REG_INGRESS_TRTCM_CFG, INGRESS_FAST_TICK_MASK, ++ FIELD_PREP(INGRESS_FAST_TICK_MASK, 125)); ++ airoha_qdma_rmw(qdma, REG_INGRESS_TRTCM_CFG, ++ INGRESS_SLOW_TICK_RATIO_MASK, ++ FIELD_PREP(INGRESS_SLOW_TICK_RATIO_MASK, 8)); ++ ++ airoha_qdma_set(qdma, REG_SLA_TRTCM_CFG, SLA_TRTCM_EN_MASK); ++ airoha_qdma_rmw(qdma, REG_SLA_TRTCM_CFG, SLA_FAST_TICK_MASK, ++ FIELD_PREP(SLA_FAST_TICK_MASK, 25)); ++ airoha_qdma_rmw(qdma, REG_SLA_TRTCM_CFG, SLA_SLOW_TICK_RATIO_MASK, ++ FIELD_PREP(SLA_SLOW_TICK_RATIO_MASK, 40)); ++} ++ ++static void airoha_qdma_init_qos_stats(struct airoha_qdma *qdma) ++{ ++ int i; ++ ++ for (i = 0; i < AIROHA_NUM_QOS_CHANNELS; i++) { ++ /* Tx-cpu transferred count */ ++ airoha_qdma_wr(qdma, REG_CNTR_VAL(i << 1), 0); ++ airoha_qdma_wr(qdma, REG_CNTR_CFG(i << 1), ++ CNTR_EN_MASK | CNTR_ALL_QUEUE_EN_MASK | ++ CNTR_ALL_DSCP_RING_EN_MASK | ++ FIELD_PREP(CNTR_CHAN_MASK, i)); ++ /* Tx-fwd transferred count */ ++ airoha_qdma_wr(qdma, REG_CNTR_VAL((i << 1) + 1), 0); ++ airoha_qdma_wr(qdma, REG_CNTR_CFG(i << 1), ++ CNTR_EN_MASK | CNTR_ALL_QUEUE_EN_MASK | ++ CNTR_ALL_DSCP_RING_EN_MASK | ++ FIELD_PREP(CNTR_SRC_MASK, 1) | ++ FIELD_PREP(CNTR_CHAN_MASK, i)); ++ } ++} ++ ++static int airoha_qdma_hw_init(struct airoha_qdma *qdma) ++{ ++ int i; ++ ++ /* clear pending irqs */ ++ for (i = 0; i < ARRAY_SIZE(qdma->irqmask); i++) ++ airoha_qdma_wr(qdma, REG_INT_STATUS(i), 0xffffffff); ++ ++ /* setup irqs */ ++ airoha_qdma_irq_enable(qdma, QDMA_INT_REG_IDX0, INT_IDX0_MASK); ++ airoha_qdma_irq_enable(qdma, QDMA_INT_REG_IDX1, INT_IDX1_MASK); ++ airoha_qdma_irq_enable(qdma, QDMA_INT_REG_IDX4, INT_IDX4_MASK); ++ ++ /* setup irq binding */ ++ for (i = 0; i < ARRAY_SIZE(qdma->q_tx); i++) { ++ if (!qdma->q_tx[i].ndesc) ++ continue; ++ ++ if (TX_RING_IRQ_BLOCKING_MAP_MASK & BIT(i)) ++ airoha_qdma_set(qdma, REG_TX_RING_BLOCKING(i), ++ TX_RING_IRQ_BLOCKING_CFG_MASK); ++ else ++ airoha_qdma_clear(qdma, REG_TX_RING_BLOCKING(i), ++ TX_RING_IRQ_BLOCKING_CFG_MASK); ++ } ++ ++ airoha_qdma_wr(qdma, REG_QDMA_GLOBAL_CFG, ++ GLOBAL_CFG_RX_2B_OFFSET_MASK | ++ FIELD_PREP(GLOBAL_CFG_DMA_PREFERENCE_MASK, 3) | ++ GLOBAL_CFG_CPU_TXR_RR_MASK | ++ GLOBAL_CFG_PAYLOAD_BYTE_SWAP_MASK | ++ GLOBAL_CFG_MULTICAST_MODIFY_FP_MASK | ++ GLOBAL_CFG_MULTICAST_EN_MASK | ++ GLOBAL_CFG_IRQ0_EN_MASK | GLOBAL_CFG_IRQ1_EN_MASK | ++ GLOBAL_CFG_TX_WB_DONE_MASK | ++ FIELD_PREP(GLOBAL_CFG_MAX_ISSUE_NUM_MASK, 2)); ++ ++ airoha_qdma_init_qos(qdma); ++ ++ /* disable qdma rx delay interrupt */ ++ for (i = 0; i < ARRAY_SIZE(qdma->q_rx); i++) { ++ if (!qdma->q_rx[i].ndesc) ++ continue; ++ ++ airoha_qdma_clear(qdma, REG_RX_DELAY_INT_IDX(i), ++ RX_DELAY_INT_MASK); ++ } ++ ++ airoha_qdma_set(qdma, REG_TXQ_CNGST_CFG, ++ TXQ_CNGST_DROP_EN | TXQ_CNGST_DEI_DROP_EN); ++ airoha_qdma_init_qos_stats(qdma); ++ ++ return 0; ++} ++ ++static irqreturn_t airoha_irq_handler(int irq, void *dev_instance) ++{ ++ struct airoha_qdma *qdma = dev_instance; ++ u32 intr[ARRAY_SIZE(qdma->irqmask)]; ++ int i; ++ ++ for (i = 0; i < ARRAY_SIZE(qdma->irqmask); i++) { ++ intr[i] = airoha_qdma_rr(qdma, REG_INT_STATUS(i)); ++ intr[i] &= qdma->irqmask[i]; ++ airoha_qdma_wr(qdma, REG_INT_STATUS(i), intr[i]); ++ } ++ ++ if (!test_bit(DEV_STATE_INITIALIZED, &qdma->eth->state)) ++ return IRQ_NONE; ++ ++ if (intr[1] & RX_DONE_INT_MASK) { ++ airoha_qdma_irq_disable(qdma, QDMA_INT_REG_IDX1, ++ RX_DONE_INT_MASK); ++ ++ for (i = 0; i < ARRAY_SIZE(qdma->q_rx); i++) { ++ if (!qdma->q_rx[i].ndesc) ++ continue; ++ ++ if (intr[1] & BIT(i)) ++ napi_schedule(&qdma->q_rx[i].napi); ++ } ++ } ++ ++ if (intr[0] & INT_TX_MASK) { ++ for (i = 0; i < ARRAY_SIZE(qdma->q_tx_irq); i++) { ++ if (!(intr[0] & TX_DONE_INT_MASK(i))) ++ continue; ++ ++ airoha_qdma_irq_disable(qdma, QDMA_INT_REG_IDX0, ++ TX_DONE_INT_MASK(i)); ++ napi_schedule(&qdma->q_tx_irq[i].napi); ++ } ++ } ++ ++ return IRQ_HANDLED; ++} ++ ++static int airoha_qdma_init(struct platform_device *pdev, ++ struct airoha_eth *eth, ++ struct airoha_qdma *qdma) ++{ ++ int err, id = qdma - ð->qdma[0]; ++ const char *res; ++ ++ spin_lock_init(&qdma->irq_lock); ++ qdma->eth = eth; ++ ++ res = devm_kasprintf(eth->dev, GFP_KERNEL, "qdma%d", id); ++ if (!res) ++ return -ENOMEM; ++ ++ qdma->regs = devm_platform_ioremap_resource_byname(pdev, res); ++ if (IS_ERR(qdma->regs)) ++ return dev_err_probe(eth->dev, PTR_ERR(qdma->regs), ++ "failed to iomap qdma%d regs\n", id); ++ ++ qdma->irq = platform_get_irq(pdev, 4 * id); ++ if (qdma->irq < 0) ++ return qdma->irq; ++ ++ err = devm_request_irq(eth->dev, qdma->irq, airoha_irq_handler, ++ IRQF_SHARED, KBUILD_MODNAME, qdma); ++ if (err) ++ return err; ++ ++ err = airoha_qdma_init_rx(qdma); ++ if (err) ++ return err; ++ ++ err = airoha_qdma_init_tx(qdma); ++ if (err) ++ return err; ++ ++ err = airoha_qdma_init_hfwd_queues(qdma); ++ if (err) ++ return err; ++ ++ return airoha_qdma_hw_init(qdma); ++} ++ ++static int airoha_hw_init(struct platform_device *pdev, ++ struct airoha_eth *eth) ++{ ++ int err, i; ++ ++ /* disable xsi */ ++ err = reset_control_bulk_assert(ARRAY_SIZE(eth->xsi_rsts), ++ eth->xsi_rsts); ++ if (err) ++ return err; ++ ++ err = reset_control_bulk_assert(ARRAY_SIZE(eth->rsts), eth->rsts); ++ if (err) ++ return err; ++ ++ msleep(20); ++ err = reset_control_bulk_deassert(ARRAY_SIZE(eth->rsts), eth->rsts); ++ if (err) ++ return err; ++ ++ msleep(20); ++ err = airoha_fe_init(eth); ++ if (err) ++ return err; ++ ++ for (i = 0; i < ARRAY_SIZE(eth->qdma); i++) { ++ err = airoha_qdma_init(pdev, eth, ð->qdma[i]); ++ if (err) ++ return err; ++ } ++ ++ set_bit(DEV_STATE_INITIALIZED, ð->state); ++ ++ return 0; ++} ++ ++static void airoha_hw_cleanup(struct airoha_qdma *qdma) ++{ ++ int i; ++ ++ for (i = 0; i < ARRAY_SIZE(qdma->q_rx); i++) { ++ if (!qdma->q_rx[i].ndesc) ++ continue; ++ ++ netif_napi_del(&qdma->q_rx[i].napi); ++ airoha_qdma_cleanup_rx_queue(&qdma->q_rx[i]); ++ if (qdma->q_rx[i].page_pool) ++ page_pool_destroy(qdma->q_rx[i].page_pool); ++ } ++ ++ for (i = 0; i < ARRAY_SIZE(qdma->q_tx_irq); i++) ++ netif_napi_del(&qdma->q_tx_irq[i].napi); ++ ++ for (i = 0; i < ARRAY_SIZE(qdma->q_tx); i++) { ++ if (!qdma->q_tx[i].ndesc) ++ continue; ++ ++ airoha_qdma_cleanup_tx_queue(&qdma->q_tx[i]); ++ } ++} ++ ++static void airoha_qdma_start_napi(struct airoha_qdma *qdma) ++{ ++ int i; ++ ++ for (i = 0; i < ARRAY_SIZE(qdma->q_tx_irq); i++) ++ napi_enable(&qdma->q_tx_irq[i].napi); ++ ++ for (i = 0; i < ARRAY_SIZE(qdma->q_rx); i++) { ++ if (!qdma->q_rx[i].ndesc) ++ continue; ++ ++ napi_enable(&qdma->q_rx[i].napi); ++ } ++} ++ ++static void airoha_qdma_stop_napi(struct airoha_qdma *qdma) ++{ ++ int i; ++ ++ for (i = 0; i < ARRAY_SIZE(qdma->q_tx_irq); i++) ++ napi_disable(&qdma->q_tx_irq[i].napi); ++ ++ for (i = 0; i < ARRAY_SIZE(qdma->q_rx); i++) { ++ if (!qdma->q_rx[i].ndesc) ++ continue; ++ ++ napi_disable(&qdma->q_rx[i].napi); ++ } ++} ++ ++static void airoha_update_hw_stats(struct airoha_gdm_port *port) ++{ ++ struct airoha_eth *eth = port->qdma->eth; ++ u32 val, i = 0; ++ ++ spin_lock(&port->stats.lock); ++ u64_stats_update_begin(&port->stats.syncp); ++ ++ /* TX */ ++ val = airoha_fe_rr(eth, REG_FE_GDM_TX_OK_PKT_CNT_H(port->id)); ++ port->stats.tx_ok_pkts += ((u64)val << 32); ++ val = airoha_fe_rr(eth, REG_FE_GDM_TX_OK_PKT_CNT_L(port->id)); ++ port->stats.tx_ok_pkts += val; ++ ++ val = airoha_fe_rr(eth, REG_FE_GDM_TX_OK_BYTE_CNT_H(port->id)); ++ port->stats.tx_ok_bytes += ((u64)val << 32); ++ val = airoha_fe_rr(eth, REG_FE_GDM_TX_OK_BYTE_CNT_L(port->id)); ++ port->stats.tx_ok_bytes += val; ++ ++ val = airoha_fe_rr(eth, REG_FE_GDM_TX_ETH_DROP_CNT(port->id)); ++ port->stats.tx_drops += val; ++ ++ val = airoha_fe_rr(eth, REG_FE_GDM_TX_ETH_BC_CNT(port->id)); ++ port->stats.tx_broadcast += val; ++ ++ val = airoha_fe_rr(eth, REG_FE_GDM_TX_ETH_MC_CNT(port->id)); ++ port->stats.tx_multicast += val; ++ ++ val = airoha_fe_rr(eth, REG_FE_GDM_TX_ETH_RUNT_CNT(port->id)); ++ port->stats.tx_len[i] += val; ++ ++ val = airoha_fe_rr(eth, REG_FE_GDM_TX_ETH_E64_CNT_H(port->id)); ++ port->stats.tx_len[i] += ((u64)val << 32); ++ val = airoha_fe_rr(eth, REG_FE_GDM_TX_ETH_E64_CNT_L(port->id)); ++ port->stats.tx_len[i++] += val; ++ ++ val = airoha_fe_rr(eth, REG_FE_GDM_TX_ETH_L64_CNT_H(port->id)); ++ port->stats.tx_len[i] += ((u64)val << 32); ++ val = airoha_fe_rr(eth, REG_FE_GDM_TX_ETH_L64_CNT_L(port->id)); ++ port->stats.tx_len[i++] += val; ++ ++ val = airoha_fe_rr(eth, REG_FE_GDM_TX_ETH_L127_CNT_H(port->id)); ++ port->stats.tx_len[i] += ((u64)val << 32); ++ val = airoha_fe_rr(eth, REG_FE_GDM_TX_ETH_L127_CNT_L(port->id)); ++ port->stats.tx_len[i++] += val; ++ ++ val = airoha_fe_rr(eth, REG_FE_GDM_TX_ETH_L255_CNT_H(port->id)); ++ port->stats.tx_len[i] += ((u64)val << 32); ++ val = airoha_fe_rr(eth, REG_FE_GDM_TX_ETH_L255_CNT_L(port->id)); ++ port->stats.tx_len[i++] += val; ++ ++ val = airoha_fe_rr(eth, REG_FE_GDM_TX_ETH_L511_CNT_H(port->id)); ++ port->stats.tx_len[i] += ((u64)val << 32); ++ val = airoha_fe_rr(eth, REG_FE_GDM_TX_ETH_L511_CNT_L(port->id)); ++ port->stats.tx_len[i++] += val; ++ ++ val = airoha_fe_rr(eth, REG_FE_GDM_TX_ETH_L1023_CNT_H(port->id)); ++ port->stats.tx_len[i] += ((u64)val << 32); ++ val = airoha_fe_rr(eth, REG_FE_GDM_TX_ETH_L1023_CNT_L(port->id)); ++ port->stats.tx_len[i++] += val; ++ ++ val = airoha_fe_rr(eth, REG_FE_GDM_TX_ETH_LONG_CNT(port->id)); ++ port->stats.tx_len[i++] += val; ++ ++ /* RX */ ++ val = airoha_fe_rr(eth, REG_FE_GDM_RX_OK_PKT_CNT_H(port->id)); ++ port->stats.rx_ok_pkts += ((u64)val << 32); ++ val = airoha_fe_rr(eth, REG_FE_GDM_RX_OK_PKT_CNT_L(port->id)); ++ port->stats.rx_ok_pkts += val; ++ ++ val = airoha_fe_rr(eth, REG_FE_GDM_RX_OK_BYTE_CNT_H(port->id)); ++ port->stats.rx_ok_bytes += ((u64)val << 32); ++ val = airoha_fe_rr(eth, REG_FE_GDM_RX_OK_BYTE_CNT_L(port->id)); ++ port->stats.rx_ok_bytes += val; ++ ++ val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_DROP_CNT(port->id)); ++ port->stats.rx_drops += val; ++ ++ val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_BC_CNT(port->id)); ++ port->stats.rx_broadcast += val; ++ ++ val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_MC_CNT(port->id)); ++ port->stats.rx_multicast += val; ++ ++ val = airoha_fe_rr(eth, REG_FE_GDM_RX_ERROR_DROP_CNT(port->id)); ++ port->stats.rx_errors += val; ++ ++ val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_CRC_ERR_CNT(port->id)); ++ port->stats.rx_crc_error += val; ++ ++ val = airoha_fe_rr(eth, REG_FE_GDM_RX_OVERFLOW_DROP_CNT(port->id)); ++ port->stats.rx_over_errors += val; ++ ++ val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_FRAG_CNT(port->id)); ++ port->stats.rx_fragment += val; ++ ++ val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_JABBER_CNT(port->id)); ++ port->stats.rx_jabber += val; ++ ++ i = 0; ++ val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_RUNT_CNT(port->id)); ++ port->stats.rx_len[i] += val; ++ ++ val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_E64_CNT_H(port->id)); ++ port->stats.rx_len[i] += ((u64)val << 32); ++ val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_E64_CNT_L(port->id)); ++ port->stats.rx_len[i++] += val; ++ ++ val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_L64_CNT_H(port->id)); ++ port->stats.rx_len[i] += ((u64)val << 32); ++ val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_L64_CNT_L(port->id)); ++ port->stats.rx_len[i++] += val; ++ ++ val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_L127_CNT_H(port->id)); ++ port->stats.rx_len[i] += ((u64)val << 32); ++ val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_L127_CNT_L(port->id)); ++ port->stats.rx_len[i++] += val; ++ ++ val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_L255_CNT_H(port->id)); ++ port->stats.rx_len[i] += ((u64)val << 32); ++ val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_L255_CNT_L(port->id)); ++ port->stats.rx_len[i++] += val; ++ ++ val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_L511_CNT_H(port->id)); ++ port->stats.rx_len[i] += ((u64)val << 32); ++ val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_L511_CNT_L(port->id)); ++ port->stats.rx_len[i++] += val; ++ ++ val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_L1023_CNT_H(port->id)); ++ port->stats.rx_len[i] += ((u64)val << 32); ++ val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_L1023_CNT_L(port->id)); ++ port->stats.rx_len[i++] += val; ++ ++ val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_LONG_CNT(port->id)); ++ port->stats.rx_len[i++] += val; ++ ++ /* reset mib counters */ ++ airoha_fe_set(eth, REG_FE_GDM_MIB_CLEAR(port->id), ++ FE_GDM_MIB_RX_CLEAR_MASK | FE_GDM_MIB_TX_CLEAR_MASK); ++ ++ u64_stats_update_end(&port->stats.syncp); ++ spin_unlock(&port->stats.lock); ++} ++ ++static int airoha_dev_open(struct net_device *dev) ++{ ++ struct airoha_gdm_port *port = netdev_priv(dev); ++ struct airoha_qdma *qdma = port->qdma; ++ int err; ++ ++ netif_tx_start_all_queues(dev); ++ err = airoha_set_gdm_ports(qdma->eth, true); ++ if (err) ++ return err; ++ ++ if (netdev_uses_dsa(dev)) ++ airoha_fe_set(qdma->eth, REG_GDM_INGRESS_CFG(port->id), ++ GDM_STAG_EN_MASK); ++ else ++ airoha_fe_clear(qdma->eth, REG_GDM_INGRESS_CFG(port->id), ++ GDM_STAG_EN_MASK); ++ ++ airoha_qdma_set(qdma, REG_QDMA_GLOBAL_CFG, ++ GLOBAL_CFG_TX_DMA_EN_MASK | ++ GLOBAL_CFG_RX_DMA_EN_MASK); ++ ++ return 0; ++} ++ ++static int airoha_dev_stop(struct net_device *dev) ++{ ++ struct airoha_gdm_port *port = netdev_priv(dev); ++ struct airoha_qdma *qdma = port->qdma; ++ int i, err; ++ ++ netif_tx_disable(dev); ++ err = airoha_set_gdm_ports(qdma->eth, false); ++ if (err) ++ return err; ++ ++ airoha_qdma_clear(qdma, REG_QDMA_GLOBAL_CFG, ++ GLOBAL_CFG_TX_DMA_EN_MASK | ++ GLOBAL_CFG_RX_DMA_EN_MASK); ++ ++ for (i = 0; i < ARRAY_SIZE(qdma->q_tx); i++) { ++ if (!qdma->q_tx[i].ndesc) ++ continue; ++ ++ airoha_qdma_cleanup_tx_queue(&qdma->q_tx[i]); ++ netdev_tx_reset_subqueue(dev, i); ++ } ++ ++ return 0; ++} ++ ++static int airoha_dev_set_macaddr(struct net_device *dev, void *p) ++{ ++ struct airoha_gdm_port *port = netdev_priv(dev); ++ int err; ++ ++ err = eth_mac_addr(dev, p); ++ if (err) ++ return err; ++ ++ airoha_set_macaddr(port, dev->dev_addr); ++ ++ return 0; ++} ++ ++static int airoha_dev_init(struct net_device *dev) ++{ ++ struct airoha_gdm_port *port = netdev_priv(dev); ++ ++ airoha_set_macaddr(port, dev->dev_addr); ++ ++ return 0; ++} ++ ++static void airoha_dev_get_stats64(struct net_device *dev, ++ struct rtnl_link_stats64 *storage) ++{ ++ struct airoha_gdm_port *port = netdev_priv(dev); ++ unsigned int start; ++ ++ airoha_update_hw_stats(port); ++ do { ++ start = u64_stats_fetch_begin(&port->stats.syncp); ++ storage->rx_packets = port->stats.rx_ok_pkts; ++ storage->tx_packets = port->stats.tx_ok_pkts; ++ storage->rx_bytes = port->stats.rx_ok_bytes; ++ storage->tx_bytes = port->stats.tx_ok_bytes; ++ storage->multicast = port->stats.rx_multicast; ++ storage->rx_errors = port->stats.rx_errors; ++ storage->rx_dropped = port->stats.rx_drops; ++ storage->tx_dropped = port->stats.tx_drops; ++ storage->rx_crc_errors = port->stats.rx_crc_error; ++ storage->rx_over_errors = port->stats.rx_over_errors; ++ } while (u64_stats_fetch_retry(&port->stats.syncp, start)); ++} ++ ++static u16 airoha_dev_select_queue(struct net_device *dev, struct sk_buff *skb, ++ struct net_device *sb_dev) ++{ ++ struct airoha_gdm_port *port = netdev_priv(dev); ++ int queue, channel; ++ ++ /* For dsa device select QoS channel according to the dsa user port ++ * index, rely on port id otherwise. Select QoS queue based on the ++ * skb priority. ++ */ ++ channel = netdev_uses_dsa(dev) ? skb_get_queue_mapping(skb) : port->id; ++ channel = channel % AIROHA_NUM_QOS_CHANNELS; ++ queue = (skb->priority - 1) % AIROHA_NUM_QOS_QUEUES; /* QoS queue */ ++ queue = channel * AIROHA_NUM_QOS_QUEUES + queue; ++ ++ return queue < dev->num_tx_queues ? queue : 0; ++} ++ ++static netdev_tx_t airoha_dev_xmit(struct sk_buff *skb, ++ struct net_device *dev) ++{ ++ struct airoha_gdm_port *port = netdev_priv(dev); ++ u32 nr_frags = 1 + skb_shinfo(skb)->nr_frags; ++ u32 msg0, msg1, len = skb_headlen(skb); ++ struct airoha_qdma *qdma = port->qdma; ++ struct netdev_queue *txq; ++ struct airoha_queue *q; ++ void *data = skb->data; ++ int i, qid; ++ u16 index; ++ u8 fport; ++ ++ qid = skb_get_queue_mapping(skb) % ARRAY_SIZE(qdma->q_tx); ++ msg0 = FIELD_PREP(QDMA_ETH_TXMSG_CHAN_MASK, ++ qid / AIROHA_NUM_QOS_QUEUES) | ++ FIELD_PREP(QDMA_ETH_TXMSG_QUEUE_MASK, ++ qid % AIROHA_NUM_QOS_QUEUES); ++ if (skb->ip_summed == CHECKSUM_PARTIAL) ++ msg0 |= FIELD_PREP(QDMA_ETH_TXMSG_TCO_MASK, 1) | ++ FIELD_PREP(QDMA_ETH_TXMSG_UCO_MASK, 1) | ++ FIELD_PREP(QDMA_ETH_TXMSG_ICO_MASK, 1); ++ ++ /* TSO: fill MSS info in tcp checksum field */ ++ if (skb_is_gso(skb)) { ++ if (skb_cow_head(skb, 0)) ++ goto error; ++ ++ if (skb_shinfo(skb)->gso_type & (SKB_GSO_TCPV4 | ++ SKB_GSO_TCPV6)) { ++ __be16 csum = cpu_to_be16(skb_shinfo(skb)->gso_size); ++ ++ tcp_hdr(skb)->check = (__force __sum16)csum; ++ msg0 |= FIELD_PREP(QDMA_ETH_TXMSG_TSO_MASK, 1); ++ } ++ } ++ ++ fport = port->id == 4 ? FE_PSE_PORT_GDM4 : port->id; ++ msg1 = FIELD_PREP(QDMA_ETH_TXMSG_FPORT_MASK, fport) | ++ FIELD_PREP(QDMA_ETH_TXMSG_METER_MASK, 0x7f); ++ ++ q = &qdma->q_tx[qid]; ++ if (WARN_ON_ONCE(!q->ndesc)) ++ goto error; ++ ++ spin_lock_bh(&q->lock); ++ ++ txq = netdev_get_tx_queue(dev, qid); ++ if (q->queued + nr_frags > q->ndesc) { ++ /* not enough space in the queue */ ++ netif_tx_stop_queue(txq); ++ spin_unlock_bh(&q->lock); ++ return NETDEV_TX_BUSY; ++ } ++ ++ index = q->head; ++ for (i = 0; i < nr_frags; i++) { ++ struct airoha_qdma_desc *desc = &q->desc[index]; ++ struct airoha_queue_entry *e = &q->entry[index]; ++ skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; ++ dma_addr_t addr; ++ u32 val; ++ ++ addr = dma_map_single(dev->dev.parent, data, len, ++ DMA_TO_DEVICE); ++ if (unlikely(dma_mapping_error(dev->dev.parent, addr))) ++ goto error_unmap; ++ ++ index = (index + 1) % q->ndesc; ++ ++ val = FIELD_PREP(QDMA_DESC_LEN_MASK, len); ++ if (i < nr_frags - 1) ++ val |= FIELD_PREP(QDMA_DESC_MORE_MASK, 1); ++ WRITE_ONCE(desc->ctrl, cpu_to_le32(val)); ++ WRITE_ONCE(desc->addr, cpu_to_le32(addr)); ++ val = FIELD_PREP(QDMA_DESC_NEXT_ID_MASK, index); ++ WRITE_ONCE(desc->data, cpu_to_le32(val)); ++ WRITE_ONCE(desc->msg0, cpu_to_le32(msg0)); ++ WRITE_ONCE(desc->msg1, cpu_to_le32(msg1)); ++ WRITE_ONCE(desc->msg2, cpu_to_le32(0xffff)); ++ ++ e->skb = i ? NULL : skb; ++ e->dma_addr = addr; ++ e->dma_len = len; ++ ++ data = skb_frag_address(frag); ++ len = skb_frag_size(frag); ++ } ++ ++ q->head = index; ++ q->queued += i; ++ ++ skb_tx_timestamp(skb); ++ netdev_tx_sent_queue(txq, skb->len); ++ ++ if (netif_xmit_stopped(txq) || !netdev_xmit_more()) ++ airoha_qdma_rmw(qdma, REG_TX_CPU_IDX(qid), ++ TX_RING_CPU_IDX_MASK, ++ FIELD_PREP(TX_RING_CPU_IDX_MASK, q->head)); ++ ++ if (q->ndesc - q->queued < q->free_thr) ++ netif_tx_stop_queue(txq); ++ ++ spin_unlock_bh(&q->lock); ++ ++ return NETDEV_TX_OK; ++ ++error_unmap: ++ for (i--; i >= 0; i--) { ++ index = (q->head + i) % q->ndesc; ++ dma_unmap_single(dev->dev.parent, q->entry[index].dma_addr, ++ q->entry[index].dma_len, DMA_TO_DEVICE); ++ } ++ ++ spin_unlock_bh(&q->lock); ++error: ++ dev_kfree_skb_any(skb); ++ dev->stats.tx_dropped++; ++ ++ return NETDEV_TX_OK; ++} ++ ++static void airoha_ethtool_get_drvinfo(struct net_device *dev, ++ struct ethtool_drvinfo *info) ++{ ++ struct airoha_gdm_port *port = netdev_priv(dev); ++ struct airoha_eth *eth = port->qdma->eth; ++ ++ strscpy(info->driver, eth->dev->driver->name, sizeof(info->driver)); ++ strscpy(info->bus_info, dev_name(eth->dev), sizeof(info->bus_info)); ++} ++ ++static void airoha_ethtool_get_mac_stats(struct net_device *dev, ++ struct ethtool_eth_mac_stats *stats) ++{ ++ struct airoha_gdm_port *port = netdev_priv(dev); ++ unsigned int start; ++ ++ airoha_update_hw_stats(port); ++ do { ++ start = u64_stats_fetch_begin(&port->stats.syncp); ++ stats->MulticastFramesXmittedOK = port->stats.tx_multicast; ++ stats->BroadcastFramesXmittedOK = port->stats.tx_broadcast; ++ stats->BroadcastFramesReceivedOK = port->stats.rx_broadcast; ++ } while (u64_stats_fetch_retry(&port->stats.syncp, start)); ++} ++ ++static const struct ethtool_rmon_hist_range airoha_ethtool_rmon_ranges[] = { ++ { 0, 64 }, ++ { 65, 127 }, ++ { 128, 255 }, ++ { 256, 511 }, ++ { 512, 1023 }, ++ { 1024, 1518 }, ++ { 1519, 10239 }, ++ {}, ++}; ++ ++static void ++airoha_ethtool_get_rmon_stats(struct net_device *dev, ++ struct ethtool_rmon_stats *stats, ++ const struct ethtool_rmon_hist_range **ranges) ++{ ++ struct airoha_gdm_port *port = netdev_priv(dev); ++ struct airoha_hw_stats *hw_stats = &port->stats; ++ unsigned int start; ++ ++ BUILD_BUG_ON(ARRAY_SIZE(airoha_ethtool_rmon_ranges) != ++ ARRAY_SIZE(hw_stats->tx_len) + 1); ++ BUILD_BUG_ON(ARRAY_SIZE(airoha_ethtool_rmon_ranges) != ++ ARRAY_SIZE(hw_stats->rx_len) + 1); ++ ++ *ranges = airoha_ethtool_rmon_ranges; ++ airoha_update_hw_stats(port); ++ do { ++ int i; ++ ++ start = u64_stats_fetch_begin(&port->stats.syncp); ++ stats->fragments = hw_stats->rx_fragment; ++ stats->jabbers = hw_stats->rx_jabber; ++ for (i = 0; i < ARRAY_SIZE(airoha_ethtool_rmon_ranges) - 1; ++ i++) { ++ stats->hist[i] = hw_stats->rx_len[i]; ++ stats->hist_tx[i] = hw_stats->tx_len[i]; ++ } ++ } while (u64_stats_fetch_retry(&port->stats.syncp, start)); ++} ++ ++static int airoha_qdma_set_chan_tx_sched(struct airoha_gdm_port *port, ++ int channel, enum tx_sched_mode mode, ++ const u16 *weights, u8 n_weights) ++{ ++ int i; ++ ++ for (i = 0; i < AIROHA_NUM_TX_RING; i++) ++ airoha_qdma_clear(port->qdma, REG_QUEUE_CLOSE_CFG(channel), ++ TXQ_DISABLE_CHAN_QUEUE_MASK(channel, i)); ++ ++ for (i = 0; i < n_weights; i++) { ++ u32 status; ++ int err; ++ ++ airoha_qdma_wr(port->qdma, REG_TXWRR_WEIGHT_CFG, ++ TWRR_RW_CMD_MASK | ++ FIELD_PREP(TWRR_CHAN_IDX_MASK, channel) | ++ FIELD_PREP(TWRR_QUEUE_IDX_MASK, i) | ++ FIELD_PREP(TWRR_VALUE_MASK, weights[i])); ++ err = read_poll_timeout(airoha_qdma_rr, status, ++ status & TWRR_RW_CMD_DONE, ++ USEC_PER_MSEC, 10 * USEC_PER_MSEC, ++ true, port->qdma, ++ REG_TXWRR_WEIGHT_CFG); ++ if (err) ++ return err; ++ } ++ ++ airoha_qdma_rmw(port->qdma, REG_CHAN_QOS_MODE(channel >> 3), ++ CHAN_QOS_MODE_MASK(channel), ++ mode << __ffs(CHAN_QOS_MODE_MASK(channel))); ++ ++ return 0; ++} ++ ++static int airoha_qdma_set_tx_prio_sched(struct airoha_gdm_port *port, ++ int channel) ++{ ++ static const u16 w[AIROHA_NUM_QOS_QUEUES] = {}; ++ ++ return airoha_qdma_set_chan_tx_sched(port, channel, TC_SCH_SP, w, ++ ARRAY_SIZE(w)); ++} ++ ++static int airoha_qdma_set_tx_ets_sched(struct airoha_gdm_port *port, ++ int channel, ++ struct tc_ets_qopt_offload *opt) ++{ ++ struct tc_ets_qopt_offload_replace_params *p = &opt->replace_params; ++ enum tx_sched_mode mode = TC_SCH_SP; ++ u16 w[AIROHA_NUM_QOS_QUEUES] = {}; ++ int i, nstrict = 0, nwrr, qidx; ++ ++ if (p->bands > AIROHA_NUM_QOS_QUEUES) ++ return -EINVAL; ++ ++ for (i = 0; i < p->bands; i++) { ++ if (!p->quanta[i]) ++ nstrict++; ++ } ++ ++ /* this configuration is not supported by the hw */ ++ if (nstrict == AIROHA_NUM_QOS_QUEUES - 1) ++ return -EINVAL; ++ ++ /* EN7581 SoC supports fixed QoS band priority where WRR queues have ++ * lowest priorities with respect to SP ones. ++ * e.g: WRR0, WRR1, .., WRRm, SP0, SP1, .., SPn ++ */ ++ nwrr = p->bands - nstrict; ++ qidx = nstrict && nwrr ? nstrict : 0; ++ for (i = 1; i <= p->bands; i++) { ++ if (p->priomap[i % AIROHA_NUM_QOS_QUEUES] != qidx) ++ return -EINVAL; ++ ++ qidx = i == nwrr ? 0 : qidx + 1; ++ } ++ ++ for (i = 0; i < nwrr; i++) ++ w[i] = p->weights[nstrict + i]; ++ ++ if (!nstrict) ++ mode = TC_SCH_WRR8; ++ else if (nstrict < AIROHA_NUM_QOS_QUEUES - 1) ++ mode = nstrict + 1; ++ ++ return airoha_qdma_set_chan_tx_sched(port, channel, mode, w, ++ ARRAY_SIZE(w)); ++} ++ ++static int airoha_qdma_get_tx_ets_stats(struct airoha_gdm_port *port, ++ int channel, ++ struct tc_ets_qopt_offload *opt) ++{ ++ u64 cpu_tx_packets = airoha_qdma_rr(port->qdma, ++ REG_CNTR_VAL(channel << 1)); ++ u64 fwd_tx_packets = airoha_qdma_rr(port->qdma, ++ REG_CNTR_VAL((channel << 1) + 1)); ++ u64 tx_packets = (cpu_tx_packets - port->cpu_tx_packets) + ++ (fwd_tx_packets - port->fwd_tx_packets); ++ _bstats_update(opt->stats.bstats, 0, tx_packets); ++ ++ port->cpu_tx_packets = cpu_tx_packets; ++ port->fwd_tx_packets = fwd_tx_packets; ++ ++ return 0; ++} ++ ++static int airoha_tc_setup_qdisc_ets(struct airoha_gdm_port *port, ++ struct tc_ets_qopt_offload *opt) ++{ ++ int channel = TC_H_MAJ(opt->handle) >> 16; ++ ++ if (opt->parent == TC_H_ROOT) ++ return -EINVAL; ++ ++ switch (opt->command) { ++ case TC_ETS_REPLACE: ++ return airoha_qdma_set_tx_ets_sched(port, channel, opt); ++ case TC_ETS_DESTROY: ++ /* PRIO is default qdisc scheduler */ ++ return airoha_qdma_set_tx_prio_sched(port, channel); ++ case TC_ETS_STATS: ++ return airoha_qdma_get_tx_ets_stats(port, channel, opt); ++ default: ++ return -EOPNOTSUPP; ++ } ++} ++ ++static int airoha_qdma_get_trtcm_param(struct airoha_qdma *qdma, int channel, ++ u32 addr, enum trtcm_param_type param, ++ enum trtcm_mode_type mode, ++ u32 *val_low, u32 *val_high) ++{ ++ u32 idx = QDMA_METER_IDX(channel), group = QDMA_METER_GROUP(channel); ++ u32 val, config = FIELD_PREP(TRTCM_PARAM_TYPE_MASK, param) | ++ FIELD_PREP(TRTCM_METER_GROUP_MASK, group) | ++ FIELD_PREP(TRTCM_PARAM_INDEX_MASK, idx) | ++ FIELD_PREP(TRTCM_PARAM_RATE_TYPE_MASK, mode); ++ ++ airoha_qdma_wr(qdma, REG_TRTCM_CFG_PARAM(addr), config); ++ if (read_poll_timeout(airoha_qdma_rr, val, ++ val & TRTCM_PARAM_RW_DONE_MASK, ++ USEC_PER_MSEC, 10 * USEC_PER_MSEC, true, ++ qdma, REG_TRTCM_CFG_PARAM(addr))) ++ return -ETIMEDOUT; ++ ++ *val_low = airoha_qdma_rr(qdma, REG_TRTCM_DATA_LOW(addr)); ++ if (val_high) ++ *val_high = airoha_qdma_rr(qdma, REG_TRTCM_DATA_HIGH(addr)); ++ ++ return 0; ++} ++ ++static int airoha_qdma_set_trtcm_param(struct airoha_qdma *qdma, int channel, ++ u32 addr, enum trtcm_param_type param, ++ enum trtcm_mode_type mode, u32 val) ++{ ++ u32 idx = QDMA_METER_IDX(channel), group = QDMA_METER_GROUP(channel); ++ u32 config = TRTCM_PARAM_RW_MASK | ++ FIELD_PREP(TRTCM_PARAM_TYPE_MASK, param) | ++ FIELD_PREP(TRTCM_METER_GROUP_MASK, group) | ++ FIELD_PREP(TRTCM_PARAM_INDEX_MASK, idx) | ++ FIELD_PREP(TRTCM_PARAM_RATE_TYPE_MASK, mode); ++ ++ airoha_qdma_wr(qdma, REG_TRTCM_DATA_LOW(addr), val); ++ airoha_qdma_wr(qdma, REG_TRTCM_CFG_PARAM(addr), config); ++ ++ return read_poll_timeout(airoha_qdma_rr, val, ++ val & TRTCM_PARAM_RW_DONE_MASK, ++ USEC_PER_MSEC, 10 * USEC_PER_MSEC, true, ++ qdma, REG_TRTCM_CFG_PARAM(addr)); ++} ++ ++static int airoha_qdma_set_trtcm_config(struct airoha_qdma *qdma, int channel, ++ u32 addr, enum trtcm_mode_type mode, ++ bool enable, u32 enable_mask) ++{ ++ u32 val; ++ ++ if (airoha_qdma_get_trtcm_param(qdma, channel, addr, TRTCM_MISC_MODE, ++ mode, &val, NULL)) ++ return -EINVAL; ++ ++ val = enable ? val | enable_mask : val & ~enable_mask; ++ ++ return airoha_qdma_set_trtcm_param(qdma, channel, addr, TRTCM_MISC_MODE, ++ mode, val); ++} ++ ++static int airoha_qdma_set_trtcm_token_bucket(struct airoha_qdma *qdma, ++ int channel, u32 addr, ++ enum trtcm_mode_type mode, ++ u32 rate_val, u32 bucket_size) ++{ ++ u32 val, config, tick, unit, rate, rate_frac; ++ int err; ++ ++ if (airoha_qdma_get_trtcm_param(qdma, channel, addr, TRTCM_MISC_MODE, ++ mode, &config, NULL)) ++ return -EINVAL; ++ ++ val = airoha_qdma_rr(qdma, addr); ++ tick = FIELD_GET(INGRESS_FAST_TICK_MASK, val); ++ if (config & TRTCM_TICK_SEL) ++ tick *= FIELD_GET(INGRESS_SLOW_TICK_RATIO_MASK, val); ++ if (!tick) ++ return -EINVAL; ++ ++ unit = (config & TRTCM_PKT_MODE) ? 1000000 / tick : 8000 / tick; ++ if (!unit) ++ return -EINVAL; ++ ++ rate = rate_val / unit; ++ rate_frac = rate_val % unit; ++ rate_frac = FIELD_PREP(TRTCM_TOKEN_RATE_MASK, rate_frac) / unit; ++ rate = FIELD_PREP(TRTCM_TOKEN_RATE_MASK, rate) | ++ FIELD_PREP(TRTCM_TOKEN_RATE_FRACTION_MASK, rate_frac); ++ ++ err = airoha_qdma_set_trtcm_param(qdma, channel, addr, ++ TRTCM_TOKEN_RATE_MODE, mode, rate); ++ if (err) ++ return err; ++ ++ val = max_t(u32, bucket_size, MIN_TOKEN_SIZE); ++ val = min_t(u32, __fls(val), MAX_TOKEN_SIZE_OFFSET); ++ ++ return airoha_qdma_set_trtcm_param(qdma, channel, addr, ++ TRTCM_BUCKETSIZE_SHIFT_MODE, ++ mode, val); ++} ++ ++static int airoha_qdma_set_tx_rate_limit(struct airoha_gdm_port *port, ++ int channel, u32 rate, ++ u32 bucket_size) ++{ ++ int i, err; ++ ++ for (i = 0; i <= TRTCM_PEAK_MODE; i++) { ++ err = airoha_qdma_set_trtcm_config(port->qdma, channel, ++ REG_EGRESS_TRTCM_CFG, i, ++ !!rate, TRTCM_METER_MODE); ++ if (err) ++ return err; ++ ++ err = airoha_qdma_set_trtcm_token_bucket(port->qdma, channel, ++ REG_EGRESS_TRTCM_CFG, ++ i, rate, bucket_size); ++ if (err) ++ return err; ++ } ++ ++ return 0; ++} ++ ++static int airoha_tc_htb_alloc_leaf_queue(struct airoha_gdm_port *port, ++ struct tc_htb_qopt_offload *opt) ++{ ++ u32 channel = TC_H_MIN(opt->classid) % AIROHA_NUM_QOS_CHANNELS; ++ u32 rate = div_u64(opt->rate, 1000) << 3; /* kbps */ ++ struct net_device *dev = port->dev; ++ int num_tx_queues = dev->real_num_tx_queues; ++ int err; ++ ++ if (opt->parent_classid != TC_HTB_CLASSID_ROOT) { ++ NL_SET_ERR_MSG_MOD(opt->extack, "invalid parent classid"); ++ return -EINVAL; ++ } ++ ++ err = airoha_qdma_set_tx_rate_limit(port, channel, rate, opt->quantum); ++ if (err) { ++ NL_SET_ERR_MSG_MOD(opt->extack, ++ "failed configuring htb offload"); ++ return err; ++ } ++ ++ if (opt->command == TC_HTB_NODE_MODIFY) ++ return 0; ++ ++ err = netif_set_real_num_tx_queues(dev, num_tx_queues + 1); ++ if (err) { ++ airoha_qdma_set_tx_rate_limit(port, channel, 0, opt->quantum); ++ NL_SET_ERR_MSG_MOD(opt->extack, ++ "failed setting real_num_tx_queues"); ++ return err; ++ } ++ ++ set_bit(channel, port->qos_sq_bmap); ++ opt->qid = AIROHA_NUM_TX_RING + channel; ++ ++ return 0; ++} ++ ++static void airoha_tc_remove_htb_queue(struct airoha_gdm_port *port, int queue) ++{ ++ struct net_device *dev = port->dev; ++ ++ netif_set_real_num_tx_queues(dev, dev->real_num_tx_queues - 1); ++ airoha_qdma_set_tx_rate_limit(port, queue + 1, 0, 0); ++ clear_bit(queue, port->qos_sq_bmap); ++} ++ ++static int airoha_tc_htb_delete_leaf_queue(struct airoha_gdm_port *port, ++ struct tc_htb_qopt_offload *opt) ++{ ++ u32 channel = TC_H_MIN(opt->classid) % AIROHA_NUM_QOS_CHANNELS; ++ ++ if (!test_bit(channel, port->qos_sq_bmap)) { ++ NL_SET_ERR_MSG_MOD(opt->extack, "invalid queue id"); ++ return -EINVAL; ++ } ++ ++ airoha_tc_remove_htb_queue(port, channel); ++ ++ return 0; ++} ++ ++static int airoha_tc_htb_destroy(struct airoha_gdm_port *port) ++{ ++ int q; ++ ++ for_each_set_bit(q, port->qos_sq_bmap, AIROHA_NUM_QOS_CHANNELS) ++ airoha_tc_remove_htb_queue(port, q); ++ ++ return 0; ++} ++ ++static int airoha_tc_get_htb_get_leaf_queue(struct airoha_gdm_port *port, ++ struct tc_htb_qopt_offload *opt) ++{ ++ u32 channel = TC_H_MIN(opt->classid) % AIROHA_NUM_QOS_CHANNELS; ++ ++ if (!test_bit(channel, port->qos_sq_bmap)) { ++ NL_SET_ERR_MSG_MOD(opt->extack, "invalid queue id"); ++ return -EINVAL; ++ } ++ ++ opt->qid = channel; ++ ++ return 0; ++} ++ ++static int airoha_tc_setup_qdisc_htb(struct airoha_gdm_port *port, ++ struct tc_htb_qopt_offload *opt) ++{ ++ switch (opt->command) { ++ case TC_HTB_CREATE: ++ break; ++ case TC_HTB_DESTROY: ++ return airoha_tc_htb_destroy(port); ++ case TC_HTB_NODE_MODIFY: ++ case TC_HTB_LEAF_ALLOC_QUEUE: ++ return airoha_tc_htb_alloc_leaf_queue(port, opt); ++ case TC_HTB_LEAF_DEL: ++ case TC_HTB_LEAF_DEL_LAST: ++ case TC_HTB_LEAF_DEL_LAST_FORCE: ++ return airoha_tc_htb_delete_leaf_queue(port, opt); ++ case TC_HTB_LEAF_QUERY_QUEUE: ++ return airoha_tc_get_htb_get_leaf_queue(port, opt); ++ default: ++ return -EOPNOTSUPP; ++ } ++ ++ return 0; ++} ++ ++static int airoha_dev_tc_setup(struct net_device *dev, enum tc_setup_type type, ++ void *type_data) ++{ ++ struct airoha_gdm_port *port = netdev_priv(dev); ++ ++ switch (type) { ++ case TC_SETUP_QDISC_ETS: ++ return airoha_tc_setup_qdisc_ets(port, type_data); ++ case TC_SETUP_QDISC_HTB: ++ return airoha_tc_setup_qdisc_htb(port, type_data); ++ default: ++ return -EOPNOTSUPP; ++ } ++} ++ ++static const struct net_device_ops airoha_netdev_ops = { ++ .ndo_init = airoha_dev_init, ++ .ndo_open = airoha_dev_open, ++ .ndo_stop = airoha_dev_stop, ++ .ndo_select_queue = airoha_dev_select_queue, ++ .ndo_start_xmit = airoha_dev_xmit, ++ .ndo_get_stats64 = airoha_dev_get_stats64, ++ .ndo_set_mac_address = airoha_dev_set_macaddr, ++ .ndo_setup_tc = airoha_dev_tc_setup, ++}; ++ ++static const struct ethtool_ops airoha_ethtool_ops = { ++ .get_drvinfo = airoha_ethtool_get_drvinfo, ++ .get_eth_mac_stats = airoha_ethtool_get_mac_stats, ++ .get_rmon_stats = airoha_ethtool_get_rmon_stats, ++}; ++ ++static int airoha_alloc_gdm_port(struct airoha_eth *eth, struct device_node *np) ++{ ++ const __be32 *id_ptr = of_get_property(np, "reg", NULL); ++ struct airoha_gdm_port *port; ++ struct airoha_qdma *qdma; ++ struct net_device *dev; ++ int err, index; ++ u32 id; ++ ++ if (!id_ptr) { ++ dev_err(eth->dev, "missing gdm port id\n"); ++ return -EINVAL; ++ } ++ ++ id = be32_to_cpup(id_ptr); ++ index = id - 1; ++ ++ if (!id || id > ARRAY_SIZE(eth->ports)) { ++ dev_err(eth->dev, "invalid gdm port id: %d\n", id); ++ return -EINVAL; ++ } ++ ++ if (eth->ports[index]) { ++ dev_err(eth->dev, "duplicate gdm port id: %d\n", id); ++ return -EINVAL; ++ } ++ ++ dev = devm_alloc_etherdev_mqs(eth->dev, sizeof(*port), ++ AIROHA_NUM_NETDEV_TX_RINGS, ++ AIROHA_NUM_RX_RING); ++ if (!dev) { ++ dev_err(eth->dev, "alloc_etherdev failed\n"); ++ return -ENOMEM; ++ } ++ ++ qdma = ð->qdma[index % AIROHA_MAX_NUM_QDMA]; ++ dev->netdev_ops = &airoha_netdev_ops; ++ dev->ethtool_ops = &airoha_ethtool_ops; ++ dev->max_mtu = AIROHA_MAX_MTU; ++ dev->watchdog_timeo = 5 * HZ; ++ dev->hw_features = NETIF_F_IP_CSUM | NETIF_F_RXCSUM | ++ NETIF_F_TSO6 | NETIF_F_IPV6_CSUM | ++ NETIF_F_SG | NETIF_F_TSO | ++ NETIF_F_HW_TC; ++ dev->features |= dev->hw_features; ++ dev->dev.of_node = np; ++ dev->irq = qdma->irq; ++ SET_NETDEV_DEV(dev, eth->dev); ++ ++ /* reserve hw queues for HTB offloading */ ++ err = netif_set_real_num_tx_queues(dev, AIROHA_NUM_TX_RING); ++ if (err) ++ return err; ++ ++ err = of_get_ethdev_address(np, dev); ++ if (err) { ++ if (err == -EPROBE_DEFER) ++ return err; ++ ++ eth_hw_addr_random(dev); ++ dev_info(eth->dev, "generated random MAC address %pM\n", ++ dev->dev_addr); ++ } ++ ++ port = netdev_priv(dev); ++ u64_stats_init(&port->stats.syncp); ++ spin_lock_init(&port->stats.lock); ++ port->qdma = qdma; ++ port->dev = dev; ++ port->id = id; ++ eth->ports[index] = port; ++ ++ return register_netdev(dev); ++} ++ ++static int airoha_probe(struct platform_device *pdev) ++{ ++ struct device_node *np; ++ struct airoha_eth *eth; ++ int i, err; ++ ++ eth = devm_kzalloc(&pdev->dev, sizeof(*eth), GFP_KERNEL); ++ if (!eth) ++ return -ENOMEM; ++ ++ eth->dev = &pdev->dev; ++ ++ err = dma_set_mask_and_coherent(eth->dev, DMA_BIT_MASK(32)); ++ if (err) { ++ dev_err(eth->dev, "failed configuring DMA mask\n"); ++ return err; ++ } ++ ++ eth->fe_regs = devm_platform_ioremap_resource_byname(pdev, "fe"); ++ if (IS_ERR(eth->fe_regs)) ++ return dev_err_probe(eth->dev, PTR_ERR(eth->fe_regs), ++ "failed to iomap fe regs\n"); ++ ++ eth->rsts[0].id = "fe"; ++ eth->rsts[1].id = "pdma"; ++ eth->rsts[2].id = "qdma"; ++ err = devm_reset_control_bulk_get_exclusive(eth->dev, ++ ARRAY_SIZE(eth->rsts), ++ eth->rsts); ++ if (err) { ++ dev_err(eth->dev, "failed to get bulk reset lines\n"); ++ return err; ++ } ++ ++ eth->xsi_rsts[0].id = "xsi-mac"; ++ eth->xsi_rsts[1].id = "hsi0-mac"; ++ eth->xsi_rsts[2].id = "hsi1-mac"; ++ eth->xsi_rsts[3].id = "hsi-mac"; ++ eth->xsi_rsts[4].id = "xfp-mac"; ++ err = devm_reset_control_bulk_get_exclusive(eth->dev, ++ ARRAY_SIZE(eth->xsi_rsts), ++ eth->xsi_rsts); ++ if (err) { ++ dev_err(eth->dev, "failed to get bulk xsi reset lines\n"); ++ return err; ++ } ++ ++ eth->napi_dev = alloc_netdev_dummy(0); ++ if (!eth->napi_dev) ++ return -ENOMEM; ++ ++ /* Enable threaded NAPI by default */ ++ eth->napi_dev->threaded = true; ++ strscpy(eth->napi_dev->name, "qdma_eth", sizeof(eth->napi_dev->name)); ++ platform_set_drvdata(pdev, eth); ++ ++ err = airoha_hw_init(pdev, eth); ++ if (err) ++ goto error_hw_cleanup; ++ ++ for (i = 0; i < ARRAY_SIZE(eth->qdma); i++) ++ airoha_qdma_start_napi(ð->qdma[i]); ++ ++ for_each_child_of_node(pdev->dev.of_node, np) { ++ if (!of_device_is_compatible(np, "airoha,eth-mac")) ++ continue; ++ ++ if (!of_device_is_available(np)) ++ continue; ++ ++ err = airoha_alloc_gdm_port(eth, np); ++ if (err) { ++ of_node_put(np); ++ goto error_napi_stop; ++ } ++ } ++ ++ return 0; ++ ++error_napi_stop: ++ for (i = 0; i < ARRAY_SIZE(eth->qdma); i++) ++ airoha_qdma_stop_napi(ð->qdma[i]); ++error_hw_cleanup: ++ for (i = 0; i < ARRAY_SIZE(eth->qdma); i++) ++ airoha_hw_cleanup(ð->qdma[i]); ++ ++ for (i = 0; i < ARRAY_SIZE(eth->ports); i++) { ++ struct airoha_gdm_port *port = eth->ports[i]; ++ ++ if (port && port->dev->reg_state == NETREG_REGISTERED) ++ unregister_netdev(port->dev); ++ } ++ free_netdev(eth->napi_dev); ++ platform_set_drvdata(pdev, NULL); ++ ++ return err; ++} ++ ++static void airoha_remove(struct platform_device *pdev) ++{ ++ struct airoha_eth *eth = platform_get_drvdata(pdev); ++ int i; ++ ++ for (i = 0; i < ARRAY_SIZE(eth->qdma); i++) { ++ airoha_qdma_stop_napi(ð->qdma[i]); ++ airoha_hw_cleanup(ð->qdma[i]); ++ } ++ ++ for (i = 0; i < ARRAY_SIZE(eth->ports); i++) { ++ struct airoha_gdm_port *port = eth->ports[i]; ++ ++ if (!port) ++ continue; ++ ++ airoha_dev_stop(port->dev); ++ unregister_netdev(port->dev); ++ } ++ free_netdev(eth->napi_dev); ++ ++ platform_set_drvdata(pdev, NULL); ++} ++ ++static const struct of_device_id of_airoha_match[] = { ++ { .compatible = "airoha,en7581-eth" }, ++ { /* sentinel */ } ++}; ++MODULE_DEVICE_TABLE(of, of_airoha_match); ++ ++static struct platform_driver airoha_driver = { ++ .probe = airoha_probe, ++ .remove_new = airoha_remove, ++ .driver = { ++ .name = KBUILD_MODNAME, ++ .of_match_table = of_airoha_match, ++ }, ++}; ++module_platform_driver(airoha_driver); ++ ++MODULE_LICENSE("GPL"); ++MODULE_AUTHOR("Lorenzo Bianconi "); ++MODULE_DESCRIPTION("Ethernet driver for Airoha SoC"); +--- a/drivers/net/ethernet/mediatek/airoha_eth.c ++++ /dev/null +@@ -1,3359 +0,0 @@ +-// SPDX-License-Identifier: GPL-2.0-only +-/* +- * Copyright (c) 2024 AIROHA Inc +- * Author: Lorenzo Bianconi +- */ +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +- +-#define AIROHA_MAX_NUM_GDM_PORTS 1 +-#define AIROHA_MAX_NUM_QDMA 2 +-#define AIROHA_MAX_NUM_RSTS 3 +-#define AIROHA_MAX_NUM_XSI_RSTS 5 +-#define AIROHA_MAX_MTU 2000 +-#define AIROHA_MAX_PACKET_SIZE 2048 +-#define AIROHA_NUM_QOS_CHANNELS 4 +-#define AIROHA_NUM_QOS_QUEUES 8 +-#define AIROHA_NUM_TX_RING 32 +-#define AIROHA_NUM_RX_RING 32 +-#define AIROHA_NUM_NETDEV_TX_RINGS (AIROHA_NUM_TX_RING + \ +- AIROHA_NUM_QOS_CHANNELS) +-#define AIROHA_FE_MC_MAX_VLAN_TABLE 64 +-#define AIROHA_FE_MC_MAX_VLAN_PORT 16 +-#define AIROHA_NUM_TX_IRQ 2 +-#define HW_DSCP_NUM 2048 +-#define IRQ_QUEUE_LEN(_n) ((_n) ? 1024 : 2048) +-#define TX_DSCP_NUM 1024 +-#define RX_DSCP_NUM(_n) \ +- ((_n) == 2 ? 128 : \ +- (_n) == 11 ? 128 : \ +- (_n) == 15 ? 128 : \ +- (_n) == 0 ? 1024 : 16) +- +-#define PSE_RSV_PAGES 128 +-#define PSE_QUEUE_RSV_PAGES 64 +- +-#define QDMA_METER_IDX(_n) ((_n) & 0xff) +-#define QDMA_METER_GROUP(_n) (((_n) >> 8) & 0x3) +- +-/* FE */ +-#define PSE_BASE 0x0100 +-#define CSR_IFC_BASE 0x0200 +-#define CDM1_BASE 0x0400 +-#define GDM1_BASE 0x0500 +-#define PPE1_BASE 0x0c00 +- +-#define CDM2_BASE 0x1400 +-#define GDM2_BASE 0x1500 +- +-#define GDM3_BASE 0x1100 +-#define GDM4_BASE 0x2500 +- +-#define GDM_BASE(_n) \ +- ((_n) == 4 ? GDM4_BASE : \ +- (_n) == 3 ? GDM3_BASE : \ +- (_n) == 2 ? GDM2_BASE : GDM1_BASE) +- +-#define REG_FE_DMA_GLO_CFG 0x0000 +-#define FE_DMA_GLO_L2_SPACE_MASK GENMASK(7, 4) +-#define FE_DMA_GLO_PG_SZ_MASK BIT(3) +- +-#define REG_FE_RST_GLO_CFG 0x0004 +-#define FE_RST_GDM4_MBI_ARB_MASK BIT(3) +-#define FE_RST_GDM3_MBI_ARB_MASK BIT(2) +-#define FE_RST_CORE_MASK BIT(0) +- +-#define REG_FE_WAN_MAC_H 0x0030 +-#define REG_FE_LAN_MAC_H 0x0040 +- +-#define REG_FE_MAC_LMIN(_n) ((_n) + 0x04) +-#define REG_FE_MAC_LMAX(_n) ((_n) + 0x08) +- +-#define REG_FE_CDM1_OQ_MAP0 0x0050 +-#define REG_FE_CDM1_OQ_MAP1 0x0054 +-#define REG_FE_CDM1_OQ_MAP2 0x0058 +-#define REG_FE_CDM1_OQ_MAP3 0x005c +- +-#define REG_FE_PCE_CFG 0x0070 +-#define PCE_DPI_EN_MASK BIT(2) +-#define PCE_KA_EN_MASK BIT(1) +-#define PCE_MC_EN_MASK BIT(0) +- +-#define REG_FE_PSE_QUEUE_CFG_WR 0x0080 +-#define PSE_CFG_PORT_ID_MASK GENMASK(27, 24) +-#define PSE_CFG_QUEUE_ID_MASK GENMASK(20, 16) +-#define PSE_CFG_WR_EN_MASK BIT(8) +-#define PSE_CFG_OQRSV_SEL_MASK BIT(0) +- +-#define REG_FE_PSE_QUEUE_CFG_VAL 0x0084 +-#define PSE_CFG_OQ_RSV_MASK GENMASK(13, 0) +- +-#define PSE_FQ_CFG 0x008c +-#define PSE_FQ_LIMIT_MASK GENMASK(14, 0) +- +-#define REG_FE_PSE_BUF_SET 0x0090 +-#define PSE_SHARE_USED_LTHD_MASK GENMASK(31, 16) +-#define PSE_ALLRSV_MASK GENMASK(14, 0) +- +-#define REG_PSE_SHARE_USED_THD 0x0094 +-#define PSE_SHARE_USED_MTHD_MASK GENMASK(31, 16) +-#define PSE_SHARE_USED_HTHD_MASK GENMASK(15, 0) +- +-#define REG_GDM_MISC_CFG 0x0148 +-#define GDM2_RDM_ACK_WAIT_PREF_MASK BIT(9) +-#define GDM2_CHN_VLD_MODE_MASK BIT(5) +- +-#define REG_FE_CSR_IFC_CFG CSR_IFC_BASE +-#define FE_IFC_EN_MASK BIT(0) +- +-#define REG_FE_VIP_PORT_EN 0x01f0 +-#define REG_FE_IFC_PORT_EN 0x01f4 +- +-#define REG_PSE_IQ_REV1 (PSE_BASE + 0x08) +-#define PSE_IQ_RES1_P2_MASK GENMASK(23, 16) +- +-#define REG_PSE_IQ_REV2 (PSE_BASE + 0x0c) +-#define PSE_IQ_RES2_P5_MASK GENMASK(15, 8) +-#define PSE_IQ_RES2_P4_MASK GENMASK(7, 0) +- +-#define REG_FE_VIP_EN(_n) (0x0300 + ((_n) << 3)) +-#define PATN_FCPU_EN_MASK BIT(7) +-#define PATN_SWP_EN_MASK BIT(6) +-#define PATN_DP_EN_MASK BIT(5) +-#define PATN_SP_EN_MASK BIT(4) +-#define PATN_TYPE_MASK GENMASK(3, 1) +-#define PATN_EN_MASK BIT(0) +- +-#define REG_FE_VIP_PATN(_n) (0x0304 + ((_n) << 3)) +-#define PATN_DP_MASK GENMASK(31, 16) +-#define PATN_SP_MASK GENMASK(15, 0) +- +-#define REG_CDM1_VLAN_CTRL CDM1_BASE +-#define CDM1_VLAN_MASK GENMASK(31, 16) +- +-#define REG_CDM1_FWD_CFG (CDM1_BASE + 0x08) +-#define CDM1_VIP_QSEL_MASK GENMASK(24, 20) +- +-#define REG_CDM1_CRSN_QSEL(_n) (CDM1_BASE + 0x10 + ((_n) << 2)) +-#define CDM1_CRSN_QSEL_REASON_MASK(_n) \ +- GENMASK(4 + (((_n) % 4) << 3), (((_n) % 4) << 3)) +- +-#define REG_CDM2_FWD_CFG (CDM2_BASE + 0x08) +-#define CDM2_OAM_QSEL_MASK GENMASK(31, 27) +-#define CDM2_VIP_QSEL_MASK GENMASK(24, 20) +- +-#define REG_CDM2_CRSN_QSEL(_n) (CDM2_BASE + 0x10 + ((_n) << 2)) +-#define CDM2_CRSN_QSEL_REASON_MASK(_n) \ +- GENMASK(4 + (((_n) % 4) << 3), (((_n) % 4) << 3)) +- +-#define REG_GDM_FWD_CFG(_n) GDM_BASE(_n) +-#define GDM_DROP_CRC_ERR BIT(23) +-#define GDM_IP4_CKSUM BIT(22) +-#define GDM_TCP_CKSUM BIT(21) +-#define GDM_UDP_CKSUM BIT(20) +-#define GDM_UCFQ_MASK GENMASK(15, 12) +-#define GDM_BCFQ_MASK GENMASK(11, 8) +-#define GDM_MCFQ_MASK GENMASK(7, 4) +-#define GDM_OCFQ_MASK GENMASK(3, 0) +- +-#define REG_GDM_INGRESS_CFG(_n) (GDM_BASE(_n) + 0x10) +-#define GDM_INGRESS_FC_EN_MASK BIT(1) +-#define GDM_STAG_EN_MASK BIT(0) +- +-#define REG_GDM_LEN_CFG(_n) (GDM_BASE(_n) + 0x14) +-#define GDM_SHORT_LEN_MASK GENMASK(13, 0) +-#define GDM_LONG_LEN_MASK GENMASK(29, 16) +- +-#define REG_FE_CPORT_CFG (GDM1_BASE + 0x40) +-#define FE_CPORT_PAD BIT(26) +-#define FE_CPORT_PORT_XFC_MASK BIT(25) +-#define FE_CPORT_QUEUE_XFC_MASK BIT(24) +- +-#define REG_FE_GDM_MIB_CLEAR(_n) (GDM_BASE(_n) + 0xf0) +-#define FE_GDM_MIB_RX_CLEAR_MASK BIT(1) +-#define FE_GDM_MIB_TX_CLEAR_MASK BIT(0) +- +-#define REG_FE_GDM1_MIB_CFG (GDM1_BASE + 0xf4) +-#define FE_STRICT_RFC2819_MODE_MASK BIT(31) +-#define FE_GDM1_TX_MIB_SPLIT_EN_MASK BIT(17) +-#define FE_GDM1_RX_MIB_SPLIT_EN_MASK BIT(16) +-#define FE_TX_MIB_ID_MASK GENMASK(15, 8) +-#define FE_RX_MIB_ID_MASK GENMASK(7, 0) +- +-#define REG_FE_GDM_TX_OK_PKT_CNT_L(_n) (GDM_BASE(_n) + 0x104) +-#define REG_FE_GDM_TX_OK_BYTE_CNT_L(_n) (GDM_BASE(_n) + 0x10c) +-#define REG_FE_GDM_TX_ETH_PKT_CNT_L(_n) (GDM_BASE(_n) + 0x110) +-#define REG_FE_GDM_TX_ETH_BYTE_CNT_L(_n) (GDM_BASE(_n) + 0x114) +-#define REG_FE_GDM_TX_ETH_DROP_CNT(_n) (GDM_BASE(_n) + 0x118) +-#define REG_FE_GDM_TX_ETH_BC_CNT(_n) (GDM_BASE(_n) + 0x11c) +-#define REG_FE_GDM_TX_ETH_MC_CNT(_n) (GDM_BASE(_n) + 0x120) +-#define REG_FE_GDM_TX_ETH_RUNT_CNT(_n) (GDM_BASE(_n) + 0x124) +-#define REG_FE_GDM_TX_ETH_LONG_CNT(_n) (GDM_BASE(_n) + 0x128) +-#define REG_FE_GDM_TX_ETH_E64_CNT_L(_n) (GDM_BASE(_n) + 0x12c) +-#define REG_FE_GDM_TX_ETH_L64_CNT_L(_n) (GDM_BASE(_n) + 0x130) +-#define REG_FE_GDM_TX_ETH_L127_CNT_L(_n) (GDM_BASE(_n) + 0x134) +-#define REG_FE_GDM_TX_ETH_L255_CNT_L(_n) (GDM_BASE(_n) + 0x138) +-#define REG_FE_GDM_TX_ETH_L511_CNT_L(_n) (GDM_BASE(_n) + 0x13c) +-#define REG_FE_GDM_TX_ETH_L1023_CNT_L(_n) (GDM_BASE(_n) + 0x140) +- +-#define REG_FE_GDM_RX_OK_PKT_CNT_L(_n) (GDM_BASE(_n) + 0x148) +-#define REG_FE_GDM_RX_FC_DROP_CNT(_n) (GDM_BASE(_n) + 0x14c) +-#define REG_FE_GDM_RX_RC_DROP_CNT(_n) (GDM_BASE(_n) + 0x150) +-#define REG_FE_GDM_RX_OVERFLOW_DROP_CNT(_n) (GDM_BASE(_n) + 0x154) +-#define REG_FE_GDM_RX_ERROR_DROP_CNT(_n) (GDM_BASE(_n) + 0x158) +-#define REG_FE_GDM_RX_OK_BYTE_CNT_L(_n) (GDM_BASE(_n) + 0x15c) +-#define REG_FE_GDM_RX_ETH_PKT_CNT_L(_n) (GDM_BASE(_n) + 0x160) +-#define REG_FE_GDM_RX_ETH_BYTE_CNT_L(_n) (GDM_BASE(_n) + 0x164) +-#define REG_FE_GDM_RX_ETH_DROP_CNT(_n) (GDM_BASE(_n) + 0x168) +-#define REG_FE_GDM_RX_ETH_BC_CNT(_n) (GDM_BASE(_n) + 0x16c) +-#define REG_FE_GDM_RX_ETH_MC_CNT(_n) (GDM_BASE(_n) + 0x170) +-#define REG_FE_GDM_RX_ETH_CRC_ERR_CNT(_n) (GDM_BASE(_n) + 0x174) +-#define REG_FE_GDM_RX_ETH_FRAG_CNT(_n) (GDM_BASE(_n) + 0x178) +-#define REG_FE_GDM_RX_ETH_JABBER_CNT(_n) (GDM_BASE(_n) + 0x17c) +-#define REG_FE_GDM_RX_ETH_RUNT_CNT(_n) (GDM_BASE(_n) + 0x180) +-#define REG_FE_GDM_RX_ETH_LONG_CNT(_n) (GDM_BASE(_n) + 0x184) +-#define REG_FE_GDM_RX_ETH_E64_CNT_L(_n) (GDM_BASE(_n) + 0x188) +-#define REG_FE_GDM_RX_ETH_L64_CNT_L(_n) (GDM_BASE(_n) + 0x18c) +-#define REG_FE_GDM_RX_ETH_L127_CNT_L(_n) (GDM_BASE(_n) + 0x190) +-#define REG_FE_GDM_RX_ETH_L255_CNT_L(_n) (GDM_BASE(_n) + 0x194) +-#define REG_FE_GDM_RX_ETH_L511_CNT_L(_n) (GDM_BASE(_n) + 0x198) +-#define REG_FE_GDM_RX_ETH_L1023_CNT_L(_n) (GDM_BASE(_n) + 0x19c) +- +-#define REG_PPE1_TB_HASH_CFG (PPE1_BASE + 0x250) +-#define PPE1_SRAM_TABLE_EN_MASK BIT(0) +-#define PPE1_SRAM_HASH1_EN_MASK BIT(8) +-#define PPE1_DRAM_TABLE_EN_MASK BIT(16) +-#define PPE1_DRAM_HASH1_EN_MASK BIT(24) +- +-#define REG_FE_GDM_TX_OK_PKT_CNT_H(_n) (GDM_BASE(_n) + 0x280) +-#define REG_FE_GDM_TX_OK_BYTE_CNT_H(_n) (GDM_BASE(_n) + 0x284) +-#define REG_FE_GDM_TX_ETH_PKT_CNT_H(_n) (GDM_BASE(_n) + 0x288) +-#define REG_FE_GDM_TX_ETH_BYTE_CNT_H(_n) (GDM_BASE(_n) + 0x28c) +- +-#define REG_FE_GDM_RX_OK_PKT_CNT_H(_n) (GDM_BASE(_n) + 0x290) +-#define REG_FE_GDM_RX_OK_BYTE_CNT_H(_n) (GDM_BASE(_n) + 0x294) +-#define REG_FE_GDM_RX_ETH_PKT_CNT_H(_n) (GDM_BASE(_n) + 0x298) +-#define REG_FE_GDM_RX_ETH_BYTE_CNT_H(_n) (GDM_BASE(_n) + 0x29c) +-#define REG_FE_GDM_TX_ETH_E64_CNT_H(_n) (GDM_BASE(_n) + 0x2b8) +-#define REG_FE_GDM_TX_ETH_L64_CNT_H(_n) (GDM_BASE(_n) + 0x2bc) +-#define REG_FE_GDM_TX_ETH_L127_CNT_H(_n) (GDM_BASE(_n) + 0x2c0) +-#define REG_FE_GDM_TX_ETH_L255_CNT_H(_n) (GDM_BASE(_n) + 0x2c4) +-#define REG_FE_GDM_TX_ETH_L511_CNT_H(_n) (GDM_BASE(_n) + 0x2c8) +-#define REG_FE_GDM_TX_ETH_L1023_CNT_H(_n) (GDM_BASE(_n) + 0x2cc) +-#define REG_FE_GDM_RX_ETH_E64_CNT_H(_n) (GDM_BASE(_n) + 0x2e8) +-#define REG_FE_GDM_RX_ETH_L64_CNT_H(_n) (GDM_BASE(_n) + 0x2ec) +-#define REG_FE_GDM_RX_ETH_L127_CNT_H(_n) (GDM_BASE(_n) + 0x2f0) +-#define REG_FE_GDM_RX_ETH_L255_CNT_H(_n) (GDM_BASE(_n) + 0x2f4) +-#define REG_FE_GDM_RX_ETH_L511_CNT_H(_n) (GDM_BASE(_n) + 0x2f8) +-#define REG_FE_GDM_RX_ETH_L1023_CNT_H(_n) (GDM_BASE(_n) + 0x2fc) +- +-#define REG_GDM2_CHN_RLS (GDM2_BASE + 0x20) +-#define MBI_RX_AGE_SEL_MASK GENMASK(26, 25) +-#define MBI_TX_AGE_SEL_MASK GENMASK(18, 17) +- +-#define REG_GDM3_FWD_CFG GDM3_BASE +-#define GDM3_PAD_EN_MASK BIT(28) +- +-#define REG_GDM4_FWD_CFG GDM4_BASE +-#define GDM4_PAD_EN_MASK BIT(28) +-#define GDM4_SPORT_OFFSET0_MASK GENMASK(11, 8) +- +-#define REG_GDM4_SRC_PORT_SET (GDM4_BASE + 0x23c) +-#define GDM4_SPORT_OFF2_MASK GENMASK(19, 16) +-#define GDM4_SPORT_OFF1_MASK GENMASK(15, 12) +-#define GDM4_SPORT_OFF0_MASK GENMASK(11, 8) +- +-#define REG_IP_FRAG_FP 0x2010 +-#define IP_ASSEMBLE_PORT_MASK GENMASK(24, 21) +-#define IP_ASSEMBLE_NBQ_MASK GENMASK(20, 16) +-#define IP_FRAGMENT_PORT_MASK GENMASK(8, 5) +-#define IP_FRAGMENT_NBQ_MASK GENMASK(4, 0) +- +-#define REG_MC_VLAN_EN 0x2100 +-#define MC_VLAN_EN_MASK BIT(0) +- +-#define REG_MC_VLAN_CFG 0x2104 +-#define MC_VLAN_CFG_CMD_DONE_MASK BIT(31) +-#define MC_VLAN_CFG_TABLE_ID_MASK GENMASK(21, 16) +-#define MC_VLAN_CFG_PORT_ID_MASK GENMASK(11, 8) +-#define MC_VLAN_CFG_TABLE_SEL_MASK BIT(4) +-#define MC_VLAN_CFG_RW_MASK BIT(0) +- +-#define REG_MC_VLAN_DATA 0x2108 +- +-#define REG_CDM5_RX_OQ1_DROP_CNT 0x29d4 +- +-/* QDMA */ +-#define REG_QDMA_GLOBAL_CFG 0x0004 +-#define GLOBAL_CFG_RX_2B_OFFSET_MASK BIT(31) +-#define GLOBAL_CFG_DMA_PREFERENCE_MASK GENMASK(30, 29) +-#define GLOBAL_CFG_CPU_TXR_RR_MASK BIT(28) +-#define GLOBAL_CFG_DSCP_BYTE_SWAP_MASK BIT(27) +-#define GLOBAL_CFG_PAYLOAD_BYTE_SWAP_MASK BIT(26) +-#define GLOBAL_CFG_MULTICAST_MODIFY_FP_MASK BIT(25) +-#define GLOBAL_CFG_OAM_MODIFY_MASK BIT(24) +-#define GLOBAL_CFG_RESET_MASK BIT(23) +-#define GLOBAL_CFG_RESET_DONE_MASK BIT(22) +-#define GLOBAL_CFG_MULTICAST_EN_MASK BIT(21) +-#define GLOBAL_CFG_IRQ1_EN_MASK BIT(20) +-#define GLOBAL_CFG_IRQ0_EN_MASK BIT(19) +-#define GLOBAL_CFG_LOOPCNT_EN_MASK BIT(18) +-#define GLOBAL_CFG_RD_BYPASS_WR_MASK BIT(17) +-#define GLOBAL_CFG_QDMA_LOOPBACK_MASK BIT(16) +-#define GLOBAL_CFG_LPBK_RXQ_SEL_MASK GENMASK(13, 8) +-#define GLOBAL_CFG_CHECK_DONE_MASK BIT(7) +-#define GLOBAL_CFG_TX_WB_DONE_MASK BIT(6) +-#define GLOBAL_CFG_MAX_ISSUE_NUM_MASK GENMASK(5, 4) +-#define GLOBAL_CFG_RX_DMA_BUSY_MASK BIT(3) +-#define GLOBAL_CFG_RX_DMA_EN_MASK BIT(2) +-#define GLOBAL_CFG_TX_DMA_BUSY_MASK BIT(1) +-#define GLOBAL_CFG_TX_DMA_EN_MASK BIT(0) +- +-#define REG_FWD_DSCP_BASE 0x0010 +-#define REG_FWD_BUF_BASE 0x0014 +- +-#define REG_HW_FWD_DSCP_CFG 0x0018 +-#define HW_FWD_DSCP_PAYLOAD_SIZE_MASK GENMASK(29, 28) +-#define HW_FWD_DSCP_SCATTER_LEN_MASK GENMASK(17, 16) +-#define HW_FWD_DSCP_MIN_SCATTER_LEN_MASK GENMASK(15, 0) +- +-#define REG_INT_STATUS(_n) \ +- (((_n) == 4) ? 0x0730 : \ +- ((_n) == 3) ? 0x0724 : \ +- ((_n) == 2) ? 0x0720 : \ +- ((_n) == 1) ? 0x0024 : 0x0020) +- +-#define REG_INT_ENABLE(_n) \ +- (((_n) == 4) ? 0x0750 : \ +- ((_n) == 3) ? 0x0744 : \ +- ((_n) == 2) ? 0x0740 : \ +- ((_n) == 1) ? 0x002c : 0x0028) +- +-/* QDMA_CSR_INT_ENABLE1 */ +-#define RX15_COHERENT_INT_MASK BIT(31) +-#define RX14_COHERENT_INT_MASK BIT(30) +-#define RX13_COHERENT_INT_MASK BIT(29) +-#define RX12_COHERENT_INT_MASK BIT(28) +-#define RX11_COHERENT_INT_MASK BIT(27) +-#define RX10_COHERENT_INT_MASK BIT(26) +-#define RX9_COHERENT_INT_MASK BIT(25) +-#define RX8_COHERENT_INT_MASK BIT(24) +-#define RX7_COHERENT_INT_MASK BIT(23) +-#define RX6_COHERENT_INT_MASK BIT(22) +-#define RX5_COHERENT_INT_MASK BIT(21) +-#define RX4_COHERENT_INT_MASK BIT(20) +-#define RX3_COHERENT_INT_MASK BIT(19) +-#define RX2_COHERENT_INT_MASK BIT(18) +-#define RX1_COHERENT_INT_MASK BIT(17) +-#define RX0_COHERENT_INT_MASK BIT(16) +-#define TX7_COHERENT_INT_MASK BIT(15) +-#define TX6_COHERENT_INT_MASK BIT(14) +-#define TX5_COHERENT_INT_MASK BIT(13) +-#define TX4_COHERENT_INT_MASK BIT(12) +-#define TX3_COHERENT_INT_MASK BIT(11) +-#define TX2_COHERENT_INT_MASK BIT(10) +-#define TX1_COHERENT_INT_MASK BIT(9) +-#define TX0_COHERENT_INT_MASK BIT(8) +-#define CNT_OVER_FLOW_INT_MASK BIT(7) +-#define IRQ1_FULL_INT_MASK BIT(5) +-#define IRQ1_INT_MASK BIT(4) +-#define HWFWD_DSCP_LOW_INT_MASK BIT(3) +-#define HWFWD_DSCP_EMPTY_INT_MASK BIT(2) +-#define IRQ0_FULL_INT_MASK BIT(1) +-#define IRQ0_INT_MASK BIT(0) +- +-#define TX_DONE_INT_MASK(_n) \ +- ((_n) ? IRQ1_INT_MASK | IRQ1_FULL_INT_MASK \ +- : IRQ0_INT_MASK | IRQ0_FULL_INT_MASK) +- +-#define INT_TX_MASK \ +- (IRQ1_INT_MASK | IRQ1_FULL_INT_MASK | \ +- IRQ0_INT_MASK | IRQ0_FULL_INT_MASK) +- +-#define INT_IDX0_MASK \ +- (TX0_COHERENT_INT_MASK | TX1_COHERENT_INT_MASK | \ +- TX2_COHERENT_INT_MASK | TX3_COHERENT_INT_MASK | \ +- TX4_COHERENT_INT_MASK | TX5_COHERENT_INT_MASK | \ +- TX6_COHERENT_INT_MASK | TX7_COHERENT_INT_MASK | \ +- RX0_COHERENT_INT_MASK | RX1_COHERENT_INT_MASK | \ +- RX2_COHERENT_INT_MASK | RX3_COHERENT_INT_MASK | \ +- RX4_COHERENT_INT_MASK | RX7_COHERENT_INT_MASK | \ +- RX8_COHERENT_INT_MASK | RX9_COHERENT_INT_MASK | \ +- RX15_COHERENT_INT_MASK | INT_TX_MASK) +- +-/* QDMA_CSR_INT_ENABLE2 */ +-#define RX15_NO_CPU_DSCP_INT_MASK BIT(31) +-#define RX14_NO_CPU_DSCP_INT_MASK BIT(30) +-#define RX13_NO_CPU_DSCP_INT_MASK BIT(29) +-#define RX12_NO_CPU_DSCP_INT_MASK BIT(28) +-#define RX11_NO_CPU_DSCP_INT_MASK BIT(27) +-#define RX10_NO_CPU_DSCP_INT_MASK BIT(26) +-#define RX9_NO_CPU_DSCP_INT_MASK BIT(25) +-#define RX8_NO_CPU_DSCP_INT_MASK BIT(24) +-#define RX7_NO_CPU_DSCP_INT_MASK BIT(23) +-#define RX6_NO_CPU_DSCP_INT_MASK BIT(22) +-#define RX5_NO_CPU_DSCP_INT_MASK BIT(21) +-#define RX4_NO_CPU_DSCP_INT_MASK BIT(20) +-#define RX3_NO_CPU_DSCP_INT_MASK BIT(19) +-#define RX2_NO_CPU_DSCP_INT_MASK BIT(18) +-#define RX1_NO_CPU_DSCP_INT_MASK BIT(17) +-#define RX0_NO_CPU_DSCP_INT_MASK BIT(16) +-#define RX15_DONE_INT_MASK BIT(15) +-#define RX14_DONE_INT_MASK BIT(14) +-#define RX13_DONE_INT_MASK BIT(13) +-#define RX12_DONE_INT_MASK BIT(12) +-#define RX11_DONE_INT_MASK BIT(11) +-#define RX10_DONE_INT_MASK BIT(10) +-#define RX9_DONE_INT_MASK BIT(9) +-#define RX8_DONE_INT_MASK BIT(8) +-#define RX7_DONE_INT_MASK BIT(7) +-#define RX6_DONE_INT_MASK BIT(6) +-#define RX5_DONE_INT_MASK BIT(5) +-#define RX4_DONE_INT_MASK BIT(4) +-#define RX3_DONE_INT_MASK BIT(3) +-#define RX2_DONE_INT_MASK BIT(2) +-#define RX1_DONE_INT_MASK BIT(1) +-#define RX0_DONE_INT_MASK BIT(0) +- +-#define RX_DONE_INT_MASK \ +- (RX0_DONE_INT_MASK | RX1_DONE_INT_MASK | \ +- RX2_DONE_INT_MASK | RX3_DONE_INT_MASK | \ +- RX4_DONE_INT_MASK | RX7_DONE_INT_MASK | \ +- RX8_DONE_INT_MASK | RX9_DONE_INT_MASK | \ +- RX15_DONE_INT_MASK) +-#define INT_IDX1_MASK \ +- (RX_DONE_INT_MASK | \ +- RX0_NO_CPU_DSCP_INT_MASK | RX1_NO_CPU_DSCP_INT_MASK | \ +- RX2_NO_CPU_DSCP_INT_MASK | RX3_NO_CPU_DSCP_INT_MASK | \ +- RX4_NO_CPU_DSCP_INT_MASK | RX7_NO_CPU_DSCP_INT_MASK | \ +- RX8_NO_CPU_DSCP_INT_MASK | RX9_NO_CPU_DSCP_INT_MASK | \ +- RX15_NO_CPU_DSCP_INT_MASK) +- +-/* QDMA_CSR_INT_ENABLE5 */ +-#define TX31_COHERENT_INT_MASK BIT(31) +-#define TX30_COHERENT_INT_MASK BIT(30) +-#define TX29_COHERENT_INT_MASK BIT(29) +-#define TX28_COHERENT_INT_MASK BIT(28) +-#define TX27_COHERENT_INT_MASK BIT(27) +-#define TX26_COHERENT_INT_MASK BIT(26) +-#define TX25_COHERENT_INT_MASK BIT(25) +-#define TX24_COHERENT_INT_MASK BIT(24) +-#define TX23_COHERENT_INT_MASK BIT(23) +-#define TX22_COHERENT_INT_MASK BIT(22) +-#define TX21_COHERENT_INT_MASK BIT(21) +-#define TX20_COHERENT_INT_MASK BIT(20) +-#define TX19_COHERENT_INT_MASK BIT(19) +-#define TX18_COHERENT_INT_MASK BIT(18) +-#define TX17_COHERENT_INT_MASK BIT(17) +-#define TX16_COHERENT_INT_MASK BIT(16) +-#define TX15_COHERENT_INT_MASK BIT(15) +-#define TX14_COHERENT_INT_MASK BIT(14) +-#define TX13_COHERENT_INT_MASK BIT(13) +-#define TX12_COHERENT_INT_MASK BIT(12) +-#define TX11_COHERENT_INT_MASK BIT(11) +-#define TX10_COHERENT_INT_MASK BIT(10) +-#define TX9_COHERENT_INT_MASK BIT(9) +-#define TX8_COHERENT_INT_MASK BIT(8) +- +-#define INT_IDX4_MASK \ +- (TX8_COHERENT_INT_MASK | TX9_COHERENT_INT_MASK | \ +- TX10_COHERENT_INT_MASK | TX11_COHERENT_INT_MASK | \ +- TX12_COHERENT_INT_MASK | TX13_COHERENT_INT_MASK | \ +- TX14_COHERENT_INT_MASK | TX15_COHERENT_INT_MASK | \ +- TX16_COHERENT_INT_MASK | TX17_COHERENT_INT_MASK | \ +- TX18_COHERENT_INT_MASK | TX19_COHERENT_INT_MASK | \ +- TX20_COHERENT_INT_MASK | TX21_COHERENT_INT_MASK | \ +- TX22_COHERENT_INT_MASK | TX23_COHERENT_INT_MASK | \ +- TX24_COHERENT_INT_MASK | TX25_COHERENT_INT_MASK | \ +- TX26_COHERENT_INT_MASK | TX27_COHERENT_INT_MASK | \ +- TX28_COHERENT_INT_MASK | TX29_COHERENT_INT_MASK | \ +- TX30_COHERENT_INT_MASK | TX31_COHERENT_INT_MASK) +- +-#define REG_TX_IRQ_BASE(_n) ((_n) ? 0x0048 : 0x0050) +- +-#define REG_TX_IRQ_CFG(_n) ((_n) ? 0x004c : 0x0054) +-#define TX_IRQ_THR_MASK GENMASK(27, 16) +-#define TX_IRQ_DEPTH_MASK GENMASK(11, 0) +- +-#define REG_IRQ_CLEAR_LEN(_n) ((_n) ? 0x0064 : 0x0058) +-#define IRQ_CLEAR_LEN_MASK GENMASK(7, 0) +- +-#define REG_IRQ_STATUS(_n) ((_n) ? 0x0068 : 0x005c) +-#define IRQ_ENTRY_LEN_MASK GENMASK(27, 16) +-#define IRQ_HEAD_IDX_MASK GENMASK(11, 0) +- +-#define REG_TX_RING_BASE(_n) \ +- (((_n) < 8) ? 0x0100 + ((_n) << 5) : 0x0b00 + (((_n) - 8) << 5)) +- +-#define REG_TX_RING_BLOCKING(_n) \ +- (((_n) < 8) ? 0x0104 + ((_n) << 5) : 0x0b04 + (((_n) - 8) << 5)) +- +-#define TX_RING_IRQ_BLOCKING_MAP_MASK BIT(6) +-#define TX_RING_IRQ_BLOCKING_CFG_MASK BIT(4) +-#define TX_RING_IRQ_BLOCKING_TX_DROP_EN_MASK BIT(2) +-#define TX_RING_IRQ_BLOCKING_MAX_TH_TXRING_EN_MASK BIT(1) +-#define TX_RING_IRQ_BLOCKING_MIN_TH_TXRING_EN_MASK BIT(0) +- +-#define REG_TX_CPU_IDX(_n) \ +- (((_n) < 8) ? 0x0108 + ((_n) << 5) : 0x0b08 + (((_n) - 8) << 5)) +- +-#define TX_RING_CPU_IDX_MASK GENMASK(15, 0) +- +-#define REG_TX_DMA_IDX(_n) \ +- (((_n) < 8) ? 0x010c + ((_n) << 5) : 0x0b0c + (((_n) - 8) << 5)) +- +-#define TX_RING_DMA_IDX_MASK GENMASK(15, 0) +- +-#define IRQ_RING_IDX_MASK GENMASK(20, 16) +-#define IRQ_DESC_IDX_MASK GENMASK(15, 0) +- +-#define REG_RX_RING_BASE(_n) \ +- (((_n) < 16) ? 0x0200 + ((_n) << 5) : 0x0e00 + (((_n) - 16) << 5)) +- +-#define REG_RX_RING_SIZE(_n) \ +- (((_n) < 16) ? 0x0204 + ((_n) << 5) : 0x0e04 + (((_n) - 16) << 5)) +- +-#define RX_RING_THR_MASK GENMASK(31, 16) +-#define RX_RING_SIZE_MASK GENMASK(15, 0) +- +-#define REG_RX_CPU_IDX(_n) \ +- (((_n) < 16) ? 0x0208 + ((_n) << 5) : 0x0e08 + (((_n) - 16) << 5)) +- +-#define RX_RING_CPU_IDX_MASK GENMASK(15, 0) +- +-#define REG_RX_DMA_IDX(_n) \ +- (((_n) < 16) ? 0x020c + ((_n) << 5) : 0x0e0c + (((_n) - 16) << 5)) +- +-#define REG_RX_DELAY_INT_IDX(_n) \ +- (((_n) < 16) ? 0x0210 + ((_n) << 5) : 0x0e10 + (((_n) - 16) << 5)) +- +-#define RX_DELAY_INT_MASK GENMASK(15, 0) +- +-#define RX_RING_DMA_IDX_MASK GENMASK(15, 0) +- +-#define REG_INGRESS_TRTCM_CFG 0x0070 +-#define INGRESS_TRTCM_EN_MASK BIT(31) +-#define INGRESS_TRTCM_MODE_MASK BIT(30) +-#define INGRESS_SLOW_TICK_RATIO_MASK GENMASK(29, 16) +-#define INGRESS_FAST_TICK_MASK GENMASK(15, 0) +- +-#define REG_QUEUE_CLOSE_CFG(_n) (0x00a0 + ((_n) & 0xfc)) +-#define TXQ_DISABLE_CHAN_QUEUE_MASK(_n, _m) BIT((_m) + (((_n) & 0x3) << 3)) +- +-#define REG_TXQ_DIS_CFG_BASE(_n) ((_n) ? 0x20a0 : 0x00a0) +-#define REG_TXQ_DIS_CFG(_n, _m) (REG_TXQ_DIS_CFG_BASE((_n)) + (_m) << 2) +- +-#define REG_CNTR_CFG(_n) (0x0400 + ((_n) << 3)) +-#define CNTR_EN_MASK BIT(31) +-#define CNTR_ALL_CHAN_EN_MASK BIT(30) +-#define CNTR_ALL_QUEUE_EN_MASK BIT(29) +-#define CNTR_ALL_DSCP_RING_EN_MASK BIT(28) +-#define CNTR_SRC_MASK GENMASK(27, 24) +-#define CNTR_DSCP_RING_MASK GENMASK(20, 16) +-#define CNTR_CHAN_MASK GENMASK(7, 3) +-#define CNTR_QUEUE_MASK GENMASK(2, 0) +- +-#define REG_CNTR_VAL(_n) (0x0404 + ((_n) << 3)) +- +-#define REG_LMGR_INIT_CFG 0x1000 +-#define LMGR_INIT_START BIT(31) +-#define LMGR_SRAM_MODE_MASK BIT(30) +-#define HW_FWD_PKTSIZE_OVERHEAD_MASK GENMASK(27, 20) +-#define HW_FWD_DESC_NUM_MASK GENMASK(16, 0) +- +-#define REG_FWD_DSCP_LOW_THR 0x1004 +-#define FWD_DSCP_LOW_THR_MASK GENMASK(17, 0) +- +-#define REG_EGRESS_RATE_METER_CFG 0x100c +-#define EGRESS_RATE_METER_EN_MASK BIT(31) +-#define EGRESS_RATE_METER_EQ_RATE_EN_MASK BIT(17) +-#define EGRESS_RATE_METER_WINDOW_SZ_MASK GENMASK(16, 12) +-#define EGRESS_RATE_METER_TIMESLICE_MASK GENMASK(10, 0) +- +-#define REG_EGRESS_TRTCM_CFG 0x1010 +-#define EGRESS_TRTCM_EN_MASK BIT(31) +-#define EGRESS_TRTCM_MODE_MASK BIT(30) +-#define EGRESS_SLOW_TICK_RATIO_MASK GENMASK(29, 16) +-#define EGRESS_FAST_TICK_MASK GENMASK(15, 0) +- +-#define TRTCM_PARAM_RW_MASK BIT(31) +-#define TRTCM_PARAM_RW_DONE_MASK BIT(30) +-#define TRTCM_PARAM_TYPE_MASK GENMASK(29, 28) +-#define TRTCM_METER_GROUP_MASK GENMASK(27, 26) +-#define TRTCM_PARAM_INDEX_MASK GENMASK(23, 17) +-#define TRTCM_PARAM_RATE_TYPE_MASK BIT(16) +- +-#define REG_TRTCM_CFG_PARAM(_n) ((_n) + 0x4) +-#define REG_TRTCM_DATA_LOW(_n) ((_n) + 0x8) +-#define REG_TRTCM_DATA_HIGH(_n) ((_n) + 0xc) +- +-#define REG_TXWRR_MODE_CFG 0x1020 +-#define TWRR_WEIGHT_SCALE_MASK BIT(31) +-#define TWRR_WEIGHT_BASE_MASK BIT(3) +- +-#define REG_TXWRR_WEIGHT_CFG 0x1024 +-#define TWRR_RW_CMD_MASK BIT(31) +-#define TWRR_RW_CMD_DONE BIT(30) +-#define TWRR_CHAN_IDX_MASK GENMASK(23, 19) +-#define TWRR_QUEUE_IDX_MASK GENMASK(18, 16) +-#define TWRR_VALUE_MASK GENMASK(15, 0) +- +-#define REG_PSE_BUF_USAGE_CFG 0x1028 +-#define PSE_BUF_ESTIMATE_EN_MASK BIT(29) +- +-#define REG_CHAN_QOS_MODE(_n) (0x1040 + ((_n) << 2)) +-#define CHAN_QOS_MODE_MASK(_n) GENMASK(2 + ((_n) << 2), (_n) << 2) +- +-#define REG_GLB_TRTCM_CFG 0x1080 +-#define GLB_TRTCM_EN_MASK BIT(31) +-#define GLB_TRTCM_MODE_MASK BIT(30) +-#define GLB_SLOW_TICK_RATIO_MASK GENMASK(29, 16) +-#define GLB_FAST_TICK_MASK GENMASK(15, 0) +- +-#define REG_TXQ_CNGST_CFG 0x10a0 +-#define TXQ_CNGST_DROP_EN BIT(31) +-#define TXQ_CNGST_DEI_DROP_EN BIT(30) +- +-#define REG_SLA_TRTCM_CFG 0x1150 +-#define SLA_TRTCM_EN_MASK BIT(31) +-#define SLA_TRTCM_MODE_MASK BIT(30) +-#define SLA_SLOW_TICK_RATIO_MASK GENMASK(29, 16) +-#define SLA_FAST_TICK_MASK GENMASK(15, 0) +- +-/* CTRL */ +-#define QDMA_DESC_DONE_MASK BIT(31) +-#define QDMA_DESC_DROP_MASK BIT(30) /* tx: drop - rx: overflow */ +-#define QDMA_DESC_MORE_MASK BIT(29) /* more SG elements */ +-#define QDMA_DESC_DEI_MASK BIT(25) +-#define QDMA_DESC_NO_DROP_MASK BIT(24) +-#define QDMA_DESC_LEN_MASK GENMASK(15, 0) +-/* DATA */ +-#define QDMA_DESC_NEXT_ID_MASK GENMASK(15, 0) +-/* TX MSG0 */ +-#define QDMA_ETH_TXMSG_MIC_IDX_MASK BIT(30) +-#define QDMA_ETH_TXMSG_SP_TAG_MASK GENMASK(29, 14) +-#define QDMA_ETH_TXMSG_ICO_MASK BIT(13) +-#define QDMA_ETH_TXMSG_UCO_MASK BIT(12) +-#define QDMA_ETH_TXMSG_TCO_MASK BIT(11) +-#define QDMA_ETH_TXMSG_TSO_MASK BIT(10) +-#define QDMA_ETH_TXMSG_FAST_MASK BIT(9) +-#define QDMA_ETH_TXMSG_OAM_MASK BIT(8) +-#define QDMA_ETH_TXMSG_CHAN_MASK GENMASK(7, 3) +-#define QDMA_ETH_TXMSG_QUEUE_MASK GENMASK(2, 0) +-/* TX MSG1 */ +-#define QDMA_ETH_TXMSG_NO_DROP BIT(31) +-#define QDMA_ETH_TXMSG_METER_MASK GENMASK(30, 24) /* 0x7f no meters */ +-#define QDMA_ETH_TXMSG_FPORT_MASK GENMASK(23, 20) +-#define QDMA_ETH_TXMSG_NBOQ_MASK GENMASK(19, 15) +-#define QDMA_ETH_TXMSG_HWF_MASK BIT(14) +-#define QDMA_ETH_TXMSG_HOP_MASK BIT(13) +-#define QDMA_ETH_TXMSG_PTP_MASK BIT(12) +-#define QDMA_ETH_TXMSG_ACNT_G1_MASK GENMASK(10, 6) /* 0x1f do not count */ +-#define QDMA_ETH_TXMSG_ACNT_G0_MASK GENMASK(5, 0) /* 0x3f do not count */ +- +-/* RX MSG1 */ +-#define QDMA_ETH_RXMSG_DEI_MASK BIT(31) +-#define QDMA_ETH_RXMSG_IP6_MASK BIT(30) +-#define QDMA_ETH_RXMSG_IP4_MASK BIT(29) +-#define QDMA_ETH_RXMSG_IP4F_MASK BIT(28) +-#define QDMA_ETH_RXMSG_L4_VALID_MASK BIT(27) +-#define QDMA_ETH_RXMSG_L4F_MASK BIT(26) +-#define QDMA_ETH_RXMSG_SPORT_MASK GENMASK(25, 21) +-#define QDMA_ETH_RXMSG_CRSN_MASK GENMASK(20, 16) +-#define QDMA_ETH_RXMSG_PPE_ENTRY_MASK GENMASK(15, 0) +- +-struct airoha_qdma_desc { +- __le32 rsv; +- __le32 ctrl; +- __le32 addr; +- __le32 data; +- __le32 msg0; +- __le32 msg1; +- __le32 msg2; +- __le32 msg3; +-}; +- +-/* CTRL0 */ +-#define QDMA_FWD_DESC_CTX_MASK BIT(31) +-#define QDMA_FWD_DESC_RING_MASK GENMASK(30, 28) +-#define QDMA_FWD_DESC_IDX_MASK GENMASK(27, 16) +-#define QDMA_FWD_DESC_LEN_MASK GENMASK(15, 0) +-/* CTRL1 */ +-#define QDMA_FWD_DESC_FIRST_IDX_MASK GENMASK(15, 0) +-/* CTRL2 */ +-#define QDMA_FWD_DESC_MORE_PKT_NUM_MASK GENMASK(2, 0) +- +-struct airoha_qdma_fwd_desc { +- __le32 addr; +- __le32 ctrl0; +- __le32 ctrl1; +- __le32 ctrl2; +- __le32 msg0; +- __le32 msg1; +- __le32 rsv0; +- __le32 rsv1; +-}; +- +-enum { +- QDMA_INT_REG_IDX0, +- QDMA_INT_REG_IDX1, +- QDMA_INT_REG_IDX2, +- QDMA_INT_REG_IDX3, +- QDMA_INT_REG_IDX4, +- QDMA_INT_REG_MAX +-}; +- +-enum { +- XSI_PCIE0_PORT, +- XSI_PCIE1_PORT, +- XSI_USB_PORT, +- XSI_AE_PORT, +- XSI_ETH_PORT, +-}; +- +-enum { +- XSI_PCIE0_VIP_PORT_MASK = BIT(22), +- XSI_PCIE1_VIP_PORT_MASK = BIT(23), +- XSI_USB_VIP_PORT_MASK = BIT(25), +- XSI_ETH_VIP_PORT_MASK = BIT(24), +-}; +- +-enum { +- DEV_STATE_INITIALIZED, +-}; +- +-enum { +- CDM_CRSN_QSEL_Q1 = 1, +- CDM_CRSN_QSEL_Q5 = 5, +- CDM_CRSN_QSEL_Q6 = 6, +- CDM_CRSN_QSEL_Q15 = 15, +-}; +- +-enum { +- CRSN_08 = 0x8, +- CRSN_21 = 0x15, /* KA */ +- CRSN_22 = 0x16, /* hit bind and force route to CPU */ +- CRSN_24 = 0x18, +- CRSN_25 = 0x19, +-}; +- +-enum { +- FE_PSE_PORT_CDM1, +- FE_PSE_PORT_GDM1, +- FE_PSE_PORT_GDM2, +- FE_PSE_PORT_GDM3, +- FE_PSE_PORT_PPE1, +- FE_PSE_PORT_CDM2, +- FE_PSE_PORT_CDM3, +- FE_PSE_PORT_CDM4, +- FE_PSE_PORT_PPE2, +- FE_PSE_PORT_GDM4, +- FE_PSE_PORT_CDM5, +- FE_PSE_PORT_DROP = 0xf, +-}; +- +-enum tx_sched_mode { +- TC_SCH_WRR8, +- TC_SCH_SP, +- TC_SCH_WRR7, +- TC_SCH_WRR6, +- TC_SCH_WRR5, +- TC_SCH_WRR4, +- TC_SCH_WRR3, +- TC_SCH_WRR2, +-}; +- +-enum trtcm_param_type { +- TRTCM_MISC_MODE, /* meter_en, pps_mode, tick_sel */ +- TRTCM_TOKEN_RATE_MODE, +- TRTCM_BUCKETSIZE_SHIFT_MODE, +- TRTCM_BUCKET_COUNTER_MODE, +-}; +- +-enum trtcm_mode_type { +- TRTCM_COMMIT_MODE, +- TRTCM_PEAK_MODE, +-}; +- +-enum trtcm_param { +- TRTCM_TICK_SEL = BIT(0), +- TRTCM_PKT_MODE = BIT(1), +- TRTCM_METER_MODE = BIT(2), +-}; +- +-#define MIN_TOKEN_SIZE 4096 +-#define MAX_TOKEN_SIZE_OFFSET 17 +-#define TRTCM_TOKEN_RATE_MASK GENMASK(23, 6) +-#define TRTCM_TOKEN_RATE_FRACTION_MASK GENMASK(5, 0) +- +-struct airoha_queue_entry { +- union { +- void *buf; +- struct sk_buff *skb; +- }; +- dma_addr_t dma_addr; +- u16 dma_len; +-}; +- +-struct airoha_queue { +- struct airoha_qdma *qdma; +- +- /* protect concurrent queue accesses */ +- spinlock_t lock; +- struct airoha_queue_entry *entry; +- struct airoha_qdma_desc *desc; +- u16 head; +- u16 tail; +- +- int queued; +- int ndesc; +- int free_thr; +- int buf_size; +- +- struct napi_struct napi; +- struct page_pool *page_pool; +-}; +- +-struct airoha_tx_irq_queue { +- struct airoha_qdma *qdma; +- +- struct napi_struct napi; +- +- int size; +- u32 *q; +-}; +- +-struct airoha_hw_stats { +- /* protect concurrent hw_stats accesses */ +- spinlock_t lock; +- struct u64_stats_sync syncp; +- +- /* get_stats64 */ +- u64 rx_ok_pkts; +- u64 tx_ok_pkts; +- u64 rx_ok_bytes; +- u64 tx_ok_bytes; +- u64 rx_multicast; +- u64 rx_errors; +- u64 rx_drops; +- u64 tx_drops; +- u64 rx_crc_error; +- u64 rx_over_errors; +- /* ethtool stats */ +- u64 tx_broadcast; +- u64 tx_multicast; +- u64 tx_len[7]; +- u64 rx_broadcast; +- u64 rx_fragment; +- u64 rx_jabber; +- u64 rx_len[7]; +-}; +- +-struct airoha_qdma { +- struct airoha_eth *eth; +- void __iomem *regs; +- +- /* protect concurrent irqmask accesses */ +- spinlock_t irq_lock; +- u32 irqmask[QDMA_INT_REG_MAX]; +- int irq; +- +- struct airoha_tx_irq_queue q_tx_irq[AIROHA_NUM_TX_IRQ]; +- +- struct airoha_queue q_tx[AIROHA_NUM_TX_RING]; +- struct airoha_queue q_rx[AIROHA_NUM_RX_RING]; +- +- /* descriptor and packet buffers for qdma hw forward */ +- struct { +- void *desc; +- void *q; +- } hfwd; +-}; +- +-struct airoha_gdm_port { +- struct airoha_qdma *qdma; +- struct net_device *dev; +- int id; +- +- struct airoha_hw_stats stats; +- +- DECLARE_BITMAP(qos_sq_bmap, AIROHA_NUM_QOS_CHANNELS); +- +- /* qos stats counters */ +- u64 cpu_tx_packets; +- u64 fwd_tx_packets; +-}; +- +-struct airoha_eth { +- struct device *dev; +- +- unsigned long state; +- void __iomem *fe_regs; +- +- struct reset_control_bulk_data rsts[AIROHA_MAX_NUM_RSTS]; +- struct reset_control_bulk_data xsi_rsts[AIROHA_MAX_NUM_XSI_RSTS]; +- +- struct net_device *napi_dev; +- +- struct airoha_qdma qdma[AIROHA_MAX_NUM_QDMA]; +- struct airoha_gdm_port *ports[AIROHA_MAX_NUM_GDM_PORTS]; +-}; +- +-static u32 airoha_rr(void __iomem *base, u32 offset) +-{ +- return readl(base + offset); +-} +- +-static void airoha_wr(void __iomem *base, u32 offset, u32 val) +-{ +- writel(val, base + offset); +-} +- +-static u32 airoha_rmw(void __iomem *base, u32 offset, u32 mask, u32 val) +-{ +- val |= (airoha_rr(base, offset) & ~mask); +- airoha_wr(base, offset, val); +- +- return val; +-} +- +-#define airoha_fe_rr(eth, offset) \ +- airoha_rr((eth)->fe_regs, (offset)) +-#define airoha_fe_wr(eth, offset, val) \ +- airoha_wr((eth)->fe_regs, (offset), (val)) +-#define airoha_fe_rmw(eth, offset, mask, val) \ +- airoha_rmw((eth)->fe_regs, (offset), (mask), (val)) +-#define airoha_fe_set(eth, offset, val) \ +- airoha_rmw((eth)->fe_regs, (offset), 0, (val)) +-#define airoha_fe_clear(eth, offset, val) \ +- airoha_rmw((eth)->fe_regs, (offset), (val), 0) +- +-#define airoha_qdma_rr(qdma, offset) \ +- airoha_rr((qdma)->regs, (offset)) +-#define airoha_qdma_wr(qdma, offset, val) \ +- airoha_wr((qdma)->regs, (offset), (val)) +-#define airoha_qdma_rmw(qdma, offset, mask, val) \ +- airoha_rmw((qdma)->regs, (offset), (mask), (val)) +-#define airoha_qdma_set(qdma, offset, val) \ +- airoha_rmw((qdma)->regs, (offset), 0, (val)) +-#define airoha_qdma_clear(qdma, offset, val) \ +- airoha_rmw((qdma)->regs, (offset), (val), 0) +- +-static void airoha_qdma_set_irqmask(struct airoha_qdma *qdma, int index, +- u32 clear, u32 set) +-{ +- unsigned long flags; +- +- if (WARN_ON_ONCE(index >= ARRAY_SIZE(qdma->irqmask))) +- return; +- +- spin_lock_irqsave(&qdma->irq_lock, flags); +- +- qdma->irqmask[index] &= ~clear; +- qdma->irqmask[index] |= set; +- airoha_qdma_wr(qdma, REG_INT_ENABLE(index), qdma->irqmask[index]); +- /* Read irq_enable register in order to guarantee the update above +- * completes in the spinlock critical section. +- */ +- airoha_qdma_rr(qdma, REG_INT_ENABLE(index)); +- +- spin_unlock_irqrestore(&qdma->irq_lock, flags); +-} +- +-static void airoha_qdma_irq_enable(struct airoha_qdma *qdma, int index, +- u32 mask) +-{ +- airoha_qdma_set_irqmask(qdma, index, 0, mask); +-} +- +-static void airoha_qdma_irq_disable(struct airoha_qdma *qdma, int index, +- u32 mask) +-{ +- airoha_qdma_set_irqmask(qdma, index, mask, 0); +-} +- +-static bool airhoa_is_lan_gdm_port(struct airoha_gdm_port *port) +-{ +- /* GDM1 port on EN7581 SoC is connected to the lan dsa switch. +- * GDM{2,3,4} can be used as wan port connected to an external +- * phy module. +- */ +- return port->id == 1; +-} +- +-static void airoha_set_macaddr(struct airoha_gdm_port *port, const u8 *addr) +-{ +- struct airoha_eth *eth = port->qdma->eth; +- u32 val, reg; +- +- reg = airhoa_is_lan_gdm_port(port) ? REG_FE_LAN_MAC_H +- : REG_FE_WAN_MAC_H; +- val = (addr[0] << 16) | (addr[1] << 8) | addr[2]; +- airoha_fe_wr(eth, reg, val); +- +- val = (addr[3] << 16) | (addr[4] << 8) | addr[5]; +- airoha_fe_wr(eth, REG_FE_MAC_LMIN(reg), val); +- airoha_fe_wr(eth, REG_FE_MAC_LMAX(reg), val); +-} +- +-static void airoha_set_gdm_port_fwd_cfg(struct airoha_eth *eth, u32 addr, +- u32 val) +-{ +- airoha_fe_rmw(eth, addr, GDM_OCFQ_MASK, +- FIELD_PREP(GDM_OCFQ_MASK, val)); +- airoha_fe_rmw(eth, addr, GDM_MCFQ_MASK, +- FIELD_PREP(GDM_MCFQ_MASK, val)); +- airoha_fe_rmw(eth, addr, GDM_BCFQ_MASK, +- FIELD_PREP(GDM_BCFQ_MASK, val)); +- airoha_fe_rmw(eth, addr, GDM_UCFQ_MASK, +- FIELD_PREP(GDM_UCFQ_MASK, val)); +-} +- +-static int airoha_set_gdm_port(struct airoha_eth *eth, int port, bool enable) +-{ +- u32 val = enable ? FE_PSE_PORT_PPE1 : FE_PSE_PORT_DROP; +- u32 vip_port, cfg_addr; +- +- switch (port) { +- case XSI_PCIE0_PORT: +- vip_port = XSI_PCIE0_VIP_PORT_MASK; +- cfg_addr = REG_GDM_FWD_CFG(3); +- break; +- case XSI_PCIE1_PORT: +- vip_port = XSI_PCIE1_VIP_PORT_MASK; +- cfg_addr = REG_GDM_FWD_CFG(3); +- break; +- case XSI_USB_PORT: +- vip_port = XSI_USB_VIP_PORT_MASK; +- cfg_addr = REG_GDM_FWD_CFG(4); +- break; +- case XSI_ETH_PORT: +- vip_port = XSI_ETH_VIP_PORT_MASK; +- cfg_addr = REG_GDM_FWD_CFG(4); +- break; +- default: +- return -EINVAL; +- } +- +- if (enable) { +- airoha_fe_set(eth, REG_FE_VIP_PORT_EN, vip_port); +- airoha_fe_set(eth, REG_FE_IFC_PORT_EN, vip_port); +- } else { +- airoha_fe_clear(eth, REG_FE_VIP_PORT_EN, vip_port); +- airoha_fe_clear(eth, REG_FE_IFC_PORT_EN, vip_port); +- } +- +- airoha_set_gdm_port_fwd_cfg(eth, cfg_addr, val); +- +- return 0; +-} +- +-static int airoha_set_gdm_ports(struct airoha_eth *eth, bool enable) +-{ +- const int port_list[] = { +- XSI_PCIE0_PORT, +- XSI_PCIE1_PORT, +- XSI_USB_PORT, +- XSI_ETH_PORT +- }; +- int i, err; +- +- for (i = 0; i < ARRAY_SIZE(port_list); i++) { +- err = airoha_set_gdm_port(eth, port_list[i], enable); +- if (err) +- goto error; +- } +- +- return 0; +- +-error: +- for (i--; i >= 0; i--) +- airoha_set_gdm_port(eth, port_list[i], false); +- +- return err; +-} +- +-static void airoha_fe_maccr_init(struct airoha_eth *eth) +-{ +- int p; +- +- for (p = 1; p <= ARRAY_SIZE(eth->ports); p++) { +- airoha_fe_set(eth, REG_GDM_FWD_CFG(p), +- GDM_TCP_CKSUM | GDM_UDP_CKSUM | GDM_IP4_CKSUM | +- GDM_DROP_CRC_ERR); +- airoha_set_gdm_port_fwd_cfg(eth, REG_GDM_FWD_CFG(p), +- FE_PSE_PORT_CDM1); +- airoha_fe_rmw(eth, REG_GDM_LEN_CFG(p), +- GDM_SHORT_LEN_MASK | GDM_LONG_LEN_MASK, +- FIELD_PREP(GDM_SHORT_LEN_MASK, 60) | +- FIELD_PREP(GDM_LONG_LEN_MASK, 4004)); +- } +- +- airoha_fe_rmw(eth, REG_CDM1_VLAN_CTRL, CDM1_VLAN_MASK, +- FIELD_PREP(CDM1_VLAN_MASK, 0x8100)); +- +- airoha_fe_set(eth, REG_FE_CPORT_CFG, FE_CPORT_PAD); +-} +- +-static void airoha_fe_vip_setup(struct airoha_eth *eth) +-{ +- airoha_fe_wr(eth, REG_FE_VIP_PATN(3), ETH_P_PPP_DISC); +- airoha_fe_wr(eth, REG_FE_VIP_EN(3), PATN_FCPU_EN_MASK | PATN_EN_MASK); +- +- airoha_fe_wr(eth, REG_FE_VIP_PATN(4), PPP_LCP); +- airoha_fe_wr(eth, REG_FE_VIP_EN(4), +- PATN_FCPU_EN_MASK | FIELD_PREP(PATN_TYPE_MASK, 1) | +- PATN_EN_MASK); +- +- airoha_fe_wr(eth, REG_FE_VIP_PATN(6), PPP_IPCP); +- airoha_fe_wr(eth, REG_FE_VIP_EN(6), +- PATN_FCPU_EN_MASK | FIELD_PREP(PATN_TYPE_MASK, 1) | +- PATN_EN_MASK); +- +- airoha_fe_wr(eth, REG_FE_VIP_PATN(7), PPP_CHAP); +- airoha_fe_wr(eth, REG_FE_VIP_EN(7), +- PATN_FCPU_EN_MASK | FIELD_PREP(PATN_TYPE_MASK, 1) | +- PATN_EN_MASK); +- +- /* BOOTP (0x43) */ +- airoha_fe_wr(eth, REG_FE_VIP_PATN(8), 0x43); +- airoha_fe_wr(eth, REG_FE_VIP_EN(8), +- PATN_FCPU_EN_MASK | PATN_SP_EN_MASK | +- FIELD_PREP(PATN_TYPE_MASK, 4) | PATN_EN_MASK); +- +- /* BOOTP (0x44) */ +- airoha_fe_wr(eth, REG_FE_VIP_PATN(9), 0x44); +- airoha_fe_wr(eth, REG_FE_VIP_EN(9), +- PATN_FCPU_EN_MASK | PATN_SP_EN_MASK | +- FIELD_PREP(PATN_TYPE_MASK, 4) | PATN_EN_MASK); +- +- /* ISAKMP */ +- airoha_fe_wr(eth, REG_FE_VIP_PATN(10), 0x1f401f4); +- airoha_fe_wr(eth, REG_FE_VIP_EN(10), +- PATN_FCPU_EN_MASK | PATN_DP_EN_MASK | PATN_SP_EN_MASK | +- FIELD_PREP(PATN_TYPE_MASK, 4) | PATN_EN_MASK); +- +- airoha_fe_wr(eth, REG_FE_VIP_PATN(11), PPP_IPV6CP); +- airoha_fe_wr(eth, REG_FE_VIP_EN(11), +- PATN_FCPU_EN_MASK | FIELD_PREP(PATN_TYPE_MASK, 1) | +- PATN_EN_MASK); +- +- /* DHCPv6 */ +- airoha_fe_wr(eth, REG_FE_VIP_PATN(12), 0x2220223); +- airoha_fe_wr(eth, REG_FE_VIP_EN(12), +- PATN_FCPU_EN_MASK | PATN_DP_EN_MASK | PATN_SP_EN_MASK | +- FIELD_PREP(PATN_TYPE_MASK, 4) | PATN_EN_MASK); +- +- airoha_fe_wr(eth, REG_FE_VIP_PATN(19), PPP_PAP); +- airoha_fe_wr(eth, REG_FE_VIP_EN(19), +- PATN_FCPU_EN_MASK | FIELD_PREP(PATN_TYPE_MASK, 1) | +- PATN_EN_MASK); +- +- /* ETH->ETH_P_1905 (0x893a) */ +- airoha_fe_wr(eth, REG_FE_VIP_PATN(20), 0x893a); +- airoha_fe_wr(eth, REG_FE_VIP_EN(20), +- PATN_FCPU_EN_MASK | PATN_EN_MASK); +- +- airoha_fe_wr(eth, REG_FE_VIP_PATN(21), ETH_P_LLDP); +- airoha_fe_wr(eth, REG_FE_VIP_EN(21), +- PATN_FCPU_EN_MASK | PATN_EN_MASK); +-} +- +-static u32 airoha_fe_get_pse_queue_rsv_pages(struct airoha_eth *eth, +- u32 port, u32 queue) +-{ +- u32 val; +- +- airoha_fe_rmw(eth, REG_FE_PSE_QUEUE_CFG_WR, +- PSE_CFG_PORT_ID_MASK | PSE_CFG_QUEUE_ID_MASK, +- FIELD_PREP(PSE_CFG_PORT_ID_MASK, port) | +- FIELD_PREP(PSE_CFG_QUEUE_ID_MASK, queue)); +- val = airoha_fe_rr(eth, REG_FE_PSE_QUEUE_CFG_VAL); +- +- return FIELD_GET(PSE_CFG_OQ_RSV_MASK, val); +-} +- +-static void airoha_fe_set_pse_queue_rsv_pages(struct airoha_eth *eth, +- u32 port, u32 queue, u32 val) +-{ +- airoha_fe_rmw(eth, REG_FE_PSE_QUEUE_CFG_VAL, PSE_CFG_OQ_RSV_MASK, +- FIELD_PREP(PSE_CFG_OQ_RSV_MASK, val)); +- airoha_fe_rmw(eth, REG_FE_PSE_QUEUE_CFG_WR, +- PSE_CFG_PORT_ID_MASK | PSE_CFG_QUEUE_ID_MASK | +- PSE_CFG_WR_EN_MASK | PSE_CFG_OQRSV_SEL_MASK, +- FIELD_PREP(PSE_CFG_PORT_ID_MASK, port) | +- FIELD_PREP(PSE_CFG_QUEUE_ID_MASK, queue) | +- PSE_CFG_WR_EN_MASK | PSE_CFG_OQRSV_SEL_MASK); +-} +- +-static u32 airoha_fe_get_pse_all_rsv(struct airoha_eth *eth) +-{ +- u32 val = airoha_fe_rr(eth, REG_FE_PSE_BUF_SET); +- +- return FIELD_GET(PSE_ALLRSV_MASK, val); +-} +- +-static int airoha_fe_set_pse_oq_rsv(struct airoha_eth *eth, +- u32 port, u32 queue, u32 val) +-{ +- u32 orig_val = airoha_fe_get_pse_queue_rsv_pages(eth, port, queue); +- u32 tmp, all_rsv, fq_limit; +- +- airoha_fe_set_pse_queue_rsv_pages(eth, port, queue, val); +- +- /* modify all rsv */ +- all_rsv = airoha_fe_get_pse_all_rsv(eth); +- all_rsv += (val - orig_val); +- airoha_fe_rmw(eth, REG_FE_PSE_BUF_SET, PSE_ALLRSV_MASK, +- FIELD_PREP(PSE_ALLRSV_MASK, all_rsv)); +- +- /* modify hthd */ +- tmp = airoha_fe_rr(eth, PSE_FQ_CFG); +- fq_limit = FIELD_GET(PSE_FQ_LIMIT_MASK, tmp); +- tmp = fq_limit - all_rsv - 0x20; +- airoha_fe_rmw(eth, REG_PSE_SHARE_USED_THD, +- PSE_SHARE_USED_HTHD_MASK, +- FIELD_PREP(PSE_SHARE_USED_HTHD_MASK, tmp)); +- +- tmp = fq_limit - all_rsv - 0x100; +- airoha_fe_rmw(eth, REG_PSE_SHARE_USED_THD, +- PSE_SHARE_USED_MTHD_MASK, +- FIELD_PREP(PSE_SHARE_USED_MTHD_MASK, tmp)); +- tmp = (3 * tmp) >> 2; +- airoha_fe_rmw(eth, REG_FE_PSE_BUF_SET, +- PSE_SHARE_USED_LTHD_MASK, +- FIELD_PREP(PSE_SHARE_USED_LTHD_MASK, tmp)); +- +- return 0; +-} +- +-static void airoha_fe_pse_ports_init(struct airoha_eth *eth) +-{ +- const u32 pse_port_num_queues[] = { +- [FE_PSE_PORT_CDM1] = 6, +- [FE_PSE_PORT_GDM1] = 6, +- [FE_PSE_PORT_GDM2] = 32, +- [FE_PSE_PORT_GDM3] = 6, +- [FE_PSE_PORT_PPE1] = 4, +- [FE_PSE_PORT_CDM2] = 6, +- [FE_PSE_PORT_CDM3] = 8, +- [FE_PSE_PORT_CDM4] = 10, +- [FE_PSE_PORT_PPE2] = 4, +- [FE_PSE_PORT_GDM4] = 2, +- [FE_PSE_PORT_CDM5] = 2, +- }; +- u32 all_rsv; +- int q; +- +- all_rsv = airoha_fe_get_pse_all_rsv(eth); +- /* hw misses PPE2 oq rsv */ +- all_rsv += PSE_RSV_PAGES * pse_port_num_queues[FE_PSE_PORT_PPE2]; +- airoha_fe_set(eth, REG_FE_PSE_BUF_SET, all_rsv); +- +- /* CMD1 */ +- for (q = 0; q < pse_port_num_queues[FE_PSE_PORT_CDM1]; q++) +- airoha_fe_set_pse_oq_rsv(eth, FE_PSE_PORT_CDM1, q, +- PSE_QUEUE_RSV_PAGES); +- /* GMD1 */ +- for (q = 0; q < pse_port_num_queues[FE_PSE_PORT_GDM1]; q++) +- airoha_fe_set_pse_oq_rsv(eth, FE_PSE_PORT_GDM1, q, +- PSE_QUEUE_RSV_PAGES); +- /* GMD2 */ +- for (q = 6; q < pse_port_num_queues[FE_PSE_PORT_GDM2]; q++) +- airoha_fe_set_pse_oq_rsv(eth, FE_PSE_PORT_GDM2, q, 0); +- /* GMD3 */ +- for (q = 0; q < pse_port_num_queues[FE_PSE_PORT_GDM3]; q++) +- airoha_fe_set_pse_oq_rsv(eth, FE_PSE_PORT_GDM3, q, +- PSE_QUEUE_RSV_PAGES); +- /* PPE1 */ +- for (q = 0; q < pse_port_num_queues[FE_PSE_PORT_PPE1]; q++) { +- if (q < pse_port_num_queues[FE_PSE_PORT_PPE1]) +- airoha_fe_set_pse_oq_rsv(eth, FE_PSE_PORT_PPE1, q, +- PSE_QUEUE_RSV_PAGES); +- else +- airoha_fe_set_pse_oq_rsv(eth, FE_PSE_PORT_PPE1, q, 0); +- } +- /* CDM2 */ +- for (q = 0; q < pse_port_num_queues[FE_PSE_PORT_CDM2]; q++) +- airoha_fe_set_pse_oq_rsv(eth, FE_PSE_PORT_CDM2, q, +- PSE_QUEUE_RSV_PAGES); +- /* CDM3 */ +- for (q = 0; q < pse_port_num_queues[FE_PSE_PORT_CDM3] - 1; q++) +- airoha_fe_set_pse_oq_rsv(eth, FE_PSE_PORT_CDM3, q, 0); +- /* CDM4 */ +- for (q = 4; q < pse_port_num_queues[FE_PSE_PORT_CDM4]; q++) +- airoha_fe_set_pse_oq_rsv(eth, FE_PSE_PORT_CDM4, q, +- PSE_QUEUE_RSV_PAGES); +- /* PPE2 */ +- for (q = 0; q < pse_port_num_queues[FE_PSE_PORT_PPE2]; q++) { +- if (q < pse_port_num_queues[FE_PSE_PORT_PPE2] / 2) +- airoha_fe_set_pse_oq_rsv(eth, FE_PSE_PORT_PPE2, q, +- PSE_QUEUE_RSV_PAGES); +- else +- airoha_fe_set_pse_oq_rsv(eth, FE_PSE_PORT_PPE2, q, 0); +- } +- /* GMD4 */ +- for (q = 0; q < pse_port_num_queues[FE_PSE_PORT_GDM4]; q++) +- airoha_fe_set_pse_oq_rsv(eth, FE_PSE_PORT_GDM4, q, +- PSE_QUEUE_RSV_PAGES); +- /* CDM5 */ +- for (q = 0; q < pse_port_num_queues[FE_PSE_PORT_CDM5]; q++) +- airoha_fe_set_pse_oq_rsv(eth, FE_PSE_PORT_CDM5, q, +- PSE_QUEUE_RSV_PAGES); +-} +- +-static int airoha_fe_mc_vlan_clear(struct airoha_eth *eth) +-{ +- int i; +- +- for (i = 0; i < AIROHA_FE_MC_MAX_VLAN_TABLE; i++) { +- int err, j; +- u32 val; +- +- airoha_fe_wr(eth, REG_MC_VLAN_DATA, 0x0); +- +- val = FIELD_PREP(MC_VLAN_CFG_TABLE_ID_MASK, i) | +- MC_VLAN_CFG_TABLE_SEL_MASK | MC_VLAN_CFG_RW_MASK; +- airoha_fe_wr(eth, REG_MC_VLAN_CFG, val); +- err = read_poll_timeout(airoha_fe_rr, val, +- val & MC_VLAN_CFG_CMD_DONE_MASK, +- USEC_PER_MSEC, 5 * USEC_PER_MSEC, +- false, eth, REG_MC_VLAN_CFG); +- if (err) +- return err; +- +- for (j = 0; j < AIROHA_FE_MC_MAX_VLAN_PORT; j++) { +- airoha_fe_wr(eth, REG_MC_VLAN_DATA, 0x0); +- +- val = FIELD_PREP(MC_VLAN_CFG_TABLE_ID_MASK, i) | +- FIELD_PREP(MC_VLAN_CFG_PORT_ID_MASK, j) | +- MC_VLAN_CFG_RW_MASK; +- airoha_fe_wr(eth, REG_MC_VLAN_CFG, val); +- err = read_poll_timeout(airoha_fe_rr, val, +- val & MC_VLAN_CFG_CMD_DONE_MASK, +- USEC_PER_MSEC, +- 5 * USEC_PER_MSEC, false, eth, +- REG_MC_VLAN_CFG); +- if (err) +- return err; +- } +- } +- +- return 0; +-} +- +-static void airoha_fe_crsn_qsel_init(struct airoha_eth *eth) +-{ +- /* CDM1_CRSN_QSEL */ +- airoha_fe_rmw(eth, REG_CDM1_CRSN_QSEL(CRSN_22 >> 2), +- CDM1_CRSN_QSEL_REASON_MASK(CRSN_22), +- FIELD_PREP(CDM1_CRSN_QSEL_REASON_MASK(CRSN_22), +- CDM_CRSN_QSEL_Q1)); +- airoha_fe_rmw(eth, REG_CDM1_CRSN_QSEL(CRSN_08 >> 2), +- CDM1_CRSN_QSEL_REASON_MASK(CRSN_08), +- FIELD_PREP(CDM1_CRSN_QSEL_REASON_MASK(CRSN_08), +- CDM_CRSN_QSEL_Q1)); +- airoha_fe_rmw(eth, REG_CDM1_CRSN_QSEL(CRSN_21 >> 2), +- CDM1_CRSN_QSEL_REASON_MASK(CRSN_21), +- FIELD_PREP(CDM1_CRSN_QSEL_REASON_MASK(CRSN_21), +- CDM_CRSN_QSEL_Q1)); +- airoha_fe_rmw(eth, REG_CDM1_CRSN_QSEL(CRSN_24 >> 2), +- CDM1_CRSN_QSEL_REASON_MASK(CRSN_24), +- FIELD_PREP(CDM1_CRSN_QSEL_REASON_MASK(CRSN_24), +- CDM_CRSN_QSEL_Q6)); +- airoha_fe_rmw(eth, REG_CDM1_CRSN_QSEL(CRSN_25 >> 2), +- CDM1_CRSN_QSEL_REASON_MASK(CRSN_25), +- FIELD_PREP(CDM1_CRSN_QSEL_REASON_MASK(CRSN_25), +- CDM_CRSN_QSEL_Q1)); +- /* CDM2_CRSN_QSEL */ +- airoha_fe_rmw(eth, REG_CDM2_CRSN_QSEL(CRSN_08 >> 2), +- CDM2_CRSN_QSEL_REASON_MASK(CRSN_08), +- FIELD_PREP(CDM2_CRSN_QSEL_REASON_MASK(CRSN_08), +- CDM_CRSN_QSEL_Q1)); +- airoha_fe_rmw(eth, REG_CDM2_CRSN_QSEL(CRSN_21 >> 2), +- CDM2_CRSN_QSEL_REASON_MASK(CRSN_21), +- FIELD_PREP(CDM2_CRSN_QSEL_REASON_MASK(CRSN_21), +- CDM_CRSN_QSEL_Q1)); +- airoha_fe_rmw(eth, REG_CDM2_CRSN_QSEL(CRSN_22 >> 2), +- CDM2_CRSN_QSEL_REASON_MASK(CRSN_22), +- FIELD_PREP(CDM2_CRSN_QSEL_REASON_MASK(CRSN_22), +- CDM_CRSN_QSEL_Q1)); +- airoha_fe_rmw(eth, REG_CDM2_CRSN_QSEL(CRSN_24 >> 2), +- CDM2_CRSN_QSEL_REASON_MASK(CRSN_24), +- FIELD_PREP(CDM2_CRSN_QSEL_REASON_MASK(CRSN_24), +- CDM_CRSN_QSEL_Q6)); +- airoha_fe_rmw(eth, REG_CDM2_CRSN_QSEL(CRSN_25 >> 2), +- CDM2_CRSN_QSEL_REASON_MASK(CRSN_25), +- FIELD_PREP(CDM2_CRSN_QSEL_REASON_MASK(CRSN_25), +- CDM_CRSN_QSEL_Q1)); +-} +- +-static int airoha_fe_init(struct airoha_eth *eth) +-{ +- airoha_fe_maccr_init(eth); +- +- /* PSE IQ reserve */ +- airoha_fe_rmw(eth, REG_PSE_IQ_REV1, PSE_IQ_RES1_P2_MASK, +- FIELD_PREP(PSE_IQ_RES1_P2_MASK, 0x10)); +- airoha_fe_rmw(eth, REG_PSE_IQ_REV2, +- PSE_IQ_RES2_P5_MASK | PSE_IQ_RES2_P4_MASK, +- FIELD_PREP(PSE_IQ_RES2_P5_MASK, 0x40) | +- FIELD_PREP(PSE_IQ_RES2_P4_MASK, 0x34)); +- +- /* enable FE copy engine for MC/KA/DPI */ +- airoha_fe_wr(eth, REG_FE_PCE_CFG, +- PCE_DPI_EN_MASK | PCE_KA_EN_MASK | PCE_MC_EN_MASK); +- /* set vip queue selection to ring 1 */ +- airoha_fe_rmw(eth, REG_CDM1_FWD_CFG, CDM1_VIP_QSEL_MASK, +- FIELD_PREP(CDM1_VIP_QSEL_MASK, 0x4)); +- airoha_fe_rmw(eth, REG_CDM2_FWD_CFG, CDM2_VIP_QSEL_MASK, +- FIELD_PREP(CDM2_VIP_QSEL_MASK, 0x4)); +- /* set GDM4 source interface offset to 8 */ +- airoha_fe_rmw(eth, REG_GDM4_SRC_PORT_SET, +- GDM4_SPORT_OFF2_MASK | +- GDM4_SPORT_OFF1_MASK | +- GDM4_SPORT_OFF0_MASK, +- FIELD_PREP(GDM4_SPORT_OFF2_MASK, 8) | +- FIELD_PREP(GDM4_SPORT_OFF1_MASK, 8) | +- FIELD_PREP(GDM4_SPORT_OFF0_MASK, 8)); +- +- /* set PSE Page as 128B */ +- airoha_fe_rmw(eth, REG_FE_DMA_GLO_CFG, +- FE_DMA_GLO_L2_SPACE_MASK | FE_DMA_GLO_PG_SZ_MASK, +- FIELD_PREP(FE_DMA_GLO_L2_SPACE_MASK, 2) | +- FE_DMA_GLO_PG_SZ_MASK); +- airoha_fe_wr(eth, REG_FE_RST_GLO_CFG, +- FE_RST_CORE_MASK | FE_RST_GDM3_MBI_ARB_MASK | +- FE_RST_GDM4_MBI_ARB_MASK); +- usleep_range(1000, 2000); +- +- /* connect RxRing1 and RxRing15 to PSE Port0 OQ-1 +- * connect other rings to PSE Port0 OQ-0 +- */ +- airoha_fe_wr(eth, REG_FE_CDM1_OQ_MAP0, BIT(4)); +- airoha_fe_wr(eth, REG_FE_CDM1_OQ_MAP1, BIT(28)); +- airoha_fe_wr(eth, REG_FE_CDM1_OQ_MAP2, BIT(4)); +- airoha_fe_wr(eth, REG_FE_CDM1_OQ_MAP3, BIT(28)); +- +- airoha_fe_vip_setup(eth); +- airoha_fe_pse_ports_init(eth); +- +- airoha_fe_set(eth, REG_GDM_MISC_CFG, +- GDM2_RDM_ACK_WAIT_PREF_MASK | +- GDM2_CHN_VLD_MODE_MASK); +- airoha_fe_rmw(eth, REG_CDM2_FWD_CFG, CDM2_OAM_QSEL_MASK, +- FIELD_PREP(CDM2_OAM_QSEL_MASK, 15)); +- +- /* init fragment and assemble Force Port */ +- /* NPU Core-3, NPU Bridge Channel-3 */ +- airoha_fe_rmw(eth, REG_IP_FRAG_FP, +- IP_FRAGMENT_PORT_MASK | IP_FRAGMENT_NBQ_MASK, +- FIELD_PREP(IP_FRAGMENT_PORT_MASK, 6) | +- FIELD_PREP(IP_FRAGMENT_NBQ_MASK, 3)); +- /* QDMA LAN, RX Ring-22 */ +- airoha_fe_rmw(eth, REG_IP_FRAG_FP, +- IP_ASSEMBLE_PORT_MASK | IP_ASSEMBLE_NBQ_MASK, +- FIELD_PREP(IP_ASSEMBLE_PORT_MASK, 0) | +- FIELD_PREP(IP_ASSEMBLE_NBQ_MASK, 22)); +- +- airoha_fe_set(eth, REG_GDM3_FWD_CFG, GDM3_PAD_EN_MASK); +- airoha_fe_set(eth, REG_GDM4_FWD_CFG, GDM4_PAD_EN_MASK); +- +- airoha_fe_crsn_qsel_init(eth); +- +- airoha_fe_clear(eth, REG_FE_CPORT_CFG, FE_CPORT_QUEUE_XFC_MASK); +- airoha_fe_set(eth, REG_FE_CPORT_CFG, FE_CPORT_PORT_XFC_MASK); +- +- /* default aging mode for mbi unlock issue */ +- airoha_fe_rmw(eth, REG_GDM2_CHN_RLS, +- MBI_RX_AGE_SEL_MASK | MBI_TX_AGE_SEL_MASK, +- FIELD_PREP(MBI_RX_AGE_SEL_MASK, 3) | +- FIELD_PREP(MBI_TX_AGE_SEL_MASK, 3)); +- +- /* disable IFC by default */ +- airoha_fe_clear(eth, REG_FE_CSR_IFC_CFG, FE_IFC_EN_MASK); +- +- /* enable 1:N vlan action, init vlan table */ +- airoha_fe_set(eth, REG_MC_VLAN_EN, MC_VLAN_EN_MASK); +- +- return airoha_fe_mc_vlan_clear(eth); +-} +- +-static int airoha_qdma_fill_rx_queue(struct airoha_queue *q) +-{ +- enum dma_data_direction dir = page_pool_get_dma_dir(q->page_pool); +- struct airoha_qdma *qdma = q->qdma; +- struct airoha_eth *eth = qdma->eth; +- int qid = q - &qdma->q_rx[0]; +- int nframes = 0; +- +- while (q->queued < q->ndesc - 1) { +- struct airoha_queue_entry *e = &q->entry[q->head]; +- struct airoha_qdma_desc *desc = &q->desc[q->head]; +- struct page *page; +- int offset; +- u32 val; +- +- page = page_pool_dev_alloc_frag(q->page_pool, &offset, +- q->buf_size); +- if (!page) +- break; +- +- q->head = (q->head + 1) % q->ndesc; +- q->queued++; +- nframes++; +- +- e->buf = page_address(page) + offset; +- e->dma_addr = page_pool_get_dma_addr(page) + offset; +- e->dma_len = SKB_WITH_OVERHEAD(q->buf_size); +- +- dma_sync_single_for_device(eth->dev, e->dma_addr, e->dma_len, +- dir); +- +- val = FIELD_PREP(QDMA_DESC_LEN_MASK, e->dma_len); +- WRITE_ONCE(desc->ctrl, cpu_to_le32(val)); +- WRITE_ONCE(desc->addr, cpu_to_le32(e->dma_addr)); +- val = FIELD_PREP(QDMA_DESC_NEXT_ID_MASK, q->head); +- WRITE_ONCE(desc->data, cpu_to_le32(val)); +- WRITE_ONCE(desc->msg0, 0); +- WRITE_ONCE(desc->msg1, 0); +- WRITE_ONCE(desc->msg2, 0); +- WRITE_ONCE(desc->msg3, 0); +- +- airoha_qdma_rmw(qdma, REG_RX_CPU_IDX(qid), +- RX_RING_CPU_IDX_MASK, +- FIELD_PREP(RX_RING_CPU_IDX_MASK, q->head)); +- } +- +- return nframes; +-} +- +-static int airoha_qdma_get_gdm_port(struct airoha_eth *eth, +- struct airoha_qdma_desc *desc) +-{ +- u32 port, sport, msg1 = le32_to_cpu(desc->msg1); +- +- sport = FIELD_GET(QDMA_ETH_RXMSG_SPORT_MASK, msg1); +- switch (sport) { +- case 0x10 ... 0x13: +- port = 0; +- break; +- case 0x2 ... 0x4: +- port = sport - 1; +- break; +- default: +- return -EINVAL; +- } +- +- return port >= ARRAY_SIZE(eth->ports) ? -EINVAL : port; +-} +- +-static int airoha_qdma_rx_process(struct airoha_queue *q, int budget) +-{ +- enum dma_data_direction dir = page_pool_get_dma_dir(q->page_pool); +- struct airoha_qdma *qdma = q->qdma; +- struct airoha_eth *eth = qdma->eth; +- int qid = q - &qdma->q_rx[0]; +- int done = 0; +- +- while (done < budget) { +- struct airoha_queue_entry *e = &q->entry[q->tail]; +- struct airoha_qdma_desc *desc = &q->desc[q->tail]; +- dma_addr_t dma_addr = le32_to_cpu(desc->addr); +- u32 desc_ctrl = le32_to_cpu(desc->ctrl); +- struct sk_buff *skb; +- int len, p; +- +- if (!(desc_ctrl & QDMA_DESC_DONE_MASK)) +- break; +- +- if (!dma_addr) +- break; +- +- len = FIELD_GET(QDMA_DESC_LEN_MASK, desc_ctrl); +- if (!len) +- break; +- +- q->tail = (q->tail + 1) % q->ndesc; +- q->queued--; +- +- dma_sync_single_for_cpu(eth->dev, dma_addr, +- SKB_WITH_OVERHEAD(q->buf_size), dir); +- +- p = airoha_qdma_get_gdm_port(eth, desc); +- if (p < 0 || !eth->ports[p]) { +- page_pool_put_full_page(q->page_pool, +- virt_to_head_page(e->buf), +- true); +- continue; +- } +- +- skb = napi_build_skb(e->buf, q->buf_size); +- if (!skb) { +- page_pool_put_full_page(q->page_pool, +- virt_to_head_page(e->buf), +- true); +- break; +- } +- +- skb_reserve(skb, 2); +- __skb_put(skb, len); +- skb_mark_for_recycle(skb); +- skb->dev = eth->ports[p]->dev; +- skb->protocol = eth_type_trans(skb, skb->dev); +- skb->ip_summed = CHECKSUM_UNNECESSARY; +- skb_record_rx_queue(skb, qid); +- napi_gro_receive(&q->napi, skb); +- +- done++; +- } +- airoha_qdma_fill_rx_queue(q); +- +- return done; +-} +- +-static int airoha_qdma_rx_napi_poll(struct napi_struct *napi, int budget) +-{ +- struct airoha_queue *q = container_of(napi, struct airoha_queue, napi); +- int cur, done = 0; +- +- do { +- cur = airoha_qdma_rx_process(q, budget - done); +- done += cur; +- } while (cur && done < budget); +- +- if (done < budget && napi_complete(napi)) +- airoha_qdma_irq_enable(q->qdma, QDMA_INT_REG_IDX1, +- RX_DONE_INT_MASK); +- +- return done; +-} +- +-static int airoha_qdma_init_rx_queue(struct airoha_queue *q, +- struct airoha_qdma *qdma, int ndesc) +-{ +- const struct page_pool_params pp_params = { +- .order = 0, +- .pool_size = 256, +- .flags = PP_FLAG_DMA_MAP | PP_FLAG_DMA_SYNC_DEV | +- PP_FLAG_PAGE_FRAG, +- .dma_dir = DMA_FROM_DEVICE, +- .max_len = PAGE_SIZE, +- .nid = NUMA_NO_NODE, +- .dev = qdma->eth->dev, +- .napi = &q->napi, +- }; +- struct airoha_eth *eth = qdma->eth; +- int qid = q - &qdma->q_rx[0], thr; +- dma_addr_t dma_addr; +- +- q->buf_size = PAGE_SIZE / 2; +- q->ndesc = ndesc; +- q->qdma = qdma; +- +- q->entry = devm_kzalloc(eth->dev, q->ndesc * sizeof(*q->entry), +- GFP_KERNEL); +- if (!q->entry) +- return -ENOMEM; +- +- q->page_pool = page_pool_create(&pp_params); +- if (IS_ERR(q->page_pool)) { +- int err = PTR_ERR(q->page_pool); +- +- q->page_pool = NULL; +- return err; +- } +- +- q->desc = dmam_alloc_coherent(eth->dev, q->ndesc * sizeof(*q->desc), +- &dma_addr, GFP_KERNEL); +- if (!q->desc) +- return -ENOMEM; +- +- netif_napi_add(eth->napi_dev, &q->napi, airoha_qdma_rx_napi_poll); +- +- airoha_qdma_wr(qdma, REG_RX_RING_BASE(qid), dma_addr); +- airoha_qdma_rmw(qdma, REG_RX_RING_SIZE(qid), +- RX_RING_SIZE_MASK, +- FIELD_PREP(RX_RING_SIZE_MASK, ndesc)); +- +- thr = clamp(ndesc >> 3, 1, 32); +- airoha_qdma_rmw(qdma, REG_RX_RING_SIZE(qid), RX_RING_THR_MASK, +- FIELD_PREP(RX_RING_THR_MASK, thr)); +- airoha_qdma_rmw(qdma, REG_RX_DMA_IDX(qid), RX_RING_DMA_IDX_MASK, +- FIELD_PREP(RX_RING_DMA_IDX_MASK, q->head)); +- +- airoha_qdma_fill_rx_queue(q); +- +- return 0; +-} +- +-static void airoha_qdma_cleanup_rx_queue(struct airoha_queue *q) +-{ +- struct airoha_eth *eth = q->qdma->eth; +- +- while (q->queued) { +- struct airoha_queue_entry *e = &q->entry[q->tail]; +- struct page *page = virt_to_head_page(e->buf); +- +- dma_sync_single_for_cpu(eth->dev, e->dma_addr, e->dma_len, +- page_pool_get_dma_dir(q->page_pool)); +- page_pool_put_full_page(q->page_pool, page, false); +- q->tail = (q->tail + 1) % q->ndesc; +- q->queued--; +- } +-} +- +-static int airoha_qdma_init_rx(struct airoha_qdma *qdma) +-{ +- int i; +- +- for (i = 0; i < ARRAY_SIZE(qdma->q_rx); i++) { +- int err; +- +- if (!(RX_DONE_INT_MASK & BIT(i))) { +- /* rx-queue not binded to irq */ +- continue; +- } +- +- err = airoha_qdma_init_rx_queue(&qdma->q_rx[i], qdma, +- RX_DSCP_NUM(i)); +- if (err) +- return err; +- } +- +- return 0; +-} +- +-static int airoha_qdma_tx_napi_poll(struct napi_struct *napi, int budget) +-{ +- struct airoha_tx_irq_queue *irq_q; +- int id, done = 0, irq_queued; +- struct airoha_qdma *qdma; +- struct airoha_eth *eth; +- u32 status, head; +- +- irq_q = container_of(napi, struct airoha_tx_irq_queue, napi); +- qdma = irq_q->qdma; +- id = irq_q - &qdma->q_tx_irq[0]; +- eth = qdma->eth; +- +- status = airoha_qdma_rr(qdma, REG_IRQ_STATUS(id)); +- head = FIELD_GET(IRQ_HEAD_IDX_MASK, status); +- head = head % irq_q->size; +- irq_queued = FIELD_GET(IRQ_ENTRY_LEN_MASK, status); +- +- while (irq_queued > 0 && done < budget) { +- u32 qid, val = irq_q->q[head]; +- struct airoha_qdma_desc *desc; +- struct airoha_queue_entry *e; +- struct airoha_queue *q; +- u32 index, desc_ctrl; +- struct sk_buff *skb; +- +- if (val == 0xff) +- break; +- +- irq_q->q[head] = 0xff; /* mark as done */ +- head = (head + 1) % irq_q->size; +- irq_queued--; +- done++; +- +- qid = FIELD_GET(IRQ_RING_IDX_MASK, val); +- if (qid >= ARRAY_SIZE(qdma->q_tx)) +- continue; +- +- q = &qdma->q_tx[qid]; +- if (!q->ndesc) +- continue; +- +- index = FIELD_GET(IRQ_DESC_IDX_MASK, val); +- if (index >= q->ndesc) +- continue; +- +- spin_lock_bh(&q->lock); +- +- if (!q->queued) +- goto unlock; +- +- desc = &q->desc[index]; +- desc_ctrl = le32_to_cpu(desc->ctrl); +- +- if (!(desc_ctrl & QDMA_DESC_DONE_MASK) && +- !(desc_ctrl & QDMA_DESC_DROP_MASK)) +- goto unlock; +- +- e = &q->entry[index]; +- skb = e->skb; +- +- dma_unmap_single(eth->dev, e->dma_addr, e->dma_len, +- DMA_TO_DEVICE); +- memset(e, 0, sizeof(*e)); +- WRITE_ONCE(desc->msg0, 0); +- WRITE_ONCE(desc->msg1, 0); +- q->queued--; +- +- /* completion ring can report out-of-order indexes if hw QoS +- * is enabled and packets with different priority are queued +- * to same DMA ring. Take into account possible out-of-order +- * reports incrementing DMA ring tail pointer +- */ +- while (q->tail != q->head && !q->entry[q->tail].dma_addr) +- q->tail = (q->tail + 1) % q->ndesc; +- +- if (skb) { +- u16 queue = skb_get_queue_mapping(skb); +- struct netdev_queue *txq; +- +- txq = netdev_get_tx_queue(skb->dev, queue); +- netdev_tx_completed_queue(txq, 1, skb->len); +- if (netif_tx_queue_stopped(txq) && +- q->ndesc - q->queued >= q->free_thr) +- netif_tx_wake_queue(txq); +- +- dev_kfree_skb_any(skb); +- } +-unlock: +- spin_unlock_bh(&q->lock); +- } +- +- if (done) { +- int i, len = done >> 7; +- +- for (i = 0; i < len; i++) +- airoha_qdma_rmw(qdma, REG_IRQ_CLEAR_LEN(id), +- IRQ_CLEAR_LEN_MASK, 0x80); +- airoha_qdma_rmw(qdma, REG_IRQ_CLEAR_LEN(id), +- IRQ_CLEAR_LEN_MASK, (done & 0x7f)); +- } +- +- if (done < budget && napi_complete(napi)) +- airoha_qdma_irq_enable(qdma, QDMA_INT_REG_IDX0, +- TX_DONE_INT_MASK(id)); +- +- return done; +-} +- +-static int airoha_qdma_init_tx_queue(struct airoha_queue *q, +- struct airoha_qdma *qdma, int size) +-{ +- struct airoha_eth *eth = qdma->eth; +- int i, qid = q - &qdma->q_tx[0]; +- dma_addr_t dma_addr; +- +- spin_lock_init(&q->lock); +- q->ndesc = size; +- q->qdma = qdma; +- q->free_thr = 1 + MAX_SKB_FRAGS; +- +- q->entry = devm_kzalloc(eth->dev, q->ndesc * sizeof(*q->entry), +- GFP_KERNEL); +- if (!q->entry) +- return -ENOMEM; +- +- q->desc = dmam_alloc_coherent(eth->dev, q->ndesc * sizeof(*q->desc), +- &dma_addr, GFP_KERNEL); +- if (!q->desc) +- return -ENOMEM; +- +- for (i = 0; i < q->ndesc; i++) { +- u32 val; +- +- val = FIELD_PREP(QDMA_DESC_DONE_MASK, 1); +- WRITE_ONCE(q->desc[i].ctrl, cpu_to_le32(val)); +- } +- +- /* xmit ring drop default setting */ +- airoha_qdma_set(qdma, REG_TX_RING_BLOCKING(qid), +- TX_RING_IRQ_BLOCKING_TX_DROP_EN_MASK); +- +- airoha_qdma_wr(qdma, REG_TX_RING_BASE(qid), dma_addr); +- airoha_qdma_rmw(qdma, REG_TX_CPU_IDX(qid), TX_RING_CPU_IDX_MASK, +- FIELD_PREP(TX_RING_CPU_IDX_MASK, q->head)); +- airoha_qdma_rmw(qdma, REG_TX_DMA_IDX(qid), TX_RING_DMA_IDX_MASK, +- FIELD_PREP(TX_RING_DMA_IDX_MASK, q->head)); +- +- return 0; +-} +- +-static int airoha_qdma_tx_irq_init(struct airoha_tx_irq_queue *irq_q, +- struct airoha_qdma *qdma, int size) +-{ +- int id = irq_q - &qdma->q_tx_irq[0]; +- struct airoha_eth *eth = qdma->eth; +- dma_addr_t dma_addr; +- +- netif_napi_add_tx(eth->napi_dev, &irq_q->napi, +- airoha_qdma_tx_napi_poll); +- irq_q->q = dmam_alloc_coherent(eth->dev, size * sizeof(u32), +- &dma_addr, GFP_KERNEL); +- if (!irq_q->q) +- return -ENOMEM; +- +- memset(irq_q->q, 0xff, size * sizeof(u32)); +- irq_q->size = size; +- irq_q->qdma = qdma; +- +- airoha_qdma_wr(qdma, REG_TX_IRQ_BASE(id), dma_addr); +- airoha_qdma_rmw(qdma, REG_TX_IRQ_CFG(id), TX_IRQ_DEPTH_MASK, +- FIELD_PREP(TX_IRQ_DEPTH_MASK, size)); +- airoha_qdma_rmw(qdma, REG_TX_IRQ_CFG(id), TX_IRQ_THR_MASK, +- FIELD_PREP(TX_IRQ_THR_MASK, 1)); +- +- return 0; +-} +- +-static int airoha_qdma_init_tx(struct airoha_qdma *qdma) +-{ +- int i, err; +- +- for (i = 0; i < ARRAY_SIZE(qdma->q_tx_irq); i++) { +- err = airoha_qdma_tx_irq_init(&qdma->q_tx_irq[i], qdma, +- IRQ_QUEUE_LEN(i)); +- if (err) +- return err; +- } +- +- for (i = 0; i < ARRAY_SIZE(qdma->q_tx); i++) { +- err = airoha_qdma_init_tx_queue(&qdma->q_tx[i], qdma, +- TX_DSCP_NUM); +- if (err) +- return err; +- } +- +- return 0; +-} +- +-static void airoha_qdma_cleanup_tx_queue(struct airoha_queue *q) +-{ +- struct airoha_eth *eth = q->qdma->eth; +- +- spin_lock_bh(&q->lock); +- while (q->queued) { +- struct airoha_queue_entry *e = &q->entry[q->tail]; +- +- dma_unmap_single(eth->dev, e->dma_addr, e->dma_len, +- DMA_TO_DEVICE); +- dev_kfree_skb_any(e->skb); +- e->skb = NULL; +- +- q->tail = (q->tail + 1) % q->ndesc; +- q->queued--; +- } +- spin_unlock_bh(&q->lock); +-} +- +-static int airoha_qdma_init_hfwd_queues(struct airoha_qdma *qdma) +-{ +- struct airoha_eth *eth = qdma->eth; +- dma_addr_t dma_addr; +- u32 status; +- int size; +- +- size = HW_DSCP_NUM * sizeof(struct airoha_qdma_fwd_desc); +- qdma->hfwd.desc = dmam_alloc_coherent(eth->dev, size, &dma_addr, +- GFP_KERNEL); +- if (!qdma->hfwd.desc) +- return -ENOMEM; +- +- airoha_qdma_wr(qdma, REG_FWD_DSCP_BASE, dma_addr); +- +- size = AIROHA_MAX_PACKET_SIZE * HW_DSCP_NUM; +- qdma->hfwd.q = dmam_alloc_coherent(eth->dev, size, &dma_addr, +- GFP_KERNEL); +- if (!qdma->hfwd.q) +- return -ENOMEM; +- +- airoha_qdma_wr(qdma, REG_FWD_BUF_BASE, dma_addr); +- +- airoha_qdma_rmw(qdma, REG_HW_FWD_DSCP_CFG, +- HW_FWD_DSCP_PAYLOAD_SIZE_MASK, +- FIELD_PREP(HW_FWD_DSCP_PAYLOAD_SIZE_MASK, 0)); +- airoha_qdma_rmw(qdma, REG_FWD_DSCP_LOW_THR, FWD_DSCP_LOW_THR_MASK, +- FIELD_PREP(FWD_DSCP_LOW_THR_MASK, 128)); +- airoha_qdma_rmw(qdma, REG_LMGR_INIT_CFG, +- LMGR_INIT_START | LMGR_SRAM_MODE_MASK | +- HW_FWD_DESC_NUM_MASK, +- FIELD_PREP(HW_FWD_DESC_NUM_MASK, HW_DSCP_NUM) | +- LMGR_INIT_START); +- +- return read_poll_timeout(airoha_qdma_rr, status, +- !(status & LMGR_INIT_START), USEC_PER_MSEC, +- 30 * USEC_PER_MSEC, true, qdma, +- REG_LMGR_INIT_CFG); +-} +- +-static void airoha_qdma_init_qos(struct airoha_qdma *qdma) +-{ +- airoha_qdma_clear(qdma, REG_TXWRR_MODE_CFG, TWRR_WEIGHT_SCALE_MASK); +- airoha_qdma_set(qdma, REG_TXWRR_MODE_CFG, TWRR_WEIGHT_BASE_MASK); +- +- airoha_qdma_clear(qdma, REG_PSE_BUF_USAGE_CFG, +- PSE_BUF_ESTIMATE_EN_MASK); +- +- airoha_qdma_set(qdma, REG_EGRESS_RATE_METER_CFG, +- EGRESS_RATE_METER_EN_MASK | +- EGRESS_RATE_METER_EQ_RATE_EN_MASK); +- /* 2047us x 31 = 63.457ms */ +- airoha_qdma_rmw(qdma, REG_EGRESS_RATE_METER_CFG, +- EGRESS_RATE_METER_WINDOW_SZ_MASK, +- FIELD_PREP(EGRESS_RATE_METER_WINDOW_SZ_MASK, 0x1f)); +- airoha_qdma_rmw(qdma, REG_EGRESS_RATE_METER_CFG, +- EGRESS_RATE_METER_TIMESLICE_MASK, +- FIELD_PREP(EGRESS_RATE_METER_TIMESLICE_MASK, 0x7ff)); +- +- /* ratelimit init */ +- airoha_qdma_set(qdma, REG_GLB_TRTCM_CFG, GLB_TRTCM_EN_MASK); +- /* fast-tick 25us */ +- airoha_qdma_rmw(qdma, REG_GLB_TRTCM_CFG, GLB_FAST_TICK_MASK, +- FIELD_PREP(GLB_FAST_TICK_MASK, 25)); +- airoha_qdma_rmw(qdma, REG_GLB_TRTCM_CFG, GLB_SLOW_TICK_RATIO_MASK, +- FIELD_PREP(GLB_SLOW_TICK_RATIO_MASK, 40)); +- +- airoha_qdma_set(qdma, REG_EGRESS_TRTCM_CFG, EGRESS_TRTCM_EN_MASK); +- airoha_qdma_rmw(qdma, REG_EGRESS_TRTCM_CFG, EGRESS_FAST_TICK_MASK, +- FIELD_PREP(EGRESS_FAST_TICK_MASK, 25)); +- airoha_qdma_rmw(qdma, REG_EGRESS_TRTCM_CFG, +- EGRESS_SLOW_TICK_RATIO_MASK, +- FIELD_PREP(EGRESS_SLOW_TICK_RATIO_MASK, 40)); +- +- airoha_qdma_set(qdma, REG_INGRESS_TRTCM_CFG, INGRESS_TRTCM_EN_MASK); +- airoha_qdma_clear(qdma, REG_INGRESS_TRTCM_CFG, +- INGRESS_TRTCM_MODE_MASK); +- airoha_qdma_rmw(qdma, REG_INGRESS_TRTCM_CFG, INGRESS_FAST_TICK_MASK, +- FIELD_PREP(INGRESS_FAST_TICK_MASK, 125)); +- airoha_qdma_rmw(qdma, REG_INGRESS_TRTCM_CFG, +- INGRESS_SLOW_TICK_RATIO_MASK, +- FIELD_PREP(INGRESS_SLOW_TICK_RATIO_MASK, 8)); +- +- airoha_qdma_set(qdma, REG_SLA_TRTCM_CFG, SLA_TRTCM_EN_MASK); +- airoha_qdma_rmw(qdma, REG_SLA_TRTCM_CFG, SLA_FAST_TICK_MASK, +- FIELD_PREP(SLA_FAST_TICK_MASK, 25)); +- airoha_qdma_rmw(qdma, REG_SLA_TRTCM_CFG, SLA_SLOW_TICK_RATIO_MASK, +- FIELD_PREP(SLA_SLOW_TICK_RATIO_MASK, 40)); +-} +- +-static void airoha_qdma_init_qos_stats(struct airoha_qdma *qdma) +-{ +- int i; +- +- for (i = 0; i < AIROHA_NUM_QOS_CHANNELS; i++) { +- /* Tx-cpu transferred count */ +- airoha_qdma_wr(qdma, REG_CNTR_VAL(i << 1), 0); +- airoha_qdma_wr(qdma, REG_CNTR_CFG(i << 1), +- CNTR_EN_MASK | CNTR_ALL_QUEUE_EN_MASK | +- CNTR_ALL_DSCP_RING_EN_MASK | +- FIELD_PREP(CNTR_CHAN_MASK, i)); +- /* Tx-fwd transferred count */ +- airoha_qdma_wr(qdma, REG_CNTR_VAL((i << 1) + 1), 0); +- airoha_qdma_wr(qdma, REG_CNTR_CFG(i << 1), +- CNTR_EN_MASK | CNTR_ALL_QUEUE_EN_MASK | +- CNTR_ALL_DSCP_RING_EN_MASK | +- FIELD_PREP(CNTR_SRC_MASK, 1) | +- FIELD_PREP(CNTR_CHAN_MASK, i)); +- } +-} +- +-static int airoha_qdma_hw_init(struct airoha_qdma *qdma) +-{ +- int i; +- +- /* clear pending irqs */ +- for (i = 0; i < ARRAY_SIZE(qdma->irqmask); i++) +- airoha_qdma_wr(qdma, REG_INT_STATUS(i), 0xffffffff); +- +- /* setup irqs */ +- airoha_qdma_irq_enable(qdma, QDMA_INT_REG_IDX0, INT_IDX0_MASK); +- airoha_qdma_irq_enable(qdma, QDMA_INT_REG_IDX1, INT_IDX1_MASK); +- airoha_qdma_irq_enable(qdma, QDMA_INT_REG_IDX4, INT_IDX4_MASK); +- +- /* setup irq binding */ +- for (i = 0; i < ARRAY_SIZE(qdma->q_tx); i++) { +- if (!qdma->q_tx[i].ndesc) +- continue; +- +- if (TX_RING_IRQ_BLOCKING_MAP_MASK & BIT(i)) +- airoha_qdma_set(qdma, REG_TX_RING_BLOCKING(i), +- TX_RING_IRQ_BLOCKING_CFG_MASK); +- else +- airoha_qdma_clear(qdma, REG_TX_RING_BLOCKING(i), +- TX_RING_IRQ_BLOCKING_CFG_MASK); +- } +- +- airoha_qdma_wr(qdma, REG_QDMA_GLOBAL_CFG, +- GLOBAL_CFG_RX_2B_OFFSET_MASK | +- FIELD_PREP(GLOBAL_CFG_DMA_PREFERENCE_MASK, 3) | +- GLOBAL_CFG_CPU_TXR_RR_MASK | +- GLOBAL_CFG_PAYLOAD_BYTE_SWAP_MASK | +- GLOBAL_CFG_MULTICAST_MODIFY_FP_MASK | +- GLOBAL_CFG_MULTICAST_EN_MASK | +- GLOBAL_CFG_IRQ0_EN_MASK | GLOBAL_CFG_IRQ1_EN_MASK | +- GLOBAL_CFG_TX_WB_DONE_MASK | +- FIELD_PREP(GLOBAL_CFG_MAX_ISSUE_NUM_MASK, 2)); +- +- airoha_qdma_init_qos(qdma); +- +- /* disable qdma rx delay interrupt */ +- for (i = 0; i < ARRAY_SIZE(qdma->q_rx); i++) { +- if (!qdma->q_rx[i].ndesc) +- continue; +- +- airoha_qdma_clear(qdma, REG_RX_DELAY_INT_IDX(i), +- RX_DELAY_INT_MASK); +- } +- +- airoha_qdma_set(qdma, REG_TXQ_CNGST_CFG, +- TXQ_CNGST_DROP_EN | TXQ_CNGST_DEI_DROP_EN); +- airoha_qdma_init_qos_stats(qdma); +- +- return 0; +-} +- +-static irqreturn_t airoha_irq_handler(int irq, void *dev_instance) +-{ +- struct airoha_qdma *qdma = dev_instance; +- u32 intr[ARRAY_SIZE(qdma->irqmask)]; +- int i; +- +- for (i = 0; i < ARRAY_SIZE(qdma->irqmask); i++) { +- intr[i] = airoha_qdma_rr(qdma, REG_INT_STATUS(i)); +- intr[i] &= qdma->irqmask[i]; +- airoha_qdma_wr(qdma, REG_INT_STATUS(i), intr[i]); +- } +- +- if (!test_bit(DEV_STATE_INITIALIZED, &qdma->eth->state)) +- return IRQ_NONE; +- +- if (intr[1] & RX_DONE_INT_MASK) { +- airoha_qdma_irq_disable(qdma, QDMA_INT_REG_IDX1, +- RX_DONE_INT_MASK); +- +- for (i = 0; i < ARRAY_SIZE(qdma->q_rx); i++) { +- if (!qdma->q_rx[i].ndesc) +- continue; +- +- if (intr[1] & BIT(i)) +- napi_schedule(&qdma->q_rx[i].napi); +- } +- } +- +- if (intr[0] & INT_TX_MASK) { +- for (i = 0; i < ARRAY_SIZE(qdma->q_tx_irq); i++) { +- if (!(intr[0] & TX_DONE_INT_MASK(i))) +- continue; +- +- airoha_qdma_irq_disable(qdma, QDMA_INT_REG_IDX0, +- TX_DONE_INT_MASK(i)); +- napi_schedule(&qdma->q_tx_irq[i].napi); +- } +- } +- +- return IRQ_HANDLED; +-} +- +-static int airoha_qdma_init(struct platform_device *pdev, +- struct airoha_eth *eth, +- struct airoha_qdma *qdma) +-{ +- int err, id = qdma - ð->qdma[0]; +- const char *res; +- +- spin_lock_init(&qdma->irq_lock); +- qdma->eth = eth; +- +- res = devm_kasprintf(eth->dev, GFP_KERNEL, "qdma%d", id); +- if (!res) +- return -ENOMEM; +- +- qdma->regs = devm_platform_ioremap_resource_byname(pdev, res); +- if (IS_ERR(qdma->regs)) +- return dev_err_probe(eth->dev, PTR_ERR(qdma->regs), +- "failed to iomap qdma%d regs\n", id); +- +- qdma->irq = platform_get_irq(pdev, 4 * id); +- if (qdma->irq < 0) +- return qdma->irq; +- +- err = devm_request_irq(eth->dev, qdma->irq, airoha_irq_handler, +- IRQF_SHARED, KBUILD_MODNAME, qdma); +- if (err) +- return err; +- +- err = airoha_qdma_init_rx(qdma); +- if (err) +- return err; +- +- err = airoha_qdma_init_tx(qdma); +- if (err) +- return err; +- +- err = airoha_qdma_init_hfwd_queues(qdma); +- if (err) +- return err; +- +- return airoha_qdma_hw_init(qdma); +-} +- +-static int airoha_hw_init(struct platform_device *pdev, +- struct airoha_eth *eth) +-{ +- int err, i; +- +- /* disable xsi */ +- err = reset_control_bulk_assert(ARRAY_SIZE(eth->xsi_rsts), +- eth->xsi_rsts); +- if (err) +- return err; +- +- err = reset_control_bulk_assert(ARRAY_SIZE(eth->rsts), eth->rsts); +- if (err) +- return err; +- +- msleep(20); +- err = reset_control_bulk_deassert(ARRAY_SIZE(eth->rsts), eth->rsts); +- if (err) +- return err; +- +- msleep(20); +- err = airoha_fe_init(eth); +- if (err) +- return err; +- +- for (i = 0; i < ARRAY_SIZE(eth->qdma); i++) { +- err = airoha_qdma_init(pdev, eth, ð->qdma[i]); +- if (err) +- return err; +- } +- +- set_bit(DEV_STATE_INITIALIZED, ð->state); +- +- return 0; +-} +- +-static void airoha_hw_cleanup(struct airoha_qdma *qdma) +-{ +- int i; +- +- for (i = 0; i < ARRAY_SIZE(qdma->q_rx); i++) { +- if (!qdma->q_rx[i].ndesc) +- continue; +- +- netif_napi_del(&qdma->q_rx[i].napi); +- airoha_qdma_cleanup_rx_queue(&qdma->q_rx[i]); +- if (qdma->q_rx[i].page_pool) +- page_pool_destroy(qdma->q_rx[i].page_pool); +- } +- +- for (i = 0; i < ARRAY_SIZE(qdma->q_tx_irq); i++) +- netif_napi_del(&qdma->q_tx_irq[i].napi); +- +- for (i = 0; i < ARRAY_SIZE(qdma->q_tx); i++) { +- if (!qdma->q_tx[i].ndesc) +- continue; +- +- airoha_qdma_cleanup_tx_queue(&qdma->q_tx[i]); +- } +-} +- +-static void airoha_qdma_start_napi(struct airoha_qdma *qdma) +-{ +- int i; +- +- for (i = 0; i < ARRAY_SIZE(qdma->q_tx_irq); i++) +- napi_enable(&qdma->q_tx_irq[i].napi); +- +- for (i = 0; i < ARRAY_SIZE(qdma->q_rx); i++) { +- if (!qdma->q_rx[i].ndesc) +- continue; +- +- napi_enable(&qdma->q_rx[i].napi); +- } +-} +- +-static void airoha_qdma_stop_napi(struct airoha_qdma *qdma) +-{ +- int i; +- +- for (i = 0; i < ARRAY_SIZE(qdma->q_tx_irq); i++) +- napi_disable(&qdma->q_tx_irq[i].napi); +- +- for (i = 0; i < ARRAY_SIZE(qdma->q_rx); i++) { +- if (!qdma->q_rx[i].ndesc) +- continue; +- +- napi_disable(&qdma->q_rx[i].napi); +- } +-} +- +-static void airoha_update_hw_stats(struct airoha_gdm_port *port) +-{ +- struct airoha_eth *eth = port->qdma->eth; +- u32 val, i = 0; +- +- spin_lock(&port->stats.lock); +- u64_stats_update_begin(&port->stats.syncp); +- +- /* TX */ +- val = airoha_fe_rr(eth, REG_FE_GDM_TX_OK_PKT_CNT_H(port->id)); +- port->stats.tx_ok_pkts += ((u64)val << 32); +- val = airoha_fe_rr(eth, REG_FE_GDM_TX_OK_PKT_CNT_L(port->id)); +- port->stats.tx_ok_pkts += val; +- +- val = airoha_fe_rr(eth, REG_FE_GDM_TX_OK_BYTE_CNT_H(port->id)); +- port->stats.tx_ok_bytes += ((u64)val << 32); +- val = airoha_fe_rr(eth, REG_FE_GDM_TX_OK_BYTE_CNT_L(port->id)); +- port->stats.tx_ok_bytes += val; +- +- val = airoha_fe_rr(eth, REG_FE_GDM_TX_ETH_DROP_CNT(port->id)); +- port->stats.tx_drops += val; +- +- val = airoha_fe_rr(eth, REG_FE_GDM_TX_ETH_BC_CNT(port->id)); +- port->stats.tx_broadcast += val; +- +- val = airoha_fe_rr(eth, REG_FE_GDM_TX_ETH_MC_CNT(port->id)); +- port->stats.tx_multicast += val; +- +- val = airoha_fe_rr(eth, REG_FE_GDM_TX_ETH_RUNT_CNT(port->id)); +- port->stats.tx_len[i] += val; +- +- val = airoha_fe_rr(eth, REG_FE_GDM_TX_ETH_E64_CNT_H(port->id)); +- port->stats.tx_len[i] += ((u64)val << 32); +- val = airoha_fe_rr(eth, REG_FE_GDM_TX_ETH_E64_CNT_L(port->id)); +- port->stats.tx_len[i++] += val; +- +- val = airoha_fe_rr(eth, REG_FE_GDM_TX_ETH_L64_CNT_H(port->id)); +- port->stats.tx_len[i] += ((u64)val << 32); +- val = airoha_fe_rr(eth, REG_FE_GDM_TX_ETH_L64_CNT_L(port->id)); +- port->stats.tx_len[i++] += val; +- +- val = airoha_fe_rr(eth, REG_FE_GDM_TX_ETH_L127_CNT_H(port->id)); +- port->stats.tx_len[i] += ((u64)val << 32); +- val = airoha_fe_rr(eth, REG_FE_GDM_TX_ETH_L127_CNT_L(port->id)); +- port->stats.tx_len[i++] += val; +- +- val = airoha_fe_rr(eth, REG_FE_GDM_TX_ETH_L255_CNT_H(port->id)); +- port->stats.tx_len[i] += ((u64)val << 32); +- val = airoha_fe_rr(eth, REG_FE_GDM_TX_ETH_L255_CNT_L(port->id)); +- port->stats.tx_len[i++] += val; +- +- val = airoha_fe_rr(eth, REG_FE_GDM_TX_ETH_L511_CNT_H(port->id)); +- port->stats.tx_len[i] += ((u64)val << 32); +- val = airoha_fe_rr(eth, REG_FE_GDM_TX_ETH_L511_CNT_L(port->id)); +- port->stats.tx_len[i++] += val; +- +- val = airoha_fe_rr(eth, REG_FE_GDM_TX_ETH_L1023_CNT_H(port->id)); +- port->stats.tx_len[i] += ((u64)val << 32); +- val = airoha_fe_rr(eth, REG_FE_GDM_TX_ETH_L1023_CNT_L(port->id)); +- port->stats.tx_len[i++] += val; +- +- val = airoha_fe_rr(eth, REG_FE_GDM_TX_ETH_LONG_CNT(port->id)); +- port->stats.tx_len[i++] += val; +- +- /* RX */ +- val = airoha_fe_rr(eth, REG_FE_GDM_RX_OK_PKT_CNT_H(port->id)); +- port->stats.rx_ok_pkts += ((u64)val << 32); +- val = airoha_fe_rr(eth, REG_FE_GDM_RX_OK_PKT_CNT_L(port->id)); +- port->stats.rx_ok_pkts += val; +- +- val = airoha_fe_rr(eth, REG_FE_GDM_RX_OK_BYTE_CNT_H(port->id)); +- port->stats.rx_ok_bytes += ((u64)val << 32); +- val = airoha_fe_rr(eth, REG_FE_GDM_RX_OK_BYTE_CNT_L(port->id)); +- port->stats.rx_ok_bytes += val; +- +- val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_DROP_CNT(port->id)); +- port->stats.rx_drops += val; +- +- val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_BC_CNT(port->id)); +- port->stats.rx_broadcast += val; +- +- val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_MC_CNT(port->id)); +- port->stats.rx_multicast += val; +- +- val = airoha_fe_rr(eth, REG_FE_GDM_RX_ERROR_DROP_CNT(port->id)); +- port->stats.rx_errors += val; +- +- val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_CRC_ERR_CNT(port->id)); +- port->stats.rx_crc_error += val; +- +- val = airoha_fe_rr(eth, REG_FE_GDM_RX_OVERFLOW_DROP_CNT(port->id)); +- port->stats.rx_over_errors += val; +- +- val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_FRAG_CNT(port->id)); +- port->stats.rx_fragment += val; +- +- val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_JABBER_CNT(port->id)); +- port->stats.rx_jabber += val; +- +- i = 0; +- val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_RUNT_CNT(port->id)); +- port->stats.rx_len[i] += val; +- +- val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_E64_CNT_H(port->id)); +- port->stats.rx_len[i] += ((u64)val << 32); +- val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_E64_CNT_L(port->id)); +- port->stats.rx_len[i++] += val; +- +- val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_L64_CNT_H(port->id)); +- port->stats.rx_len[i] += ((u64)val << 32); +- val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_L64_CNT_L(port->id)); +- port->stats.rx_len[i++] += val; +- +- val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_L127_CNT_H(port->id)); +- port->stats.rx_len[i] += ((u64)val << 32); +- val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_L127_CNT_L(port->id)); +- port->stats.rx_len[i++] += val; +- +- val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_L255_CNT_H(port->id)); +- port->stats.rx_len[i] += ((u64)val << 32); +- val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_L255_CNT_L(port->id)); +- port->stats.rx_len[i++] += val; +- +- val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_L511_CNT_H(port->id)); +- port->stats.rx_len[i] += ((u64)val << 32); +- val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_L511_CNT_L(port->id)); +- port->stats.rx_len[i++] += val; +- +- val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_L1023_CNT_H(port->id)); +- port->stats.rx_len[i] += ((u64)val << 32); +- val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_L1023_CNT_L(port->id)); +- port->stats.rx_len[i++] += val; +- +- val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_LONG_CNT(port->id)); +- port->stats.rx_len[i++] += val; +- +- /* reset mib counters */ +- airoha_fe_set(eth, REG_FE_GDM_MIB_CLEAR(port->id), +- FE_GDM_MIB_RX_CLEAR_MASK | FE_GDM_MIB_TX_CLEAR_MASK); +- +- u64_stats_update_end(&port->stats.syncp); +- spin_unlock(&port->stats.lock); +-} +- +-static int airoha_dev_open(struct net_device *dev) +-{ +- struct airoha_gdm_port *port = netdev_priv(dev); +- struct airoha_qdma *qdma = port->qdma; +- int err; +- +- netif_tx_start_all_queues(dev); +- err = airoha_set_gdm_ports(qdma->eth, true); +- if (err) +- return err; +- +- if (netdev_uses_dsa(dev)) +- airoha_fe_set(qdma->eth, REG_GDM_INGRESS_CFG(port->id), +- GDM_STAG_EN_MASK); +- else +- airoha_fe_clear(qdma->eth, REG_GDM_INGRESS_CFG(port->id), +- GDM_STAG_EN_MASK); +- +- airoha_qdma_set(qdma, REG_QDMA_GLOBAL_CFG, +- GLOBAL_CFG_TX_DMA_EN_MASK | +- GLOBAL_CFG_RX_DMA_EN_MASK); +- +- return 0; +-} +- +-static int airoha_dev_stop(struct net_device *dev) +-{ +- struct airoha_gdm_port *port = netdev_priv(dev); +- struct airoha_qdma *qdma = port->qdma; +- int i, err; +- +- netif_tx_disable(dev); +- err = airoha_set_gdm_ports(qdma->eth, false); +- if (err) +- return err; +- +- airoha_qdma_clear(qdma, REG_QDMA_GLOBAL_CFG, +- GLOBAL_CFG_TX_DMA_EN_MASK | +- GLOBAL_CFG_RX_DMA_EN_MASK); +- +- for (i = 0; i < ARRAY_SIZE(qdma->q_tx); i++) { +- if (!qdma->q_tx[i].ndesc) +- continue; +- +- airoha_qdma_cleanup_tx_queue(&qdma->q_tx[i]); +- netdev_tx_reset_subqueue(dev, i); +- } +- +- return 0; +-} +- +-static int airoha_dev_set_macaddr(struct net_device *dev, void *p) +-{ +- struct airoha_gdm_port *port = netdev_priv(dev); +- int err; +- +- err = eth_mac_addr(dev, p); +- if (err) +- return err; +- +- airoha_set_macaddr(port, dev->dev_addr); +- +- return 0; +-} +- +-static int airoha_dev_init(struct net_device *dev) +-{ +- struct airoha_gdm_port *port = netdev_priv(dev); +- +- airoha_set_macaddr(port, dev->dev_addr); +- +- return 0; +-} +- +-static void airoha_dev_get_stats64(struct net_device *dev, +- struct rtnl_link_stats64 *storage) +-{ +- struct airoha_gdm_port *port = netdev_priv(dev); +- unsigned int start; +- +- airoha_update_hw_stats(port); +- do { +- start = u64_stats_fetch_begin(&port->stats.syncp); +- storage->rx_packets = port->stats.rx_ok_pkts; +- storage->tx_packets = port->stats.tx_ok_pkts; +- storage->rx_bytes = port->stats.rx_ok_bytes; +- storage->tx_bytes = port->stats.tx_ok_bytes; +- storage->multicast = port->stats.rx_multicast; +- storage->rx_errors = port->stats.rx_errors; +- storage->rx_dropped = port->stats.rx_drops; +- storage->tx_dropped = port->stats.tx_drops; +- storage->rx_crc_errors = port->stats.rx_crc_error; +- storage->rx_over_errors = port->stats.rx_over_errors; +- } while (u64_stats_fetch_retry(&port->stats.syncp, start)); +-} +- +-static u16 airoha_dev_select_queue(struct net_device *dev, struct sk_buff *skb, +- struct net_device *sb_dev) +-{ +- struct airoha_gdm_port *port = netdev_priv(dev); +- int queue, channel; +- +- /* For dsa device select QoS channel according to the dsa user port +- * index, rely on port id otherwise. Select QoS queue based on the +- * skb priority. +- */ +- channel = netdev_uses_dsa(dev) ? skb_get_queue_mapping(skb) : port->id; +- channel = channel % AIROHA_NUM_QOS_CHANNELS; +- queue = (skb->priority - 1) % AIROHA_NUM_QOS_QUEUES; /* QoS queue */ +- queue = channel * AIROHA_NUM_QOS_QUEUES + queue; +- +- return queue < dev->num_tx_queues ? queue : 0; +-} +- +-static netdev_tx_t airoha_dev_xmit(struct sk_buff *skb, +- struct net_device *dev) +-{ +- struct airoha_gdm_port *port = netdev_priv(dev); +- u32 nr_frags = 1 + skb_shinfo(skb)->nr_frags; +- u32 msg0, msg1, len = skb_headlen(skb); +- struct airoha_qdma *qdma = port->qdma; +- struct netdev_queue *txq; +- struct airoha_queue *q; +- void *data = skb->data; +- int i, qid; +- u16 index; +- u8 fport; +- +- qid = skb_get_queue_mapping(skb) % ARRAY_SIZE(qdma->q_tx); +- msg0 = FIELD_PREP(QDMA_ETH_TXMSG_CHAN_MASK, +- qid / AIROHA_NUM_QOS_QUEUES) | +- FIELD_PREP(QDMA_ETH_TXMSG_QUEUE_MASK, +- qid % AIROHA_NUM_QOS_QUEUES); +- if (skb->ip_summed == CHECKSUM_PARTIAL) +- msg0 |= FIELD_PREP(QDMA_ETH_TXMSG_TCO_MASK, 1) | +- FIELD_PREP(QDMA_ETH_TXMSG_UCO_MASK, 1) | +- FIELD_PREP(QDMA_ETH_TXMSG_ICO_MASK, 1); +- +- /* TSO: fill MSS info in tcp checksum field */ +- if (skb_is_gso(skb)) { +- if (skb_cow_head(skb, 0)) +- goto error; +- +- if (skb_shinfo(skb)->gso_type & (SKB_GSO_TCPV4 | +- SKB_GSO_TCPV6)) { +- __be16 csum = cpu_to_be16(skb_shinfo(skb)->gso_size); +- +- tcp_hdr(skb)->check = (__force __sum16)csum; +- msg0 |= FIELD_PREP(QDMA_ETH_TXMSG_TSO_MASK, 1); +- } +- } +- +- fport = port->id == 4 ? FE_PSE_PORT_GDM4 : port->id; +- msg1 = FIELD_PREP(QDMA_ETH_TXMSG_FPORT_MASK, fport) | +- FIELD_PREP(QDMA_ETH_TXMSG_METER_MASK, 0x7f); +- +- q = &qdma->q_tx[qid]; +- if (WARN_ON_ONCE(!q->ndesc)) +- goto error; +- +- spin_lock_bh(&q->lock); +- +- txq = netdev_get_tx_queue(dev, qid); +- if (q->queued + nr_frags > q->ndesc) { +- /* not enough space in the queue */ +- netif_tx_stop_queue(txq); +- spin_unlock_bh(&q->lock); +- return NETDEV_TX_BUSY; +- } +- +- index = q->head; +- for (i = 0; i < nr_frags; i++) { +- struct airoha_qdma_desc *desc = &q->desc[index]; +- struct airoha_queue_entry *e = &q->entry[index]; +- skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; +- dma_addr_t addr; +- u32 val; +- +- addr = dma_map_single(dev->dev.parent, data, len, +- DMA_TO_DEVICE); +- if (unlikely(dma_mapping_error(dev->dev.parent, addr))) +- goto error_unmap; +- +- index = (index + 1) % q->ndesc; +- +- val = FIELD_PREP(QDMA_DESC_LEN_MASK, len); +- if (i < nr_frags - 1) +- val |= FIELD_PREP(QDMA_DESC_MORE_MASK, 1); +- WRITE_ONCE(desc->ctrl, cpu_to_le32(val)); +- WRITE_ONCE(desc->addr, cpu_to_le32(addr)); +- val = FIELD_PREP(QDMA_DESC_NEXT_ID_MASK, index); +- WRITE_ONCE(desc->data, cpu_to_le32(val)); +- WRITE_ONCE(desc->msg0, cpu_to_le32(msg0)); +- WRITE_ONCE(desc->msg1, cpu_to_le32(msg1)); +- WRITE_ONCE(desc->msg2, cpu_to_le32(0xffff)); +- +- e->skb = i ? NULL : skb; +- e->dma_addr = addr; +- e->dma_len = len; +- +- data = skb_frag_address(frag); +- len = skb_frag_size(frag); +- } +- +- q->head = index; +- q->queued += i; +- +- skb_tx_timestamp(skb); +- netdev_tx_sent_queue(txq, skb->len); +- +- if (netif_xmit_stopped(txq) || !netdev_xmit_more()) +- airoha_qdma_rmw(qdma, REG_TX_CPU_IDX(qid), +- TX_RING_CPU_IDX_MASK, +- FIELD_PREP(TX_RING_CPU_IDX_MASK, q->head)); +- +- if (q->ndesc - q->queued < q->free_thr) +- netif_tx_stop_queue(txq); +- +- spin_unlock_bh(&q->lock); +- +- return NETDEV_TX_OK; +- +-error_unmap: +- for (i--; i >= 0; i--) { +- index = (q->head + i) % q->ndesc; +- dma_unmap_single(dev->dev.parent, q->entry[index].dma_addr, +- q->entry[index].dma_len, DMA_TO_DEVICE); +- } +- +- spin_unlock_bh(&q->lock); +-error: +- dev_kfree_skb_any(skb); +- dev->stats.tx_dropped++; +- +- return NETDEV_TX_OK; +-} +- +-static void airoha_ethtool_get_drvinfo(struct net_device *dev, +- struct ethtool_drvinfo *info) +-{ +- struct airoha_gdm_port *port = netdev_priv(dev); +- struct airoha_eth *eth = port->qdma->eth; +- +- strscpy(info->driver, eth->dev->driver->name, sizeof(info->driver)); +- strscpy(info->bus_info, dev_name(eth->dev), sizeof(info->bus_info)); +-} +- +-static void airoha_ethtool_get_mac_stats(struct net_device *dev, +- struct ethtool_eth_mac_stats *stats) +-{ +- struct airoha_gdm_port *port = netdev_priv(dev); +- unsigned int start; +- +- airoha_update_hw_stats(port); +- do { +- start = u64_stats_fetch_begin(&port->stats.syncp); +- stats->MulticastFramesXmittedOK = port->stats.tx_multicast; +- stats->BroadcastFramesXmittedOK = port->stats.tx_broadcast; +- stats->BroadcastFramesReceivedOK = port->stats.rx_broadcast; +- } while (u64_stats_fetch_retry(&port->stats.syncp, start)); +-} +- +-static const struct ethtool_rmon_hist_range airoha_ethtool_rmon_ranges[] = { +- { 0, 64 }, +- { 65, 127 }, +- { 128, 255 }, +- { 256, 511 }, +- { 512, 1023 }, +- { 1024, 1518 }, +- { 1519, 10239 }, +- {}, +-}; +- +-static void +-airoha_ethtool_get_rmon_stats(struct net_device *dev, +- struct ethtool_rmon_stats *stats, +- const struct ethtool_rmon_hist_range **ranges) +-{ +- struct airoha_gdm_port *port = netdev_priv(dev); +- struct airoha_hw_stats *hw_stats = &port->stats; +- unsigned int start; +- +- BUILD_BUG_ON(ARRAY_SIZE(airoha_ethtool_rmon_ranges) != +- ARRAY_SIZE(hw_stats->tx_len) + 1); +- BUILD_BUG_ON(ARRAY_SIZE(airoha_ethtool_rmon_ranges) != +- ARRAY_SIZE(hw_stats->rx_len) + 1); +- +- *ranges = airoha_ethtool_rmon_ranges; +- airoha_update_hw_stats(port); +- do { +- int i; +- +- start = u64_stats_fetch_begin(&port->stats.syncp); +- stats->fragments = hw_stats->rx_fragment; +- stats->jabbers = hw_stats->rx_jabber; +- for (i = 0; i < ARRAY_SIZE(airoha_ethtool_rmon_ranges) - 1; +- i++) { +- stats->hist[i] = hw_stats->rx_len[i]; +- stats->hist_tx[i] = hw_stats->tx_len[i]; +- } +- } while (u64_stats_fetch_retry(&port->stats.syncp, start)); +-} +- +-static int airoha_qdma_set_chan_tx_sched(struct airoha_gdm_port *port, +- int channel, enum tx_sched_mode mode, +- const u16 *weights, u8 n_weights) +-{ +- int i; +- +- for (i = 0; i < AIROHA_NUM_TX_RING; i++) +- airoha_qdma_clear(port->qdma, REG_QUEUE_CLOSE_CFG(channel), +- TXQ_DISABLE_CHAN_QUEUE_MASK(channel, i)); +- +- for (i = 0; i < n_weights; i++) { +- u32 status; +- int err; +- +- airoha_qdma_wr(port->qdma, REG_TXWRR_WEIGHT_CFG, +- TWRR_RW_CMD_MASK | +- FIELD_PREP(TWRR_CHAN_IDX_MASK, channel) | +- FIELD_PREP(TWRR_QUEUE_IDX_MASK, i) | +- FIELD_PREP(TWRR_VALUE_MASK, weights[i])); +- err = read_poll_timeout(airoha_qdma_rr, status, +- status & TWRR_RW_CMD_DONE, +- USEC_PER_MSEC, 10 * USEC_PER_MSEC, +- true, port->qdma, +- REG_TXWRR_WEIGHT_CFG); +- if (err) +- return err; +- } +- +- airoha_qdma_rmw(port->qdma, REG_CHAN_QOS_MODE(channel >> 3), +- CHAN_QOS_MODE_MASK(channel), +- mode << __ffs(CHAN_QOS_MODE_MASK(channel))); +- +- return 0; +-} +- +-static int airoha_qdma_set_tx_prio_sched(struct airoha_gdm_port *port, +- int channel) +-{ +- static const u16 w[AIROHA_NUM_QOS_QUEUES] = {}; +- +- return airoha_qdma_set_chan_tx_sched(port, channel, TC_SCH_SP, w, +- ARRAY_SIZE(w)); +-} +- +-static int airoha_qdma_set_tx_ets_sched(struct airoha_gdm_port *port, +- int channel, +- struct tc_ets_qopt_offload *opt) +-{ +- struct tc_ets_qopt_offload_replace_params *p = &opt->replace_params; +- enum tx_sched_mode mode = TC_SCH_SP; +- u16 w[AIROHA_NUM_QOS_QUEUES] = {}; +- int i, nstrict = 0, nwrr, qidx; +- +- if (p->bands > AIROHA_NUM_QOS_QUEUES) +- return -EINVAL; +- +- for (i = 0; i < p->bands; i++) { +- if (!p->quanta[i]) +- nstrict++; +- } +- +- /* this configuration is not supported by the hw */ +- if (nstrict == AIROHA_NUM_QOS_QUEUES - 1) +- return -EINVAL; +- +- /* EN7581 SoC supports fixed QoS band priority where WRR queues have +- * lowest priorities with respect to SP ones. +- * e.g: WRR0, WRR1, .., WRRm, SP0, SP1, .., SPn +- */ +- nwrr = p->bands - nstrict; +- qidx = nstrict && nwrr ? nstrict : 0; +- for (i = 1; i <= p->bands; i++) { +- if (p->priomap[i % AIROHA_NUM_QOS_QUEUES] != qidx) +- return -EINVAL; +- +- qidx = i == nwrr ? 0 : qidx + 1; +- } +- +- for (i = 0; i < nwrr; i++) +- w[i] = p->weights[nstrict + i]; +- +- if (!nstrict) +- mode = TC_SCH_WRR8; +- else if (nstrict < AIROHA_NUM_QOS_QUEUES - 1) +- mode = nstrict + 1; +- +- return airoha_qdma_set_chan_tx_sched(port, channel, mode, w, +- ARRAY_SIZE(w)); +-} +- +-static int airoha_qdma_get_tx_ets_stats(struct airoha_gdm_port *port, +- int channel, +- struct tc_ets_qopt_offload *opt) +-{ +- u64 cpu_tx_packets = airoha_qdma_rr(port->qdma, +- REG_CNTR_VAL(channel << 1)); +- u64 fwd_tx_packets = airoha_qdma_rr(port->qdma, +- REG_CNTR_VAL((channel << 1) + 1)); +- u64 tx_packets = (cpu_tx_packets - port->cpu_tx_packets) + +- (fwd_tx_packets - port->fwd_tx_packets); +- _bstats_update(opt->stats.bstats, 0, tx_packets); +- +- port->cpu_tx_packets = cpu_tx_packets; +- port->fwd_tx_packets = fwd_tx_packets; +- +- return 0; +-} +- +-static int airoha_tc_setup_qdisc_ets(struct airoha_gdm_port *port, +- struct tc_ets_qopt_offload *opt) +-{ +- int channel = TC_H_MAJ(opt->handle) >> 16; +- +- if (opt->parent == TC_H_ROOT) +- return -EINVAL; +- +- switch (opt->command) { +- case TC_ETS_REPLACE: +- return airoha_qdma_set_tx_ets_sched(port, channel, opt); +- case TC_ETS_DESTROY: +- /* PRIO is default qdisc scheduler */ +- return airoha_qdma_set_tx_prio_sched(port, channel); +- case TC_ETS_STATS: +- return airoha_qdma_get_tx_ets_stats(port, channel, opt); +- default: +- return -EOPNOTSUPP; +- } +-} +- +-static int airoha_qdma_get_trtcm_param(struct airoha_qdma *qdma, int channel, +- u32 addr, enum trtcm_param_type param, +- enum trtcm_mode_type mode, +- u32 *val_low, u32 *val_high) +-{ +- u32 idx = QDMA_METER_IDX(channel), group = QDMA_METER_GROUP(channel); +- u32 val, config = FIELD_PREP(TRTCM_PARAM_TYPE_MASK, param) | +- FIELD_PREP(TRTCM_METER_GROUP_MASK, group) | +- FIELD_PREP(TRTCM_PARAM_INDEX_MASK, idx) | +- FIELD_PREP(TRTCM_PARAM_RATE_TYPE_MASK, mode); +- +- airoha_qdma_wr(qdma, REG_TRTCM_CFG_PARAM(addr), config); +- if (read_poll_timeout(airoha_qdma_rr, val, +- val & TRTCM_PARAM_RW_DONE_MASK, +- USEC_PER_MSEC, 10 * USEC_PER_MSEC, true, +- qdma, REG_TRTCM_CFG_PARAM(addr))) +- return -ETIMEDOUT; +- +- *val_low = airoha_qdma_rr(qdma, REG_TRTCM_DATA_LOW(addr)); +- if (val_high) +- *val_high = airoha_qdma_rr(qdma, REG_TRTCM_DATA_HIGH(addr)); +- +- return 0; +-} +- +-static int airoha_qdma_set_trtcm_param(struct airoha_qdma *qdma, int channel, +- u32 addr, enum trtcm_param_type param, +- enum trtcm_mode_type mode, u32 val) +-{ +- u32 idx = QDMA_METER_IDX(channel), group = QDMA_METER_GROUP(channel); +- u32 config = TRTCM_PARAM_RW_MASK | +- FIELD_PREP(TRTCM_PARAM_TYPE_MASK, param) | +- FIELD_PREP(TRTCM_METER_GROUP_MASK, group) | +- FIELD_PREP(TRTCM_PARAM_INDEX_MASK, idx) | +- FIELD_PREP(TRTCM_PARAM_RATE_TYPE_MASK, mode); +- +- airoha_qdma_wr(qdma, REG_TRTCM_DATA_LOW(addr), val); +- airoha_qdma_wr(qdma, REG_TRTCM_CFG_PARAM(addr), config); +- +- return read_poll_timeout(airoha_qdma_rr, val, +- val & TRTCM_PARAM_RW_DONE_MASK, +- USEC_PER_MSEC, 10 * USEC_PER_MSEC, true, +- qdma, REG_TRTCM_CFG_PARAM(addr)); +-} +- +-static int airoha_qdma_set_trtcm_config(struct airoha_qdma *qdma, int channel, +- u32 addr, enum trtcm_mode_type mode, +- bool enable, u32 enable_mask) +-{ +- u32 val; +- +- if (airoha_qdma_get_trtcm_param(qdma, channel, addr, TRTCM_MISC_MODE, +- mode, &val, NULL)) +- return -EINVAL; +- +- val = enable ? val | enable_mask : val & ~enable_mask; +- +- return airoha_qdma_set_trtcm_param(qdma, channel, addr, TRTCM_MISC_MODE, +- mode, val); +-} +- +-static int airoha_qdma_set_trtcm_token_bucket(struct airoha_qdma *qdma, +- int channel, u32 addr, +- enum trtcm_mode_type mode, +- u32 rate_val, u32 bucket_size) +-{ +- u32 val, config, tick, unit, rate, rate_frac; +- int err; +- +- if (airoha_qdma_get_trtcm_param(qdma, channel, addr, TRTCM_MISC_MODE, +- mode, &config, NULL)) +- return -EINVAL; +- +- val = airoha_qdma_rr(qdma, addr); +- tick = FIELD_GET(INGRESS_FAST_TICK_MASK, val); +- if (config & TRTCM_TICK_SEL) +- tick *= FIELD_GET(INGRESS_SLOW_TICK_RATIO_MASK, val); +- if (!tick) +- return -EINVAL; +- +- unit = (config & TRTCM_PKT_MODE) ? 1000000 / tick : 8000 / tick; +- if (!unit) +- return -EINVAL; +- +- rate = rate_val / unit; +- rate_frac = rate_val % unit; +- rate_frac = FIELD_PREP(TRTCM_TOKEN_RATE_MASK, rate_frac) / unit; +- rate = FIELD_PREP(TRTCM_TOKEN_RATE_MASK, rate) | +- FIELD_PREP(TRTCM_TOKEN_RATE_FRACTION_MASK, rate_frac); +- +- err = airoha_qdma_set_trtcm_param(qdma, channel, addr, +- TRTCM_TOKEN_RATE_MODE, mode, rate); +- if (err) +- return err; +- +- val = max_t(u32, bucket_size, MIN_TOKEN_SIZE); +- val = min_t(u32, __fls(val), MAX_TOKEN_SIZE_OFFSET); +- +- return airoha_qdma_set_trtcm_param(qdma, channel, addr, +- TRTCM_BUCKETSIZE_SHIFT_MODE, +- mode, val); +-} +- +-static int airoha_qdma_set_tx_rate_limit(struct airoha_gdm_port *port, +- int channel, u32 rate, +- u32 bucket_size) +-{ +- int i, err; +- +- for (i = 0; i <= TRTCM_PEAK_MODE; i++) { +- err = airoha_qdma_set_trtcm_config(port->qdma, channel, +- REG_EGRESS_TRTCM_CFG, i, +- !!rate, TRTCM_METER_MODE); +- if (err) +- return err; +- +- err = airoha_qdma_set_trtcm_token_bucket(port->qdma, channel, +- REG_EGRESS_TRTCM_CFG, +- i, rate, bucket_size); +- if (err) +- return err; +- } +- +- return 0; +-} +- +-static int airoha_tc_htb_alloc_leaf_queue(struct airoha_gdm_port *port, +- struct tc_htb_qopt_offload *opt) +-{ +- u32 channel = TC_H_MIN(opt->classid) % AIROHA_NUM_QOS_CHANNELS; +- u32 rate = div_u64(opt->rate, 1000) << 3; /* kbps */ +- struct net_device *dev = port->dev; +- int num_tx_queues = dev->real_num_tx_queues; +- int err; +- +- if (opt->parent_classid != TC_HTB_CLASSID_ROOT) { +- NL_SET_ERR_MSG_MOD(opt->extack, "invalid parent classid"); +- return -EINVAL; +- } +- +- err = airoha_qdma_set_tx_rate_limit(port, channel, rate, opt->quantum); +- if (err) { +- NL_SET_ERR_MSG_MOD(opt->extack, +- "failed configuring htb offload"); +- return err; +- } +- +- if (opt->command == TC_HTB_NODE_MODIFY) +- return 0; +- +- err = netif_set_real_num_tx_queues(dev, num_tx_queues + 1); +- if (err) { +- airoha_qdma_set_tx_rate_limit(port, channel, 0, opt->quantum); +- NL_SET_ERR_MSG_MOD(opt->extack, +- "failed setting real_num_tx_queues"); +- return err; +- } +- +- set_bit(channel, port->qos_sq_bmap); +- opt->qid = AIROHA_NUM_TX_RING + channel; +- +- return 0; +-} +- +-static void airoha_tc_remove_htb_queue(struct airoha_gdm_port *port, int queue) +-{ +- struct net_device *dev = port->dev; +- +- netif_set_real_num_tx_queues(dev, dev->real_num_tx_queues - 1); +- airoha_qdma_set_tx_rate_limit(port, queue + 1, 0, 0); +- clear_bit(queue, port->qos_sq_bmap); +-} +- +-static int airoha_tc_htb_delete_leaf_queue(struct airoha_gdm_port *port, +- struct tc_htb_qopt_offload *opt) +-{ +- u32 channel = TC_H_MIN(opt->classid) % AIROHA_NUM_QOS_CHANNELS; +- +- if (!test_bit(channel, port->qos_sq_bmap)) { +- NL_SET_ERR_MSG_MOD(opt->extack, "invalid queue id"); +- return -EINVAL; +- } +- +- airoha_tc_remove_htb_queue(port, channel); +- +- return 0; +-} +- +-static int airoha_tc_htb_destroy(struct airoha_gdm_port *port) +-{ +- int q; +- +- for_each_set_bit(q, port->qos_sq_bmap, AIROHA_NUM_QOS_CHANNELS) +- airoha_tc_remove_htb_queue(port, q); +- +- return 0; +-} +- +-static int airoha_tc_get_htb_get_leaf_queue(struct airoha_gdm_port *port, +- struct tc_htb_qopt_offload *opt) +-{ +- u32 channel = TC_H_MIN(opt->classid) % AIROHA_NUM_QOS_CHANNELS; +- +- if (!test_bit(channel, port->qos_sq_bmap)) { +- NL_SET_ERR_MSG_MOD(opt->extack, "invalid queue id"); +- return -EINVAL; +- } +- +- opt->qid = channel; +- +- return 0; +-} +- +-static int airoha_tc_setup_qdisc_htb(struct airoha_gdm_port *port, +- struct tc_htb_qopt_offload *opt) +-{ +- switch (opt->command) { +- case TC_HTB_CREATE: +- break; +- case TC_HTB_DESTROY: +- return airoha_tc_htb_destroy(port); +- case TC_HTB_NODE_MODIFY: +- case TC_HTB_LEAF_ALLOC_QUEUE: +- return airoha_tc_htb_alloc_leaf_queue(port, opt); +- case TC_HTB_LEAF_DEL: +- case TC_HTB_LEAF_DEL_LAST: +- case TC_HTB_LEAF_DEL_LAST_FORCE: +- return airoha_tc_htb_delete_leaf_queue(port, opt); +- case TC_HTB_LEAF_QUERY_QUEUE: +- return airoha_tc_get_htb_get_leaf_queue(port, opt); +- default: +- return -EOPNOTSUPP; +- } +- +- return 0; +-} +- +-static int airoha_dev_tc_setup(struct net_device *dev, enum tc_setup_type type, +- void *type_data) +-{ +- struct airoha_gdm_port *port = netdev_priv(dev); +- +- switch (type) { +- case TC_SETUP_QDISC_ETS: +- return airoha_tc_setup_qdisc_ets(port, type_data); +- case TC_SETUP_QDISC_HTB: +- return airoha_tc_setup_qdisc_htb(port, type_data); +- default: +- return -EOPNOTSUPP; +- } +-} +- +-static const struct net_device_ops airoha_netdev_ops = { +- .ndo_init = airoha_dev_init, +- .ndo_open = airoha_dev_open, +- .ndo_stop = airoha_dev_stop, +- .ndo_select_queue = airoha_dev_select_queue, +- .ndo_start_xmit = airoha_dev_xmit, +- .ndo_get_stats64 = airoha_dev_get_stats64, +- .ndo_set_mac_address = airoha_dev_set_macaddr, +- .ndo_setup_tc = airoha_dev_tc_setup, +-}; +- +-static const struct ethtool_ops airoha_ethtool_ops = { +- .get_drvinfo = airoha_ethtool_get_drvinfo, +- .get_eth_mac_stats = airoha_ethtool_get_mac_stats, +- .get_rmon_stats = airoha_ethtool_get_rmon_stats, +-}; +- +-static int airoha_alloc_gdm_port(struct airoha_eth *eth, struct device_node *np) +-{ +- const __be32 *id_ptr = of_get_property(np, "reg", NULL); +- struct airoha_gdm_port *port; +- struct airoha_qdma *qdma; +- struct net_device *dev; +- int err, index; +- u32 id; +- +- if (!id_ptr) { +- dev_err(eth->dev, "missing gdm port id\n"); +- return -EINVAL; +- } +- +- id = be32_to_cpup(id_ptr); +- index = id - 1; +- +- if (!id || id > ARRAY_SIZE(eth->ports)) { +- dev_err(eth->dev, "invalid gdm port id: %d\n", id); +- return -EINVAL; +- } +- +- if (eth->ports[index]) { +- dev_err(eth->dev, "duplicate gdm port id: %d\n", id); +- return -EINVAL; +- } +- +- dev = devm_alloc_etherdev_mqs(eth->dev, sizeof(*port), +- AIROHA_NUM_NETDEV_TX_RINGS, +- AIROHA_NUM_RX_RING); +- if (!dev) { +- dev_err(eth->dev, "alloc_etherdev failed\n"); +- return -ENOMEM; +- } +- +- qdma = ð->qdma[index % AIROHA_MAX_NUM_QDMA]; +- dev->netdev_ops = &airoha_netdev_ops; +- dev->ethtool_ops = &airoha_ethtool_ops; +- dev->max_mtu = AIROHA_MAX_MTU; +- dev->watchdog_timeo = 5 * HZ; +- dev->hw_features = NETIF_F_IP_CSUM | NETIF_F_RXCSUM | +- NETIF_F_TSO6 | NETIF_F_IPV6_CSUM | +- NETIF_F_SG | NETIF_F_TSO | +- NETIF_F_HW_TC; +- dev->features |= dev->hw_features; +- dev->dev.of_node = np; +- dev->irq = qdma->irq; +- SET_NETDEV_DEV(dev, eth->dev); +- +- /* reserve hw queues for HTB offloading */ +- err = netif_set_real_num_tx_queues(dev, AIROHA_NUM_TX_RING); +- if (err) +- return err; +- +- err = of_get_ethdev_address(np, dev); +- if (err) { +- if (err == -EPROBE_DEFER) +- return err; +- +- eth_hw_addr_random(dev); +- dev_info(eth->dev, "generated random MAC address %pM\n", +- dev->dev_addr); +- } +- +- port = netdev_priv(dev); +- u64_stats_init(&port->stats.syncp); +- spin_lock_init(&port->stats.lock); +- port->qdma = qdma; +- port->dev = dev; +- port->id = id; +- eth->ports[index] = port; +- +- return register_netdev(dev); +-} +- +-static int airoha_probe(struct platform_device *pdev) +-{ +- struct device_node *np; +- struct airoha_eth *eth; +- int i, err; +- +- eth = devm_kzalloc(&pdev->dev, sizeof(*eth), GFP_KERNEL); +- if (!eth) +- return -ENOMEM; +- +- eth->dev = &pdev->dev; +- +- err = dma_set_mask_and_coherent(eth->dev, DMA_BIT_MASK(32)); +- if (err) { +- dev_err(eth->dev, "failed configuring DMA mask\n"); +- return err; +- } +- +- eth->fe_regs = devm_platform_ioremap_resource_byname(pdev, "fe"); +- if (IS_ERR(eth->fe_regs)) +- return dev_err_probe(eth->dev, PTR_ERR(eth->fe_regs), +- "failed to iomap fe regs\n"); +- +- eth->rsts[0].id = "fe"; +- eth->rsts[1].id = "pdma"; +- eth->rsts[2].id = "qdma"; +- err = devm_reset_control_bulk_get_exclusive(eth->dev, +- ARRAY_SIZE(eth->rsts), +- eth->rsts); +- if (err) { +- dev_err(eth->dev, "failed to get bulk reset lines\n"); +- return err; +- } +- +- eth->xsi_rsts[0].id = "xsi-mac"; +- eth->xsi_rsts[1].id = "hsi0-mac"; +- eth->xsi_rsts[2].id = "hsi1-mac"; +- eth->xsi_rsts[3].id = "hsi-mac"; +- eth->xsi_rsts[4].id = "xfp-mac"; +- err = devm_reset_control_bulk_get_exclusive(eth->dev, +- ARRAY_SIZE(eth->xsi_rsts), +- eth->xsi_rsts); +- if (err) { +- dev_err(eth->dev, "failed to get bulk xsi reset lines\n"); +- return err; +- } +- +- eth->napi_dev = alloc_netdev_dummy(0); +- if (!eth->napi_dev) +- return -ENOMEM; +- +- /* Enable threaded NAPI by default */ +- eth->napi_dev->threaded = true; +- strscpy(eth->napi_dev->name, "qdma_eth", sizeof(eth->napi_dev->name)); +- platform_set_drvdata(pdev, eth); +- +- err = airoha_hw_init(pdev, eth); +- if (err) +- goto error_hw_cleanup; +- +- for (i = 0; i < ARRAY_SIZE(eth->qdma); i++) +- airoha_qdma_start_napi(ð->qdma[i]); +- +- for_each_child_of_node(pdev->dev.of_node, np) { +- if (!of_device_is_compatible(np, "airoha,eth-mac")) +- continue; +- +- if (!of_device_is_available(np)) +- continue; +- +- err = airoha_alloc_gdm_port(eth, np); +- if (err) { +- of_node_put(np); +- goto error_napi_stop; +- } +- } +- +- return 0; +- +-error_napi_stop: +- for (i = 0; i < ARRAY_SIZE(eth->qdma); i++) +- airoha_qdma_stop_napi(ð->qdma[i]); +-error_hw_cleanup: +- for (i = 0; i < ARRAY_SIZE(eth->qdma); i++) +- airoha_hw_cleanup(ð->qdma[i]); +- +- for (i = 0; i < ARRAY_SIZE(eth->ports); i++) { +- struct airoha_gdm_port *port = eth->ports[i]; +- +- if (port && port->dev->reg_state == NETREG_REGISTERED) +- unregister_netdev(port->dev); +- } +- free_netdev(eth->napi_dev); +- platform_set_drvdata(pdev, NULL); +- +- return err; +-} +- +-static void airoha_remove(struct platform_device *pdev) +-{ +- struct airoha_eth *eth = platform_get_drvdata(pdev); +- int i; +- +- for (i = 0; i < ARRAY_SIZE(eth->qdma); i++) { +- airoha_qdma_stop_napi(ð->qdma[i]); +- airoha_hw_cleanup(ð->qdma[i]); +- } +- +- for (i = 0; i < ARRAY_SIZE(eth->ports); i++) { +- struct airoha_gdm_port *port = eth->ports[i]; +- +- if (!port) +- continue; +- +- airoha_dev_stop(port->dev); +- unregister_netdev(port->dev); +- } +- free_netdev(eth->napi_dev); +- +- platform_set_drvdata(pdev, NULL); +-} +- +-static const struct of_device_id of_airoha_match[] = { +- { .compatible = "airoha,en7581-eth" }, +- { /* sentinel */ } +-}; +-MODULE_DEVICE_TABLE(of, of_airoha_match); +- +-static struct platform_driver airoha_driver = { +- .probe = airoha_probe, +- .remove_new = airoha_remove, +- .driver = { +- .name = KBUILD_MODNAME, +- .of_match_table = of_airoha_match, +- }, +-}; +-module_platform_driver(airoha_driver); +- +-MODULE_LICENSE("GPL"); +-MODULE_AUTHOR("Lorenzo Bianconi "); +-MODULE_DESCRIPTION("Ethernet driver for Airoha SoC"); diff --git a/target/linux/airoha/patches-6.6/048-02-v6.15-net-airoha-Move-definitions-in-airoha_eth.h.patch b/target/linux/airoha/patches-6.6/048-02-v6.15-net-airoha-Move-definitions-in-airoha_eth.h.patch new file mode 100644 index 00000000000000..85391281a25934 --- /dev/null +++ b/target/linux/airoha/patches-6.6/048-02-v6.15-net-airoha-Move-definitions-in-airoha_eth.h.patch @@ -0,0 +1,538 @@ +From b38f4ff0ceacd6ce8d333a8dc90f405a040968d3 Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Fri, 28 Feb 2025 11:54:10 +0100 +Subject: [PATCH 02/15] net: airoha: Move definitions in airoha_eth.h + +Move common airoha_eth definitions in airoha_eth.h in order to reuse +them for Packet Processor Engine (PPE) codebase. +PPE module is used to enable support for flowtable hw offloading in +airoha_eth driver. + +Signed-off-by: Lorenzo Bianconi +Signed-off-by: Paolo Abeni +--- + drivers/net/ethernet/airoha/airoha_eth.c | 240 +--------------------- + drivers/net/ethernet/airoha/airoha_eth.h | 251 +++++++++++++++++++++++ + 2 files changed, 252 insertions(+), 239 deletions(-) + create mode 100644 drivers/net/ethernet/airoha/airoha_eth.h + +--- a/drivers/net/ethernet/airoha/airoha_eth.c ++++ b/drivers/net/ethernet/airoha/airoha_eth.c +@@ -3,14 +3,9 @@ + * Copyright (c) 2024 AIROHA Inc + * Author: Lorenzo Bianconi + */ +-#include +-#include +-#include +-#include + #include + #include + #include +-#include + #include + #include + #include +@@ -18,35 +13,7 @@ + #include + #include + +-#define AIROHA_MAX_NUM_GDM_PORTS 1 +-#define AIROHA_MAX_NUM_QDMA 2 +-#define AIROHA_MAX_NUM_RSTS 3 +-#define AIROHA_MAX_NUM_XSI_RSTS 5 +-#define AIROHA_MAX_MTU 2000 +-#define AIROHA_MAX_PACKET_SIZE 2048 +-#define AIROHA_NUM_QOS_CHANNELS 4 +-#define AIROHA_NUM_QOS_QUEUES 8 +-#define AIROHA_NUM_TX_RING 32 +-#define AIROHA_NUM_RX_RING 32 +-#define AIROHA_NUM_NETDEV_TX_RINGS (AIROHA_NUM_TX_RING + \ +- AIROHA_NUM_QOS_CHANNELS) +-#define AIROHA_FE_MC_MAX_VLAN_TABLE 64 +-#define AIROHA_FE_MC_MAX_VLAN_PORT 16 +-#define AIROHA_NUM_TX_IRQ 2 +-#define HW_DSCP_NUM 2048 +-#define IRQ_QUEUE_LEN(_n) ((_n) ? 1024 : 2048) +-#define TX_DSCP_NUM 1024 +-#define RX_DSCP_NUM(_n) \ +- ((_n) == 2 ? 128 : \ +- (_n) == 11 ? 128 : \ +- (_n) == 15 ? 128 : \ +- (_n) == 0 ? 1024 : 16) +- +-#define PSE_RSV_PAGES 128 +-#define PSE_QUEUE_RSV_PAGES 64 +- +-#define QDMA_METER_IDX(_n) ((_n) & 0xff) +-#define QDMA_METER_GROUP(_n) (((_n) >> 8) & 0x3) ++#include "airoha_eth.h" + + /* FE */ + #define PSE_BASE 0x0100 +@@ -706,211 +673,6 @@ struct airoha_qdma_fwd_desc { + __le32 rsv1; + }; + +-enum { +- QDMA_INT_REG_IDX0, +- QDMA_INT_REG_IDX1, +- QDMA_INT_REG_IDX2, +- QDMA_INT_REG_IDX3, +- QDMA_INT_REG_IDX4, +- QDMA_INT_REG_MAX +-}; +- +-enum { +- XSI_PCIE0_PORT, +- XSI_PCIE1_PORT, +- XSI_USB_PORT, +- XSI_AE_PORT, +- XSI_ETH_PORT, +-}; +- +-enum { +- XSI_PCIE0_VIP_PORT_MASK = BIT(22), +- XSI_PCIE1_VIP_PORT_MASK = BIT(23), +- XSI_USB_VIP_PORT_MASK = BIT(25), +- XSI_ETH_VIP_PORT_MASK = BIT(24), +-}; +- +-enum { +- DEV_STATE_INITIALIZED, +-}; +- +-enum { +- CDM_CRSN_QSEL_Q1 = 1, +- CDM_CRSN_QSEL_Q5 = 5, +- CDM_CRSN_QSEL_Q6 = 6, +- CDM_CRSN_QSEL_Q15 = 15, +-}; +- +-enum { +- CRSN_08 = 0x8, +- CRSN_21 = 0x15, /* KA */ +- CRSN_22 = 0x16, /* hit bind and force route to CPU */ +- CRSN_24 = 0x18, +- CRSN_25 = 0x19, +-}; +- +-enum { +- FE_PSE_PORT_CDM1, +- FE_PSE_PORT_GDM1, +- FE_PSE_PORT_GDM2, +- FE_PSE_PORT_GDM3, +- FE_PSE_PORT_PPE1, +- FE_PSE_PORT_CDM2, +- FE_PSE_PORT_CDM3, +- FE_PSE_PORT_CDM4, +- FE_PSE_PORT_PPE2, +- FE_PSE_PORT_GDM4, +- FE_PSE_PORT_CDM5, +- FE_PSE_PORT_DROP = 0xf, +-}; +- +-enum tx_sched_mode { +- TC_SCH_WRR8, +- TC_SCH_SP, +- TC_SCH_WRR7, +- TC_SCH_WRR6, +- TC_SCH_WRR5, +- TC_SCH_WRR4, +- TC_SCH_WRR3, +- TC_SCH_WRR2, +-}; +- +-enum trtcm_param_type { +- TRTCM_MISC_MODE, /* meter_en, pps_mode, tick_sel */ +- TRTCM_TOKEN_RATE_MODE, +- TRTCM_BUCKETSIZE_SHIFT_MODE, +- TRTCM_BUCKET_COUNTER_MODE, +-}; +- +-enum trtcm_mode_type { +- TRTCM_COMMIT_MODE, +- TRTCM_PEAK_MODE, +-}; +- +-enum trtcm_param { +- TRTCM_TICK_SEL = BIT(0), +- TRTCM_PKT_MODE = BIT(1), +- TRTCM_METER_MODE = BIT(2), +-}; +- +-#define MIN_TOKEN_SIZE 4096 +-#define MAX_TOKEN_SIZE_OFFSET 17 +-#define TRTCM_TOKEN_RATE_MASK GENMASK(23, 6) +-#define TRTCM_TOKEN_RATE_FRACTION_MASK GENMASK(5, 0) +- +-struct airoha_queue_entry { +- union { +- void *buf; +- struct sk_buff *skb; +- }; +- dma_addr_t dma_addr; +- u16 dma_len; +-}; +- +-struct airoha_queue { +- struct airoha_qdma *qdma; +- +- /* protect concurrent queue accesses */ +- spinlock_t lock; +- struct airoha_queue_entry *entry; +- struct airoha_qdma_desc *desc; +- u16 head; +- u16 tail; +- +- int queued; +- int ndesc; +- int free_thr; +- int buf_size; +- +- struct napi_struct napi; +- struct page_pool *page_pool; +-}; +- +-struct airoha_tx_irq_queue { +- struct airoha_qdma *qdma; +- +- struct napi_struct napi; +- +- int size; +- u32 *q; +-}; +- +-struct airoha_hw_stats { +- /* protect concurrent hw_stats accesses */ +- spinlock_t lock; +- struct u64_stats_sync syncp; +- +- /* get_stats64 */ +- u64 rx_ok_pkts; +- u64 tx_ok_pkts; +- u64 rx_ok_bytes; +- u64 tx_ok_bytes; +- u64 rx_multicast; +- u64 rx_errors; +- u64 rx_drops; +- u64 tx_drops; +- u64 rx_crc_error; +- u64 rx_over_errors; +- /* ethtool stats */ +- u64 tx_broadcast; +- u64 tx_multicast; +- u64 tx_len[7]; +- u64 rx_broadcast; +- u64 rx_fragment; +- u64 rx_jabber; +- u64 rx_len[7]; +-}; +- +-struct airoha_qdma { +- struct airoha_eth *eth; +- void __iomem *regs; +- +- /* protect concurrent irqmask accesses */ +- spinlock_t irq_lock; +- u32 irqmask[QDMA_INT_REG_MAX]; +- int irq; +- +- struct airoha_tx_irq_queue q_tx_irq[AIROHA_NUM_TX_IRQ]; +- +- struct airoha_queue q_tx[AIROHA_NUM_TX_RING]; +- struct airoha_queue q_rx[AIROHA_NUM_RX_RING]; +- +- /* descriptor and packet buffers for qdma hw forward */ +- struct { +- void *desc; +- void *q; +- } hfwd; +-}; +- +-struct airoha_gdm_port { +- struct airoha_qdma *qdma; +- struct net_device *dev; +- int id; +- +- struct airoha_hw_stats stats; +- +- DECLARE_BITMAP(qos_sq_bmap, AIROHA_NUM_QOS_CHANNELS); +- +- /* qos stats counters */ +- u64 cpu_tx_packets; +- u64 fwd_tx_packets; +-}; +- +-struct airoha_eth { +- struct device *dev; +- +- unsigned long state; +- void __iomem *fe_regs; +- +- struct reset_control_bulk_data rsts[AIROHA_MAX_NUM_RSTS]; +- struct reset_control_bulk_data xsi_rsts[AIROHA_MAX_NUM_XSI_RSTS]; +- +- struct net_device *napi_dev; +- +- struct airoha_qdma qdma[AIROHA_MAX_NUM_QDMA]; +- struct airoha_gdm_port *ports[AIROHA_MAX_NUM_GDM_PORTS]; +-}; +- + static u32 airoha_rr(void __iomem *base, u32 offset) + { + return readl(base + offset); +--- /dev/null ++++ b/drivers/net/ethernet/airoha/airoha_eth.h +@@ -0,0 +1,251 @@ ++/* SPDX-License-Identifier: GPL-2.0-only */ ++/* ++ * Copyright (c) 2024 AIROHA Inc ++ * Author: Lorenzo Bianconi ++ */ ++ ++#ifndef AIROHA_ETH_H ++#define AIROHA_ETH_H ++ ++#include ++#include ++#include ++#include ++#include ++ ++#define AIROHA_MAX_NUM_GDM_PORTS 1 ++#define AIROHA_MAX_NUM_QDMA 2 ++#define AIROHA_MAX_NUM_RSTS 3 ++#define AIROHA_MAX_NUM_XSI_RSTS 5 ++#define AIROHA_MAX_MTU 2000 ++#define AIROHA_MAX_PACKET_SIZE 2048 ++#define AIROHA_NUM_QOS_CHANNELS 4 ++#define AIROHA_NUM_QOS_QUEUES 8 ++#define AIROHA_NUM_TX_RING 32 ++#define AIROHA_NUM_RX_RING 32 ++#define AIROHA_NUM_NETDEV_TX_RINGS (AIROHA_NUM_TX_RING + \ ++ AIROHA_NUM_QOS_CHANNELS) ++#define AIROHA_FE_MC_MAX_VLAN_TABLE 64 ++#define AIROHA_FE_MC_MAX_VLAN_PORT 16 ++#define AIROHA_NUM_TX_IRQ 2 ++#define HW_DSCP_NUM 2048 ++#define IRQ_QUEUE_LEN(_n) ((_n) ? 1024 : 2048) ++#define TX_DSCP_NUM 1024 ++#define RX_DSCP_NUM(_n) \ ++ ((_n) == 2 ? 128 : \ ++ (_n) == 11 ? 128 : \ ++ (_n) == 15 ? 128 : \ ++ (_n) == 0 ? 1024 : 16) ++ ++#define PSE_RSV_PAGES 128 ++#define PSE_QUEUE_RSV_PAGES 64 ++ ++#define QDMA_METER_IDX(_n) ((_n) & 0xff) ++#define QDMA_METER_GROUP(_n) (((_n) >> 8) & 0x3) ++ ++enum { ++ QDMA_INT_REG_IDX0, ++ QDMA_INT_REG_IDX1, ++ QDMA_INT_REG_IDX2, ++ QDMA_INT_REG_IDX3, ++ QDMA_INT_REG_IDX4, ++ QDMA_INT_REG_MAX ++}; ++ ++enum { ++ XSI_PCIE0_PORT, ++ XSI_PCIE1_PORT, ++ XSI_USB_PORT, ++ XSI_AE_PORT, ++ XSI_ETH_PORT, ++}; ++ ++enum { ++ XSI_PCIE0_VIP_PORT_MASK = BIT(22), ++ XSI_PCIE1_VIP_PORT_MASK = BIT(23), ++ XSI_USB_VIP_PORT_MASK = BIT(25), ++ XSI_ETH_VIP_PORT_MASK = BIT(24), ++}; ++ ++enum { ++ DEV_STATE_INITIALIZED, ++}; ++ ++enum { ++ CDM_CRSN_QSEL_Q1 = 1, ++ CDM_CRSN_QSEL_Q5 = 5, ++ CDM_CRSN_QSEL_Q6 = 6, ++ CDM_CRSN_QSEL_Q15 = 15, ++}; ++ ++enum { ++ CRSN_08 = 0x8, ++ CRSN_21 = 0x15, /* KA */ ++ CRSN_22 = 0x16, /* hit bind and force route to CPU */ ++ CRSN_24 = 0x18, ++ CRSN_25 = 0x19, ++}; ++ ++enum { ++ FE_PSE_PORT_CDM1, ++ FE_PSE_PORT_GDM1, ++ FE_PSE_PORT_GDM2, ++ FE_PSE_PORT_GDM3, ++ FE_PSE_PORT_PPE1, ++ FE_PSE_PORT_CDM2, ++ FE_PSE_PORT_CDM3, ++ FE_PSE_PORT_CDM4, ++ FE_PSE_PORT_PPE2, ++ FE_PSE_PORT_GDM4, ++ FE_PSE_PORT_CDM5, ++ FE_PSE_PORT_DROP = 0xf, ++}; ++ ++enum tx_sched_mode { ++ TC_SCH_WRR8, ++ TC_SCH_SP, ++ TC_SCH_WRR7, ++ TC_SCH_WRR6, ++ TC_SCH_WRR5, ++ TC_SCH_WRR4, ++ TC_SCH_WRR3, ++ TC_SCH_WRR2, ++}; ++ ++enum trtcm_param_type { ++ TRTCM_MISC_MODE, /* meter_en, pps_mode, tick_sel */ ++ TRTCM_TOKEN_RATE_MODE, ++ TRTCM_BUCKETSIZE_SHIFT_MODE, ++ TRTCM_BUCKET_COUNTER_MODE, ++}; ++ ++enum trtcm_mode_type { ++ TRTCM_COMMIT_MODE, ++ TRTCM_PEAK_MODE, ++}; ++ ++enum trtcm_param { ++ TRTCM_TICK_SEL = BIT(0), ++ TRTCM_PKT_MODE = BIT(1), ++ TRTCM_METER_MODE = BIT(2), ++}; ++ ++#define MIN_TOKEN_SIZE 4096 ++#define MAX_TOKEN_SIZE_OFFSET 17 ++#define TRTCM_TOKEN_RATE_MASK GENMASK(23, 6) ++#define TRTCM_TOKEN_RATE_FRACTION_MASK GENMASK(5, 0) ++ ++struct airoha_queue_entry { ++ union { ++ void *buf; ++ struct sk_buff *skb; ++ }; ++ dma_addr_t dma_addr; ++ u16 dma_len; ++}; ++ ++struct airoha_queue { ++ struct airoha_qdma *qdma; ++ ++ /* protect concurrent queue accesses */ ++ spinlock_t lock; ++ struct airoha_queue_entry *entry; ++ struct airoha_qdma_desc *desc; ++ u16 head; ++ u16 tail; ++ ++ int queued; ++ int ndesc; ++ int free_thr; ++ int buf_size; ++ ++ struct napi_struct napi; ++ struct page_pool *page_pool; ++}; ++ ++struct airoha_tx_irq_queue { ++ struct airoha_qdma *qdma; ++ ++ struct napi_struct napi; ++ ++ int size; ++ u32 *q; ++}; ++ ++struct airoha_hw_stats { ++ /* protect concurrent hw_stats accesses */ ++ spinlock_t lock; ++ struct u64_stats_sync syncp; ++ ++ /* get_stats64 */ ++ u64 rx_ok_pkts; ++ u64 tx_ok_pkts; ++ u64 rx_ok_bytes; ++ u64 tx_ok_bytes; ++ u64 rx_multicast; ++ u64 rx_errors; ++ u64 rx_drops; ++ u64 tx_drops; ++ u64 rx_crc_error; ++ u64 rx_over_errors; ++ /* ethtool stats */ ++ u64 tx_broadcast; ++ u64 tx_multicast; ++ u64 tx_len[7]; ++ u64 rx_broadcast; ++ u64 rx_fragment; ++ u64 rx_jabber; ++ u64 rx_len[7]; ++}; ++ ++struct airoha_qdma { ++ struct airoha_eth *eth; ++ void __iomem *regs; ++ ++ /* protect concurrent irqmask accesses */ ++ spinlock_t irq_lock; ++ u32 irqmask[QDMA_INT_REG_MAX]; ++ int irq; ++ ++ struct airoha_tx_irq_queue q_tx_irq[AIROHA_NUM_TX_IRQ]; ++ ++ struct airoha_queue q_tx[AIROHA_NUM_TX_RING]; ++ struct airoha_queue q_rx[AIROHA_NUM_RX_RING]; ++ ++ /* descriptor and packet buffers for qdma hw forward */ ++ struct { ++ void *desc; ++ void *q; ++ } hfwd; ++}; ++ ++struct airoha_gdm_port { ++ struct airoha_qdma *qdma; ++ struct net_device *dev; ++ int id; ++ ++ struct airoha_hw_stats stats; ++ ++ DECLARE_BITMAP(qos_sq_bmap, AIROHA_NUM_QOS_CHANNELS); ++ ++ /* qos stats counters */ ++ u64 cpu_tx_packets; ++ u64 fwd_tx_packets; ++}; ++ ++struct airoha_eth { ++ struct device *dev; ++ ++ unsigned long state; ++ void __iomem *fe_regs; ++ ++ struct reset_control_bulk_data rsts[AIROHA_MAX_NUM_RSTS]; ++ struct reset_control_bulk_data xsi_rsts[AIROHA_MAX_NUM_XSI_RSTS]; ++ ++ struct net_device *napi_dev; ++ ++ struct airoha_qdma qdma[AIROHA_MAX_NUM_QDMA]; ++ struct airoha_gdm_port *ports[AIROHA_MAX_NUM_GDM_PORTS]; ++}; ++ ++#endif /* AIROHA_ETH_H */ diff --git a/target/linux/airoha/patches-6.6/048-03-v6.15-net-airoha-Move-reg-write-utility-routines-in-airoha.patch b/target/linux/airoha/patches-6.6/048-03-v6.15-net-airoha-Move-reg-write-utility-routines-in-airoha.patch new file mode 100644 index 00000000000000..bf24638ec91fb9 --- /dev/null +++ b/target/linux/airoha/patches-6.6/048-03-v6.15-net-airoha-Move-reg-write-utility-routines-in-airoha.patch @@ -0,0 +1,101 @@ +From e0758a8694fbaffdc72940774db295585e951119 Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Fri, 28 Feb 2025 11:54:11 +0100 +Subject: [PATCH 03/15] net: airoha: Move reg/write utility routines in + airoha_eth.h + +This is a preliminary patch to introduce flowtable hw offloading +support for airoha_eth driver. + +Signed-off-by: Lorenzo Bianconi +Signed-off-by: Paolo Abeni +--- + drivers/net/ethernet/airoha/airoha_eth.c | 28 +++--------------------- + drivers/net/ethernet/airoha/airoha_eth.h | 26 ++++++++++++++++++++++ + 2 files changed, 29 insertions(+), 25 deletions(-) + +--- a/drivers/net/ethernet/airoha/airoha_eth.c ++++ b/drivers/net/ethernet/airoha/airoha_eth.c +@@ -673,17 +673,17 @@ struct airoha_qdma_fwd_desc { + __le32 rsv1; + }; + +-static u32 airoha_rr(void __iomem *base, u32 offset) ++u32 airoha_rr(void __iomem *base, u32 offset) + { + return readl(base + offset); + } + +-static void airoha_wr(void __iomem *base, u32 offset, u32 val) ++void airoha_wr(void __iomem *base, u32 offset, u32 val) + { + writel(val, base + offset); + } + +-static u32 airoha_rmw(void __iomem *base, u32 offset, u32 mask, u32 val) ++u32 airoha_rmw(void __iomem *base, u32 offset, u32 mask, u32 val) + { + val |= (airoha_rr(base, offset) & ~mask); + airoha_wr(base, offset, val); +@@ -691,28 +691,6 @@ static u32 airoha_rmw(void __iomem *base + return val; + } + +-#define airoha_fe_rr(eth, offset) \ +- airoha_rr((eth)->fe_regs, (offset)) +-#define airoha_fe_wr(eth, offset, val) \ +- airoha_wr((eth)->fe_regs, (offset), (val)) +-#define airoha_fe_rmw(eth, offset, mask, val) \ +- airoha_rmw((eth)->fe_regs, (offset), (mask), (val)) +-#define airoha_fe_set(eth, offset, val) \ +- airoha_rmw((eth)->fe_regs, (offset), 0, (val)) +-#define airoha_fe_clear(eth, offset, val) \ +- airoha_rmw((eth)->fe_regs, (offset), (val), 0) +- +-#define airoha_qdma_rr(qdma, offset) \ +- airoha_rr((qdma)->regs, (offset)) +-#define airoha_qdma_wr(qdma, offset, val) \ +- airoha_wr((qdma)->regs, (offset), (val)) +-#define airoha_qdma_rmw(qdma, offset, mask, val) \ +- airoha_rmw((qdma)->regs, (offset), (mask), (val)) +-#define airoha_qdma_set(qdma, offset, val) \ +- airoha_rmw((qdma)->regs, (offset), 0, (val)) +-#define airoha_qdma_clear(qdma, offset, val) \ +- airoha_rmw((qdma)->regs, (offset), (val), 0) +- + static void airoha_qdma_set_irqmask(struct airoha_qdma *qdma, int index, + u32 clear, u32 set) + { +--- a/drivers/net/ethernet/airoha/airoha_eth.h ++++ b/drivers/net/ethernet/airoha/airoha_eth.h +@@ -248,4 +248,30 @@ struct airoha_eth { + struct airoha_gdm_port *ports[AIROHA_MAX_NUM_GDM_PORTS]; + }; + ++u32 airoha_rr(void __iomem *base, u32 offset); ++void airoha_wr(void __iomem *base, u32 offset, u32 val); ++u32 airoha_rmw(void __iomem *base, u32 offset, u32 mask, u32 val); ++ ++#define airoha_fe_rr(eth, offset) \ ++ airoha_rr((eth)->fe_regs, (offset)) ++#define airoha_fe_wr(eth, offset, val) \ ++ airoha_wr((eth)->fe_regs, (offset), (val)) ++#define airoha_fe_rmw(eth, offset, mask, val) \ ++ airoha_rmw((eth)->fe_regs, (offset), (mask), (val)) ++#define airoha_fe_set(eth, offset, val) \ ++ airoha_rmw((eth)->fe_regs, (offset), 0, (val)) ++#define airoha_fe_clear(eth, offset, val) \ ++ airoha_rmw((eth)->fe_regs, (offset), (val), 0) ++ ++#define airoha_qdma_rr(qdma, offset) \ ++ airoha_rr((qdma)->regs, (offset)) ++#define airoha_qdma_wr(qdma, offset, val) \ ++ airoha_wr((qdma)->regs, (offset), (val)) ++#define airoha_qdma_rmw(qdma, offset, mask, val) \ ++ airoha_rmw((qdma)->regs, (offset), (mask), (val)) ++#define airoha_qdma_set(qdma, offset, val) \ ++ airoha_rmw((qdma)->regs, (offset), 0, (val)) ++#define airoha_qdma_clear(qdma, offset, val) \ ++ airoha_rmw((qdma)->regs, (offset), (val), 0) ++ + #endif /* AIROHA_ETH_H */ diff --git a/target/linux/airoha/patches-6.6/048-04-v6.15-net-airoha-Move-register-definitions-in-airoha_regs..patch b/target/linux/airoha/patches-6.6/048-04-v6.15-net-airoha-Move-register-definitions-in-airoha_regs..patch new file mode 100644 index 00000000000000..3b2b8bfe5dcfdd --- /dev/null +++ b/target/linux/airoha/patches-6.6/048-04-v6.15-net-airoha-Move-register-definitions-in-airoha_regs..patch @@ -0,0 +1,1361 @@ +From ec663d9a82bf4d16721f6b1fc29df4892ba6c088 Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Fri, 28 Feb 2025 11:54:12 +0100 +Subject: [PATCH 04/15] net: airoha: Move register definitions in airoha_regs.h + +Move common airoha_eth register definitions in airoha_regs.h in order +to reuse them for Packet Processor Engine (PPE) codebase. +PPE module is used to enable support for flowtable hw offloading in +airoha_eth driver. + +Signed-off-by: Lorenzo Bianconi +Signed-off-by: Paolo Abeni +--- + drivers/net/ethernet/airoha/airoha_eth.c | 659 +-------------------- + drivers/net/ethernet/airoha/airoha_regs.h | 670 ++++++++++++++++++++++ + 2 files changed, 671 insertions(+), 658 deletions(-) + create mode 100644 drivers/net/ethernet/airoha/airoha_regs.h + +--- a/drivers/net/ethernet/airoha/airoha_eth.c ++++ b/drivers/net/ethernet/airoha/airoha_eth.c +@@ -13,666 +13,9 @@ + #include + #include + ++#include "airoha_regs.h" + #include "airoha_eth.h" + +-/* FE */ +-#define PSE_BASE 0x0100 +-#define CSR_IFC_BASE 0x0200 +-#define CDM1_BASE 0x0400 +-#define GDM1_BASE 0x0500 +-#define PPE1_BASE 0x0c00 +- +-#define CDM2_BASE 0x1400 +-#define GDM2_BASE 0x1500 +- +-#define GDM3_BASE 0x1100 +-#define GDM4_BASE 0x2500 +- +-#define GDM_BASE(_n) \ +- ((_n) == 4 ? GDM4_BASE : \ +- (_n) == 3 ? GDM3_BASE : \ +- (_n) == 2 ? GDM2_BASE : GDM1_BASE) +- +-#define REG_FE_DMA_GLO_CFG 0x0000 +-#define FE_DMA_GLO_L2_SPACE_MASK GENMASK(7, 4) +-#define FE_DMA_GLO_PG_SZ_MASK BIT(3) +- +-#define REG_FE_RST_GLO_CFG 0x0004 +-#define FE_RST_GDM4_MBI_ARB_MASK BIT(3) +-#define FE_RST_GDM3_MBI_ARB_MASK BIT(2) +-#define FE_RST_CORE_MASK BIT(0) +- +-#define REG_FE_WAN_MAC_H 0x0030 +-#define REG_FE_LAN_MAC_H 0x0040 +- +-#define REG_FE_MAC_LMIN(_n) ((_n) + 0x04) +-#define REG_FE_MAC_LMAX(_n) ((_n) + 0x08) +- +-#define REG_FE_CDM1_OQ_MAP0 0x0050 +-#define REG_FE_CDM1_OQ_MAP1 0x0054 +-#define REG_FE_CDM1_OQ_MAP2 0x0058 +-#define REG_FE_CDM1_OQ_MAP3 0x005c +- +-#define REG_FE_PCE_CFG 0x0070 +-#define PCE_DPI_EN_MASK BIT(2) +-#define PCE_KA_EN_MASK BIT(1) +-#define PCE_MC_EN_MASK BIT(0) +- +-#define REG_FE_PSE_QUEUE_CFG_WR 0x0080 +-#define PSE_CFG_PORT_ID_MASK GENMASK(27, 24) +-#define PSE_CFG_QUEUE_ID_MASK GENMASK(20, 16) +-#define PSE_CFG_WR_EN_MASK BIT(8) +-#define PSE_CFG_OQRSV_SEL_MASK BIT(0) +- +-#define REG_FE_PSE_QUEUE_CFG_VAL 0x0084 +-#define PSE_CFG_OQ_RSV_MASK GENMASK(13, 0) +- +-#define PSE_FQ_CFG 0x008c +-#define PSE_FQ_LIMIT_MASK GENMASK(14, 0) +- +-#define REG_FE_PSE_BUF_SET 0x0090 +-#define PSE_SHARE_USED_LTHD_MASK GENMASK(31, 16) +-#define PSE_ALLRSV_MASK GENMASK(14, 0) +- +-#define REG_PSE_SHARE_USED_THD 0x0094 +-#define PSE_SHARE_USED_MTHD_MASK GENMASK(31, 16) +-#define PSE_SHARE_USED_HTHD_MASK GENMASK(15, 0) +- +-#define REG_GDM_MISC_CFG 0x0148 +-#define GDM2_RDM_ACK_WAIT_PREF_MASK BIT(9) +-#define GDM2_CHN_VLD_MODE_MASK BIT(5) +- +-#define REG_FE_CSR_IFC_CFG CSR_IFC_BASE +-#define FE_IFC_EN_MASK BIT(0) +- +-#define REG_FE_VIP_PORT_EN 0x01f0 +-#define REG_FE_IFC_PORT_EN 0x01f4 +- +-#define REG_PSE_IQ_REV1 (PSE_BASE + 0x08) +-#define PSE_IQ_RES1_P2_MASK GENMASK(23, 16) +- +-#define REG_PSE_IQ_REV2 (PSE_BASE + 0x0c) +-#define PSE_IQ_RES2_P5_MASK GENMASK(15, 8) +-#define PSE_IQ_RES2_P4_MASK GENMASK(7, 0) +- +-#define REG_FE_VIP_EN(_n) (0x0300 + ((_n) << 3)) +-#define PATN_FCPU_EN_MASK BIT(7) +-#define PATN_SWP_EN_MASK BIT(6) +-#define PATN_DP_EN_MASK BIT(5) +-#define PATN_SP_EN_MASK BIT(4) +-#define PATN_TYPE_MASK GENMASK(3, 1) +-#define PATN_EN_MASK BIT(0) +- +-#define REG_FE_VIP_PATN(_n) (0x0304 + ((_n) << 3)) +-#define PATN_DP_MASK GENMASK(31, 16) +-#define PATN_SP_MASK GENMASK(15, 0) +- +-#define REG_CDM1_VLAN_CTRL CDM1_BASE +-#define CDM1_VLAN_MASK GENMASK(31, 16) +- +-#define REG_CDM1_FWD_CFG (CDM1_BASE + 0x08) +-#define CDM1_VIP_QSEL_MASK GENMASK(24, 20) +- +-#define REG_CDM1_CRSN_QSEL(_n) (CDM1_BASE + 0x10 + ((_n) << 2)) +-#define CDM1_CRSN_QSEL_REASON_MASK(_n) \ +- GENMASK(4 + (((_n) % 4) << 3), (((_n) % 4) << 3)) +- +-#define REG_CDM2_FWD_CFG (CDM2_BASE + 0x08) +-#define CDM2_OAM_QSEL_MASK GENMASK(31, 27) +-#define CDM2_VIP_QSEL_MASK GENMASK(24, 20) +- +-#define REG_CDM2_CRSN_QSEL(_n) (CDM2_BASE + 0x10 + ((_n) << 2)) +-#define CDM2_CRSN_QSEL_REASON_MASK(_n) \ +- GENMASK(4 + (((_n) % 4) << 3), (((_n) % 4) << 3)) +- +-#define REG_GDM_FWD_CFG(_n) GDM_BASE(_n) +-#define GDM_DROP_CRC_ERR BIT(23) +-#define GDM_IP4_CKSUM BIT(22) +-#define GDM_TCP_CKSUM BIT(21) +-#define GDM_UDP_CKSUM BIT(20) +-#define GDM_UCFQ_MASK GENMASK(15, 12) +-#define GDM_BCFQ_MASK GENMASK(11, 8) +-#define GDM_MCFQ_MASK GENMASK(7, 4) +-#define GDM_OCFQ_MASK GENMASK(3, 0) +- +-#define REG_GDM_INGRESS_CFG(_n) (GDM_BASE(_n) + 0x10) +-#define GDM_INGRESS_FC_EN_MASK BIT(1) +-#define GDM_STAG_EN_MASK BIT(0) +- +-#define REG_GDM_LEN_CFG(_n) (GDM_BASE(_n) + 0x14) +-#define GDM_SHORT_LEN_MASK GENMASK(13, 0) +-#define GDM_LONG_LEN_MASK GENMASK(29, 16) +- +-#define REG_FE_CPORT_CFG (GDM1_BASE + 0x40) +-#define FE_CPORT_PAD BIT(26) +-#define FE_CPORT_PORT_XFC_MASK BIT(25) +-#define FE_CPORT_QUEUE_XFC_MASK BIT(24) +- +-#define REG_FE_GDM_MIB_CLEAR(_n) (GDM_BASE(_n) + 0xf0) +-#define FE_GDM_MIB_RX_CLEAR_MASK BIT(1) +-#define FE_GDM_MIB_TX_CLEAR_MASK BIT(0) +- +-#define REG_FE_GDM1_MIB_CFG (GDM1_BASE + 0xf4) +-#define FE_STRICT_RFC2819_MODE_MASK BIT(31) +-#define FE_GDM1_TX_MIB_SPLIT_EN_MASK BIT(17) +-#define FE_GDM1_RX_MIB_SPLIT_EN_MASK BIT(16) +-#define FE_TX_MIB_ID_MASK GENMASK(15, 8) +-#define FE_RX_MIB_ID_MASK GENMASK(7, 0) +- +-#define REG_FE_GDM_TX_OK_PKT_CNT_L(_n) (GDM_BASE(_n) + 0x104) +-#define REG_FE_GDM_TX_OK_BYTE_CNT_L(_n) (GDM_BASE(_n) + 0x10c) +-#define REG_FE_GDM_TX_ETH_PKT_CNT_L(_n) (GDM_BASE(_n) + 0x110) +-#define REG_FE_GDM_TX_ETH_BYTE_CNT_L(_n) (GDM_BASE(_n) + 0x114) +-#define REG_FE_GDM_TX_ETH_DROP_CNT(_n) (GDM_BASE(_n) + 0x118) +-#define REG_FE_GDM_TX_ETH_BC_CNT(_n) (GDM_BASE(_n) + 0x11c) +-#define REG_FE_GDM_TX_ETH_MC_CNT(_n) (GDM_BASE(_n) + 0x120) +-#define REG_FE_GDM_TX_ETH_RUNT_CNT(_n) (GDM_BASE(_n) + 0x124) +-#define REG_FE_GDM_TX_ETH_LONG_CNT(_n) (GDM_BASE(_n) + 0x128) +-#define REG_FE_GDM_TX_ETH_E64_CNT_L(_n) (GDM_BASE(_n) + 0x12c) +-#define REG_FE_GDM_TX_ETH_L64_CNT_L(_n) (GDM_BASE(_n) + 0x130) +-#define REG_FE_GDM_TX_ETH_L127_CNT_L(_n) (GDM_BASE(_n) + 0x134) +-#define REG_FE_GDM_TX_ETH_L255_CNT_L(_n) (GDM_BASE(_n) + 0x138) +-#define REG_FE_GDM_TX_ETH_L511_CNT_L(_n) (GDM_BASE(_n) + 0x13c) +-#define REG_FE_GDM_TX_ETH_L1023_CNT_L(_n) (GDM_BASE(_n) + 0x140) +- +-#define REG_FE_GDM_RX_OK_PKT_CNT_L(_n) (GDM_BASE(_n) + 0x148) +-#define REG_FE_GDM_RX_FC_DROP_CNT(_n) (GDM_BASE(_n) + 0x14c) +-#define REG_FE_GDM_RX_RC_DROP_CNT(_n) (GDM_BASE(_n) + 0x150) +-#define REG_FE_GDM_RX_OVERFLOW_DROP_CNT(_n) (GDM_BASE(_n) + 0x154) +-#define REG_FE_GDM_RX_ERROR_DROP_CNT(_n) (GDM_BASE(_n) + 0x158) +-#define REG_FE_GDM_RX_OK_BYTE_CNT_L(_n) (GDM_BASE(_n) + 0x15c) +-#define REG_FE_GDM_RX_ETH_PKT_CNT_L(_n) (GDM_BASE(_n) + 0x160) +-#define REG_FE_GDM_RX_ETH_BYTE_CNT_L(_n) (GDM_BASE(_n) + 0x164) +-#define REG_FE_GDM_RX_ETH_DROP_CNT(_n) (GDM_BASE(_n) + 0x168) +-#define REG_FE_GDM_RX_ETH_BC_CNT(_n) (GDM_BASE(_n) + 0x16c) +-#define REG_FE_GDM_RX_ETH_MC_CNT(_n) (GDM_BASE(_n) + 0x170) +-#define REG_FE_GDM_RX_ETH_CRC_ERR_CNT(_n) (GDM_BASE(_n) + 0x174) +-#define REG_FE_GDM_RX_ETH_FRAG_CNT(_n) (GDM_BASE(_n) + 0x178) +-#define REG_FE_GDM_RX_ETH_JABBER_CNT(_n) (GDM_BASE(_n) + 0x17c) +-#define REG_FE_GDM_RX_ETH_RUNT_CNT(_n) (GDM_BASE(_n) + 0x180) +-#define REG_FE_GDM_RX_ETH_LONG_CNT(_n) (GDM_BASE(_n) + 0x184) +-#define REG_FE_GDM_RX_ETH_E64_CNT_L(_n) (GDM_BASE(_n) + 0x188) +-#define REG_FE_GDM_RX_ETH_L64_CNT_L(_n) (GDM_BASE(_n) + 0x18c) +-#define REG_FE_GDM_RX_ETH_L127_CNT_L(_n) (GDM_BASE(_n) + 0x190) +-#define REG_FE_GDM_RX_ETH_L255_CNT_L(_n) (GDM_BASE(_n) + 0x194) +-#define REG_FE_GDM_RX_ETH_L511_CNT_L(_n) (GDM_BASE(_n) + 0x198) +-#define REG_FE_GDM_RX_ETH_L1023_CNT_L(_n) (GDM_BASE(_n) + 0x19c) +- +-#define REG_PPE1_TB_HASH_CFG (PPE1_BASE + 0x250) +-#define PPE1_SRAM_TABLE_EN_MASK BIT(0) +-#define PPE1_SRAM_HASH1_EN_MASK BIT(8) +-#define PPE1_DRAM_TABLE_EN_MASK BIT(16) +-#define PPE1_DRAM_HASH1_EN_MASK BIT(24) +- +-#define REG_FE_GDM_TX_OK_PKT_CNT_H(_n) (GDM_BASE(_n) + 0x280) +-#define REG_FE_GDM_TX_OK_BYTE_CNT_H(_n) (GDM_BASE(_n) + 0x284) +-#define REG_FE_GDM_TX_ETH_PKT_CNT_H(_n) (GDM_BASE(_n) + 0x288) +-#define REG_FE_GDM_TX_ETH_BYTE_CNT_H(_n) (GDM_BASE(_n) + 0x28c) +- +-#define REG_FE_GDM_RX_OK_PKT_CNT_H(_n) (GDM_BASE(_n) + 0x290) +-#define REG_FE_GDM_RX_OK_BYTE_CNT_H(_n) (GDM_BASE(_n) + 0x294) +-#define REG_FE_GDM_RX_ETH_PKT_CNT_H(_n) (GDM_BASE(_n) + 0x298) +-#define REG_FE_GDM_RX_ETH_BYTE_CNT_H(_n) (GDM_BASE(_n) + 0x29c) +-#define REG_FE_GDM_TX_ETH_E64_CNT_H(_n) (GDM_BASE(_n) + 0x2b8) +-#define REG_FE_GDM_TX_ETH_L64_CNT_H(_n) (GDM_BASE(_n) + 0x2bc) +-#define REG_FE_GDM_TX_ETH_L127_CNT_H(_n) (GDM_BASE(_n) + 0x2c0) +-#define REG_FE_GDM_TX_ETH_L255_CNT_H(_n) (GDM_BASE(_n) + 0x2c4) +-#define REG_FE_GDM_TX_ETH_L511_CNT_H(_n) (GDM_BASE(_n) + 0x2c8) +-#define REG_FE_GDM_TX_ETH_L1023_CNT_H(_n) (GDM_BASE(_n) + 0x2cc) +-#define REG_FE_GDM_RX_ETH_E64_CNT_H(_n) (GDM_BASE(_n) + 0x2e8) +-#define REG_FE_GDM_RX_ETH_L64_CNT_H(_n) (GDM_BASE(_n) + 0x2ec) +-#define REG_FE_GDM_RX_ETH_L127_CNT_H(_n) (GDM_BASE(_n) + 0x2f0) +-#define REG_FE_GDM_RX_ETH_L255_CNT_H(_n) (GDM_BASE(_n) + 0x2f4) +-#define REG_FE_GDM_RX_ETH_L511_CNT_H(_n) (GDM_BASE(_n) + 0x2f8) +-#define REG_FE_GDM_RX_ETH_L1023_CNT_H(_n) (GDM_BASE(_n) + 0x2fc) +- +-#define REG_GDM2_CHN_RLS (GDM2_BASE + 0x20) +-#define MBI_RX_AGE_SEL_MASK GENMASK(26, 25) +-#define MBI_TX_AGE_SEL_MASK GENMASK(18, 17) +- +-#define REG_GDM3_FWD_CFG GDM3_BASE +-#define GDM3_PAD_EN_MASK BIT(28) +- +-#define REG_GDM4_FWD_CFG GDM4_BASE +-#define GDM4_PAD_EN_MASK BIT(28) +-#define GDM4_SPORT_OFFSET0_MASK GENMASK(11, 8) +- +-#define REG_GDM4_SRC_PORT_SET (GDM4_BASE + 0x23c) +-#define GDM4_SPORT_OFF2_MASK GENMASK(19, 16) +-#define GDM4_SPORT_OFF1_MASK GENMASK(15, 12) +-#define GDM4_SPORT_OFF0_MASK GENMASK(11, 8) +- +-#define REG_IP_FRAG_FP 0x2010 +-#define IP_ASSEMBLE_PORT_MASK GENMASK(24, 21) +-#define IP_ASSEMBLE_NBQ_MASK GENMASK(20, 16) +-#define IP_FRAGMENT_PORT_MASK GENMASK(8, 5) +-#define IP_FRAGMENT_NBQ_MASK GENMASK(4, 0) +- +-#define REG_MC_VLAN_EN 0x2100 +-#define MC_VLAN_EN_MASK BIT(0) +- +-#define REG_MC_VLAN_CFG 0x2104 +-#define MC_VLAN_CFG_CMD_DONE_MASK BIT(31) +-#define MC_VLAN_CFG_TABLE_ID_MASK GENMASK(21, 16) +-#define MC_VLAN_CFG_PORT_ID_MASK GENMASK(11, 8) +-#define MC_VLAN_CFG_TABLE_SEL_MASK BIT(4) +-#define MC_VLAN_CFG_RW_MASK BIT(0) +- +-#define REG_MC_VLAN_DATA 0x2108 +- +-#define REG_CDM5_RX_OQ1_DROP_CNT 0x29d4 +- +-/* QDMA */ +-#define REG_QDMA_GLOBAL_CFG 0x0004 +-#define GLOBAL_CFG_RX_2B_OFFSET_MASK BIT(31) +-#define GLOBAL_CFG_DMA_PREFERENCE_MASK GENMASK(30, 29) +-#define GLOBAL_CFG_CPU_TXR_RR_MASK BIT(28) +-#define GLOBAL_CFG_DSCP_BYTE_SWAP_MASK BIT(27) +-#define GLOBAL_CFG_PAYLOAD_BYTE_SWAP_MASK BIT(26) +-#define GLOBAL_CFG_MULTICAST_MODIFY_FP_MASK BIT(25) +-#define GLOBAL_CFG_OAM_MODIFY_MASK BIT(24) +-#define GLOBAL_CFG_RESET_MASK BIT(23) +-#define GLOBAL_CFG_RESET_DONE_MASK BIT(22) +-#define GLOBAL_CFG_MULTICAST_EN_MASK BIT(21) +-#define GLOBAL_CFG_IRQ1_EN_MASK BIT(20) +-#define GLOBAL_CFG_IRQ0_EN_MASK BIT(19) +-#define GLOBAL_CFG_LOOPCNT_EN_MASK BIT(18) +-#define GLOBAL_CFG_RD_BYPASS_WR_MASK BIT(17) +-#define GLOBAL_CFG_QDMA_LOOPBACK_MASK BIT(16) +-#define GLOBAL_CFG_LPBK_RXQ_SEL_MASK GENMASK(13, 8) +-#define GLOBAL_CFG_CHECK_DONE_MASK BIT(7) +-#define GLOBAL_CFG_TX_WB_DONE_MASK BIT(6) +-#define GLOBAL_CFG_MAX_ISSUE_NUM_MASK GENMASK(5, 4) +-#define GLOBAL_CFG_RX_DMA_BUSY_MASK BIT(3) +-#define GLOBAL_CFG_RX_DMA_EN_MASK BIT(2) +-#define GLOBAL_CFG_TX_DMA_BUSY_MASK BIT(1) +-#define GLOBAL_CFG_TX_DMA_EN_MASK BIT(0) +- +-#define REG_FWD_DSCP_BASE 0x0010 +-#define REG_FWD_BUF_BASE 0x0014 +- +-#define REG_HW_FWD_DSCP_CFG 0x0018 +-#define HW_FWD_DSCP_PAYLOAD_SIZE_MASK GENMASK(29, 28) +-#define HW_FWD_DSCP_SCATTER_LEN_MASK GENMASK(17, 16) +-#define HW_FWD_DSCP_MIN_SCATTER_LEN_MASK GENMASK(15, 0) +- +-#define REG_INT_STATUS(_n) \ +- (((_n) == 4) ? 0x0730 : \ +- ((_n) == 3) ? 0x0724 : \ +- ((_n) == 2) ? 0x0720 : \ +- ((_n) == 1) ? 0x0024 : 0x0020) +- +-#define REG_INT_ENABLE(_n) \ +- (((_n) == 4) ? 0x0750 : \ +- ((_n) == 3) ? 0x0744 : \ +- ((_n) == 2) ? 0x0740 : \ +- ((_n) == 1) ? 0x002c : 0x0028) +- +-/* QDMA_CSR_INT_ENABLE1 */ +-#define RX15_COHERENT_INT_MASK BIT(31) +-#define RX14_COHERENT_INT_MASK BIT(30) +-#define RX13_COHERENT_INT_MASK BIT(29) +-#define RX12_COHERENT_INT_MASK BIT(28) +-#define RX11_COHERENT_INT_MASK BIT(27) +-#define RX10_COHERENT_INT_MASK BIT(26) +-#define RX9_COHERENT_INT_MASK BIT(25) +-#define RX8_COHERENT_INT_MASK BIT(24) +-#define RX7_COHERENT_INT_MASK BIT(23) +-#define RX6_COHERENT_INT_MASK BIT(22) +-#define RX5_COHERENT_INT_MASK BIT(21) +-#define RX4_COHERENT_INT_MASK BIT(20) +-#define RX3_COHERENT_INT_MASK BIT(19) +-#define RX2_COHERENT_INT_MASK BIT(18) +-#define RX1_COHERENT_INT_MASK BIT(17) +-#define RX0_COHERENT_INT_MASK BIT(16) +-#define TX7_COHERENT_INT_MASK BIT(15) +-#define TX6_COHERENT_INT_MASK BIT(14) +-#define TX5_COHERENT_INT_MASK BIT(13) +-#define TX4_COHERENT_INT_MASK BIT(12) +-#define TX3_COHERENT_INT_MASK BIT(11) +-#define TX2_COHERENT_INT_MASK BIT(10) +-#define TX1_COHERENT_INT_MASK BIT(9) +-#define TX0_COHERENT_INT_MASK BIT(8) +-#define CNT_OVER_FLOW_INT_MASK BIT(7) +-#define IRQ1_FULL_INT_MASK BIT(5) +-#define IRQ1_INT_MASK BIT(4) +-#define HWFWD_DSCP_LOW_INT_MASK BIT(3) +-#define HWFWD_DSCP_EMPTY_INT_MASK BIT(2) +-#define IRQ0_FULL_INT_MASK BIT(1) +-#define IRQ0_INT_MASK BIT(0) +- +-#define TX_DONE_INT_MASK(_n) \ +- ((_n) ? IRQ1_INT_MASK | IRQ1_FULL_INT_MASK \ +- : IRQ0_INT_MASK | IRQ0_FULL_INT_MASK) +- +-#define INT_TX_MASK \ +- (IRQ1_INT_MASK | IRQ1_FULL_INT_MASK | \ +- IRQ0_INT_MASK | IRQ0_FULL_INT_MASK) +- +-#define INT_IDX0_MASK \ +- (TX0_COHERENT_INT_MASK | TX1_COHERENT_INT_MASK | \ +- TX2_COHERENT_INT_MASK | TX3_COHERENT_INT_MASK | \ +- TX4_COHERENT_INT_MASK | TX5_COHERENT_INT_MASK | \ +- TX6_COHERENT_INT_MASK | TX7_COHERENT_INT_MASK | \ +- RX0_COHERENT_INT_MASK | RX1_COHERENT_INT_MASK | \ +- RX2_COHERENT_INT_MASK | RX3_COHERENT_INT_MASK | \ +- RX4_COHERENT_INT_MASK | RX7_COHERENT_INT_MASK | \ +- RX8_COHERENT_INT_MASK | RX9_COHERENT_INT_MASK | \ +- RX15_COHERENT_INT_MASK | INT_TX_MASK) +- +-/* QDMA_CSR_INT_ENABLE2 */ +-#define RX15_NO_CPU_DSCP_INT_MASK BIT(31) +-#define RX14_NO_CPU_DSCP_INT_MASK BIT(30) +-#define RX13_NO_CPU_DSCP_INT_MASK BIT(29) +-#define RX12_NO_CPU_DSCP_INT_MASK BIT(28) +-#define RX11_NO_CPU_DSCP_INT_MASK BIT(27) +-#define RX10_NO_CPU_DSCP_INT_MASK BIT(26) +-#define RX9_NO_CPU_DSCP_INT_MASK BIT(25) +-#define RX8_NO_CPU_DSCP_INT_MASK BIT(24) +-#define RX7_NO_CPU_DSCP_INT_MASK BIT(23) +-#define RX6_NO_CPU_DSCP_INT_MASK BIT(22) +-#define RX5_NO_CPU_DSCP_INT_MASK BIT(21) +-#define RX4_NO_CPU_DSCP_INT_MASK BIT(20) +-#define RX3_NO_CPU_DSCP_INT_MASK BIT(19) +-#define RX2_NO_CPU_DSCP_INT_MASK BIT(18) +-#define RX1_NO_CPU_DSCP_INT_MASK BIT(17) +-#define RX0_NO_CPU_DSCP_INT_MASK BIT(16) +-#define RX15_DONE_INT_MASK BIT(15) +-#define RX14_DONE_INT_MASK BIT(14) +-#define RX13_DONE_INT_MASK BIT(13) +-#define RX12_DONE_INT_MASK BIT(12) +-#define RX11_DONE_INT_MASK BIT(11) +-#define RX10_DONE_INT_MASK BIT(10) +-#define RX9_DONE_INT_MASK BIT(9) +-#define RX8_DONE_INT_MASK BIT(8) +-#define RX7_DONE_INT_MASK BIT(7) +-#define RX6_DONE_INT_MASK BIT(6) +-#define RX5_DONE_INT_MASK BIT(5) +-#define RX4_DONE_INT_MASK BIT(4) +-#define RX3_DONE_INT_MASK BIT(3) +-#define RX2_DONE_INT_MASK BIT(2) +-#define RX1_DONE_INT_MASK BIT(1) +-#define RX0_DONE_INT_MASK BIT(0) +- +-#define RX_DONE_INT_MASK \ +- (RX0_DONE_INT_MASK | RX1_DONE_INT_MASK | \ +- RX2_DONE_INT_MASK | RX3_DONE_INT_MASK | \ +- RX4_DONE_INT_MASK | RX7_DONE_INT_MASK | \ +- RX8_DONE_INT_MASK | RX9_DONE_INT_MASK | \ +- RX15_DONE_INT_MASK) +-#define INT_IDX1_MASK \ +- (RX_DONE_INT_MASK | \ +- RX0_NO_CPU_DSCP_INT_MASK | RX1_NO_CPU_DSCP_INT_MASK | \ +- RX2_NO_CPU_DSCP_INT_MASK | RX3_NO_CPU_DSCP_INT_MASK | \ +- RX4_NO_CPU_DSCP_INT_MASK | RX7_NO_CPU_DSCP_INT_MASK | \ +- RX8_NO_CPU_DSCP_INT_MASK | RX9_NO_CPU_DSCP_INT_MASK | \ +- RX15_NO_CPU_DSCP_INT_MASK) +- +-/* QDMA_CSR_INT_ENABLE5 */ +-#define TX31_COHERENT_INT_MASK BIT(31) +-#define TX30_COHERENT_INT_MASK BIT(30) +-#define TX29_COHERENT_INT_MASK BIT(29) +-#define TX28_COHERENT_INT_MASK BIT(28) +-#define TX27_COHERENT_INT_MASK BIT(27) +-#define TX26_COHERENT_INT_MASK BIT(26) +-#define TX25_COHERENT_INT_MASK BIT(25) +-#define TX24_COHERENT_INT_MASK BIT(24) +-#define TX23_COHERENT_INT_MASK BIT(23) +-#define TX22_COHERENT_INT_MASK BIT(22) +-#define TX21_COHERENT_INT_MASK BIT(21) +-#define TX20_COHERENT_INT_MASK BIT(20) +-#define TX19_COHERENT_INT_MASK BIT(19) +-#define TX18_COHERENT_INT_MASK BIT(18) +-#define TX17_COHERENT_INT_MASK BIT(17) +-#define TX16_COHERENT_INT_MASK BIT(16) +-#define TX15_COHERENT_INT_MASK BIT(15) +-#define TX14_COHERENT_INT_MASK BIT(14) +-#define TX13_COHERENT_INT_MASK BIT(13) +-#define TX12_COHERENT_INT_MASK BIT(12) +-#define TX11_COHERENT_INT_MASK BIT(11) +-#define TX10_COHERENT_INT_MASK BIT(10) +-#define TX9_COHERENT_INT_MASK BIT(9) +-#define TX8_COHERENT_INT_MASK BIT(8) +- +-#define INT_IDX4_MASK \ +- (TX8_COHERENT_INT_MASK | TX9_COHERENT_INT_MASK | \ +- TX10_COHERENT_INT_MASK | TX11_COHERENT_INT_MASK | \ +- TX12_COHERENT_INT_MASK | TX13_COHERENT_INT_MASK | \ +- TX14_COHERENT_INT_MASK | TX15_COHERENT_INT_MASK | \ +- TX16_COHERENT_INT_MASK | TX17_COHERENT_INT_MASK | \ +- TX18_COHERENT_INT_MASK | TX19_COHERENT_INT_MASK | \ +- TX20_COHERENT_INT_MASK | TX21_COHERENT_INT_MASK | \ +- TX22_COHERENT_INT_MASK | TX23_COHERENT_INT_MASK | \ +- TX24_COHERENT_INT_MASK | TX25_COHERENT_INT_MASK | \ +- TX26_COHERENT_INT_MASK | TX27_COHERENT_INT_MASK | \ +- TX28_COHERENT_INT_MASK | TX29_COHERENT_INT_MASK | \ +- TX30_COHERENT_INT_MASK | TX31_COHERENT_INT_MASK) +- +-#define REG_TX_IRQ_BASE(_n) ((_n) ? 0x0048 : 0x0050) +- +-#define REG_TX_IRQ_CFG(_n) ((_n) ? 0x004c : 0x0054) +-#define TX_IRQ_THR_MASK GENMASK(27, 16) +-#define TX_IRQ_DEPTH_MASK GENMASK(11, 0) +- +-#define REG_IRQ_CLEAR_LEN(_n) ((_n) ? 0x0064 : 0x0058) +-#define IRQ_CLEAR_LEN_MASK GENMASK(7, 0) +- +-#define REG_IRQ_STATUS(_n) ((_n) ? 0x0068 : 0x005c) +-#define IRQ_ENTRY_LEN_MASK GENMASK(27, 16) +-#define IRQ_HEAD_IDX_MASK GENMASK(11, 0) +- +-#define REG_TX_RING_BASE(_n) \ +- (((_n) < 8) ? 0x0100 + ((_n) << 5) : 0x0b00 + (((_n) - 8) << 5)) +- +-#define REG_TX_RING_BLOCKING(_n) \ +- (((_n) < 8) ? 0x0104 + ((_n) << 5) : 0x0b04 + (((_n) - 8) << 5)) +- +-#define TX_RING_IRQ_BLOCKING_MAP_MASK BIT(6) +-#define TX_RING_IRQ_BLOCKING_CFG_MASK BIT(4) +-#define TX_RING_IRQ_BLOCKING_TX_DROP_EN_MASK BIT(2) +-#define TX_RING_IRQ_BLOCKING_MAX_TH_TXRING_EN_MASK BIT(1) +-#define TX_RING_IRQ_BLOCKING_MIN_TH_TXRING_EN_MASK BIT(0) +- +-#define REG_TX_CPU_IDX(_n) \ +- (((_n) < 8) ? 0x0108 + ((_n) << 5) : 0x0b08 + (((_n) - 8) << 5)) +- +-#define TX_RING_CPU_IDX_MASK GENMASK(15, 0) +- +-#define REG_TX_DMA_IDX(_n) \ +- (((_n) < 8) ? 0x010c + ((_n) << 5) : 0x0b0c + (((_n) - 8) << 5)) +- +-#define TX_RING_DMA_IDX_MASK GENMASK(15, 0) +- +-#define IRQ_RING_IDX_MASK GENMASK(20, 16) +-#define IRQ_DESC_IDX_MASK GENMASK(15, 0) +- +-#define REG_RX_RING_BASE(_n) \ +- (((_n) < 16) ? 0x0200 + ((_n) << 5) : 0x0e00 + (((_n) - 16) << 5)) +- +-#define REG_RX_RING_SIZE(_n) \ +- (((_n) < 16) ? 0x0204 + ((_n) << 5) : 0x0e04 + (((_n) - 16) << 5)) +- +-#define RX_RING_THR_MASK GENMASK(31, 16) +-#define RX_RING_SIZE_MASK GENMASK(15, 0) +- +-#define REG_RX_CPU_IDX(_n) \ +- (((_n) < 16) ? 0x0208 + ((_n) << 5) : 0x0e08 + (((_n) - 16) << 5)) +- +-#define RX_RING_CPU_IDX_MASK GENMASK(15, 0) +- +-#define REG_RX_DMA_IDX(_n) \ +- (((_n) < 16) ? 0x020c + ((_n) << 5) : 0x0e0c + (((_n) - 16) << 5)) +- +-#define REG_RX_DELAY_INT_IDX(_n) \ +- (((_n) < 16) ? 0x0210 + ((_n) << 5) : 0x0e10 + (((_n) - 16) << 5)) +- +-#define RX_DELAY_INT_MASK GENMASK(15, 0) +- +-#define RX_RING_DMA_IDX_MASK GENMASK(15, 0) +- +-#define REG_INGRESS_TRTCM_CFG 0x0070 +-#define INGRESS_TRTCM_EN_MASK BIT(31) +-#define INGRESS_TRTCM_MODE_MASK BIT(30) +-#define INGRESS_SLOW_TICK_RATIO_MASK GENMASK(29, 16) +-#define INGRESS_FAST_TICK_MASK GENMASK(15, 0) +- +-#define REG_QUEUE_CLOSE_CFG(_n) (0x00a0 + ((_n) & 0xfc)) +-#define TXQ_DISABLE_CHAN_QUEUE_MASK(_n, _m) BIT((_m) + (((_n) & 0x3) << 3)) +- +-#define REG_TXQ_DIS_CFG_BASE(_n) ((_n) ? 0x20a0 : 0x00a0) +-#define REG_TXQ_DIS_CFG(_n, _m) (REG_TXQ_DIS_CFG_BASE((_n)) + (_m) << 2) +- +-#define REG_CNTR_CFG(_n) (0x0400 + ((_n) << 3)) +-#define CNTR_EN_MASK BIT(31) +-#define CNTR_ALL_CHAN_EN_MASK BIT(30) +-#define CNTR_ALL_QUEUE_EN_MASK BIT(29) +-#define CNTR_ALL_DSCP_RING_EN_MASK BIT(28) +-#define CNTR_SRC_MASK GENMASK(27, 24) +-#define CNTR_DSCP_RING_MASK GENMASK(20, 16) +-#define CNTR_CHAN_MASK GENMASK(7, 3) +-#define CNTR_QUEUE_MASK GENMASK(2, 0) +- +-#define REG_CNTR_VAL(_n) (0x0404 + ((_n) << 3)) +- +-#define REG_LMGR_INIT_CFG 0x1000 +-#define LMGR_INIT_START BIT(31) +-#define LMGR_SRAM_MODE_MASK BIT(30) +-#define HW_FWD_PKTSIZE_OVERHEAD_MASK GENMASK(27, 20) +-#define HW_FWD_DESC_NUM_MASK GENMASK(16, 0) +- +-#define REG_FWD_DSCP_LOW_THR 0x1004 +-#define FWD_DSCP_LOW_THR_MASK GENMASK(17, 0) +- +-#define REG_EGRESS_RATE_METER_CFG 0x100c +-#define EGRESS_RATE_METER_EN_MASK BIT(31) +-#define EGRESS_RATE_METER_EQ_RATE_EN_MASK BIT(17) +-#define EGRESS_RATE_METER_WINDOW_SZ_MASK GENMASK(16, 12) +-#define EGRESS_RATE_METER_TIMESLICE_MASK GENMASK(10, 0) +- +-#define REG_EGRESS_TRTCM_CFG 0x1010 +-#define EGRESS_TRTCM_EN_MASK BIT(31) +-#define EGRESS_TRTCM_MODE_MASK BIT(30) +-#define EGRESS_SLOW_TICK_RATIO_MASK GENMASK(29, 16) +-#define EGRESS_FAST_TICK_MASK GENMASK(15, 0) +- +-#define TRTCM_PARAM_RW_MASK BIT(31) +-#define TRTCM_PARAM_RW_DONE_MASK BIT(30) +-#define TRTCM_PARAM_TYPE_MASK GENMASK(29, 28) +-#define TRTCM_METER_GROUP_MASK GENMASK(27, 26) +-#define TRTCM_PARAM_INDEX_MASK GENMASK(23, 17) +-#define TRTCM_PARAM_RATE_TYPE_MASK BIT(16) +- +-#define REG_TRTCM_CFG_PARAM(_n) ((_n) + 0x4) +-#define REG_TRTCM_DATA_LOW(_n) ((_n) + 0x8) +-#define REG_TRTCM_DATA_HIGH(_n) ((_n) + 0xc) +- +-#define REG_TXWRR_MODE_CFG 0x1020 +-#define TWRR_WEIGHT_SCALE_MASK BIT(31) +-#define TWRR_WEIGHT_BASE_MASK BIT(3) +- +-#define REG_TXWRR_WEIGHT_CFG 0x1024 +-#define TWRR_RW_CMD_MASK BIT(31) +-#define TWRR_RW_CMD_DONE BIT(30) +-#define TWRR_CHAN_IDX_MASK GENMASK(23, 19) +-#define TWRR_QUEUE_IDX_MASK GENMASK(18, 16) +-#define TWRR_VALUE_MASK GENMASK(15, 0) +- +-#define REG_PSE_BUF_USAGE_CFG 0x1028 +-#define PSE_BUF_ESTIMATE_EN_MASK BIT(29) +- +-#define REG_CHAN_QOS_MODE(_n) (0x1040 + ((_n) << 2)) +-#define CHAN_QOS_MODE_MASK(_n) GENMASK(2 + ((_n) << 2), (_n) << 2) +- +-#define REG_GLB_TRTCM_CFG 0x1080 +-#define GLB_TRTCM_EN_MASK BIT(31) +-#define GLB_TRTCM_MODE_MASK BIT(30) +-#define GLB_SLOW_TICK_RATIO_MASK GENMASK(29, 16) +-#define GLB_FAST_TICK_MASK GENMASK(15, 0) +- +-#define REG_TXQ_CNGST_CFG 0x10a0 +-#define TXQ_CNGST_DROP_EN BIT(31) +-#define TXQ_CNGST_DEI_DROP_EN BIT(30) +- +-#define REG_SLA_TRTCM_CFG 0x1150 +-#define SLA_TRTCM_EN_MASK BIT(31) +-#define SLA_TRTCM_MODE_MASK BIT(30) +-#define SLA_SLOW_TICK_RATIO_MASK GENMASK(29, 16) +-#define SLA_FAST_TICK_MASK GENMASK(15, 0) +- +-/* CTRL */ +-#define QDMA_DESC_DONE_MASK BIT(31) +-#define QDMA_DESC_DROP_MASK BIT(30) /* tx: drop - rx: overflow */ +-#define QDMA_DESC_MORE_MASK BIT(29) /* more SG elements */ +-#define QDMA_DESC_DEI_MASK BIT(25) +-#define QDMA_DESC_NO_DROP_MASK BIT(24) +-#define QDMA_DESC_LEN_MASK GENMASK(15, 0) +-/* DATA */ +-#define QDMA_DESC_NEXT_ID_MASK GENMASK(15, 0) +-/* TX MSG0 */ +-#define QDMA_ETH_TXMSG_MIC_IDX_MASK BIT(30) +-#define QDMA_ETH_TXMSG_SP_TAG_MASK GENMASK(29, 14) +-#define QDMA_ETH_TXMSG_ICO_MASK BIT(13) +-#define QDMA_ETH_TXMSG_UCO_MASK BIT(12) +-#define QDMA_ETH_TXMSG_TCO_MASK BIT(11) +-#define QDMA_ETH_TXMSG_TSO_MASK BIT(10) +-#define QDMA_ETH_TXMSG_FAST_MASK BIT(9) +-#define QDMA_ETH_TXMSG_OAM_MASK BIT(8) +-#define QDMA_ETH_TXMSG_CHAN_MASK GENMASK(7, 3) +-#define QDMA_ETH_TXMSG_QUEUE_MASK GENMASK(2, 0) +-/* TX MSG1 */ +-#define QDMA_ETH_TXMSG_NO_DROP BIT(31) +-#define QDMA_ETH_TXMSG_METER_MASK GENMASK(30, 24) /* 0x7f no meters */ +-#define QDMA_ETH_TXMSG_FPORT_MASK GENMASK(23, 20) +-#define QDMA_ETH_TXMSG_NBOQ_MASK GENMASK(19, 15) +-#define QDMA_ETH_TXMSG_HWF_MASK BIT(14) +-#define QDMA_ETH_TXMSG_HOP_MASK BIT(13) +-#define QDMA_ETH_TXMSG_PTP_MASK BIT(12) +-#define QDMA_ETH_TXMSG_ACNT_G1_MASK GENMASK(10, 6) /* 0x1f do not count */ +-#define QDMA_ETH_TXMSG_ACNT_G0_MASK GENMASK(5, 0) /* 0x3f do not count */ +- +-/* RX MSG1 */ +-#define QDMA_ETH_RXMSG_DEI_MASK BIT(31) +-#define QDMA_ETH_RXMSG_IP6_MASK BIT(30) +-#define QDMA_ETH_RXMSG_IP4_MASK BIT(29) +-#define QDMA_ETH_RXMSG_IP4F_MASK BIT(28) +-#define QDMA_ETH_RXMSG_L4_VALID_MASK BIT(27) +-#define QDMA_ETH_RXMSG_L4F_MASK BIT(26) +-#define QDMA_ETH_RXMSG_SPORT_MASK GENMASK(25, 21) +-#define QDMA_ETH_RXMSG_CRSN_MASK GENMASK(20, 16) +-#define QDMA_ETH_RXMSG_PPE_ENTRY_MASK GENMASK(15, 0) +- +-struct airoha_qdma_desc { +- __le32 rsv; +- __le32 ctrl; +- __le32 addr; +- __le32 data; +- __le32 msg0; +- __le32 msg1; +- __le32 msg2; +- __le32 msg3; +-}; +- +-/* CTRL0 */ +-#define QDMA_FWD_DESC_CTX_MASK BIT(31) +-#define QDMA_FWD_DESC_RING_MASK GENMASK(30, 28) +-#define QDMA_FWD_DESC_IDX_MASK GENMASK(27, 16) +-#define QDMA_FWD_DESC_LEN_MASK GENMASK(15, 0) +-/* CTRL1 */ +-#define QDMA_FWD_DESC_FIRST_IDX_MASK GENMASK(15, 0) +-/* CTRL2 */ +-#define QDMA_FWD_DESC_MORE_PKT_NUM_MASK GENMASK(2, 0) +- +-struct airoha_qdma_fwd_desc { +- __le32 addr; +- __le32 ctrl0; +- __le32 ctrl1; +- __le32 ctrl2; +- __le32 msg0; +- __le32 msg1; +- __le32 rsv0; +- __le32 rsv1; +-}; +- + u32 airoha_rr(void __iomem *base, u32 offset) + { + return readl(base + offset); +--- /dev/null ++++ b/drivers/net/ethernet/airoha/airoha_regs.h +@@ -0,0 +1,670 @@ ++/* SPDX-License-Identifier: GPL-2.0-only */ ++/* ++ * Copyright (c) 2024 AIROHA Inc ++ * Author: Lorenzo Bianconi ++ */ ++ ++#ifndef AIROHA_REGS_H ++#define AIROHA_REGS_H ++ ++#include ++ ++/* FE */ ++#define PSE_BASE 0x0100 ++#define CSR_IFC_BASE 0x0200 ++#define CDM1_BASE 0x0400 ++#define GDM1_BASE 0x0500 ++#define PPE1_BASE 0x0c00 ++ ++#define CDM2_BASE 0x1400 ++#define GDM2_BASE 0x1500 ++ ++#define GDM3_BASE 0x1100 ++#define GDM4_BASE 0x2500 ++ ++#define GDM_BASE(_n) \ ++ ((_n) == 4 ? GDM4_BASE : \ ++ (_n) == 3 ? GDM3_BASE : \ ++ (_n) == 2 ? GDM2_BASE : GDM1_BASE) ++ ++#define REG_FE_DMA_GLO_CFG 0x0000 ++#define FE_DMA_GLO_L2_SPACE_MASK GENMASK(7, 4) ++#define FE_DMA_GLO_PG_SZ_MASK BIT(3) ++ ++#define REG_FE_RST_GLO_CFG 0x0004 ++#define FE_RST_GDM4_MBI_ARB_MASK BIT(3) ++#define FE_RST_GDM3_MBI_ARB_MASK BIT(2) ++#define FE_RST_CORE_MASK BIT(0) ++ ++#define REG_FE_WAN_MAC_H 0x0030 ++#define REG_FE_LAN_MAC_H 0x0040 ++ ++#define REG_FE_MAC_LMIN(_n) ((_n) + 0x04) ++#define REG_FE_MAC_LMAX(_n) ((_n) + 0x08) ++ ++#define REG_FE_CDM1_OQ_MAP0 0x0050 ++#define REG_FE_CDM1_OQ_MAP1 0x0054 ++#define REG_FE_CDM1_OQ_MAP2 0x0058 ++#define REG_FE_CDM1_OQ_MAP3 0x005c ++ ++#define REG_FE_PCE_CFG 0x0070 ++#define PCE_DPI_EN_MASK BIT(2) ++#define PCE_KA_EN_MASK BIT(1) ++#define PCE_MC_EN_MASK BIT(0) ++ ++#define REG_FE_PSE_QUEUE_CFG_WR 0x0080 ++#define PSE_CFG_PORT_ID_MASK GENMASK(27, 24) ++#define PSE_CFG_QUEUE_ID_MASK GENMASK(20, 16) ++#define PSE_CFG_WR_EN_MASK BIT(8) ++#define PSE_CFG_OQRSV_SEL_MASK BIT(0) ++ ++#define REG_FE_PSE_QUEUE_CFG_VAL 0x0084 ++#define PSE_CFG_OQ_RSV_MASK GENMASK(13, 0) ++ ++#define PSE_FQ_CFG 0x008c ++#define PSE_FQ_LIMIT_MASK GENMASK(14, 0) ++ ++#define REG_FE_PSE_BUF_SET 0x0090 ++#define PSE_SHARE_USED_LTHD_MASK GENMASK(31, 16) ++#define PSE_ALLRSV_MASK GENMASK(14, 0) ++ ++#define REG_PSE_SHARE_USED_THD 0x0094 ++#define PSE_SHARE_USED_MTHD_MASK GENMASK(31, 16) ++#define PSE_SHARE_USED_HTHD_MASK GENMASK(15, 0) ++ ++#define REG_GDM_MISC_CFG 0x0148 ++#define GDM2_RDM_ACK_WAIT_PREF_MASK BIT(9) ++#define GDM2_CHN_VLD_MODE_MASK BIT(5) ++ ++#define REG_FE_CSR_IFC_CFG CSR_IFC_BASE ++#define FE_IFC_EN_MASK BIT(0) ++ ++#define REG_FE_VIP_PORT_EN 0x01f0 ++#define REG_FE_IFC_PORT_EN 0x01f4 ++ ++#define REG_PSE_IQ_REV1 (PSE_BASE + 0x08) ++#define PSE_IQ_RES1_P2_MASK GENMASK(23, 16) ++ ++#define REG_PSE_IQ_REV2 (PSE_BASE + 0x0c) ++#define PSE_IQ_RES2_P5_MASK GENMASK(15, 8) ++#define PSE_IQ_RES2_P4_MASK GENMASK(7, 0) ++ ++#define REG_FE_VIP_EN(_n) (0x0300 + ((_n) << 3)) ++#define PATN_FCPU_EN_MASK BIT(7) ++#define PATN_SWP_EN_MASK BIT(6) ++#define PATN_DP_EN_MASK BIT(5) ++#define PATN_SP_EN_MASK BIT(4) ++#define PATN_TYPE_MASK GENMASK(3, 1) ++#define PATN_EN_MASK BIT(0) ++ ++#define REG_FE_VIP_PATN(_n) (0x0304 + ((_n) << 3)) ++#define PATN_DP_MASK GENMASK(31, 16) ++#define PATN_SP_MASK GENMASK(15, 0) ++ ++#define REG_CDM1_VLAN_CTRL CDM1_BASE ++#define CDM1_VLAN_MASK GENMASK(31, 16) ++ ++#define REG_CDM1_FWD_CFG (CDM1_BASE + 0x08) ++#define CDM1_VIP_QSEL_MASK GENMASK(24, 20) ++ ++#define REG_CDM1_CRSN_QSEL(_n) (CDM1_BASE + 0x10 + ((_n) << 2)) ++#define CDM1_CRSN_QSEL_REASON_MASK(_n) \ ++ GENMASK(4 + (((_n) % 4) << 3), (((_n) % 4) << 3)) ++ ++#define REG_CDM2_FWD_CFG (CDM2_BASE + 0x08) ++#define CDM2_OAM_QSEL_MASK GENMASK(31, 27) ++#define CDM2_VIP_QSEL_MASK GENMASK(24, 20) ++ ++#define REG_CDM2_CRSN_QSEL(_n) (CDM2_BASE + 0x10 + ((_n) << 2)) ++#define CDM2_CRSN_QSEL_REASON_MASK(_n) \ ++ GENMASK(4 + (((_n) % 4) << 3), (((_n) % 4) << 3)) ++ ++#define REG_GDM_FWD_CFG(_n) GDM_BASE(_n) ++#define GDM_DROP_CRC_ERR BIT(23) ++#define GDM_IP4_CKSUM BIT(22) ++#define GDM_TCP_CKSUM BIT(21) ++#define GDM_UDP_CKSUM BIT(20) ++#define GDM_UCFQ_MASK GENMASK(15, 12) ++#define GDM_BCFQ_MASK GENMASK(11, 8) ++#define GDM_MCFQ_MASK GENMASK(7, 4) ++#define GDM_OCFQ_MASK GENMASK(3, 0) ++ ++#define REG_GDM_INGRESS_CFG(_n) (GDM_BASE(_n) + 0x10) ++#define GDM_INGRESS_FC_EN_MASK BIT(1) ++#define GDM_STAG_EN_MASK BIT(0) ++ ++#define REG_GDM_LEN_CFG(_n) (GDM_BASE(_n) + 0x14) ++#define GDM_SHORT_LEN_MASK GENMASK(13, 0) ++#define GDM_LONG_LEN_MASK GENMASK(29, 16) ++ ++#define REG_FE_CPORT_CFG (GDM1_BASE + 0x40) ++#define FE_CPORT_PAD BIT(26) ++#define FE_CPORT_PORT_XFC_MASK BIT(25) ++#define FE_CPORT_QUEUE_XFC_MASK BIT(24) ++ ++#define REG_FE_GDM_MIB_CLEAR(_n) (GDM_BASE(_n) + 0xf0) ++#define FE_GDM_MIB_RX_CLEAR_MASK BIT(1) ++#define FE_GDM_MIB_TX_CLEAR_MASK BIT(0) ++ ++#define REG_FE_GDM1_MIB_CFG (GDM1_BASE + 0xf4) ++#define FE_STRICT_RFC2819_MODE_MASK BIT(31) ++#define FE_GDM1_TX_MIB_SPLIT_EN_MASK BIT(17) ++#define FE_GDM1_RX_MIB_SPLIT_EN_MASK BIT(16) ++#define FE_TX_MIB_ID_MASK GENMASK(15, 8) ++#define FE_RX_MIB_ID_MASK GENMASK(7, 0) ++ ++#define REG_FE_GDM_TX_OK_PKT_CNT_L(_n) (GDM_BASE(_n) + 0x104) ++#define REG_FE_GDM_TX_OK_BYTE_CNT_L(_n) (GDM_BASE(_n) + 0x10c) ++#define REG_FE_GDM_TX_ETH_PKT_CNT_L(_n) (GDM_BASE(_n) + 0x110) ++#define REG_FE_GDM_TX_ETH_BYTE_CNT_L(_n) (GDM_BASE(_n) + 0x114) ++#define REG_FE_GDM_TX_ETH_DROP_CNT(_n) (GDM_BASE(_n) + 0x118) ++#define REG_FE_GDM_TX_ETH_BC_CNT(_n) (GDM_BASE(_n) + 0x11c) ++#define REG_FE_GDM_TX_ETH_MC_CNT(_n) (GDM_BASE(_n) + 0x120) ++#define REG_FE_GDM_TX_ETH_RUNT_CNT(_n) (GDM_BASE(_n) + 0x124) ++#define REG_FE_GDM_TX_ETH_LONG_CNT(_n) (GDM_BASE(_n) + 0x128) ++#define REG_FE_GDM_TX_ETH_E64_CNT_L(_n) (GDM_BASE(_n) + 0x12c) ++#define REG_FE_GDM_TX_ETH_L64_CNT_L(_n) (GDM_BASE(_n) + 0x130) ++#define REG_FE_GDM_TX_ETH_L127_CNT_L(_n) (GDM_BASE(_n) + 0x134) ++#define REG_FE_GDM_TX_ETH_L255_CNT_L(_n) (GDM_BASE(_n) + 0x138) ++#define REG_FE_GDM_TX_ETH_L511_CNT_L(_n) (GDM_BASE(_n) + 0x13c) ++#define REG_FE_GDM_TX_ETH_L1023_CNT_L(_n) (GDM_BASE(_n) + 0x140) ++ ++#define REG_FE_GDM_RX_OK_PKT_CNT_L(_n) (GDM_BASE(_n) + 0x148) ++#define REG_FE_GDM_RX_FC_DROP_CNT(_n) (GDM_BASE(_n) + 0x14c) ++#define REG_FE_GDM_RX_RC_DROP_CNT(_n) (GDM_BASE(_n) + 0x150) ++#define REG_FE_GDM_RX_OVERFLOW_DROP_CNT(_n) (GDM_BASE(_n) + 0x154) ++#define REG_FE_GDM_RX_ERROR_DROP_CNT(_n) (GDM_BASE(_n) + 0x158) ++#define REG_FE_GDM_RX_OK_BYTE_CNT_L(_n) (GDM_BASE(_n) + 0x15c) ++#define REG_FE_GDM_RX_ETH_PKT_CNT_L(_n) (GDM_BASE(_n) + 0x160) ++#define REG_FE_GDM_RX_ETH_BYTE_CNT_L(_n) (GDM_BASE(_n) + 0x164) ++#define REG_FE_GDM_RX_ETH_DROP_CNT(_n) (GDM_BASE(_n) + 0x168) ++#define REG_FE_GDM_RX_ETH_BC_CNT(_n) (GDM_BASE(_n) + 0x16c) ++#define REG_FE_GDM_RX_ETH_MC_CNT(_n) (GDM_BASE(_n) + 0x170) ++#define REG_FE_GDM_RX_ETH_CRC_ERR_CNT(_n) (GDM_BASE(_n) + 0x174) ++#define REG_FE_GDM_RX_ETH_FRAG_CNT(_n) (GDM_BASE(_n) + 0x178) ++#define REG_FE_GDM_RX_ETH_JABBER_CNT(_n) (GDM_BASE(_n) + 0x17c) ++#define REG_FE_GDM_RX_ETH_RUNT_CNT(_n) (GDM_BASE(_n) + 0x180) ++#define REG_FE_GDM_RX_ETH_LONG_CNT(_n) (GDM_BASE(_n) + 0x184) ++#define REG_FE_GDM_RX_ETH_E64_CNT_L(_n) (GDM_BASE(_n) + 0x188) ++#define REG_FE_GDM_RX_ETH_L64_CNT_L(_n) (GDM_BASE(_n) + 0x18c) ++#define REG_FE_GDM_RX_ETH_L127_CNT_L(_n) (GDM_BASE(_n) + 0x190) ++#define REG_FE_GDM_RX_ETH_L255_CNT_L(_n) (GDM_BASE(_n) + 0x194) ++#define REG_FE_GDM_RX_ETH_L511_CNT_L(_n) (GDM_BASE(_n) + 0x198) ++#define REG_FE_GDM_RX_ETH_L1023_CNT_L(_n) (GDM_BASE(_n) + 0x19c) ++ ++#define REG_PPE1_TB_HASH_CFG (PPE1_BASE + 0x250) ++#define PPE1_SRAM_TABLE_EN_MASK BIT(0) ++#define PPE1_SRAM_HASH1_EN_MASK BIT(8) ++#define PPE1_DRAM_TABLE_EN_MASK BIT(16) ++#define PPE1_DRAM_HASH1_EN_MASK BIT(24) ++ ++#define REG_FE_GDM_TX_OK_PKT_CNT_H(_n) (GDM_BASE(_n) + 0x280) ++#define REG_FE_GDM_TX_OK_BYTE_CNT_H(_n) (GDM_BASE(_n) + 0x284) ++#define REG_FE_GDM_TX_ETH_PKT_CNT_H(_n) (GDM_BASE(_n) + 0x288) ++#define REG_FE_GDM_TX_ETH_BYTE_CNT_H(_n) (GDM_BASE(_n) + 0x28c) ++ ++#define REG_FE_GDM_RX_OK_PKT_CNT_H(_n) (GDM_BASE(_n) + 0x290) ++#define REG_FE_GDM_RX_OK_BYTE_CNT_H(_n) (GDM_BASE(_n) + 0x294) ++#define REG_FE_GDM_RX_ETH_PKT_CNT_H(_n) (GDM_BASE(_n) + 0x298) ++#define REG_FE_GDM_RX_ETH_BYTE_CNT_H(_n) (GDM_BASE(_n) + 0x29c) ++#define REG_FE_GDM_TX_ETH_E64_CNT_H(_n) (GDM_BASE(_n) + 0x2b8) ++#define REG_FE_GDM_TX_ETH_L64_CNT_H(_n) (GDM_BASE(_n) + 0x2bc) ++#define REG_FE_GDM_TX_ETH_L127_CNT_H(_n) (GDM_BASE(_n) + 0x2c0) ++#define REG_FE_GDM_TX_ETH_L255_CNT_H(_n) (GDM_BASE(_n) + 0x2c4) ++#define REG_FE_GDM_TX_ETH_L511_CNT_H(_n) (GDM_BASE(_n) + 0x2c8) ++#define REG_FE_GDM_TX_ETH_L1023_CNT_H(_n) (GDM_BASE(_n) + 0x2cc) ++#define REG_FE_GDM_RX_ETH_E64_CNT_H(_n) (GDM_BASE(_n) + 0x2e8) ++#define REG_FE_GDM_RX_ETH_L64_CNT_H(_n) (GDM_BASE(_n) + 0x2ec) ++#define REG_FE_GDM_RX_ETH_L127_CNT_H(_n) (GDM_BASE(_n) + 0x2f0) ++#define REG_FE_GDM_RX_ETH_L255_CNT_H(_n) (GDM_BASE(_n) + 0x2f4) ++#define REG_FE_GDM_RX_ETH_L511_CNT_H(_n) (GDM_BASE(_n) + 0x2f8) ++#define REG_FE_GDM_RX_ETH_L1023_CNT_H(_n) (GDM_BASE(_n) + 0x2fc) ++ ++#define REG_GDM2_CHN_RLS (GDM2_BASE + 0x20) ++#define MBI_RX_AGE_SEL_MASK GENMASK(26, 25) ++#define MBI_TX_AGE_SEL_MASK GENMASK(18, 17) ++ ++#define REG_GDM3_FWD_CFG GDM3_BASE ++#define GDM3_PAD_EN_MASK BIT(28) ++ ++#define REG_GDM4_FWD_CFG GDM4_BASE ++#define GDM4_PAD_EN_MASK BIT(28) ++#define GDM4_SPORT_OFFSET0_MASK GENMASK(11, 8) ++ ++#define REG_GDM4_SRC_PORT_SET (GDM4_BASE + 0x23c) ++#define GDM4_SPORT_OFF2_MASK GENMASK(19, 16) ++#define GDM4_SPORT_OFF1_MASK GENMASK(15, 12) ++#define GDM4_SPORT_OFF0_MASK GENMASK(11, 8) ++ ++#define REG_IP_FRAG_FP 0x2010 ++#define IP_ASSEMBLE_PORT_MASK GENMASK(24, 21) ++#define IP_ASSEMBLE_NBQ_MASK GENMASK(20, 16) ++#define IP_FRAGMENT_PORT_MASK GENMASK(8, 5) ++#define IP_FRAGMENT_NBQ_MASK GENMASK(4, 0) ++ ++#define REG_MC_VLAN_EN 0x2100 ++#define MC_VLAN_EN_MASK BIT(0) ++ ++#define REG_MC_VLAN_CFG 0x2104 ++#define MC_VLAN_CFG_CMD_DONE_MASK BIT(31) ++#define MC_VLAN_CFG_TABLE_ID_MASK GENMASK(21, 16) ++#define MC_VLAN_CFG_PORT_ID_MASK GENMASK(11, 8) ++#define MC_VLAN_CFG_TABLE_SEL_MASK BIT(4) ++#define MC_VLAN_CFG_RW_MASK BIT(0) ++ ++#define REG_MC_VLAN_DATA 0x2108 ++ ++#define REG_CDM5_RX_OQ1_DROP_CNT 0x29d4 ++ ++/* QDMA */ ++#define REG_QDMA_GLOBAL_CFG 0x0004 ++#define GLOBAL_CFG_RX_2B_OFFSET_MASK BIT(31) ++#define GLOBAL_CFG_DMA_PREFERENCE_MASK GENMASK(30, 29) ++#define GLOBAL_CFG_CPU_TXR_RR_MASK BIT(28) ++#define GLOBAL_CFG_DSCP_BYTE_SWAP_MASK BIT(27) ++#define GLOBAL_CFG_PAYLOAD_BYTE_SWAP_MASK BIT(26) ++#define GLOBAL_CFG_MULTICAST_MODIFY_FP_MASK BIT(25) ++#define GLOBAL_CFG_OAM_MODIFY_MASK BIT(24) ++#define GLOBAL_CFG_RESET_MASK BIT(23) ++#define GLOBAL_CFG_RESET_DONE_MASK BIT(22) ++#define GLOBAL_CFG_MULTICAST_EN_MASK BIT(21) ++#define GLOBAL_CFG_IRQ1_EN_MASK BIT(20) ++#define GLOBAL_CFG_IRQ0_EN_MASK BIT(19) ++#define GLOBAL_CFG_LOOPCNT_EN_MASK BIT(18) ++#define GLOBAL_CFG_RD_BYPASS_WR_MASK BIT(17) ++#define GLOBAL_CFG_QDMA_LOOPBACK_MASK BIT(16) ++#define GLOBAL_CFG_LPBK_RXQ_SEL_MASK GENMASK(13, 8) ++#define GLOBAL_CFG_CHECK_DONE_MASK BIT(7) ++#define GLOBAL_CFG_TX_WB_DONE_MASK BIT(6) ++#define GLOBAL_CFG_MAX_ISSUE_NUM_MASK GENMASK(5, 4) ++#define GLOBAL_CFG_RX_DMA_BUSY_MASK BIT(3) ++#define GLOBAL_CFG_RX_DMA_EN_MASK BIT(2) ++#define GLOBAL_CFG_TX_DMA_BUSY_MASK BIT(1) ++#define GLOBAL_CFG_TX_DMA_EN_MASK BIT(0) ++ ++#define REG_FWD_DSCP_BASE 0x0010 ++#define REG_FWD_BUF_BASE 0x0014 ++ ++#define REG_HW_FWD_DSCP_CFG 0x0018 ++#define HW_FWD_DSCP_PAYLOAD_SIZE_MASK GENMASK(29, 28) ++#define HW_FWD_DSCP_SCATTER_LEN_MASK GENMASK(17, 16) ++#define HW_FWD_DSCP_MIN_SCATTER_LEN_MASK GENMASK(15, 0) ++ ++#define REG_INT_STATUS(_n) \ ++ (((_n) == 4) ? 0x0730 : \ ++ ((_n) == 3) ? 0x0724 : \ ++ ((_n) == 2) ? 0x0720 : \ ++ ((_n) == 1) ? 0x0024 : 0x0020) ++ ++#define REG_INT_ENABLE(_n) \ ++ (((_n) == 4) ? 0x0750 : \ ++ ((_n) == 3) ? 0x0744 : \ ++ ((_n) == 2) ? 0x0740 : \ ++ ((_n) == 1) ? 0x002c : 0x0028) ++ ++/* QDMA_CSR_INT_ENABLE1 */ ++#define RX15_COHERENT_INT_MASK BIT(31) ++#define RX14_COHERENT_INT_MASK BIT(30) ++#define RX13_COHERENT_INT_MASK BIT(29) ++#define RX12_COHERENT_INT_MASK BIT(28) ++#define RX11_COHERENT_INT_MASK BIT(27) ++#define RX10_COHERENT_INT_MASK BIT(26) ++#define RX9_COHERENT_INT_MASK BIT(25) ++#define RX8_COHERENT_INT_MASK BIT(24) ++#define RX7_COHERENT_INT_MASK BIT(23) ++#define RX6_COHERENT_INT_MASK BIT(22) ++#define RX5_COHERENT_INT_MASK BIT(21) ++#define RX4_COHERENT_INT_MASK BIT(20) ++#define RX3_COHERENT_INT_MASK BIT(19) ++#define RX2_COHERENT_INT_MASK BIT(18) ++#define RX1_COHERENT_INT_MASK BIT(17) ++#define RX0_COHERENT_INT_MASK BIT(16) ++#define TX7_COHERENT_INT_MASK BIT(15) ++#define TX6_COHERENT_INT_MASK BIT(14) ++#define TX5_COHERENT_INT_MASK BIT(13) ++#define TX4_COHERENT_INT_MASK BIT(12) ++#define TX3_COHERENT_INT_MASK BIT(11) ++#define TX2_COHERENT_INT_MASK BIT(10) ++#define TX1_COHERENT_INT_MASK BIT(9) ++#define TX0_COHERENT_INT_MASK BIT(8) ++#define CNT_OVER_FLOW_INT_MASK BIT(7) ++#define IRQ1_FULL_INT_MASK BIT(5) ++#define IRQ1_INT_MASK BIT(4) ++#define HWFWD_DSCP_LOW_INT_MASK BIT(3) ++#define HWFWD_DSCP_EMPTY_INT_MASK BIT(2) ++#define IRQ0_FULL_INT_MASK BIT(1) ++#define IRQ0_INT_MASK BIT(0) ++ ++#define TX_DONE_INT_MASK(_n) \ ++ ((_n) ? IRQ1_INT_MASK | IRQ1_FULL_INT_MASK \ ++ : IRQ0_INT_MASK | IRQ0_FULL_INT_MASK) ++ ++#define INT_TX_MASK \ ++ (IRQ1_INT_MASK | IRQ1_FULL_INT_MASK | \ ++ IRQ0_INT_MASK | IRQ0_FULL_INT_MASK) ++ ++#define INT_IDX0_MASK \ ++ (TX0_COHERENT_INT_MASK | TX1_COHERENT_INT_MASK | \ ++ TX2_COHERENT_INT_MASK | TX3_COHERENT_INT_MASK | \ ++ TX4_COHERENT_INT_MASK | TX5_COHERENT_INT_MASK | \ ++ TX6_COHERENT_INT_MASK | TX7_COHERENT_INT_MASK | \ ++ RX0_COHERENT_INT_MASK | RX1_COHERENT_INT_MASK | \ ++ RX2_COHERENT_INT_MASK | RX3_COHERENT_INT_MASK | \ ++ RX4_COHERENT_INT_MASK | RX7_COHERENT_INT_MASK | \ ++ RX8_COHERENT_INT_MASK | RX9_COHERENT_INT_MASK | \ ++ RX15_COHERENT_INT_MASK | INT_TX_MASK) ++ ++/* QDMA_CSR_INT_ENABLE2 */ ++#define RX15_NO_CPU_DSCP_INT_MASK BIT(31) ++#define RX14_NO_CPU_DSCP_INT_MASK BIT(30) ++#define RX13_NO_CPU_DSCP_INT_MASK BIT(29) ++#define RX12_NO_CPU_DSCP_INT_MASK BIT(28) ++#define RX11_NO_CPU_DSCP_INT_MASK BIT(27) ++#define RX10_NO_CPU_DSCP_INT_MASK BIT(26) ++#define RX9_NO_CPU_DSCP_INT_MASK BIT(25) ++#define RX8_NO_CPU_DSCP_INT_MASK BIT(24) ++#define RX7_NO_CPU_DSCP_INT_MASK BIT(23) ++#define RX6_NO_CPU_DSCP_INT_MASK BIT(22) ++#define RX5_NO_CPU_DSCP_INT_MASK BIT(21) ++#define RX4_NO_CPU_DSCP_INT_MASK BIT(20) ++#define RX3_NO_CPU_DSCP_INT_MASK BIT(19) ++#define RX2_NO_CPU_DSCP_INT_MASK BIT(18) ++#define RX1_NO_CPU_DSCP_INT_MASK BIT(17) ++#define RX0_NO_CPU_DSCP_INT_MASK BIT(16) ++#define RX15_DONE_INT_MASK BIT(15) ++#define RX14_DONE_INT_MASK BIT(14) ++#define RX13_DONE_INT_MASK BIT(13) ++#define RX12_DONE_INT_MASK BIT(12) ++#define RX11_DONE_INT_MASK BIT(11) ++#define RX10_DONE_INT_MASK BIT(10) ++#define RX9_DONE_INT_MASK BIT(9) ++#define RX8_DONE_INT_MASK BIT(8) ++#define RX7_DONE_INT_MASK BIT(7) ++#define RX6_DONE_INT_MASK BIT(6) ++#define RX5_DONE_INT_MASK BIT(5) ++#define RX4_DONE_INT_MASK BIT(4) ++#define RX3_DONE_INT_MASK BIT(3) ++#define RX2_DONE_INT_MASK BIT(2) ++#define RX1_DONE_INT_MASK BIT(1) ++#define RX0_DONE_INT_MASK BIT(0) ++ ++#define RX_DONE_INT_MASK \ ++ (RX0_DONE_INT_MASK | RX1_DONE_INT_MASK | \ ++ RX2_DONE_INT_MASK | RX3_DONE_INT_MASK | \ ++ RX4_DONE_INT_MASK | RX7_DONE_INT_MASK | \ ++ RX8_DONE_INT_MASK | RX9_DONE_INT_MASK | \ ++ RX15_DONE_INT_MASK) ++#define INT_IDX1_MASK \ ++ (RX_DONE_INT_MASK | \ ++ RX0_NO_CPU_DSCP_INT_MASK | RX1_NO_CPU_DSCP_INT_MASK | \ ++ RX2_NO_CPU_DSCP_INT_MASK | RX3_NO_CPU_DSCP_INT_MASK | \ ++ RX4_NO_CPU_DSCP_INT_MASK | RX7_NO_CPU_DSCP_INT_MASK | \ ++ RX8_NO_CPU_DSCP_INT_MASK | RX9_NO_CPU_DSCP_INT_MASK | \ ++ RX15_NO_CPU_DSCP_INT_MASK) ++ ++/* QDMA_CSR_INT_ENABLE5 */ ++#define TX31_COHERENT_INT_MASK BIT(31) ++#define TX30_COHERENT_INT_MASK BIT(30) ++#define TX29_COHERENT_INT_MASK BIT(29) ++#define TX28_COHERENT_INT_MASK BIT(28) ++#define TX27_COHERENT_INT_MASK BIT(27) ++#define TX26_COHERENT_INT_MASK BIT(26) ++#define TX25_COHERENT_INT_MASK BIT(25) ++#define TX24_COHERENT_INT_MASK BIT(24) ++#define TX23_COHERENT_INT_MASK BIT(23) ++#define TX22_COHERENT_INT_MASK BIT(22) ++#define TX21_COHERENT_INT_MASK BIT(21) ++#define TX20_COHERENT_INT_MASK BIT(20) ++#define TX19_COHERENT_INT_MASK BIT(19) ++#define TX18_COHERENT_INT_MASK BIT(18) ++#define TX17_COHERENT_INT_MASK BIT(17) ++#define TX16_COHERENT_INT_MASK BIT(16) ++#define TX15_COHERENT_INT_MASK BIT(15) ++#define TX14_COHERENT_INT_MASK BIT(14) ++#define TX13_COHERENT_INT_MASK BIT(13) ++#define TX12_COHERENT_INT_MASK BIT(12) ++#define TX11_COHERENT_INT_MASK BIT(11) ++#define TX10_COHERENT_INT_MASK BIT(10) ++#define TX9_COHERENT_INT_MASK BIT(9) ++#define TX8_COHERENT_INT_MASK BIT(8) ++ ++#define INT_IDX4_MASK \ ++ (TX8_COHERENT_INT_MASK | TX9_COHERENT_INT_MASK | \ ++ TX10_COHERENT_INT_MASK | TX11_COHERENT_INT_MASK | \ ++ TX12_COHERENT_INT_MASK | TX13_COHERENT_INT_MASK | \ ++ TX14_COHERENT_INT_MASK | TX15_COHERENT_INT_MASK | \ ++ TX16_COHERENT_INT_MASK | TX17_COHERENT_INT_MASK | \ ++ TX18_COHERENT_INT_MASK | TX19_COHERENT_INT_MASK | \ ++ TX20_COHERENT_INT_MASK | TX21_COHERENT_INT_MASK | \ ++ TX22_COHERENT_INT_MASK | TX23_COHERENT_INT_MASK | \ ++ TX24_COHERENT_INT_MASK | TX25_COHERENT_INT_MASK | \ ++ TX26_COHERENT_INT_MASK | TX27_COHERENT_INT_MASK | \ ++ TX28_COHERENT_INT_MASK | TX29_COHERENT_INT_MASK | \ ++ TX30_COHERENT_INT_MASK | TX31_COHERENT_INT_MASK) ++ ++#define REG_TX_IRQ_BASE(_n) ((_n) ? 0x0048 : 0x0050) ++ ++#define REG_TX_IRQ_CFG(_n) ((_n) ? 0x004c : 0x0054) ++#define TX_IRQ_THR_MASK GENMASK(27, 16) ++#define TX_IRQ_DEPTH_MASK GENMASK(11, 0) ++ ++#define REG_IRQ_CLEAR_LEN(_n) ((_n) ? 0x0064 : 0x0058) ++#define IRQ_CLEAR_LEN_MASK GENMASK(7, 0) ++ ++#define REG_IRQ_STATUS(_n) ((_n) ? 0x0068 : 0x005c) ++#define IRQ_ENTRY_LEN_MASK GENMASK(27, 16) ++#define IRQ_HEAD_IDX_MASK GENMASK(11, 0) ++ ++#define REG_TX_RING_BASE(_n) \ ++ (((_n) < 8) ? 0x0100 + ((_n) << 5) : 0x0b00 + (((_n) - 8) << 5)) ++ ++#define REG_TX_RING_BLOCKING(_n) \ ++ (((_n) < 8) ? 0x0104 + ((_n) << 5) : 0x0b04 + (((_n) - 8) << 5)) ++ ++#define TX_RING_IRQ_BLOCKING_MAP_MASK BIT(6) ++#define TX_RING_IRQ_BLOCKING_CFG_MASK BIT(4) ++#define TX_RING_IRQ_BLOCKING_TX_DROP_EN_MASK BIT(2) ++#define TX_RING_IRQ_BLOCKING_MAX_TH_TXRING_EN_MASK BIT(1) ++#define TX_RING_IRQ_BLOCKING_MIN_TH_TXRING_EN_MASK BIT(0) ++ ++#define REG_TX_CPU_IDX(_n) \ ++ (((_n) < 8) ? 0x0108 + ((_n) << 5) : 0x0b08 + (((_n) - 8) << 5)) ++ ++#define TX_RING_CPU_IDX_MASK GENMASK(15, 0) ++ ++#define REG_TX_DMA_IDX(_n) \ ++ (((_n) < 8) ? 0x010c + ((_n) << 5) : 0x0b0c + (((_n) - 8) << 5)) ++ ++#define TX_RING_DMA_IDX_MASK GENMASK(15, 0) ++ ++#define IRQ_RING_IDX_MASK GENMASK(20, 16) ++#define IRQ_DESC_IDX_MASK GENMASK(15, 0) ++ ++#define REG_RX_RING_BASE(_n) \ ++ (((_n) < 16) ? 0x0200 + ((_n) << 5) : 0x0e00 + (((_n) - 16) << 5)) ++ ++#define REG_RX_RING_SIZE(_n) \ ++ (((_n) < 16) ? 0x0204 + ((_n) << 5) : 0x0e04 + (((_n) - 16) << 5)) ++ ++#define RX_RING_THR_MASK GENMASK(31, 16) ++#define RX_RING_SIZE_MASK GENMASK(15, 0) ++ ++#define REG_RX_CPU_IDX(_n) \ ++ (((_n) < 16) ? 0x0208 + ((_n) << 5) : 0x0e08 + (((_n) - 16) << 5)) ++ ++#define RX_RING_CPU_IDX_MASK GENMASK(15, 0) ++ ++#define REG_RX_DMA_IDX(_n) \ ++ (((_n) < 16) ? 0x020c + ((_n) << 5) : 0x0e0c + (((_n) - 16) << 5)) ++ ++#define REG_RX_DELAY_INT_IDX(_n) \ ++ (((_n) < 16) ? 0x0210 + ((_n) << 5) : 0x0e10 + (((_n) - 16) << 5)) ++ ++#define RX_DELAY_INT_MASK GENMASK(15, 0) ++ ++#define RX_RING_DMA_IDX_MASK GENMASK(15, 0) ++ ++#define REG_INGRESS_TRTCM_CFG 0x0070 ++#define INGRESS_TRTCM_EN_MASK BIT(31) ++#define INGRESS_TRTCM_MODE_MASK BIT(30) ++#define INGRESS_SLOW_TICK_RATIO_MASK GENMASK(29, 16) ++#define INGRESS_FAST_TICK_MASK GENMASK(15, 0) ++ ++#define REG_QUEUE_CLOSE_CFG(_n) (0x00a0 + ((_n) & 0xfc)) ++#define TXQ_DISABLE_CHAN_QUEUE_MASK(_n, _m) BIT((_m) + (((_n) & 0x3) << 3)) ++ ++#define REG_TXQ_DIS_CFG_BASE(_n) ((_n) ? 0x20a0 : 0x00a0) ++#define REG_TXQ_DIS_CFG(_n, _m) (REG_TXQ_DIS_CFG_BASE((_n)) + (_m) << 2) ++ ++#define REG_CNTR_CFG(_n) (0x0400 + ((_n) << 3)) ++#define CNTR_EN_MASK BIT(31) ++#define CNTR_ALL_CHAN_EN_MASK BIT(30) ++#define CNTR_ALL_QUEUE_EN_MASK BIT(29) ++#define CNTR_ALL_DSCP_RING_EN_MASK BIT(28) ++#define CNTR_SRC_MASK GENMASK(27, 24) ++#define CNTR_DSCP_RING_MASK GENMASK(20, 16) ++#define CNTR_CHAN_MASK GENMASK(7, 3) ++#define CNTR_QUEUE_MASK GENMASK(2, 0) ++ ++#define REG_CNTR_VAL(_n) (0x0404 + ((_n) << 3)) ++ ++#define REG_LMGR_INIT_CFG 0x1000 ++#define LMGR_INIT_START BIT(31) ++#define LMGR_SRAM_MODE_MASK BIT(30) ++#define HW_FWD_PKTSIZE_OVERHEAD_MASK GENMASK(27, 20) ++#define HW_FWD_DESC_NUM_MASK GENMASK(16, 0) ++ ++#define REG_FWD_DSCP_LOW_THR 0x1004 ++#define FWD_DSCP_LOW_THR_MASK GENMASK(17, 0) ++ ++#define REG_EGRESS_RATE_METER_CFG 0x100c ++#define EGRESS_RATE_METER_EN_MASK BIT(31) ++#define EGRESS_RATE_METER_EQ_RATE_EN_MASK BIT(17) ++#define EGRESS_RATE_METER_WINDOW_SZ_MASK GENMASK(16, 12) ++#define EGRESS_RATE_METER_TIMESLICE_MASK GENMASK(10, 0) ++ ++#define REG_EGRESS_TRTCM_CFG 0x1010 ++#define EGRESS_TRTCM_EN_MASK BIT(31) ++#define EGRESS_TRTCM_MODE_MASK BIT(30) ++#define EGRESS_SLOW_TICK_RATIO_MASK GENMASK(29, 16) ++#define EGRESS_FAST_TICK_MASK GENMASK(15, 0) ++ ++#define TRTCM_PARAM_RW_MASK BIT(31) ++#define TRTCM_PARAM_RW_DONE_MASK BIT(30) ++#define TRTCM_PARAM_TYPE_MASK GENMASK(29, 28) ++#define TRTCM_METER_GROUP_MASK GENMASK(27, 26) ++#define TRTCM_PARAM_INDEX_MASK GENMASK(23, 17) ++#define TRTCM_PARAM_RATE_TYPE_MASK BIT(16) ++ ++#define REG_TRTCM_CFG_PARAM(_n) ((_n) + 0x4) ++#define REG_TRTCM_DATA_LOW(_n) ((_n) + 0x8) ++#define REG_TRTCM_DATA_HIGH(_n) ((_n) + 0xc) ++ ++#define REG_TXWRR_MODE_CFG 0x1020 ++#define TWRR_WEIGHT_SCALE_MASK BIT(31) ++#define TWRR_WEIGHT_BASE_MASK BIT(3) ++ ++#define REG_TXWRR_WEIGHT_CFG 0x1024 ++#define TWRR_RW_CMD_MASK BIT(31) ++#define TWRR_RW_CMD_DONE BIT(30) ++#define TWRR_CHAN_IDX_MASK GENMASK(23, 19) ++#define TWRR_QUEUE_IDX_MASK GENMASK(18, 16) ++#define TWRR_VALUE_MASK GENMASK(15, 0) ++ ++#define REG_PSE_BUF_USAGE_CFG 0x1028 ++#define PSE_BUF_ESTIMATE_EN_MASK BIT(29) ++ ++#define REG_CHAN_QOS_MODE(_n) (0x1040 + ((_n) << 2)) ++#define CHAN_QOS_MODE_MASK(_n) GENMASK(2 + ((_n) << 2), (_n) << 2) ++ ++#define REG_GLB_TRTCM_CFG 0x1080 ++#define GLB_TRTCM_EN_MASK BIT(31) ++#define GLB_TRTCM_MODE_MASK BIT(30) ++#define GLB_SLOW_TICK_RATIO_MASK GENMASK(29, 16) ++#define GLB_FAST_TICK_MASK GENMASK(15, 0) ++ ++#define REG_TXQ_CNGST_CFG 0x10a0 ++#define TXQ_CNGST_DROP_EN BIT(31) ++#define TXQ_CNGST_DEI_DROP_EN BIT(30) ++ ++#define REG_SLA_TRTCM_CFG 0x1150 ++#define SLA_TRTCM_EN_MASK BIT(31) ++#define SLA_TRTCM_MODE_MASK BIT(30) ++#define SLA_SLOW_TICK_RATIO_MASK GENMASK(29, 16) ++#define SLA_FAST_TICK_MASK GENMASK(15, 0) ++ ++/* CTRL */ ++#define QDMA_DESC_DONE_MASK BIT(31) ++#define QDMA_DESC_DROP_MASK BIT(30) /* tx: drop - rx: overflow */ ++#define QDMA_DESC_MORE_MASK BIT(29) /* more SG elements */ ++#define QDMA_DESC_DEI_MASK BIT(25) ++#define QDMA_DESC_NO_DROP_MASK BIT(24) ++#define QDMA_DESC_LEN_MASK GENMASK(15, 0) ++/* DATA */ ++#define QDMA_DESC_NEXT_ID_MASK GENMASK(15, 0) ++/* TX MSG0 */ ++#define QDMA_ETH_TXMSG_MIC_IDX_MASK BIT(30) ++#define QDMA_ETH_TXMSG_SP_TAG_MASK GENMASK(29, 14) ++#define QDMA_ETH_TXMSG_ICO_MASK BIT(13) ++#define QDMA_ETH_TXMSG_UCO_MASK BIT(12) ++#define QDMA_ETH_TXMSG_TCO_MASK BIT(11) ++#define QDMA_ETH_TXMSG_TSO_MASK BIT(10) ++#define QDMA_ETH_TXMSG_FAST_MASK BIT(9) ++#define QDMA_ETH_TXMSG_OAM_MASK BIT(8) ++#define QDMA_ETH_TXMSG_CHAN_MASK GENMASK(7, 3) ++#define QDMA_ETH_TXMSG_QUEUE_MASK GENMASK(2, 0) ++/* TX MSG1 */ ++#define QDMA_ETH_TXMSG_NO_DROP BIT(31) ++#define QDMA_ETH_TXMSG_METER_MASK GENMASK(30, 24) /* 0x7f no meters */ ++#define QDMA_ETH_TXMSG_FPORT_MASK GENMASK(23, 20) ++#define QDMA_ETH_TXMSG_NBOQ_MASK GENMASK(19, 15) ++#define QDMA_ETH_TXMSG_HWF_MASK BIT(14) ++#define QDMA_ETH_TXMSG_HOP_MASK BIT(13) ++#define QDMA_ETH_TXMSG_PTP_MASK BIT(12) ++#define QDMA_ETH_TXMSG_ACNT_G1_MASK GENMASK(10, 6) /* 0x1f do not count */ ++#define QDMA_ETH_TXMSG_ACNT_G0_MASK GENMASK(5, 0) /* 0x3f do not count */ ++ ++/* RX MSG1 */ ++#define QDMA_ETH_RXMSG_DEI_MASK BIT(31) ++#define QDMA_ETH_RXMSG_IP6_MASK BIT(30) ++#define QDMA_ETH_RXMSG_IP4_MASK BIT(29) ++#define QDMA_ETH_RXMSG_IP4F_MASK BIT(28) ++#define QDMA_ETH_RXMSG_L4_VALID_MASK BIT(27) ++#define QDMA_ETH_RXMSG_L4F_MASK BIT(26) ++#define QDMA_ETH_RXMSG_SPORT_MASK GENMASK(25, 21) ++#define QDMA_ETH_RXMSG_CRSN_MASK GENMASK(20, 16) ++#define QDMA_ETH_RXMSG_PPE_ENTRY_MASK GENMASK(15, 0) ++ ++struct airoha_qdma_desc { ++ __le32 rsv; ++ __le32 ctrl; ++ __le32 addr; ++ __le32 data; ++ __le32 msg0; ++ __le32 msg1; ++ __le32 msg2; ++ __le32 msg3; ++}; ++ ++/* CTRL0 */ ++#define QDMA_FWD_DESC_CTX_MASK BIT(31) ++#define QDMA_FWD_DESC_RING_MASK GENMASK(30, 28) ++#define QDMA_FWD_DESC_IDX_MASK GENMASK(27, 16) ++#define QDMA_FWD_DESC_LEN_MASK GENMASK(15, 0) ++/* CTRL1 */ ++#define QDMA_FWD_DESC_FIRST_IDX_MASK GENMASK(15, 0) ++/* CTRL2 */ ++#define QDMA_FWD_DESC_MORE_PKT_NUM_MASK GENMASK(2, 0) ++ ++struct airoha_qdma_fwd_desc { ++ __le32 addr; ++ __le32 ctrl0; ++ __le32 ctrl1; ++ __le32 ctrl2; ++ __le32 msg0; ++ __le32 msg1; ++ __le32 rsv0; ++ __le32 rsv1; ++}; ++ ++#endif /* AIROHA_REGS_H */ diff --git a/target/linux/airoha/patches-6.6/048-05-v6.15-net-airoha-Move-DSA-tag-in-DMA-descriptor.patch b/target/linux/airoha/patches-6.6/048-05-v6.15-net-airoha-Move-DSA-tag-in-DMA-descriptor.patch new file mode 100644 index 00000000000000..61e889f3d2ad99 --- /dev/null +++ b/target/linux/airoha/patches-6.6/048-05-v6.15-net-airoha-Move-DSA-tag-in-DMA-descriptor.patch @@ -0,0 +1,287 @@ +From af3cf757d5c99011b9b94ea8d78aeaccc0153fdc Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Fri, 28 Feb 2025 11:54:13 +0100 +Subject: [PATCH 05/15] net: airoha: Move DSA tag in DMA descriptor + +Packet Processor Engine (PPE) module reads DSA tags from the DMA descriptor +and requires untagged DSA packets to properly parse them. Move DSA tag +in the DMA descriptor on TX side and read DSA tag from DMA descriptor +on RX side. In order to avoid skb reallocation, store tag in skb_dst on +RX side. +This is a preliminary patch to enable netfilter flowtable hw offloading +on EN7581 SoC. + +Tested-by: Sayantan Nandy +Signed-off-by: Lorenzo Bianconi +Signed-off-by: Paolo Abeni +--- + drivers/net/ethernet/airoha/airoha_eth.c | 125 ++++++++++++++++++++-- + drivers/net/ethernet/airoha/airoha_eth.h | 7 ++ + drivers/net/ethernet/airoha/airoha_regs.h | 2 + + 3 files changed, 128 insertions(+), 6 deletions(-) + +--- a/drivers/net/ethernet/airoha/airoha_eth.c ++++ b/drivers/net/ethernet/airoha/airoha_eth.c +@@ -9,6 +9,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -656,6 +657,7 @@ static int airoha_qdma_rx_process(struct + struct airoha_qdma_desc *desc = &q->desc[q->tail]; + dma_addr_t dma_addr = le32_to_cpu(desc->addr); + u32 desc_ctrl = le32_to_cpu(desc->ctrl); ++ struct airoha_gdm_port *port; + struct sk_buff *skb; + int len, p; + +@@ -683,6 +685,7 @@ static int airoha_qdma_rx_process(struct + continue; + } + ++ port = eth->ports[p]; + skb = napi_build_skb(e->buf, q->buf_size); + if (!skb) { + page_pool_put_full_page(q->page_pool, +@@ -694,10 +697,26 @@ static int airoha_qdma_rx_process(struct + skb_reserve(skb, 2); + __skb_put(skb, len); + skb_mark_for_recycle(skb); +- skb->dev = eth->ports[p]->dev; ++ skb->dev = port->dev; + skb->protocol = eth_type_trans(skb, skb->dev); + skb->ip_summed = CHECKSUM_UNNECESSARY; + skb_record_rx_queue(skb, qid); ++ ++ if (netdev_uses_dsa(port->dev)) { ++ /* PPE module requires untagged packets to work ++ * properly and it provides DSA port index via the ++ * DMA descriptor. Report DSA tag to the DSA stack ++ * via skb dst info. ++ */ ++ u32 sptag = FIELD_GET(QDMA_ETH_RXMSG_SPTAG, ++ le32_to_cpu(desc->msg0)); ++ ++ if (sptag < ARRAY_SIZE(port->dsa_meta) && ++ port->dsa_meta[sptag]) ++ skb_dst_set_noref(skb, ++ &port->dsa_meta[sptag]->dst); ++ } ++ + napi_gro_receive(&q->napi, skb); + + done++; +@@ -1637,25 +1656,76 @@ static u16 airoha_dev_select_queue(struc + return queue < dev->num_tx_queues ? queue : 0; + } + ++static u32 airoha_get_dsa_tag(struct sk_buff *skb, struct net_device *dev) ++{ ++#if IS_ENABLED(CONFIG_NET_DSA) ++ struct ethhdr *ehdr; ++ struct dsa_port *dp; ++ u8 xmit_tpid; ++ u16 tag; ++ ++ if (!netdev_uses_dsa(dev)) ++ return 0; ++ ++ dp = dev->dsa_ptr; ++ if (IS_ERR(dp)) ++ return 0; ++ ++ if (dp->tag_ops->proto != DSA_TAG_PROTO_MTK) ++ return 0; ++ ++ if (skb_cow_head(skb, 0)) ++ return 0; ++ ++ ehdr = (struct ethhdr *)skb->data; ++ tag = be16_to_cpu(ehdr->h_proto); ++ xmit_tpid = tag >> 8; ++ ++ switch (xmit_tpid) { ++ case MTK_HDR_XMIT_TAGGED_TPID_8100: ++ ehdr->h_proto = cpu_to_be16(ETH_P_8021Q); ++ tag &= ~(MTK_HDR_XMIT_TAGGED_TPID_8100 << 8); ++ break; ++ case MTK_HDR_XMIT_TAGGED_TPID_88A8: ++ ehdr->h_proto = cpu_to_be16(ETH_P_8021AD); ++ tag &= ~(MTK_HDR_XMIT_TAGGED_TPID_88A8 << 8); ++ break; ++ default: ++ /* PPE module requires untagged DSA packets to work properly, ++ * so move DSA tag to DMA descriptor. ++ */ ++ memmove(skb->data + MTK_HDR_LEN, skb->data, 2 * ETH_ALEN); ++ __skb_pull(skb, MTK_HDR_LEN); ++ break; ++ } ++ ++ return tag; ++#else ++ return 0; ++#endif ++} ++ + static netdev_tx_t airoha_dev_xmit(struct sk_buff *skb, + struct net_device *dev) + { + struct airoha_gdm_port *port = netdev_priv(dev); +- u32 nr_frags = 1 + skb_shinfo(skb)->nr_frags; +- u32 msg0, msg1, len = skb_headlen(skb); + struct airoha_qdma *qdma = port->qdma; ++ u32 nr_frags, tag, msg0, msg1, len; + struct netdev_queue *txq; + struct airoha_queue *q; +- void *data = skb->data; ++ void *data; + int i, qid; + u16 index; + u8 fport; + + qid = skb_get_queue_mapping(skb) % ARRAY_SIZE(qdma->q_tx); ++ tag = airoha_get_dsa_tag(skb, dev); ++ + msg0 = FIELD_PREP(QDMA_ETH_TXMSG_CHAN_MASK, + qid / AIROHA_NUM_QOS_QUEUES) | + FIELD_PREP(QDMA_ETH_TXMSG_QUEUE_MASK, +- qid % AIROHA_NUM_QOS_QUEUES); ++ qid % AIROHA_NUM_QOS_QUEUES) | ++ FIELD_PREP(QDMA_ETH_TXMSG_SP_TAG_MASK, tag); + if (skb->ip_summed == CHECKSUM_PARTIAL) + msg0 |= FIELD_PREP(QDMA_ETH_TXMSG_TCO_MASK, 1) | + FIELD_PREP(QDMA_ETH_TXMSG_UCO_MASK, 1) | +@@ -1686,6 +1756,8 @@ static netdev_tx_t airoha_dev_xmit(struc + spin_lock_bh(&q->lock); + + txq = netdev_get_tx_queue(dev, qid); ++ nr_frags = 1 + skb_shinfo(skb)->nr_frags; ++ + if (q->queued + nr_frags > q->ndesc) { + /* not enough space in the queue */ + netif_tx_stop_queue(txq); +@@ -1693,7 +1765,10 @@ static netdev_tx_t airoha_dev_xmit(struc + return NETDEV_TX_BUSY; + } + ++ len = skb_headlen(skb); ++ data = skb->data; + index = q->head; ++ + for (i = 0; i < nr_frags; i++) { + struct airoha_qdma_desc *desc = &q->desc[index]; + struct airoha_queue_entry *e = &q->entry[index]; +@@ -2224,6 +2299,37 @@ static const struct ethtool_ops airoha_e + .get_rmon_stats = airoha_ethtool_get_rmon_stats, + }; + ++static int airoha_metadata_dst_alloc(struct airoha_gdm_port *port) ++{ ++ int i; ++ ++ for (i = 0; i < ARRAY_SIZE(port->dsa_meta); i++) { ++ struct metadata_dst *md_dst; ++ ++ md_dst = metadata_dst_alloc(0, METADATA_HW_PORT_MUX, ++ GFP_KERNEL); ++ if (!md_dst) ++ return -ENOMEM; ++ ++ md_dst->u.port_info.port_id = i; ++ port->dsa_meta[i] = md_dst; ++ } ++ ++ return 0; ++} ++ ++static void airoha_metadata_dst_free(struct airoha_gdm_port *port) ++{ ++ int i; ++ ++ for (i = 0; i < ARRAY_SIZE(port->dsa_meta); i++) { ++ if (!port->dsa_meta[i]) ++ continue; ++ ++ metadata_dst_free(port->dsa_meta[i]); ++ } ++} ++ + static int airoha_alloc_gdm_port(struct airoha_eth *eth, struct device_node *np) + { + const __be32 *id_ptr = of_get_property(np, "reg", NULL); +@@ -2296,6 +2402,10 @@ static int airoha_alloc_gdm_port(struct + port->id = id; + eth->ports[index] = port; + ++ err = airoha_metadata_dst_alloc(port); ++ if (err) ++ return err; ++ + return register_netdev(dev); + } + +@@ -2388,8 +2498,10 @@ error_hw_cleanup: + for (i = 0; i < ARRAY_SIZE(eth->ports); i++) { + struct airoha_gdm_port *port = eth->ports[i]; + +- if (port && port->dev->reg_state == NETREG_REGISTERED) ++ if (port && port->dev->reg_state == NETREG_REGISTERED) { + unregister_netdev(port->dev); ++ airoha_metadata_dst_free(port); ++ } + } + free_netdev(eth->napi_dev); + platform_set_drvdata(pdev, NULL); +@@ -2415,6 +2527,7 @@ static void airoha_remove(struct platfor + + airoha_dev_stop(port->dev); + unregister_netdev(port->dev); ++ airoha_metadata_dst_free(port); + } + free_netdev(eth->napi_dev); + +--- a/drivers/net/ethernet/airoha/airoha_eth.h ++++ b/drivers/net/ethernet/airoha/airoha_eth.h +@@ -15,6 +15,7 @@ + + #define AIROHA_MAX_NUM_GDM_PORTS 1 + #define AIROHA_MAX_NUM_QDMA 2 ++#define AIROHA_MAX_DSA_PORTS 7 + #define AIROHA_MAX_NUM_RSTS 3 + #define AIROHA_MAX_NUM_XSI_RSTS 5 + #define AIROHA_MAX_MTU 2000 +@@ -43,6 +44,10 @@ + #define QDMA_METER_IDX(_n) ((_n) & 0xff) + #define QDMA_METER_GROUP(_n) (((_n) >> 8) & 0x3) + ++#define MTK_HDR_LEN 4 ++#define MTK_HDR_XMIT_TAGGED_TPID_8100 1 ++#define MTK_HDR_XMIT_TAGGED_TPID_88A8 2 ++ + enum { + QDMA_INT_REG_IDX0, + QDMA_INT_REG_IDX1, +@@ -231,6 +236,8 @@ struct airoha_gdm_port { + /* qos stats counters */ + u64 cpu_tx_packets; + u64 fwd_tx_packets; ++ ++ struct metadata_dst *dsa_meta[AIROHA_MAX_DSA_PORTS]; + }; + + struct airoha_eth { +--- a/drivers/net/ethernet/airoha/airoha_regs.h ++++ b/drivers/net/ethernet/airoha/airoha_regs.h +@@ -624,6 +624,8 @@ + #define QDMA_ETH_TXMSG_ACNT_G1_MASK GENMASK(10, 6) /* 0x1f do not count */ + #define QDMA_ETH_TXMSG_ACNT_G0_MASK GENMASK(5, 0) /* 0x3f do not count */ + ++/* RX MSG0 */ ++#define QDMA_ETH_RXMSG_SPTAG GENMASK(21, 14) + /* RX MSG1 */ + #define QDMA_ETH_RXMSG_DEI_MASK BIT(31) + #define QDMA_ETH_RXMSG_IP6_MASK BIT(30) diff --git a/target/linux/airoha/patches-6.6/048-06-v6.15-net-dsa-mt7530-Enable-Rx-sptag-for-EN7581-SoC.patch b/target/linux/airoha/patches-6.6/048-06-v6.15-net-dsa-mt7530-Enable-Rx-sptag-for-EN7581-SoC.patch new file mode 100644 index 00000000000000..27956d553af05a --- /dev/null +++ b/target/linux/airoha/patches-6.6/048-06-v6.15-net-dsa-mt7530-Enable-Rx-sptag-for-EN7581-SoC.patch @@ -0,0 +1,46 @@ +From ab667db1e6014634c6607ebdddc16c1b8394a935 Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Fri, 28 Feb 2025 11:54:14 +0100 +Subject: [PATCH 06/15] net: dsa: mt7530: Enable Rx sptag for EN7581 SoC + +Packet Processor Engine (PPE) module used for hw acceleration on EN7581 +mac block, in order to properly parse packets, requires DSA untagged +packets on TX side and read DSA tag from DMA descriptor on RX side. +For this reason, enable RX Special Tag (SPTAG) for EN7581 SoC. +This is a preliminary patch to enable netfilter flowtable hw offloading +on EN7581 SoC. + +Signed-off-by: Lorenzo Bianconi +Signed-off-by: Paolo Abeni +--- + drivers/net/dsa/mt7530.c | 5 +++++ + drivers/net/dsa/mt7530.h | 4 ++++ + 2 files changed, 9 insertions(+) + +--- a/drivers/net/dsa/mt7530.c ++++ b/drivers/net/dsa/mt7530.c +@@ -2588,6 +2588,11 @@ mt7531_setup_common(struct dsa_switch *d + /* Allow mirroring frames received on the local port (monitor port). */ + mt7530_set(priv, MT753X_AGC, LOCAL_EN); + ++ /* Enable Special Tag for rx frames */ ++ if (priv->id == ID_EN7581) ++ mt7530_write(priv, MT753X_CPORT_SPTAG_CFG, ++ CPORT_SW2FE_STAG_EN | CPORT_FE2SW_STAG_EN); ++ + /* Flush the FDB table */ + ret = mt7530_fdb_cmd(priv, MT7530_FDB_FLUSH, NULL); + if (ret < 0) +--- a/drivers/net/dsa/mt7530.h ++++ b/drivers/net/dsa/mt7530.h +@@ -615,6 +615,10 @@ enum mt7531_xtal_fsel { + #define MT7531_GPIO12_RG_RXD3_MASK GENMASK(19, 16) + #define MT7531_EXT_P_MDIO_12 (2 << 16) + ++#define MT753X_CPORT_SPTAG_CFG 0x7c10 ++#define CPORT_SW2FE_STAG_EN BIT(1) ++#define CPORT_FE2SW_STAG_EN BIT(0) ++ + /* Registers for LED GPIO control (MT7530 only) + * All registers follow this pattern: + * [ 2: 0] port 0 diff --git a/target/linux/airoha/patches-6.6/048-07-v6.15-net-airoha-Enable-support-for-multiple-net_devices.patch b/target/linux/airoha/patches-6.6/048-07-v6.15-net-airoha-Enable-support-for-multiple-net_devices.patch new file mode 100644 index 00000000000000..af4fa78c90958c --- /dev/null +++ b/target/linux/airoha/patches-6.6/048-07-v6.15-net-airoha-Enable-support-for-multiple-net_devices.patch @@ -0,0 +1,144 @@ +From 80369686737fe07c233a1152da0b84372dabdcd6 Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Fri, 28 Feb 2025 11:54:15 +0100 +Subject: [PATCH 07/15] net: airoha: Enable support for multiple net_devices + +In the current codebase airoha_eth driver supports just a single +net_device connected to the Packet Switch Engine (PSE) lan port (GDM1). +As shown in commit 23020f049327 ("net: airoha: Introduce ethernet +support for EN7581 SoC"), PSE can switch packets between four GDM ports. +Enable the capability to create a net_device for each GDM port of the +PSE module. Moreover, since the QDMA blocks can be shared between +net_devices, do not stop TX/RX DMA in airoha_dev_stop() if there are +active net_devices for this QDMA block. +This is a preliminary patch to enable flowtable hw offloading for EN7581 +SoC. + +Co-developed-by: Christian Marangi +Signed-off-by: Christian Marangi +Signed-off-by: Lorenzo Bianconi +Signed-off-by: Paolo Abeni +--- + drivers/net/ethernet/airoha/airoha_eth.c | 35 ++++++++++++++---------- + drivers/net/ethernet/airoha/airoha_eth.h | 4 ++- + 2 files changed, 24 insertions(+), 15 deletions(-) + +--- a/drivers/net/ethernet/airoha/airoha_eth.c ++++ b/drivers/net/ethernet/airoha/airoha_eth.c +@@ -1563,6 +1563,7 @@ static int airoha_dev_open(struct net_de + airoha_qdma_set(qdma, REG_QDMA_GLOBAL_CFG, + GLOBAL_CFG_TX_DMA_EN_MASK | + GLOBAL_CFG_RX_DMA_EN_MASK); ++ atomic_inc(&qdma->users); + + return 0; + } +@@ -1578,16 +1579,20 @@ static int airoha_dev_stop(struct net_de + if (err) + return err; + +- airoha_qdma_clear(qdma, REG_QDMA_GLOBAL_CFG, +- GLOBAL_CFG_TX_DMA_EN_MASK | +- GLOBAL_CFG_RX_DMA_EN_MASK); ++ for (i = 0; i < ARRAY_SIZE(qdma->q_tx); i++) ++ netdev_tx_reset_subqueue(dev, i); + +- for (i = 0; i < ARRAY_SIZE(qdma->q_tx); i++) { +- if (!qdma->q_tx[i].ndesc) +- continue; ++ if (atomic_dec_and_test(&qdma->users)) { ++ airoha_qdma_clear(qdma, REG_QDMA_GLOBAL_CFG, ++ GLOBAL_CFG_TX_DMA_EN_MASK | ++ GLOBAL_CFG_RX_DMA_EN_MASK); ++ ++ for (i = 0; i < ARRAY_SIZE(qdma->q_tx); i++) { ++ if (!qdma->q_tx[i].ndesc) ++ continue; + +- airoha_qdma_cleanup_tx_queue(&qdma->q_tx[i]); +- netdev_tx_reset_subqueue(dev, i); ++ airoha_qdma_cleanup_tx_queue(&qdma->q_tx[i]); ++ } + } + + return 0; +@@ -2330,13 +2335,14 @@ static void airoha_metadata_dst_free(str + } + } + +-static int airoha_alloc_gdm_port(struct airoha_eth *eth, struct device_node *np) ++static int airoha_alloc_gdm_port(struct airoha_eth *eth, ++ struct device_node *np, int index) + { + const __be32 *id_ptr = of_get_property(np, "reg", NULL); + struct airoha_gdm_port *port; + struct airoha_qdma *qdma; + struct net_device *dev; +- int err, index; ++ int err, p; + u32 id; + + if (!id_ptr) { +@@ -2345,14 +2351,14 @@ static int airoha_alloc_gdm_port(struct + } + + id = be32_to_cpup(id_ptr); +- index = id - 1; ++ p = id - 1; + + if (!id || id > ARRAY_SIZE(eth->ports)) { + dev_err(eth->dev, "invalid gdm port id: %d\n", id); + return -EINVAL; + } + +- if (eth->ports[index]) { ++ if (eth->ports[p]) { + dev_err(eth->dev, "duplicate gdm port id: %d\n", id); + return -EINVAL; + } +@@ -2400,7 +2406,7 @@ static int airoha_alloc_gdm_port(struct + port->qdma = qdma; + port->dev = dev; + port->id = id; +- eth->ports[index] = port; ++ eth->ports[p] = port; + + err = airoha_metadata_dst_alloc(port); + if (err) +@@ -2472,6 +2478,7 @@ static int airoha_probe(struct platform_ + for (i = 0; i < ARRAY_SIZE(eth->qdma); i++) + airoha_qdma_start_napi(ð->qdma[i]); + ++ i = 0; + for_each_child_of_node(pdev->dev.of_node, np) { + if (!of_device_is_compatible(np, "airoha,eth-mac")) + continue; +@@ -2479,7 +2486,7 @@ static int airoha_probe(struct platform_ + if (!of_device_is_available(np)) + continue; + +- err = airoha_alloc_gdm_port(eth, np); ++ err = airoha_alloc_gdm_port(eth, np, i++); + if (err) { + of_node_put(np); + goto error_napi_stop; +--- a/drivers/net/ethernet/airoha/airoha_eth.h ++++ b/drivers/net/ethernet/airoha/airoha_eth.h +@@ -13,7 +13,7 @@ + #include + #include + +-#define AIROHA_MAX_NUM_GDM_PORTS 1 ++#define AIROHA_MAX_NUM_GDM_PORTS 4 + #define AIROHA_MAX_NUM_QDMA 2 + #define AIROHA_MAX_DSA_PORTS 7 + #define AIROHA_MAX_NUM_RSTS 3 +@@ -212,6 +212,8 @@ struct airoha_qdma { + u32 irqmask[QDMA_INT_REG_MAX]; + int irq; + ++ atomic_t users; ++ + struct airoha_tx_irq_queue q_tx_irq[AIROHA_NUM_TX_IRQ]; + + struct airoha_queue q_tx[AIROHA_NUM_TX_RING]; diff --git a/target/linux/airoha/patches-6.6/048-08-v6.15-net-airoha-Move-REG_GDM_FWD_CFG-initialization-in-ai.patch b/target/linux/airoha/patches-6.6/048-08-v6.15-net-airoha-Move-REG_GDM_FWD_CFG-initialization-in-ai.patch new file mode 100644 index 00000000000000..8bc0f856577cd4 --- /dev/null +++ b/target/linux/airoha/patches-6.6/048-08-v6.15-net-airoha-Move-REG_GDM_FWD_CFG-initialization-in-ai.patch @@ -0,0 +1,77 @@ +From 67fde5d58cd43d129a979e918ec9cd5d2e2fbcfb Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Fri, 28 Feb 2025 11:54:16 +0100 +Subject: [PATCH 08/15] net: airoha: Move REG_GDM_FWD_CFG() initialization in + airoha_dev_init() + +Move REG_GDM_FWD_CFG() register initialization in airoha_dev_init +routine. Moreover, always send traffic PPE module in order to be +processed by hw accelerator. +This is a preliminary patch to enable netfilter flowtable hw offloading +on EN7581 SoC. + +Signed-off-by: Lorenzo Bianconi +Signed-off-by: Paolo Abeni +--- + drivers/net/ethernet/airoha/airoha_eth.c | 14 ++++---------- + 1 file changed, 4 insertions(+), 10 deletions(-) + +--- a/drivers/net/ethernet/airoha/airoha_eth.c ++++ b/drivers/net/ethernet/airoha/airoha_eth.c +@@ -107,25 +107,20 @@ static void airoha_set_gdm_port_fwd_cfg( + + static int airoha_set_gdm_port(struct airoha_eth *eth, int port, bool enable) + { +- u32 val = enable ? FE_PSE_PORT_PPE1 : FE_PSE_PORT_DROP; +- u32 vip_port, cfg_addr; ++ u32 vip_port; + + switch (port) { + case XSI_PCIE0_PORT: + vip_port = XSI_PCIE0_VIP_PORT_MASK; +- cfg_addr = REG_GDM_FWD_CFG(3); + break; + case XSI_PCIE1_PORT: + vip_port = XSI_PCIE1_VIP_PORT_MASK; +- cfg_addr = REG_GDM_FWD_CFG(3); + break; + case XSI_USB_PORT: + vip_port = XSI_USB_VIP_PORT_MASK; +- cfg_addr = REG_GDM_FWD_CFG(4); + break; + case XSI_ETH_PORT: + vip_port = XSI_ETH_VIP_PORT_MASK; +- cfg_addr = REG_GDM_FWD_CFG(4); + break; + default: + return -EINVAL; +@@ -139,8 +134,6 @@ static int airoha_set_gdm_port(struct ai + airoha_fe_clear(eth, REG_FE_IFC_PORT_EN, vip_port); + } + +- airoha_set_gdm_port_fwd_cfg(eth, cfg_addr, val); +- + return 0; + } + +@@ -177,8 +170,6 @@ static void airoha_fe_maccr_init(struct + airoha_fe_set(eth, REG_GDM_FWD_CFG(p), + GDM_TCP_CKSUM | GDM_UDP_CKSUM | GDM_IP4_CKSUM | + GDM_DROP_CRC_ERR); +- airoha_set_gdm_port_fwd_cfg(eth, REG_GDM_FWD_CFG(p), +- FE_PSE_PORT_CDM1); + airoha_fe_rmw(eth, REG_GDM_LEN_CFG(p), + GDM_SHORT_LEN_MASK | GDM_LONG_LEN_MASK, + FIELD_PREP(GDM_SHORT_LEN_MASK, 60) | +@@ -1615,8 +1606,11 @@ static int airoha_dev_set_macaddr(struct + static int airoha_dev_init(struct net_device *dev) + { + struct airoha_gdm_port *port = netdev_priv(dev); ++ struct airoha_eth *eth = port->qdma->eth; + + airoha_set_macaddr(port, dev->dev_addr); ++ airoha_set_gdm_port_fwd_cfg(eth, REG_GDM_FWD_CFG(port->id), ++ FE_PSE_PORT_PPE1); + + return 0; + } diff --git a/target/linux/airoha/patches-6.6/048-09-v6.15-net-airoha-Rename-airoha_set_gdm_port_fwd_cfg-in-air.patch b/target/linux/airoha/patches-6.6/048-09-v6.15-net-airoha-Rename-airoha_set_gdm_port_fwd_cfg-in-air.patch new file mode 100644 index 00000000000000..11f879de1c407f --- /dev/null +++ b/target/linux/airoha/patches-6.6/048-09-v6.15-net-airoha-Rename-airoha_set_gdm_port_fwd_cfg-in-air.patch @@ -0,0 +1,120 @@ +From c28b8375f6d02ef3b5e8c51234cc3f6d47d9fb7f Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Fri, 28 Feb 2025 11:54:17 +0100 +Subject: [PATCH 09/15] net: airoha: Rename airoha_set_gdm_port_fwd_cfg() in + airoha_set_vip_for_gdm_port() + +Rename airoha_set_gdm_port() in airoha_set_vip_for_gdm_port(). +Get rid of airoha_set_gdm_ports routine. + +Signed-off-by: Lorenzo Bianconi +Signed-off-by: Paolo Abeni +--- + drivers/net/ethernet/airoha/airoha_eth.c | 49 ++++++------------------ + drivers/net/ethernet/airoha/airoha_eth.h | 8 ---- + 2 files changed, 11 insertions(+), 46 deletions(-) + +--- a/drivers/net/ethernet/airoha/airoha_eth.c ++++ b/drivers/net/ethernet/airoha/airoha_eth.c +@@ -105,25 +105,23 @@ static void airoha_set_gdm_port_fwd_cfg( + FIELD_PREP(GDM_UCFQ_MASK, val)); + } + +-static int airoha_set_gdm_port(struct airoha_eth *eth, int port, bool enable) ++static int airoha_set_vip_for_gdm_port(struct airoha_gdm_port *port, ++ bool enable) + { ++ struct airoha_eth *eth = port->qdma->eth; + u32 vip_port; + +- switch (port) { +- case XSI_PCIE0_PORT: ++ switch (port->id) { ++ case 3: ++ /* FIXME: handle XSI_PCIE1_PORT */ + vip_port = XSI_PCIE0_VIP_PORT_MASK; + break; +- case XSI_PCIE1_PORT: +- vip_port = XSI_PCIE1_VIP_PORT_MASK; +- break; +- case XSI_USB_PORT: +- vip_port = XSI_USB_VIP_PORT_MASK; +- break; +- case XSI_ETH_PORT: ++ case 4: ++ /* FIXME: handle XSI_USB_PORT */ + vip_port = XSI_ETH_VIP_PORT_MASK; + break; + default: +- return -EINVAL; ++ return 0; + } + + if (enable) { +@@ -137,31 +135,6 @@ static int airoha_set_gdm_port(struct ai + return 0; + } + +-static int airoha_set_gdm_ports(struct airoha_eth *eth, bool enable) +-{ +- const int port_list[] = { +- XSI_PCIE0_PORT, +- XSI_PCIE1_PORT, +- XSI_USB_PORT, +- XSI_ETH_PORT +- }; +- int i, err; +- +- for (i = 0; i < ARRAY_SIZE(port_list); i++) { +- err = airoha_set_gdm_port(eth, port_list[i], enable); +- if (err) +- goto error; +- } +- +- return 0; +- +-error: +- for (i--; i >= 0; i--) +- airoha_set_gdm_port(eth, port_list[i], false); +- +- return err; +-} +- + static void airoha_fe_maccr_init(struct airoha_eth *eth) + { + int p; +@@ -1540,7 +1513,7 @@ static int airoha_dev_open(struct net_de + int err; + + netif_tx_start_all_queues(dev); +- err = airoha_set_gdm_ports(qdma->eth, true); ++ err = airoha_set_vip_for_gdm_port(port, true); + if (err) + return err; + +@@ -1566,7 +1539,7 @@ static int airoha_dev_stop(struct net_de + int i, err; + + netif_tx_disable(dev); +- err = airoha_set_gdm_ports(qdma->eth, false); ++ err = airoha_set_vip_for_gdm_port(port, false); + if (err) + return err; + +--- a/drivers/net/ethernet/airoha/airoha_eth.h ++++ b/drivers/net/ethernet/airoha/airoha_eth.h +@@ -58,14 +58,6 @@ enum { + }; + + enum { +- XSI_PCIE0_PORT, +- XSI_PCIE1_PORT, +- XSI_USB_PORT, +- XSI_AE_PORT, +- XSI_ETH_PORT, +-}; +- +-enum { + XSI_PCIE0_VIP_PORT_MASK = BIT(22), + XSI_PCIE1_VIP_PORT_MASK = BIT(23), + XSI_USB_VIP_PORT_MASK = BIT(25), diff --git a/target/linux/airoha/patches-6.6/048-12-v6.15-net-airoha-Introduce-Airoha-NPU-support.patch b/target/linux/airoha/patches-6.6/048-12-v6.15-net-airoha-Introduce-Airoha-NPU-support.patch new file mode 100644 index 00000000000000..41c5622304096f --- /dev/null +++ b/target/linux/airoha/patches-6.6/048-12-v6.15-net-airoha-Introduce-Airoha-NPU-support.patch @@ -0,0 +1,627 @@ +From 23290c7bc190def4e1ca61610992d9b7c32e33f3 Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Fri, 28 Feb 2025 11:54:20 +0100 +Subject: [PATCH 12/15] net: airoha: Introduce Airoha NPU support + +Packet Processor Engine (PPE) module available on EN7581 SoC populates +the PPE table with 5-tuples flower rules learned from traffic forwarded +between the GDM ports connected to the Packet Switch Engine (PSE) module. +The airoha_eth driver can enable hw acceleration of learned 5-tuples +rules if the user configure them in netfilter flowtable (netfilter +flowtable support will be added with subsequent patches). +airoha_eth driver configures and collects data from the PPE module via a +Network Processor Unit (NPU) RISC-V module available on the EN7581 SoC. +Introduce basic support for Airoha NPU module. + +Tested-by: Sayantan Nandy +Signed-off-by: Lorenzo Bianconi +Signed-off-by: Paolo Abeni +--- + drivers/net/ethernet/airoha/Kconfig | 9 + + drivers/net/ethernet/airoha/Makefile | 1 + + drivers/net/ethernet/airoha/airoha_eth.h | 2 + + drivers/net/ethernet/airoha/airoha_npu.c | 520 +++++++++++++++++++++++ + drivers/net/ethernet/airoha/airoha_npu.h | 34 ++ + 5 files changed, 566 insertions(+) + create mode 100644 drivers/net/ethernet/airoha/airoha_npu.c + create mode 100644 drivers/net/ethernet/airoha/airoha_npu.h + +--- a/drivers/net/ethernet/airoha/Kconfig ++++ b/drivers/net/ethernet/airoha/Kconfig +@@ -7,9 +7,18 @@ config NET_VENDOR_AIROHA + + if NET_VENDOR_AIROHA + ++config NET_AIROHA_NPU ++ tristate "Airoha NPU support" ++ select WANT_DEV_COREDUMP ++ select REGMAP_MMIO ++ help ++ This driver supports Airoha Network Processor (NPU) available ++ on the Airoha Soc family. ++ + config NET_AIROHA + tristate "Airoha SoC Gigabit Ethernet support" + depends on NET_DSA || !NET_DSA ++ select NET_AIROHA_NPU + select PAGE_POOL + help + This driver supports the gigabit ethernet MACs in the +--- a/drivers/net/ethernet/airoha/Makefile ++++ b/drivers/net/ethernet/airoha/Makefile +@@ -4,3 +4,4 @@ + # + + obj-$(CONFIG_NET_AIROHA) += airoha_eth.o ++obj-$(CONFIG_NET_AIROHA_NPU) += airoha_npu.o +--- a/drivers/net/ethernet/airoha/airoha_eth.h ++++ b/drivers/net/ethernet/airoha/airoha_eth.h +@@ -240,6 +240,8 @@ struct airoha_eth { + unsigned long state; + void __iomem *fe_regs; + ++ struct airoha_npu __rcu *npu; ++ + struct reset_control_bulk_data rsts[AIROHA_MAX_NUM_RSTS]; + struct reset_control_bulk_data xsi_rsts[AIROHA_MAX_NUM_XSI_RSTS]; + +--- /dev/null ++++ b/drivers/net/ethernet/airoha/airoha_npu.c +@@ -0,0 +1,520 @@ ++// SPDX-License-Identifier: GPL-2.0-only ++/* ++ * Copyright (c) 2025 AIROHA Inc ++ * Author: Lorenzo Bianconi ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "airoha_npu.h" ++ ++#define NPU_EN7581_FIRMWARE_DATA "airoha/en7581_npu_data.bin" ++#define NPU_EN7581_FIRMWARE_RV32 "airoha/en7581_npu_rv32.bin" ++#define NPU_EN7581_FIRMWARE_RV32_MAX_SIZE 0x200000 ++#define NPU_EN7581_FIRMWARE_DATA_MAX_SIZE 0x10000 ++#define NPU_DUMP_SIZE 512 ++ ++#define REG_NPU_LOCAL_SRAM 0x0 ++ ++#define NPU_PC_BASE_ADDR 0x305000 ++#define REG_PC_DBG(_n) (0x305000 + ((_n) * 0x100)) ++ ++#define NPU_CLUSTER_BASE_ADDR 0x306000 ++ ++#define REG_CR_BOOT_TRIGGER (NPU_CLUSTER_BASE_ADDR + 0x000) ++#define REG_CR_BOOT_CONFIG (NPU_CLUSTER_BASE_ADDR + 0x004) ++#define REG_CR_BOOT_BASE(_n) (NPU_CLUSTER_BASE_ADDR + 0x020 + ((_n) << 2)) ++ ++#define NPU_MBOX_BASE_ADDR 0x30c000 ++ ++#define REG_CR_MBOX_INT_STATUS (NPU_MBOX_BASE_ADDR + 0x000) ++#define MBOX_INT_STATUS_MASK BIT(8) ++ ++#define REG_CR_MBOX_INT_MASK(_n) (NPU_MBOX_BASE_ADDR + 0x004 + ((_n) << 2)) ++#define REG_CR_MBQ0_CTRL(_n) (NPU_MBOX_BASE_ADDR + 0x030 + ((_n) << 2)) ++#define REG_CR_MBQ8_CTRL(_n) (NPU_MBOX_BASE_ADDR + 0x0b0 + ((_n) << 2)) ++#define REG_CR_NPU_MIB(_n) (NPU_MBOX_BASE_ADDR + 0x140 + ((_n) << 2)) ++ ++#define NPU_TIMER_BASE_ADDR 0x310100 ++#define REG_WDT_TIMER_CTRL(_n) (NPU_TIMER_BASE_ADDR + ((_n) * 0x100)) ++#define WDT_EN_MASK BIT(25) ++#define WDT_INTR_MASK BIT(21) ++ ++enum { ++ NPU_OP_SET = 1, ++ NPU_OP_SET_NO_WAIT, ++ NPU_OP_GET, ++ NPU_OP_GET_NO_WAIT, ++}; ++ ++enum { ++ NPU_FUNC_WIFI, ++ NPU_FUNC_TUNNEL, ++ NPU_FUNC_NOTIFY, ++ NPU_FUNC_DBA, ++ NPU_FUNC_TR471, ++ NPU_FUNC_PPE, ++}; ++ ++enum { ++ NPU_MBOX_ERROR, ++ NPU_MBOX_SUCCESS, ++}; ++ ++enum { ++ PPE_FUNC_SET_WAIT, ++ PPE_FUNC_SET_WAIT_HWNAT_INIT, ++ PPE_FUNC_SET_WAIT_HWNAT_DEINIT, ++ PPE_FUNC_SET_WAIT_API, ++}; ++ ++enum { ++ PPE2_SRAM_SET_ENTRY, ++ PPE_SRAM_SET_ENTRY, ++ PPE_SRAM_SET_VAL, ++ PPE_SRAM_RESET_VAL, ++}; ++ ++enum { ++ QDMA_WAN_ETHER = 1, ++ QDMA_WAN_PON_XDSL, ++}; ++ ++#define MBOX_MSG_FUNC_ID GENMASK(14, 11) ++#define MBOX_MSG_STATIC_BUF BIT(5) ++#define MBOX_MSG_STATUS GENMASK(4, 2) ++#define MBOX_MSG_DONE BIT(1) ++#define MBOX_MSG_WAIT_RSP BIT(0) ++ ++#define PPE_TYPE_L2B_IPV4 2 ++#define PPE_TYPE_L2B_IPV4_IPV6 3 ++ ++struct ppe_mbox_data { ++ u32 func_type; ++ u32 func_id; ++ union { ++ struct { ++ u8 cds; ++ u8 xpon_hal_api; ++ u8 wan_xsi; ++ u8 ct_joyme4; ++ int ppe_type; ++ int wan_mode; ++ int wan_sel; ++ } init_info; ++ struct { ++ int func_id; ++ u32 size; ++ u32 data; ++ } set_info; ++ }; ++}; ++ ++static int airoha_npu_send_msg(struct airoha_npu *npu, int func_id, ++ void *p, int size) ++{ ++ u16 core = 0; /* FIXME */ ++ u32 val, offset = core << 4; ++ dma_addr_t dma_addr; ++ void *addr; ++ int ret; ++ ++ addr = kmemdup(p, size, GFP_ATOMIC); ++ if (!addr) ++ return -ENOMEM; ++ ++ dma_addr = dma_map_single(npu->dev, addr, size, DMA_TO_DEVICE); ++ ret = dma_mapping_error(npu->dev, dma_addr); ++ if (ret) ++ goto out; ++ ++ spin_lock_bh(&npu->cores[core].lock); ++ ++ regmap_write(npu->regmap, REG_CR_MBQ0_CTRL(0) + offset, dma_addr); ++ regmap_write(npu->regmap, REG_CR_MBQ0_CTRL(1) + offset, size); ++ regmap_read(npu->regmap, REG_CR_MBQ0_CTRL(2) + offset, &val); ++ regmap_write(npu->regmap, REG_CR_MBQ0_CTRL(2) + offset, val + 1); ++ val = FIELD_PREP(MBOX_MSG_FUNC_ID, func_id) | MBOX_MSG_WAIT_RSP; ++ regmap_write(npu->regmap, REG_CR_MBQ0_CTRL(3) + offset, val); ++ ++ ret = regmap_read_poll_timeout_atomic(npu->regmap, ++ REG_CR_MBQ0_CTRL(3) + offset, ++ val, (val & MBOX_MSG_DONE), ++ 100, 100 * MSEC_PER_SEC); ++ if (!ret && FIELD_GET(MBOX_MSG_STATUS, val) != NPU_MBOX_SUCCESS) ++ ret = -EINVAL; ++ ++ spin_unlock_bh(&npu->cores[core].lock); ++ ++ dma_unmap_single(npu->dev, dma_addr, size, DMA_TO_DEVICE); ++out: ++ kfree(addr); ++ ++ return ret; ++} ++ ++static int airoha_npu_run_firmware(struct device *dev, void __iomem *base, ++ struct reserved_mem *rmem) ++{ ++ const struct firmware *fw; ++ void __iomem *addr; ++ int ret; ++ ++ ret = request_firmware(&fw, NPU_EN7581_FIRMWARE_RV32, dev); ++ if (ret) ++ return ret == -ENOENT ? -EPROBE_DEFER : ret; ++ ++ if (fw->size > NPU_EN7581_FIRMWARE_RV32_MAX_SIZE) { ++ dev_err(dev, "%s: fw size too overlimit (%zu)\n", ++ NPU_EN7581_FIRMWARE_RV32, fw->size); ++ ret = -E2BIG; ++ goto out; ++ } ++ ++ addr = devm_ioremap(dev, rmem->base, rmem->size); ++ if (!addr) { ++ ret = -ENOMEM; ++ goto out; ++ } ++ ++ memcpy_toio(addr, fw->data, fw->size); ++ release_firmware(fw); ++ ++ ret = request_firmware(&fw, NPU_EN7581_FIRMWARE_DATA, dev); ++ if (ret) ++ return ret == -ENOENT ? -EPROBE_DEFER : ret; ++ ++ if (fw->size > NPU_EN7581_FIRMWARE_DATA_MAX_SIZE) { ++ dev_err(dev, "%s: fw size too overlimit (%zu)\n", ++ NPU_EN7581_FIRMWARE_DATA, fw->size); ++ ret = -E2BIG; ++ goto out; ++ } ++ ++ memcpy_toio(base + REG_NPU_LOCAL_SRAM, fw->data, fw->size); ++out: ++ release_firmware(fw); ++ ++ return ret; ++} ++ ++static irqreturn_t airoha_npu_mbox_handler(int irq, void *npu_instance) ++{ ++ struct airoha_npu *npu = npu_instance; ++ ++ /* clear mbox interrupt status */ ++ regmap_write(npu->regmap, REG_CR_MBOX_INT_STATUS, ++ MBOX_INT_STATUS_MASK); ++ ++ /* acknowledge npu */ ++ regmap_update_bits(npu->regmap, REG_CR_MBQ8_CTRL(3), ++ MBOX_MSG_STATUS | MBOX_MSG_DONE, MBOX_MSG_DONE); ++ ++ return IRQ_HANDLED; ++} ++ ++static void airoha_npu_wdt_work(struct work_struct *work) ++{ ++ struct airoha_npu_core *core; ++ struct airoha_npu *npu; ++ void *dump; ++ u32 val[3]; ++ int c; ++ ++ core = container_of(work, struct airoha_npu_core, wdt_work); ++ npu = core->npu; ++ ++ dump = vzalloc(NPU_DUMP_SIZE); ++ if (!dump) ++ return; ++ ++ c = core - &npu->cores[0]; ++ regmap_bulk_read(npu->regmap, REG_PC_DBG(c), val, ARRAY_SIZE(val)); ++ snprintf(dump, NPU_DUMP_SIZE, "PC: %08x SP: %08x LR: %08x\n", ++ val[0], val[1], val[2]); ++ ++ dev_coredumpv(npu->dev, dump, NPU_DUMP_SIZE, GFP_KERNEL); ++} ++ ++static irqreturn_t airoha_npu_wdt_handler(int irq, void *core_instance) ++{ ++ struct airoha_npu_core *core = core_instance; ++ struct airoha_npu *npu = core->npu; ++ int c = core - &npu->cores[0]; ++ u32 val; ++ ++ regmap_set_bits(npu->regmap, REG_WDT_TIMER_CTRL(c), WDT_INTR_MASK); ++ if (!regmap_read(npu->regmap, REG_WDT_TIMER_CTRL(c), &val) && ++ FIELD_GET(WDT_EN_MASK, val)) ++ schedule_work(&core->wdt_work); ++ ++ return IRQ_HANDLED; ++} ++ ++static int airoha_npu_ppe_init(struct airoha_npu *npu) ++{ ++ struct ppe_mbox_data ppe_data = { ++ .func_type = NPU_OP_SET, ++ .func_id = PPE_FUNC_SET_WAIT_HWNAT_INIT, ++ .init_info = { ++ .ppe_type = PPE_TYPE_L2B_IPV4_IPV6, ++ .wan_mode = QDMA_WAN_ETHER, ++ }, ++ }; ++ ++ return airoha_npu_send_msg(npu, NPU_FUNC_PPE, &ppe_data, ++ sizeof(struct ppe_mbox_data)); ++} ++ ++static int airoha_npu_ppe_deinit(struct airoha_npu *npu) ++{ ++ struct ppe_mbox_data ppe_data = { ++ .func_type = NPU_OP_SET, ++ .func_id = PPE_FUNC_SET_WAIT_HWNAT_DEINIT, ++ }; ++ ++ return airoha_npu_send_msg(npu, NPU_FUNC_PPE, &ppe_data, ++ sizeof(struct ppe_mbox_data)); ++} ++ ++static int airoha_npu_ppe_flush_sram_entries(struct airoha_npu *npu, ++ dma_addr_t foe_addr, ++ int sram_num_entries) ++{ ++ struct ppe_mbox_data ppe_data = { ++ .func_type = NPU_OP_SET, ++ .func_id = PPE_FUNC_SET_WAIT_API, ++ .set_info = { ++ .func_id = PPE_SRAM_RESET_VAL, ++ .data = foe_addr, ++ .size = sram_num_entries, ++ }, ++ }; ++ ++ return airoha_npu_send_msg(npu, NPU_FUNC_PPE, &ppe_data, ++ sizeof(struct ppe_mbox_data)); ++} ++ ++static int airoha_npu_foe_commit_entry(struct airoha_npu *npu, ++ dma_addr_t foe_addr, ++ u32 entry_size, u32 hash, bool ppe2) ++{ ++ struct ppe_mbox_data ppe_data = { ++ .func_type = NPU_OP_SET, ++ .func_id = PPE_FUNC_SET_WAIT_API, ++ .set_info = { ++ .data = foe_addr, ++ .size = entry_size, ++ }, ++ }; ++ int err; ++ ++ ppe_data.set_info.func_id = ppe2 ? PPE2_SRAM_SET_ENTRY ++ : PPE_SRAM_SET_ENTRY; ++ ++ err = airoha_npu_send_msg(npu, NPU_FUNC_PPE, &ppe_data, ++ sizeof(struct ppe_mbox_data)); ++ if (err) ++ return err; ++ ++ ppe_data.set_info.func_id = PPE_SRAM_SET_VAL; ++ ppe_data.set_info.data = hash; ++ ppe_data.set_info.size = sizeof(u32); ++ ++ return airoha_npu_send_msg(npu, NPU_FUNC_PPE, &ppe_data, ++ sizeof(struct ppe_mbox_data)); ++} ++ ++struct airoha_npu *airoha_npu_get(struct device *dev) ++{ ++ struct platform_device *pdev; ++ struct device_node *np; ++ struct airoha_npu *npu; ++ ++ np = of_parse_phandle(dev->of_node, "airoha,npu", 0); ++ if (!np) ++ return ERR_PTR(-ENODEV); ++ ++ pdev = of_find_device_by_node(np); ++ of_node_put(np); ++ ++ if (!pdev) { ++ dev_err(dev, "cannot find device node %s\n", np->name); ++ return ERR_PTR(-ENODEV); ++ } ++ ++ if (!try_module_get(THIS_MODULE)) { ++ dev_err(dev, "failed to get the device driver module\n"); ++ npu = ERR_PTR(-ENODEV); ++ goto error_pdev_put; ++ } ++ ++ npu = platform_get_drvdata(pdev); ++ if (!npu) { ++ npu = ERR_PTR(-ENODEV); ++ goto error_module_put; ++ } ++ ++ if (!device_link_add(dev, &pdev->dev, DL_FLAG_AUTOREMOVE_SUPPLIER)) { ++ dev_err(&pdev->dev, ++ "failed to create device link to consumer %s\n", ++ dev_name(dev)); ++ npu = ERR_PTR(-EINVAL); ++ goto error_module_put; ++ } ++ ++ return npu; ++ ++error_module_put: ++ module_put(THIS_MODULE); ++error_pdev_put: ++ platform_device_put(pdev); ++ ++ return npu; ++} ++EXPORT_SYMBOL_GPL(airoha_npu_get); ++ ++void airoha_npu_put(struct airoha_npu *npu) ++{ ++ module_put(THIS_MODULE); ++ put_device(npu->dev); ++} ++EXPORT_SYMBOL_GPL(airoha_npu_put); ++ ++static const struct of_device_id of_airoha_npu_match[] = { ++ { .compatible = "airoha,en7581-npu" }, ++ { /* sentinel */ } ++}; ++MODULE_DEVICE_TABLE(of, of_airoha_npu_match); ++ ++static const struct regmap_config regmap_config = { ++ .name = "npu", ++ .reg_bits = 32, ++ .val_bits = 32, ++ .reg_stride = 4, ++ .disable_locking = true, ++}; ++ ++static int airoha_npu_probe(struct platform_device *pdev) ++{ ++ struct device *dev = &pdev->dev; ++ struct reserved_mem *rmem; ++ struct airoha_npu *npu; ++ struct device_node *np; ++ void __iomem *base; ++ int i, irq, err; ++ ++ base = devm_platform_ioremap_resource(pdev, 0); ++ if (IS_ERR(base)) ++ return PTR_ERR(base); ++ ++ npu = devm_kzalloc(dev, sizeof(*npu), GFP_KERNEL); ++ if (!npu) ++ return -ENOMEM; ++ ++ npu->dev = dev; ++ npu->ops.ppe_init = airoha_npu_ppe_init; ++ npu->ops.ppe_deinit = airoha_npu_ppe_deinit; ++ npu->ops.ppe_flush_sram_entries = airoha_npu_ppe_flush_sram_entries; ++ npu->ops.ppe_foe_commit_entry = airoha_npu_foe_commit_entry; ++ ++ npu->regmap = devm_regmap_init_mmio(dev, base, ®map_config); ++ if (IS_ERR(npu->regmap)) ++ return PTR_ERR(npu->regmap); ++ ++ np = of_parse_phandle(dev->of_node, "memory-region", 0); ++ if (!np) ++ return -ENODEV; ++ ++ rmem = of_reserved_mem_lookup(np); ++ of_node_put(np); ++ ++ if (!rmem) ++ return -ENODEV; ++ ++ irq = platform_get_irq(pdev, 0); ++ if (irq < 0) ++ return irq; ++ ++ err = devm_request_irq(dev, irq, airoha_npu_mbox_handler, ++ IRQF_SHARED, "airoha-npu-mbox", npu); ++ if (err) ++ return err; ++ ++ for (i = 0; i < ARRAY_SIZE(npu->cores); i++) { ++ struct airoha_npu_core *core = &npu->cores[i]; ++ ++ spin_lock_init(&core->lock); ++ core->npu = npu; ++ ++ irq = platform_get_irq(pdev, i + 1); ++ if (irq < 0) ++ return irq; ++ ++ err = devm_request_irq(dev, irq, airoha_npu_wdt_handler, ++ IRQF_SHARED, "airoha-npu-wdt", core); ++ if (err) ++ return err; ++ ++ INIT_WORK(&core->wdt_work, airoha_npu_wdt_work); ++ } ++ ++ err = dma_set_coherent_mask(dev, DMA_BIT_MASK(32)); ++ if (err) ++ return err; ++ ++ err = airoha_npu_run_firmware(dev, base, rmem); ++ if (err) ++ return dev_err_probe(dev, err, "failed to run npu firmware\n"); ++ ++ regmap_write(npu->regmap, REG_CR_NPU_MIB(10), ++ rmem->base + NPU_EN7581_FIRMWARE_RV32_MAX_SIZE); ++ regmap_write(npu->regmap, REG_CR_NPU_MIB(11), 0x40000); /* SRAM 256K */ ++ regmap_write(npu->regmap, REG_CR_NPU_MIB(12), 0); ++ regmap_write(npu->regmap, REG_CR_NPU_MIB(21), 1); ++ msleep(100); ++ ++ /* setting booting address */ ++ for (i = 0; i < NPU_NUM_CORES; i++) ++ regmap_write(npu->regmap, REG_CR_BOOT_BASE(i), rmem->base); ++ usleep_range(1000, 2000); ++ ++ /* enable NPU cores */ ++ /* do not start core3 since it is used for WiFi offloading */ ++ regmap_write(npu->regmap, REG_CR_BOOT_CONFIG, 0xf7); ++ regmap_write(npu->regmap, REG_CR_BOOT_TRIGGER, 0x1); ++ msleep(100); ++ ++ platform_set_drvdata(pdev, npu); ++ ++ return 0; ++} ++ ++static void airoha_npu_remove(struct platform_device *pdev) ++{ ++ struct airoha_npu *npu = platform_get_drvdata(pdev); ++ int i; ++ ++ for (i = 0; i < ARRAY_SIZE(npu->cores); i++) ++ cancel_work_sync(&npu->cores[i].wdt_work); ++} ++ ++static struct platform_driver airoha_npu_driver = { ++ .probe = airoha_npu_probe, ++ .remove_new = airoha_npu_remove, ++ .driver = { ++ .name = "airoha-npu", ++ .of_match_table = of_airoha_npu_match, ++ }, ++}; ++module_platform_driver(airoha_npu_driver); ++ ++MODULE_LICENSE("GPL"); ++MODULE_AUTHOR("Lorenzo Bianconi "); ++MODULE_DESCRIPTION("Airoha Network Processor Unit driver"); +--- /dev/null ++++ b/drivers/net/ethernet/airoha/airoha_npu.h +@@ -0,0 +1,34 @@ ++/* SPDX-License-Identifier: GPL-2.0-only */ ++/* ++ * Copyright (c) 2025 AIROHA Inc ++ * Author: Lorenzo Bianconi ++ */ ++ ++#define NPU_NUM_CORES 8 ++ ++struct airoha_npu { ++ struct device *dev; ++ struct regmap *regmap; ++ ++ struct airoha_npu_core { ++ struct airoha_npu *npu; ++ /* protect concurrent npu memory accesses */ ++ spinlock_t lock; ++ struct work_struct wdt_work; ++ } cores[NPU_NUM_CORES]; ++ ++ struct { ++ int (*ppe_init)(struct airoha_npu *npu); ++ int (*ppe_deinit)(struct airoha_npu *npu); ++ int (*ppe_flush_sram_entries)(struct airoha_npu *npu, ++ dma_addr_t foe_addr, ++ int sram_num_entries); ++ int (*ppe_foe_commit_entry)(struct airoha_npu *npu, ++ dma_addr_t foe_addr, ++ u32 entry_size, u32 hash, ++ bool ppe2); ++ } ops; ++}; ++ ++struct airoha_npu *airoha_npu_get(struct device *dev); ++void airoha_npu_put(struct airoha_npu *npu); diff --git a/target/linux/airoha/patches-6.6/048-13-v6.15-net-airoha-Introduce-flowtable-offload-support.patch b/target/linux/airoha/patches-6.6/048-13-v6.15-net-airoha-Introduce-flowtable-offload-support.patch new file mode 100644 index 00000000000000..225165fca5ab39 --- /dev/null +++ b/target/linux/airoha/patches-6.6/048-13-v6.15-net-airoha-Introduce-flowtable-offload-support.patch @@ -0,0 +1,1481 @@ +From 00a7678310fe3d3f408513e55d9a0b67f0db380f Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Fri, 28 Feb 2025 11:54:21 +0100 +Subject: [PATCH 13/15] net: airoha: Introduce flowtable offload support + +Introduce netfilter flowtable integration in order to allow airoha_eth +driver to offload 5-tuple flower rules learned by the PPE module if the +user accelerates them using a nft configuration similar to the one reported +below: + +table inet filter { + flowtable ft { + hook ingress priority filter + devices = { lan1, lan2, lan3, lan4, eth1 } + flags offload; + } + chain forward { + type filter hook forward priority filter; policy accept; + meta l4proto { tcp, udp } flow add @ft + } +} + +Tested-by: Sayantan Nandy +Signed-off-by: Lorenzo Bianconi +Signed-off-by: Paolo Abeni +--- + drivers/net/ethernet/airoha/Makefile | 3 +- + drivers/net/ethernet/airoha/airoha_eth.c | 60 +- + drivers/net/ethernet/airoha/airoha_eth.h | 250 ++++++ + drivers/net/ethernet/airoha/airoha_ppe.c | 901 ++++++++++++++++++++++ + drivers/net/ethernet/airoha/airoha_regs.h | 107 ++- + 5 files changed, 1314 insertions(+), 7 deletions(-) + create mode 100644 drivers/net/ethernet/airoha/airoha_ppe.c + +--- a/drivers/net/ethernet/airoha/Makefile ++++ b/drivers/net/ethernet/airoha/Makefile +@@ -3,5 +3,6 @@ + # Airoha for the Mediatek SoCs built-in ethernet macs + # + +-obj-$(CONFIG_NET_AIROHA) += airoha_eth.o ++obj-$(CONFIG_NET_AIROHA) += airoha-eth.o ++airoha-eth-y := airoha_eth.o airoha_ppe.o + obj-$(CONFIG_NET_AIROHA_NPU) += airoha_npu.o +--- a/drivers/net/ethernet/airoha/airoha_eth.c ++++ b/drivers/net/ethernet/airoha/airoha_eth.c +@@ -8,7 +8,6 @@ + #include + #include + #include +-#include + #include + #include + #include +@@ -619,6 +618,7 @@ static int airoha_qdma_rx_process(struct + while (done < budget) { + struct airoha_queue_entry *e = &q->entry[q->tail]; + struct airoha_qdma_desc *desc = &q->desc[q->tail]; ++ u32 hash, reason, msg1 = le32_to_cpu(desc->msg1); + dma_addr_t dma_addr = le32_to_cpu(desc->addr); + u32 desc_ctrl = le32_to_cpu(desc->ctrl); + struct airoha_gdm_port *port; +@@ -681,6 +681,15 @@ static int airoha_qdma_rx_process(struct + &port->dsa_meta[sptag]->dst); + } + ++ hash = FIELD_GET(AIROHA_RXD4_FOE_ENTRY, msg1); ++ if (hash != AIROHA_RXD4_FOE_ENTRY) ++ skb_set_hash(skb, jhash_1word(hash, 0), ++ PKT_HASH_TYPE_L4); ++ ++ reason = FIELD_GET(AIROHA_RXD4_PPE_CPU_REASON, msg1); ++ if (reason == PPE_CPU_REASON_HIT_UNBIND_RATE_REACHED) ++ airoha_ppe_check_skb(eth->ppe, hash); ++ + napi_gro_receive(&q->napi, skb); + + done++; +@@ -1302,6 +1311,10 @@ static int airoha_hw_init(struct platfor + return err; + } + ++ err = airoha_ppe_init(eth); ++ if (err) ++ return err; ++ + set_bit(DEV_STATE_INITIALIZED, ð->state); + + return 0; +@@ -2166,6 +2179,47 @@ static int airoha_tc_htb_alloc_leaf_queu + return 0; + } + ++static int airoha_dev_setup_tc_block(struct airoha_gdm_port *port, ++ struct flow_block_offload *f) ++{ ++ flow_setup_cb_t *cb = airoha_ppe_setup_tc_block_cb; ++ static LIST_HEAD(block_cb_list); ++ struct flow_block_cb *block_cb; ++ ++ if (f->binder_type != FLOW_BLOCK_BINDER_TYPE_CLSACT_INGRESS) ++ return -EOPNOTSUPP; ++ ++ f->driver_block_list = &block_cb_list; ++ switch (f->command) { ++ case FLOW_BLOCK_BIND: ++ block_cb = flow_block_cb_lookup(f->block, cb, port->dev); ++ if (block_cb) { ++ flow_block_cb_incref(block_cb); ++ return 0; ++ } ++ block_cb = flow_block_cb_alloc(cb, port->dev, port->dev, NULL); ++ if (IS_ERR(block_cb)) ++ return PTR_ERR(block_cb); ++ ++ flow_block_cb_incref(block_cb); ++ flow_block_cb_add(block_cb, f); ++ list_add_tail(&block_cb->driver_list, &block_cb_list); ++ return 0; ++ case FLOW_BLOCK_UNBIND: ++ block_cb = flow_block_cb_lookup(f->block, cb, port->dev); ++ if (!block_cb) ++ return -ENOENT; ++ ++ if (!flow_block_cb_decref(block_cb)) { ++ flow_block_cb_remove(block_cb, f); ++ list_del(&block_cb->driver_list); ++ } ++ return 0; ++ default: ++ return -EOPNOTSUPP; ++ } ++} ++ + static void airoha_tc_remove_htb_queue(struct airoha_gdm_port *port, int queue) + { + struct net_device *dev = port->dev; +@@ -2249,6 +2303,9 @@ static int airoha_dev_tc_setup(struct ne + return airoha_tc_setup_qdisc_ets(port, type_data); + case TC_SETUP_QDISC_HTB: + return airoha_tc_setup_qdisc_htb(port, type_data); ++ case TC_SETUP_BLOCK: ++ case TC_SETUP_FT: ++ return airoha_dev_setup_tc_block(port, type_data); + default: + return -EOPNOTSUPP; + } +@@ -2505,6 +2562,7 @@ static void airoha_remove(struct platfor + } + free_netdev(eth->napi_dev); + ++ airoha_ppe_deinit(eth); + platform_set_drvdata(pdev, NULL); + } + +--- a/drivers/net/ethernet/airoha/airoha_eth.h ++++ b/drivers/net/ethernet/airoha/airoha_eth.h +@@ -12,6 +12,7 @@ + #include + #include + #include ++#include + + #define AIROHA_MAX_NUM_GDM_PORTS 4 + #define AIROHA_MAX_NUM_QDMA 2 +@@ -44,6 +45,15 @@ + #define QDMA_METER_IDX(_n) ((_n) & 0xff) + #define QDMA_METER_GROUP(_n) (((_n) >> 8) & 0x3) + ++#define PPE_NUM 2 ++#define PPE1_SRAM_NUM_ENTRIES (8 * 1024) ++#define PPE_SRAM_NUM_ENTRIES (2 * PPE1_SRAM_NUM_ENTRIES) ++#define PPE_DRAM_NUM_ENTRIES (16 * 1024) ++#define PPE_NUM_ENTRIES (PPE_SRAM_NUM_ENTRIES + PPE_DRAM_NUM_ENTRIES) ++#define PPE_HASH_MASK (PPE_NUM_ENTRIES - 1) ++#define PPE_ENTRY_SIZE 80 ++#define PPE_RAM_NUM_ENTRIES_SHIFT(_n) (__ffs((_n) >> 10)) ++ + #define MTK_HDR_LEN 4 + #define MTK_HDR_XMIT_TAGGED_TPID_8100 1 + #define MTK_HDR_XMIT_TAGGED_TPID_88A8 2 +@@ -195,6 +205,224 @@ struct airoha_hw_stats { + u64 rx_len[7]; + }; + ++enum { ++ PPE_CPU_REASON_HIT_UNBIND_RATE_REACHED = 0x0f, ++}; ++ ++enum { ++ AIROHA_FOE_STATE_INVALID, ++ AIROHA_FOE_STATE_UNBIND, ++ AIROHA_FOE_STATE_BIND, ++ AIROHA_FOE_STATE_FIN ++}; ++ ++enum { ++ PPE_PKT_TYPE_IPV4_HNAPT = 0, ++ PPE_PKT_TYPE_IPV4_ROUTE = 1, ++ PPE_PKT_TYPE_BRIDGE = 2, ++ PPE_PKT_TYPE_IPV4_DSLITE = 3, ++ PPE_PKT_TYPE_IPV6_ROUTE_3T = 4, ++ PPE_PKT_TYPE_IPV6_ROUTE_5T = 5, ++ PPE_PKT_TYPE_IPV6_6RD = 7, ++}; ++ ++#define AIROHA_FOE_MAC_SMAC_ID GENMASK(20, 16) ++#define AIROHA_FOE_MAC_PPPOE_ID GENMASK(15, 0) ++ ++struct airoha_foe_mac_info_common { ++ u16 vlan1; ++ u16 etype; ++ ++ u32 dest_mac_hi; ++ ++ u16 vlan2; ++ u16 dest_mac_lo; ++ ++ u32 src_mac_hi; ++}; ++ ++struct airoha_foe_mac_info { ++ struct airoha_foe_mac_info_common common; ++ ++ u16 pppoe_id; ++ u16 src_mac_lo; ++}; ++ ++#define AIROHA_FOE_IB1_UNBIND_PREBIND BIT(24) ++#define AIROHA_FOE_IB1_UNBIND_PACKETS GENMASK(23, 8) ++#define AIROHA_FOE_IB1_UNBIND_TIMESTAMP GENMASK(7, 0) ++ ++#define AIROHA_FOE_IB1_BIND_STATIC BIT(31) ++#define AIROHA_FOE_IB1_BIND_UDP BIT(30) ++#define AIROHA_FOE_IB1_BIND_STATE GENMASK(29, 28) ++#define AIROHA_FOE_IB1_BIND_PACKET_TYPE GENMASK(27, 25) ++#define AIROHA_FOE_IB1_BIND_TTL BIT(24) ++#define AIROHA_FOE_IB1_BIND_TUNNEL_DECAP BIT(23) ++#define AIROHA_FOE_IB1_BIND_PPPOE BIT(22) ++#define AIROHA_FOE_IB1_BIND_VPM GENMASK(21, 20) ++#define AIROHA_FOE_IB1_BIND_VLAN_LAYER GENMASK(19, 16) ++#define AIROHA_FOE_IB1_BIND_KEEPALIVE BIT(15) ++#define AIROHA_FOE_IB1_BIND_TIMESTAMP GENMASK(14, 0) ++ ++#define AIROHA_FOE_IB2_DSCP GENMASK(31, 24) ++#define AIROHA_FOE_IB2_PORT_AG GENMASK(23, 13) ++#define AIROHA_FOE_IB2_PCP BIT(12) ++#define AIROHA_FOE_IB2_MULTICAST BIT(11) ++#define AIROHA_FOE_IB2_FAST_PATH BIT(10) ++#define AIROHA_FOE_IB2_PSE_QOS BIT(9) ++#define AIROHA_FOE_IB2_PSE_PORT GENMASK(8, 5) ++#define AIROHA_FOE_IB2_NBQ GENMASK(4, 0) ++ ++#define AIROHA_FOE_ACTDP GENMASK(31, 24) ++#define AIROHA_FOE_SHAPER_ID GENMASK(23, 16) ++#define AIROHA_FOE_CHANNEL GENMASK(15, 11) ++#define AIROHA_FOE_QID GENMASK(10, 8) ++#define AIROHA_FOE_DPI BIT(7) ++#define AIROHA_FOE_TUNNEL BIT(6) ++#define AIROHA_FOE_TUNNEL_ID GENMASK(5, 0) ++ ++struct airoha_foe_bridge { ++ u32 dest_mac_hi; ++ ++ u16 src_mac_hi; ++ u16 dest_mac_lo; ++ ++ u32 src_mac_lo; ++ ++ u32 ib2; ++ ++ u32 rsv[5]; ++ ++ u32 data; ++ ++ struct airoha_foe_mac_info l2; ++}; ++ ++struct airoha_foe_ipv4_tuple { ++ u32 src_ip; ++ u32 dest_ip; ++ union { ++ struct { ++ u16 dest_port; ++ u16 src_port; ++ }; ++ struct { ++ u8 protocol; ++ u8 _pad[3]; /* fill with 0xa5a5a5 */ ++ }; ++ u32 ports; ++ }; ++}; ++ ++struct airoha_foe_ipv4 { ++ struct airoha_foe_ipv4_tuple orig_tuple; ++ ++ u32 ib2; ++ ++ struct airoha_foe_ipv4_tuple new_tuple; ++ ++ u32 rsv[2]; ++ ++ u32 data; ++ ++ struct airoha_foe_mac_info l2; ++}; ++ ++struct airoha_foe_ipv4_dslite { ++ struct airoha_foe_ipv4_tuple ip4; ++ ++ u32 ib2; ++ ++ u8 flow_label[3]; ++ u8 priority; ++ ++ u32 rsv[4]; ++ ++ u32 data; ++ ++ struct airoha_foe_mac_info l2; ++}; ++ ++struct airoha_foe_ipv6 { ++ u32 src_ip[4]; ++ u32 dest_ip[4]; ++ ++ union { ++ struct { ++ u16 dest_port; ++ u16 src_port; ++ }; ++ struct { ++ u8 protocol; ++ u8 pad[3]; ++ }; ++ u32 ports; ++ }; ++ ++ u32 data; ++ ++ u32 ib2; ++ ++ struct airoha_foe_mac_info_common l2; ++}; ++ ++struct airoha_foe_entry { ++ union { ++ struct { ++ u32 ib1; ++ union { ++ struct airoha_foe_bridge bridge; ++ struct airoha_foe_ipv4 ipv4; ++ struct airoha_foe_ipv4_dslite dslite; ++ struct airoha_foe_ipv6 ipv6; ++ DECLARE_FLEX_ARRAY(u32, d); ++ }; ++ }; ++ u8 data[PPE_ENTRY_SIZE]; ++ }; ++}; ++ ++struct airoha_flow_data { ++ struct ethhdr eth; ++ ++ union { ++ struct { ++ __be32 src_addr; ++ __be32 dst_addr; ++ } v4; ++ ++ struct { ++ struct in6_addr src_addr; ++ struct in6_addr dst_addr; ++ } v6; ++ }; ++ ++ __be16 src_port; ++ __be16 dst_port; ++ ++ struct { ++ struct { ++ u16 id; ++ __be16 proto; ++ } hdr[2]; ++ u8 num; ++ } vlan; ++ struct { ++ u16 sid; ++ u8 num; ++ } pppoe; ++}; ++ ++struct airoha_flow_table_entry { ++ struct hlist_node list; ++ ++ struct airoha_foe_entry data; ++ u32 hash; ++ ++ struct rhash_head node; ++ unsigned long cookie; ++}; ++ + struct airoha_qdma { + struct airoha_eth *eth; + void __iomem *regs; +@@ -234,6 +462,19 @@ struct airoha_gdm_port { + struct metadata_dst *dsa_meta[AIROHA_MAX_DSA_PORTS]; + }; + ++#define AIROHA_RXD4_PPE_CPU_REASON GENMASK(20, 16) ++#define AIROHA_RXD4_FOE_ENTRY GENMASK(15, 0) ++ ++struct airoha_ppe { ++ struct airoha_eth *eth; ++ ++ void *foe; ++ dma_addr_t foe_dma; ++ ++ struct hlist_head *foe_flow; ++ u16 foe_check_time[PPE_NUM_ENTRIES]; ++}; ++ + struct airoha_eth { + struct device *dev; + +@@ -242,6 +483,9 @@ struct airoha_eth { + + struct airoha_npu __rcu *npu; + ++ struct airoha_ppe *ppe; ++ struct rhashtable flow_table; ++ + struct reset_control_bulk_data rsts[AIROHA_MAX_NUM_RSTS]; + struct reset_control_bulk_data xsi_rsts[AIROHA_MAX_NUM_XSI_RSTS]; + +@@ -277,4 +521,10 @@ u32 airoha_rmw(void __iomem *base, u32 o + #define airoha_qdma_clear(qdma, offset, val) \ + airoha_rmw((qdma)->regs, (offset), (val), 0) + ++void airoha_ppe_check_skb(struct airoha_ppe *ppe, u16 hash); ++int airoha_ppe_setup_tc_block_cb(enum tc_setup_type type, void *type_data, ++ void *cb_priv); ++int airoha_ppe_init(struct airoha_eth *eth); ++void airoha_ppe_deinit(struct airoha_eth *eth); ++ + #endif /* AIROHA_ETH_H */ +--- /dev/null ++++ b/drivers/net/ethernet/airoha/airoha_ppe.c +@@ -0,0 +1,901 @@ ++// SPDX-License-Identifier: GPL-2.0-only ++/* ++ * Copyright (c) 2025 AIROHA Inc ++ * Author: Lorenzo Bianconi ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++#include "airoha_npu.h" ++#include "airoha_regs.h" ++#include "airoha_eth.h" ++ ++static DEFINE_MUTEX(flow_offload_mutex); ++static DEFINE_SPINLOCK(ppe_lock); ++ ++static const struct rhashtable_params airoha_flow_table_params = { ++ .head_offset = offsetof(struct airoha_flow_table_entry, node), ++ .key_offset = offsetof(struct airoha_flow_table_entry, cookie), ++ .key_len = sizeof(unsigned long), ++ .automatic_shrinking = true, ++}; ++ ++static bool airoha_ppe2_is_enabled(struct airoha_eth *eth) ++{ ++ return airoha_fe_rr(eth, REG_PPE_GLO_CFG(1)) & PPE_GLO_CFG_EN_MASK; ++} ++ ++static u32 airoha_ppe_get_timestamp(struct airoha_ppe *ppe) ++{ ++ u16 timestamp = airoha_fe_rr(ppe->eth, REG_FE_FOE_TS); ++ ++ return FIELD_GET(AIROHA_FOE_IB1_BIND_TIMESTAMP, timestamp); ++} ++ ++static void airoha_ppe_hw_init(struct airoha_ppe *ppe) ++{ ++ u32 sram_tb_size, sram_num_entries, dram_num_entries; ++ struct airoha_eth *eth = ppe->eth; ++ int i; ++ ++ sram_tb_size = PPE_SRAM_NUM_ENTRIES * sizeof(struct airoha_foe_entry); ++ dram_num_entries = PPE_RAM_NUM_ENTRIES_SHIFT(PPE_DRAM_NUM_ENTRIES); ++ ++ for (i = 0; i < PPE_NUM; i++) { ++ int p; ++ ++ airoha_fe_wr(eth, REG_PPE_TB_BASE(i), ++ ppe->foe_dma + sram_tb_size); ++ ++ airoha_fe_rmw(eth, REG_PPE_BND_AGE0(i), ++ PPE_BIND_AGE0_DELTA_NON_L4 | ++ PPE_BIND_AGE0_DELTA_UDP, ++ FIELD_PREP(PPE_BIND_AGE0_DELTA_NON_L4, 1) | ++ FIELD_PREP(PPE_BIND_AGE0_DELTA_UDP, 12)); ++ airoha_fe_rmw(eth, REG_PPE_BND_AGE1(i), ++ PPE_BIND_AGE1_DELTA_TCP_FIN | ++ PPE_BIND_AGE1_DELTA_TCP, ++ FIELD_PREP(PPE_BIND_AGE1_DELTA_TCP_FIN, 1) | ++ FIELD_PREP(PPE_BIND_AGE1_DELTA_TCP, 7)); ++ ++ airoha_fe_rmw(eth, REG_PPE_TB_HASH_CFG(i), ++ PPE_SRAM_TABLE_EN_MASK | ++ PPE_SRAM_HASH1_EN_MASK | ++ PPE_DRAM_TABLE_EN_MASK | ++ PPE_SRAM_HASH0_MODE_MASK | ++ PPE_SRAM_HASH1_MODE_MASK | ++ PPE_DRAM_HASH0_MODE_MASK | ++ PPE_DRAM_HASH1_MODE_MASK, ++ FIELD_PREP(PPE_SRAM_TABLE_EN_MASK, 1) | ++ FIELD_PREP(PPE_SRAM_HASH1_EN_MASK, 1) | ++ FIELD_PREP(PPE_SRAM_HASH1_MODE_MASK, 1) | ++ FIELD_PREP(PPE_DRAM_HASH1_MODE_MASK, 3)); ++ ++ airoha_fe_rmw(eth, REG_PPE_TB_CFG(i), ++ PPE_TB_CFG_SEARCH_MISS_MASK | ++ PPE_TB_ENTRY_SIZE_MASK, ++ FIELD_PREP(PPE_TB_CFG_SEARCH_MISS_MASK, 3) | ++ FIELD_PREP(PPE_TB_ENTRY_SIZE_MASK, 0)); ++ ++ airoha_fe_wr(eth, REG_PPE_HASH_SEED(i), PPE_HASH_SEED); ++ ++ for (p = 0; p < ARRAY_SIZE(eth->ports); p++) ++ airoha_fe_rmw(eth, REG_PPE_MTU(i, p), ++ FP0_EGRESS_MTU_MASK | ++ FP1_EGRESS_MTU_MASK, ++ FIELD_PREP(FP0_EGRESS_MTU_MASK, ++ AIROHA_MAX_MTU) | ++ FIELD_PREP(FP1_EGRESS_MTU_MASK, ++ AIROHA_MAX_MTU)); ++ } ++ ++ if (airoha_ppe2_is_enabled(eth)) { ++ sram_num_entries = ++ PPE_RAM_NUM_ENTRIES_SHIFT(PPE1_SRAM_NUM_ENTRIES); ++ airoha_fe_rmw(eth, REG_PPE_TB_CFG(0), ++ PPE_SRAM_TB_NUM_ENTRY_MASK | ++ PPE_DRAM_TB_NUM_ENTRY_MASK, ++ FIELD_PREP(PPE_SRAM_TB_NUM_ENTRY_MASK, ++ sram_num_entries) | ++ FIELD_PREP(PPE_DRAM_TB_NUM_ENTRY_MASK, ++ dram_num_entries)); ++ airoha_fe_rmw(eth, REG_PPE_TB_CFG(1), ++ PPE_SRAM_TB_NUM_ENTRY_MASK | ++ PPE_DRAM_TB_NUM_ENTRY_MASK, ++ FIELD_PREP(PPE_SRAM_TB_NUM_ENTRY_MASK, ++ sram_num_entries) | ++ FIELD_PREP(PPE_DRAM_TB_NUM_ENTRY_MASK, ++ dram_num_entries)); ++ } else { ++ sram_num_entries = ++ PPE_RAM_NUM_ENTRIES_SHIFT(PPE_SRAM_NUM_ENTRIES); ++ airoha_fe_rmw(eth, REG_PPE_TB_CFG(0), ++ PPE_SRAM_TB_NUM_ENTRY_MASK | ++ PPE_DRAM_TB_NUM_ENTRY_MASK, ++ FIELD_PREP(PPE_SRAM_TB_NUM_ENTRY_MASK, ++ sram_num_entries) | ++ FIELD_PREP(PPE_DRAM_TB_NUM_ENTRY_MASK, ++ dram_num_entries)); ++ } ++} ++ ++static void airoha_ppe_flow_mangle_eth(const struct flow_action_entry *act, void *eth) ++{ ++ void *dest = eth + act->mangle.offset; ++ const void *src = &act->mangle.val; ++ ++ if (act->mangle.offset > 8) ++ return; ++ ++ if (act->mangle.mask == 0xffff) { ++ src += 2; ++ dest += 2; ++ } ++ ++ memcpy(dest, src, act->mangle.mask ? 2 : 4); ++} ++ ++static int airoha_ppe_flow_mangle_ports(const struct flow_action_entry *act, ++ struct airoha_flow_data *data) ++{ ++ u32 val = be32_to_cpu((__force __be32)act->mangle.val); ++ ++ switch (act->mangle.offset) { ++ case 0: ++ if ((__force __be32)act->mangle.mask == ~cpu_to_be32(0xffff)) ++ data->dst_port = cpu_to_be16(val); ++ else ++ data->src_port = cpu_to_be16(val >> 16); ++ break; ++ case 2: ++ data->dst_port = cpu_to_be16(val); ++ break; ++ default: ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ ++static int airoha_ppe_flow_mangle_ipv4(const struct flow_action_entry *act, ++ struct airoha_flow_data *data) ++{ ++ __be32 *dest; ++ ++ switch (act->mangle.offset) { ++ case offsetof(struct iphdr, saddr): ++ dest = &data->v4.src_addr; ++ break; ++ case offsetof(struct iphdr, daddr): ++ dest = &data->v4.dst_addr; ++ break; ++ default: ++ return -EINVAL; ++ } ++ ++ memcpy(dest, &act->mangle.val, sizeof(u32)); ++ ++ return 0; ++} ++ ++static int airoha_get_dsa_port(struct net_device **dev) ++{ ++#if IS_ENABLED(CONFIG_NET_DSA) ++ struct dsa_port *dp = dsa_port_from_netdev(*dev); ++ ++ if (IS_ERR(dp)) ++ return -ENODEV; ++ ++ *dev = dsa_port_to_master(dp); ++ return dp->index; ++#else ++ return -ENODEV; ++#endif ++} ++ ++static int airoha_ppe_foe_entry_prepare(struct airoha_foe_entry *hwe, ++ struct net_device *dev, int type, ++ struct airoha_flow_data *data, ++ int l4proto) ++{ ++ int dsa_port = airoha_get_dsa_port(&dev); ++ struct airoha_foe_mac_info_common *l2; ++ u32 qdata, ports_pad, val; ++ ++ memset(hwe, 0, sizeof(*hwe)); ++ ++ val = FIELD_PREP(AIROHA_FOE_IB1_BIND_STATE, AIROHA_FOE_STATE_BIND) | ++ FIELD_PREP(AIROHA_FOE_IB1_BIND_PACKET_TYPE, type) | ++ FIELD_PREP(AIROHA_FOE_IB1_BIND_UDP, l4proto == IPPROTO_UDP) | ++ FIELD_PREP(AIROHA_FOE_IB1_BIND_VLAN_LAYER, data->vlan.num) | ++ FIELD_PREP(AIROHA_FOE_IB1_BIND_VPM, data->vlan.num) | ++ AIROHA_FOE_IB1_BIND_TTL; ++ hwe->ib1 = val; ++ ++ val = FIELD_PREP(AIROHA_FOE_IB2_PORT_AG, 0x1f); ++ if (dsa_port >= 0) ++ val |= FIELD_PREP(AIROHA_FOE_IB2_NBQ, dsa_port); ++ ++ if (dev) { ++ struct airoha_gdm_port *port = netdev_priv(dev); ++ u8 pse_port; ++ ++ pse_port = port->id == 4 ? FE_PSE_PORT_GDM4 : port->id; ++ val |= FIELD_PREP(AIROHA_FOE_IB2_PSE_PORT, pse_port); ++ } ++ ++ /* FIXME: implement QoS support setting pse_port to 2 (loopback) ++ * for uplink and setting qos bit in ib2 ++ */ ++ ++ if (is_multicast_ether_addr(data->eth.h_dest)) ++ val |= AIROHA_FOE_IB2_MULTICAST; ++ ++ ports_pad = 0xa5a5a500 | (l4proto & 0xff); ++ if (type == PPE_PKT_TYPE_IPV4_ROUTE) ++ hwe->ipv4.orig_tuple.ports = ports_pad; ++ if (type == PPE_PKT_TYPE_IPV6_ROUTE_3T) ++ hwe->ipv6.ports = ports_pad; ++ ++ qdata = FIELD_PREP(AIROHA_FOE_SHAPER_ID, 0x7f); ++ if (type == PPE_PKT_TYPE_BRIDGE) { ++ hwe->bridge.dest_mac_hi = get_unaligned_be32(data->eth.h_dest); ++ hwe->bridge.dest_mac_lo = ++ get_unaligned_be16(data->eth.h_dest + 4); ++ hwe->bridge.src_mac_hi = ++ get_unaligned_be16(data->eth.h_source); ++ hwe->bridge.src_mac_lo = ++ get_unaligned_be32(data->eth.h_source + 2); ++ hwe->bridge.data = qdata; ++ hwe->bridge.ib2 = val; ++ l2 = &hwe->bridge.l2.common; ++ } else if (type >= PPE_PKT_TYPE_IPV6_ROUTE_3T) { ++ hwe->ipv6.data = qdata; ++ hwe->ipv6.ib2 = val; ++ l2 = &hwe->ipv6.l2; ++ } else { ++ hwe->ipv4.data = qdata; ++ hwe->ipv4.ib2 = val; ++ l2 = &hwe->ipv4.l2.common; ++ } ++ ++ l2->dest_mac_hi = get_unaligned_be32(data->eth.h_dest); ++ l2->dest_mac_lo = get_unaligned_be16(data->eth.h_dest + 4); ++ if (type <= PPE_PKT_TYPE_IPV4_DSLITE) { ++ l2->src_mac_hi = get_unaligned_be32(data->eth.h_source); ++ hwe->ipv4.l2.src_mac_lo = ++ get_unaligned_be16(data->eth.h_source + 4); ++ } else { ++ l2->src_mac_hi = FIELD_PREP(AIROHA_FOE_MAC_SMAC_ID, 0xf); ++ } ++ ++ if (data->vlan.num) { ++ l2->etype = dsa_port >= 0 ? BIT(dsa_port) : 0; ++ l2->vlan1 = data->vlan.hdr[0].id; ++ if (data->vlan.num == 2) ++ l2->vlan2 = data->vlan.hdr[1].id; ++ } else if (dsa_port >= 0) { ++ l2->etype = BIT(15) | BIT(dsa_port); ++ } else if (type >= PPE_PKT_TYPE_IPV6_ROUTE_3T) { ++ l2->etype = ETH_P_IPV6; ++ } else { ++ l2->etype = ETH_P_IP; ++ } ++ ++ return 0; ++} ++ ++static int airoha_ppe_foe_entry_set_ipv4_tuple(struct airoha_foe_entry *hwe, ++ struct airoha_flow_data *data, ++ bool egress) ++{ ++ int type = FIELD_GET(AIROHA_FOE_IB1_BIND_PACKET_TYPE, hwe->ib1); ++ struct airoha_foe_ipv4_tuple *t; ++ ++ switch (type) { ++ case PPE_PKT_TYPE_IPV4_HNAPT: ++ if (egress) { ++ t = &hwe->ipv4.new_tuple; ++ break; ++ } ++ fallthrough; ++ case PPE_PKT_TYPE_IPV4_DSLITE: ++ case PPE_PKT_TYPE_IPV4_ROUTE: ++ t = &hwe->ipv4.orig_tuple; ++ break; ++ default: ++ WARN_ON_ONCE(1); ++ return -EINVAL; ++ } ++ ++ t->src_ip = be32_to_cpu(data->v4.src_addr); ++ t->dest_ip = be32_to_cpu(data->v4.dst_addr); ++ ++ if (type != PPE_PKT_TYPE_IPV4_ROUTE) { ++ t->src_port = be16_to_cpu(data->src_port); ++ t->dest_port = be16_to_cpu(data->dst_port); ++ } ++ ++ return 0; ++} ++ ++static int airoha_ppe_foe_entry_set_ipv6_tuple(struct airoha_foe_entry *hwe, ++ struct airoha_flow_data *data) ++ ++{ ++ int type = FIELD_GET(AIROHA_FOE_IB1_BIND_PACKET_TYPE, hwe->ib1); ++ u32 *src, *dest; ++ ++ switch (type) { ++ case PPE_PKT_TYPE_IPV6_ROUTE_5T: ++ case PPE_PKT_TYPE_IPV6_6RD: ++ hwe->ipv6.src_port = be16_to_cpu(data->src_port); ++ hwe->ipv6.dest_port = be16_to_cpu(data->dst_port); ++ fallthrough; ++ case PPE_PKT_TYPE_IPV6_ROUTE_3T: ++ src = hwe->ipv6.src_ip; ++ dest = hwe->ipv6.dest_ip; ++ break; ++ default: ++ WARN_ON_ONCE(1); ++ return -EINVAL; ++ } ++ ++ ipv6_addr_be32_to_cpu(src, data->v6.src_addr.s6_addr32); ++ ipv6_addr_be32_to_cpu(dest, data->v6.dst_addr.s6_addr32); ++ ++ return 0; ++} ++ ++static u32 airoha_ppe_foe_get_entry_hash(struct airoha_foe_entry *hwe) ++{ ++ int type = FIELD_GET(AIROHA_FOE_IB1_BIND_PACKET_TYPE, hwe->ib1); ++ u32 hash, hv1, hv2, hv3; ++ ++ switch (type) { ++ case PPE_PKT_TYPE_IPV4_ROUTE: ++ case PPE_PKT_TYPE_IPV4_HNAPT: ++ hv1 = hwe->ipv4.orig_tuple.ports; ++ hv2 = hwe->ipv4.orig_tuple.dest_ip; ++ hv3 = hwe->ipv4.orig_tuple.src_ip; ++ break; ++ case PPE_PKT_TYPE_IPV6_ROUTE_3T: ++ case PPE_PKT_TYPE_IPV6_ROUTE_5T: ++ hv1 = hwe->ipv6.src_ip[3] ^ hwe->ipv6.dest_ip[3]; ++ hv1 ^= hwe->ipv6.ports; ++ ++ hv2 = hwe->ipv6.src_ip[2] ^ hwe->ipv6.dest_ip[2]; ++ hv2 ^= hwe->ipv6.dest_ip[0]; ++ ++ hv3 = hwe->ipv6.src_ip[1] ^ hwe->ipv6.dest_ip[1]; ++ hv3 ^= hwe->ipv6.src_ip[0]; ++ break; ++ case PPE_PKT_TYPE_IPV4_DSLITE: ++ case PPE_PKT_TYPE_IPV6_6RD: ++ default: ++ WARN_ON_ONCE(1); ++ return PPE_HASH_MASK; ++ } ++ ++ hash = (hv1 & hv2) | ((~hv1) & hv3); ++ hash = (hash >> 24) | ((hash & 0xffffff) << 8); ++ hash ^= hv1 ^ hv2 ^ hv3; ++ hash ^= hash >> 16; ++ hash &= PPE_NUM_ENTRIES - 1; ++ ++ return hash; ++} ++ ++static struct airoha_foe_entry * ++airoha_ppe_foe_get_entry(struct airoha_ppe *ppe, u32 hash) ++{ ++ if (hash < PPE_SRAM_NUM_ENTRIES) { ++ u32 *hwe = ppe->foe + hash * sizeof(struct airoha_foe_entry); ++ struct airoha_eth *eth = ppe->eth; ++ bool ppe2; ++ u32 val; ++ int i; ++ ++ ppe2 = airoha_ppe2_is_enabled(ppe->eth) && ++ hash >= PPE1_SRAM_NUM_ENTRIES; ++ airoha_fe_wr(ppe->eth, REG_PPE_RAM_CTRL(ppe2), ++ FIELD_PREP(PPE_SRAM_CTRL_ENTRY_MASK, hash) | ++ PPE_SRAM_CTRL_REQ_MASK); ++ if (read_poll_timeout_atomic(airoha_fe_rr, val, ++ val & PPE_SRAM_CTRL_ACK_MASK, ++ 10, 100, false, eth, ++ REG_PPE_RAM_CTRL(ppe2))) ++ return NULL; ++ ++ for (i = 0; i < sizeof(struct airoha_foe_entry) / 4; i++) ++ hwe[i] = airoha_fe_rr(eth, ++ REG_PPE_RAM_ENTRY(ppe2, i)); ++ } ++ ++ return ppe->foe + hash * sizeof(struct airoha_foe_entry); ++} ++ ++static bool airoha_ppe_foe_compare_entry(struct airoha_flow_table_entry *e, ++ struct airoha_foe_entry *hwe) ++{ ++ int type = FIELD_GET(AIROHA_FOE_IB1_BIND_PACKET_TYPE, e->data.ib1); ++ int len; ++ ++ if ((hwe->ib1 ^ e->data.ib1) & AIROHA_FOE_IB1_BIND_UDP) ++ return false; ++ ++ if (type > PPE_PKT_TYPE_IPV4_DSLITE) ++ len = offsetof(struct airoha_foe_entry, ipv6.data); ++ else ++ len = offsetof(struct airoha_foe_entry, ipv4.ib2); ++ ++ return !memcmp(&e->data.d, &hwe->d, len - sizeof(hwe->ib1)); ++} ++ ++static int airoha_ppe_foe_commit_entry(struct airoha_ppe *ppe, ++ struct airoha_foe_entry *e, ++ u32 hash) ++{ ++ struct airoha_foe_entry *hwe = ppe->foe + hash * sizeof(*hwe); ++ u32 ts = airoha_ppe_get_timestamp(ppe); ++ struct airoha_eth *eth = ppe->eth; ++ ++ memcpy(&hwe->d, &e->d, sizeof(*hwe) - sizeof(hwe->ib1)); ++ wmb(); ++ ++ e->ib1 &= ~AIROHA_FOE_IB1_BIND_TIMESTAMP; ++ e->ib1 |= FIELD_PREP(AIROHA_FOE_IB1_BIND_TIMESTAMP, ts); ++ hwe->ib1 = e->ib1; ++ ++ if (hash < PPE_SRAM_NUM_ENTRIES) { ++ dma_addr_t addr = ppe->foe_dma + hash * sizeof(*hwe); ++ bool ppe2 = airoha_ppe2_is_enabled(eth) && ++ hash >= PPE1_SRAM_NUM_ENTRIES; ++ struct airoha_npu *npu; ++ int err = -ENODEV; ++ ++ rcu_read_lock(); ++ npu = rcu_dereference(eth->npu); ++ if (npu) ++ err = npu->ops.ppe_foe_commit_entry(npu, addr, ++ sizeof(*hwe), hash, ++ ppe2); ++ rcu_read_unlock(); ++ ++ return err; ++ } ++ ++ return 0; ++} ++ ++static void airoha_ppe_foe_insert_entry(struct airoha_ppe *ppe, u32 hash) ++{ ++ struct airoha_flow_table_entry *e; ++ struct airoha_foe_entry *hwe; ++ struct hlist_node *n; ++ u32 index, state; ++ ++ spin_lock_bh(&ppe_lock); ++ ++ hwe = airoha_ppe_foe_get_entry(ppe, hash); ++ if (!hwe) ++ goto unlock; ++ ++ state = FIELD_GET(AIROHA_FOE_IB1_BIND_STATE, hwe->ib1); ++ if (state == AIROHA_FOE_STATE_BIND) ++ goto unlock; ++ ++ index = airoha_ppe_foe_get_entry_hash(hwe); ++ hlist_for_each_entry_safe(e, n, &ppe->foe_flow[index], list) { ++ if (airoha_ppe_foe_compare_entry(e, hwe)) { ++ airoha_ppe_foe_commit_entry(ppe, &e->data, hash); ++ e->hash = hash; ++ break; ++ } ++ } ++unlock: ++ spin_unlock_bh(&ppe_lock); ++} ++ ++static int airoha_ppe_foe_flow_commit_entry(struct airoha_ppe *ppe, ++ struct airoha_flow_table_entry *e) ++{ ++ u32 hash = airoha_ppe_foe_get_entry_hash(&e->data); ++ ++ e->hash = 0xffff; ++ ++ spin_lock_bh(&ppe_lock); ++ hlist_add_head(&e->list, &ppe->foe_flow[hash]); ++ spin_unlock_bh(&ppe_lock); ++ ++ return 0; ++} ++ ++static void airoha_ppe_foe_flow_remove_entry(struct airoha_ppe *ppe, ++ struct airoha_flow_table_entry *e) ++{ ++ spin_lock_bh(&ppe_lock); ++ ++ hlist_del_init(&e->list); ++ if (e->hash != 0xffff) { ++ e->data.ib1 &= ~AIROHA_FOE_IB1_BIND_STATE; ++ e->data.ib1 |= FIELD_PREP(AIROHA_FOE_IB1_BIND_STATE, ++ AIROHA_FOE_STATE_INVALID); ++ airoha_ppe_foe_commit_entry(ppe, &e->data, e->hash); ++ e->hash = 0xffff; ++ } ++ ++ spin_unlock_bh(&ppe_lock); ++} ++ ++static int airoha_ppe_flow_offload_replace(struct airoha_gdm_port *port, ++ struct flow_cls_offload *f) ++{ ++ struct flow_rule *rule = flow_cls_offload_flow_rule(f); ++ struct airoha_eth *eth = port->qdma->eth; ++ struct airoha_flow_table_entry *e; ++ struct airoha_flow_data data = {}; ++ struct net_device *odev = NULL; ++ struct flow_action_entry *act; ++ struct airoha_foe_entry hwe; ++ int err, i, offload_type; ++ u16 addr_type = 0; ++ u8 l4proto = 0; ++ ++ if (rhashtable_lookup(ð->flow_table, &f->cookie, ++ airoha_flow_table_params)) ++ return -EEXIST; ++ ++ if (!flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_META)) ++ return -EOPNOTSUPP; ++ ++ if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_CONTROL)) { ++ struct flow_match_control match; ++ ++ flow_rule_match_control(rule, &match); ++ addr_type = match.key->addr_type; ++ if (flow_rule_has_control_flags(match.mask->flags, ++ f->common.extack)) ++ return -EOPNOTSUPP; ++ } else { ++ return -EOPNOTSUPP; ++ } ++ ++ if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_BASIC)) { ++ struct flow_match_basic match; ++ ++ flow_rule_match_basic(rule, &match); ++ l4proto = match.key->ip_proto; ++ } else { ++ return -EOPNOTSUPP; ++ } ++ ++ switch (addr_type) { ++ case 0: ++ offload_type = PPE_PKT_TYPE_BRIDGE; ++ if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_ETH_ADDRS)) { ++ struct flow_match_eth_addrs match; ++ ++ flow_rule_match_eth_addrs(rule, &match); ++ memcpy(data.eth.h_dest, match.key->dst, ETH_ALEN); ++ memcpy(data.eth.h_source, match.key->src, ETH_ALEN); ++ } else { ++ return -EOPNOTSUPP; ++ } ++ break; ++ case FLOW_DISSECTOR_KEY_IPV4_ADDRS: ++ offload_type = PPE_PKT_TYPE_IPV4_HNAPT; ++ break; ++ case FLOW_DISSECTOR_KEY_IPV6_ADDRS: ++ offload_type = PPE_PKT_TYPE_IPV6_ROUTE_5T; ++ break; ++ default: ++ return -EOPNOTSUPP; ++ } ++ ++ flow_action_for_each(i, act, &rule->action) { ++ switch (act->id) { ++ case FLOW_ACTION_MANGLE: ++ if (offload_type == PPE_PKT_TYPE_BRIDGE) ++ return -EOPNOTSUPP; ++ ++ if (act->mangle.htype == FLOW_ACT_MANGLE_HDR_TYPE_ETH) ++ airoha_ppe_flow_mangle_eth(act, &data.eth); ++ break; ++ case FLOW_ACTION_REDIRECT: ++ odev = act->dev; ++ break; ++ case FLOW_ACTION_CSUM: ++ break; ++ case FLOW_ACTION_VLAN_PUSH: ++ if (data.vlan.num == 2 || ++ act->vlan.proto != htons(ETH_P_8021Q)) ++ return -EOPNOTSUPP; ++ ++ data.vlan.hdr[data.vlan.num].id = act->vlan.vid; ++ data.vlan.hdr[data.vlan.num].proto = act->vlan.proto; ++ data.vlan.num++; ++ break; ++ case FLOW_ACTION_VLAN_POP: ++ break; ++ case FLOW_ACTION_PPPOE_PUSH: ++ break; ++ default: ++ return -EOPNOTSUPP; ++ } ++ } ++ ++ if (!is_valid_ether_addr(data.eth.h_source) || ++ !is_valid_ether_addr(data.eth.h_dest)) ++ return -EINVAL; ++ ++ err = airoha_ppe_foe_entry_prepare(&hwe, odev, offload_type, ++ &data, l4proto); ++ if (err) ++ return err; ++ ++ if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_PORTS)) { ++ struct flow_match_ports ports; ++ ++ if (offload_type == PPE_PKT_TYPE_BRIDGE) ++ return -EOPNOTSUPP; ++ ++ flow_rule_match_ports(rule, &ports); ++ data.src_port = ports.key->src; ++ data.dst_port = ports.key->dst; ++ } else if (offload_type != PPE_PKT_TYPE_BRIDGE) { ++ return -EOPNOTSUPP; ++ } ++ ++ if (addr_type == FLOW_DISSECTOR_KEY_IPV4_ADDRS) { ++ struct flow_match_ipv4_addrs addrs; ++ ++ flow_rule_match_ipv4_addrs(rule, &addrs); ++ data.v4.src_addr = addrs.key->src; ++ data.v4.dst_addr = addrs.key->dst; ++ airoha_ppe_foe_entry_set_ipv4_tuple(&hwe, &data, false); ++ } ++ ++ if (addr_type == FLOW_DISSECTOR_KEY_IPV6_ADDRS) { ++ struct flow_match_ipv6_addrs addrs; ++ ++ flow_rule_match_ipv6_addrs(rule, &addrs); ++ ++ data.v6.src_addr = addrs.key->src; ++ data.v6.dst_addr = addrs.key->dst; ++ airoha_ppe_foe_entry_set_ipv6_tuple(&hwe, &data); ++ } ++ ++ flow_action_for_each(i, act, &rule->action) { ++ if (act->id != FLOW_ACTION_MANGLE) ++ continue; ++ ++ if (offload_type == PPE_PKT_TYPE_BRIDGE) ++ return -EOPNOTSUPP; ++ ++ switch (act->mangle.htype) { ++ case FLOW_ACT_MANGLE_HDR_TYPE_TCP: ++ case FLOW_ACT_MANGLE_HDR_TYPE_UDP: ++ err = airoha_ppe_flow_mangle_ports(act, &data); ++ break; ++ case FLOW_ACT_MANGLE_HDR_TYPE_IP4: ++ err = airoha_ppe_flow_mangle_ipv4(act, &data); ++ break; ++ case FLOW_ACT_MANGLE_HDR_TYPE_ETH: ++ /* handled earlier */ ++ break; ++ default: ++ return -EOPNOTSUPP; ++ } ++ ++ if (err) ++ return err; ++ } ++ ++ if (addr_type == FLOW_DISSECTOR_KEY_IPV4_ADDRS) { ++ err = airoha_ppe_foe_entry_set_ipv4_tuple(&hwe, &data, true); ++ if (err) ++ return err; ++ } ++ ++ e = kzalloc(sizeof(*e), GFP_KERNEL); ++ if (!e) ++ return -ENOMEM; ++ ++ e->cookie = f->cookie; ++ memcpy(&e->data, &hwe, sizeof(e->data)); ++ ++ err = airoha_ppe_foe_flow_commit_entry(eth->ppe, e); ++ if (err) ++ goto free_entry; ++ ++ err = rhashtable_insert_fast(ð->flow_table, &e->node, ++ airoha_flow_table_params); ++ if (err < 0) ++ goto remove_foe_entry; ++ ++ return 0; ++ ++remove_foe_entry: ++ airoha_ppe_foe_flow_remove_entry(eth->ppe, e); ++free_entry: ++ kfree(e); ++ ++ return err; ++} ++ ++static int airoha_ppe_flow_offload_destroy(struct airoha_gdm_port *port, ++ struct flow_cls_offload *f) ++{ ++ struct airoha_eth *eth = port->qdma->eth; ++ struct airoha_flow_table_entry *e; ++ ++ e = rhashtable_lookup(ð->flow_table, &f->cookie, ++ airoha_flow_table_params); ++ if (!e) ++ return -ENOENT; ++ ++ airoha_ppe_foe_flow_remove_entry(eth->ppe, e); ++ rhashtable_remove_fast(ð->flow_table, &e->node, ++ airoha_flow_table_params); ++ kfree(e); ++ ++ return 0; ++} ++ ++static int airoha_ppe_flow_offload_cmd(struct airoha_gdm_port *port, ++ struct flow_cls_offload *f) ++{ ++ switch (f->command) { ++ case FLOW_CLS_REPLACE: ++ return airoha_ppe_flow_offload_replace(port, f); ++ case FLOW_CLS_DESTROY: ++ return airoha_ppe_flow_offload_destroy(port, f); ++ default: ++ break; ++ } ++ ++ return -EOPNOTSUPP; ++} ++ ++static int airoha_ppe_flush_sram_entries(struct airoha_ppe *ppe, ++ struct airoha_npu *npu) ++{ ++ int i, sram_num_entries = PPE_SRAM_NUM_ENTRIES; ++ struct airoha_foe_entry *hwe = ppe->foe; ++ ++ if (airoha_ppe2_is_enabled(ppe->eth)) ++ sram_num_entries = sram_num_entries / 2; ++ ++ for (i = 0; i < sram_num_entries; i++) ++ memset(&hwe[i], 0, sizeof(*hwe)); ++ ++ return npu->ops.ppe_flush_sram_entries(npu, ppe->foe_dma, ++ PPE_SRAM_NUM_ENTRIES); ++} ++ ++static struct airoha_npu *airoha_ppe_npu_get(struct airoha_eth *eth) ++{ ++ struct airoha_npu *npu = airoha_npu_get(eth->dev); ++ ++ if (IS_ERR(npu)) { ++ request_module("airoha-npu"); ++ npu = airoha_npu_get(eth->dev); ++ } ++ ++ return npu; ++} ++ ++static int airoha_ppe_offload_setup(struct airoha_eth *eth) ++{ ++ struct airoha_npu *npu = airoha_ppe_npu_get(eth); ++ int err; ++ ++ if (IS_ERR(npu)) ++ return PTR_ERR(npu); ++ ++ err = npu->ops.ppe_init(npu); ++ if (err) ++ goto error_npu_put; ++ ++ airoha_ppe_hw_init(eth->ppe); ++ err = airoha_ppe_flush_sram_entries(eth->ppe, npu); ++ if (err) ++ goto error_npu_put; ++ ++ rcu_assign_pointer(eth->npu, npu); ++ synchronize_rcu(); ++ ++ return 0; ++ ++error_npu_put: ++ airoha_npu_put(npu); ++ ++ return err; ++} ++ ++int airoha_ppe_setup_tc_block_cb(enum tc_setup_type type, void *type_data, ++ void *cb_priv) ++{ ++ struct flow_cls_offload *cls = type_data; ++ struct net_device *dev = cb_priv; ++ struct airoha_gdm_port *port = netdev_priv(dev); ++ struct airoha_eth *eth = port->qdma->eth; ++ int err = 0; ++ ++ if (!tc_can_offload(dev) || type != TC_SETUP_CLSFLOWER) ++ return -EOPNOTSUPP; ++ ++ mutex_lock(&flow_offload_mutex); ++ ++ if (!eth->npu) ++ err = airoha_ppe_offload_setup(eth); ++ if (!err) ++ err = airoha_ppe_flow_offload_cmd(port, cls); ++ ++ mutex_unlock(&flow_offload_mutex); ++ ++ return err; ++} ++ ++void airoha_ppe_check_skb(struct airoha_ppe *ppe, u16 hash) ++{ ++ u16 now, diff; ++ ++ if (hash > PPE_HASH_MASK) ++ return; ++ ++ now = (u16)jiffies; ++ diff = now - ppe->foe_check_time[hash]; ++ if (diff < HZ / 10) ++ return; ++ ++ ppe->foe_check_time[hash] = now; ++ airoha_ppe_foe_insert_entry(ppe, hash); ++} ++ ++int airoha_ppe_init(struct airoha_eth *eth) ++{ ++ struct airoha_ppe *ppe; ++ int foe_size; ++ ++ ppe = devm_kzalloc(eth->dev, sizeof(*ppe), GFP_KERNEL); ++ if (!ppe) ++ return -ENOMEM; ++ ++ foe_size = PPE_NUM_ENTRIES * sizeof(struct airoha_foe_entry); ++ ppe->foe = dmam_alloc_coherent(eth->dev, foe_size, &ppe->foe_dma, ++ GFP_KERNEL); ++ if (!ppe->foe) ++ return -ENOMEM; ++ ++ ppe->eth = eth; ++ eth->ppe = ppe; ++ ++ ppe->foe_flow = devm_kzalloc(eth->dev, ++ PPE_NUM_ENTRIES * sizeof(*ppe->foe_flow), ++ GFP_KERNEL); ++ if (!ppe->foe_flow) ++ return -ENOMEM; ++ ++ return rhashtable_init(ð->flow_table, &airoha_flow_table_params); ++} ++ ++void airoha_ppe_deinit(struct airoha_eth *eth) ++{ ++ struct airoha_npu *npu; ++ ++ rcu_read_lock(); ++ npu = rcu_dereference(eth->npu); ++ if (npu) { ++ npu->ops.ppe_deinit(npu); ++ airoha_npu_put(npu); ++ } ++ rcu_read_unlock(); ++ ++ rhashtable_destroy(ð->flow_table); ++} +--- a/drivers/net/ethernet/airoha/airoha_regs.h ++++ b/drivers/net/ethernet/airoha/airoha_regs.h +@@ -15,6 +15,7 @@ + #define CDM1_BASE 0x0400 + #define GDM1_BASE 0x0500 + #define PPE1_BASE 0x0c00 ++#define PPE2_BASE 0x1c00 + + #define CDM2_BASE 0x1400 + #define GDM2_BASE 0x1500 +@@ -36,6 +37,7 @@ + #define FE_RST_GDM3_MBI_ARB_MASK BIT(2) + #define FE_RST_CORE_MASK BIT(0) + ++#define REG_FE_FOE_TS 0x0010 + #define REG_FE_WAN_MAC_H 0x0030 + #define REG_FE_LAN_MAC_H 0x0040 + +@@ -192,11 +194,106 @@ + #define REG_FE_GDM_RX_ETH_L511_CNT_L(_n) (GDM_BASE(_n) + 0x198) + #define REG_FE_GDM_RX_ETH_L1023_CNT_L(_n) (GDM_BASE(_n) + 0x19c) + +-#define REG_PPE1_TB_HASH_CFG (PPE1_BASE + 0x250) +-#define PPE1_SRAM_TABLE_EN_MASK BIT(0) +-#define PPE1_SRAM_HASH1_EN_MASK BIT(8) +-#define PPE1_DRAM_TABLE_EN_MASK BIT(16) +-#define PPE1_DRAM_HASH1_EN_MASK BIT(24) ++#define REG_PPE_GLO_CFG(_n) (((_n) ? PPE2_BASE : PPE1_BASE) + 0x200) ++#define PPE_GLO_CFG_BUSY_MASK BIT(31) ++#define PPE_GLO_CFG_FLOW_DROP_UPDATE_MASK BIT(9) ++#define PPE_GLO_CFG_PSE_HASH_OFS_MASK BIT(6) ++#define PPE_GLO_CFG_PPE_BSWAP_MASK BIT(5) ++#define PPE_GLO_CFG_TTL_DROP_MASK BIT(4) ++#define PPE_GLO_CFG_IP4_CS_DROP_MASK BIT(3) ++#define PPE_GLO_CFG_IP4_L4_CS_DROP_MASK BIT(2) ++#define PPE_GLO_CFG_EN_MASK BIT(0) ++ ++#define REG_PPE_PPE_FLOW_CFG(_n) (((_n) ? PPE2_BASE : PPE1_BASE) + 0x204) ++#define PPE_FLOW_CFG_IP6_HASH_GRE_KEY_MASK BIT(20) ++#define PPE_FLOW_CFG_IP4_HASH_GRE_KEY_MASK BIT(19) ++#define PPE_FLOW_CFG_IP4_HASH_FLOW_LABEL_MASK BIT(18) ++#define PPE_FLOW_CFG_IP4_NAT_FRAG_MASK BIT(17) ++#define PPE_FLOW_CFG_IP_PROTO_BLACKLIST_MASK BIT(16) ++#define PPE_FLOW_CFG_IP4_DSLITE_MASK BIT(14) ++#define PPE_FLOW_CFG_IP4_NAPT_MASK BIT(13) ++#define PPE_FLOW_CFG_IP4_NAT_MASK BIT(12) ++#define PPE_FLOW_CFG_IP6_6RD_MASK BIT(10) ++#define PPE_FLOW_CFG_IP6_5T_ROUTE_MASK BIT(9) ++#define PPE_FLOW_CFG_IP6_3T_ROUTE_MASK BIT(8) ++#define PPE_FLOW_CFG_IP4_UDP_FRAG_MASK BIT(7) ++#define PPE_FLOW_CFG_IP4_TCP_FRAG_MASK BIT(6) ++ ++#define REG_PPE_IP_PROTO_CHK(_n) (((_n) ? PPE2_BASE : PPE1_BASE) + 0x208) ++#define PPE_IP_PROTO_CHK_IPV4_MASK GENMASK(15, 0) ++#define PPE_IP_PROTO_CHK_IPV6_MASK GENMASK(31, 16) ++ ++#define REG_PPE_TB_CFG(_n) (((_n) ? PPE2_BASE : PPE1_BASE) + 0x21c) ++#define PPE_SRAM_TB_NUM_ENTRY_MASK GENMASK(26, 24) ++#define PPE_TB_CFG_KEEPALIVE_MASK GENMASK(13, 12) ++#define PPE_TB_CFG_AGE_TCP_FIN_MASK BIT(11) ++#define PPE_TB_CFG_AGE_UDP_MASK BIT(10) ++#define PPE_TB_CFG_AGE_TCP_MASK BIT(9) ++#define PPE_TB_CFG_AGE_UNBIND_MASK BIT(8) ++#define PPE_TB_CFG_AGE_NON_L4_MASK BIT(7) ++#define PPE_TB_CFG_AGE_PREBIND_MASK BIT(6) ++#define PPE_TB_CFG_SEARCH_MISS_MASK GENMASK(5, 4) ++#define PPE_TB_ENTRY_SIZE_MASK BIT(3) ++#define PPE_DRAM_TB_NUM_ENTRY_MASK GENMASK(2, 0) ++ ++#define REG_PPE_TB_BASE(_n) (((_n) ? PPE2_BASE : PPE1_BASE) + 0x220) ++ ++#define REG_PPE_BIND_RATE(_n) (((_n) ? PPE2_BASE : PPE1_BASE) + 0x228) ++#define PPE_BIND_RATE_L2B_BIND_MASK GENMASK(31, 16) ++#define PPE_BIND_RATE_BIND_MASK GENMASK(15, 0) ++ ++#define REG_PPE_BIND_LIMIT0(_n) (((_n) ? PPE2_BASE : PPE1_BASE) + 0x22c) ++#define PPE_BIND_LIMIT0_HALF_MASK GENMASK(29, 16) ++#define PPE_BIND_LIMIT0_QUARTER_MASK GENMASK(13, 0) ++ ++#define REG_PPE_BIND_LIMIT1(_n) (((_n) ? PPE2_BASE : PPE1_BASE) + 0x230) ++#define PPE_BIND_LIMIT1_NON_L4_MASK GENMASK(23, 16) ++#define PPE_BIND_LIMIT1_FULL_MASK GENMASK(13, 0) ++ ++#define REG_PPE_BND_AGE0(_n) (((_n) ? PPE2_BASE : PPE1_BASE) + 0x23c) ++#define PPE_BIND_AGE0_DELTA_NON_L4 GENMASK(30, 16) ++#define PPE_BIND_AGE0_DELTA_UDP GENMASK(14, 0) ++ ++#define REG_PPE_UNBIND_AGE(_n) (((_n) ? PPE2_BASE : PPE1_BASE) + 0x238) ++#define PPE_UNBIND_AGE_MIN_PACKETS_MASK GENMASK(31, 16) ++#define PPE_UNBIND_AGE_DELTA_MASK GENMASK(7, 0) ++ ++#define REG_PPE_BND_AGE1(_n) (((_n) ? PPE2_BASE : PPE1_BASE) + 0x240) ++#define PPE_BIND_AGE1_DELTA_TCP_FIN GENMASK(30, 16) ++#define PPE_BIND_AGE1_DELTA_TCP GENMASK(14, 0) ++ ++#define REG_PPE_HASH_SEED(_n) (((_n) ? PPE2_BASE : PPE1_BASE) + 0x244) ++#define PPE_HASH_SEED 0x12345678 ++ ++#define REG_PPE_DFT_CPORT0(_n) (((_n) ? PPE2_BASE : PPE1_BASE) + 0x248) ++ ++#define REG_PPE_DFT_CPORT1(_n) (((_n) ? PPE2_BASE : PPE1_BASE) + 0x24c) ++ ++#define REG_PPE_TB_HASH_CFG(_n) (((_n) ? PPE2_BASE : PPE1_BASE) + 0x250) ++#define PPE_DRAM_HASH1_MODE_MASK GENMASK(31, 28) ++#define PPE_DRAM_HASH1_EN_MASK BIT(24) ++#define PPE_DRAM_HASH0_MODE_MASK GENMASK(23, 20) ++#define PPE_DRAM_TABLE_EN_MASK BIT(16) ++#define PPE_SRAM_HASH1_MODE_MASK GENMASK(15, 12) ++#define PPE_SRAM_HASH1_EN_MASK BIT(8) ++#define PPE_SRAM_HASH0_MODE_MASK GENMASK(7, 4) ++#define PPE_SRAM_TABLE_EN_MASK BIT(0) ++ ++#define REG_PPE_MTU_BASE(_n) (((_n) ? PPE2_BASE : PPE1_BASE) + 0x304) ++#define REG_PPE_MTU(_m, _n) (REG_PPE_MTU_BASE(_m) + ((_n) << 2)) ++#define FP1_EGRESS_MTU_MASK GENMASK(29, 16) ++#define FP0_EGRESS_MTU_MASK GENMASK(13, 0) ++ ++#define REG_PPE_RAM_CTRL(_n) (((_n) ? PPE2_BASE : PPE1_BASE) + 0x31c) ++#define PPE_SRAM_CTRL_ACK_MASK BIT(31) ++#define PPE_SRAM_CTRL_DUAL_SUCESS_MASK BIT(30) ++#define PPE_SRAM_CTRL_ENTRY_MASK GENMASK(23, 8) ++#define PPE_SRAM_WR_DUAL_DIRECTION_MASK BIT(2) ++#define PPE_SRAM_CTRL_WR_MASK BIT(1) ++#define PPE_SRAM_CTRL_REQ_MASK BIT(0) ++ ++#define REG_PPE_RAM_BASE(_n) (((_n) ? PPE2_BASE : PPE1_BASE) + 0x320) ++#define REG_PPE_RAM_ENTRY(_m, _n) (REG_PPE_RAM_BASE(_m) + ((_n) << 2)) + + #define REG_FE_GDM_TX_OK_PKT_CNT_H(_n) (GDM_BASE(_n) + 0x280) + #define REG_FE_GDM_TX_OK_BYTE_CNT_H(_n) (GDM_BASE(_n) + 0x284) diff --git a/target/linux/airoha/patches-6.6/048-14-v6.15-net-airoha-Add-loopback-support-for-GDM2.patch b/target/linux/airoha/patches-6.6/048-14-v6.15-net-airoha-Add-loopback-support-for-GDM2.patch new file mode 100644 index 00000000000000..224fe04f4472b2 --- /dev/null +++ b/target/linux/airoha/patches-6.6/048-14-v6.15-net-airoha-Add-loopback-support-for-GDM2.patch @@ -0,0 +1,210 @@ +From 9cd451d414f6e29f507a216fb3b19fa68c011f8c Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Fri, 28 Feb 2025 11:54:22 +0100 +Subject: [PATCH 14/15] net: airoha: Add loopback support for GDM2 + +Enable hw redirection for traffic received on GDM2 port to GDM{3,4}. +This is required to apply Qdisc offloading (HTB or ETS) for traffic to +and from GDM{3,4} port. + +Signed-off-by: Lorenzo Bianconi +Signed-off-by: Paolo Abeni +--- + drivers/net/ethernet/airoha/airoha_eth.c | 71 ++++++++++++++++++++++- + drivers/net/ethernet/airoha/airoha_eth.h | 7 +++ + drivers/net/ethernet/airoha/airoha_ppe.c | 12 ++-- + drivers/net/ethernet/airoha/airoha_regs.h | 29 +++++++++ + 4 files changed, 111 insertions(+), 8 deletions(-) + +--- a/drivers/net/ethernet/airoha/airoha_eth.c ++++ b/drivers/net/ethernet/airoha/airoha_eth.c +@@ -1589,14 +1589,81 @@ static int airoha_dev_set_macaddr(struct + return 0; + } + ++static void airhoha_set_gdm2_loopback(struct airoha_gdm_port *port) ++{ ++ u32 pse_port = port->id == 3 ? FE_PSE_PORT_GDM3 : FE_PSE_PORT_GDM4; ++ struct airoha_eth *eth = port->qdma->eth; ++ u32 chan = port->id == 3 ? 4 : 0; ++ ++ /* Forward the traffic to the proper GDM port */ ++ airoha_set_gdm_port_fwd_cfg(eth, REG_GDM_FWD_CFG(2), pse_port); ++ airoha_fe_clear(eth, REG_GDM_FWD_CFG(2), GDM_STRIP_CRC); ++ ++ /* Enable GDM2 loopback */ ++ airoha_fe_wr(eth, REG_GDM_TXCHN_EN(2), 0xffffffff); ++ airoha_fe_wr(eth, REG_GDM_RXCHN_EN(2), 0xffff); ++ airoha_fe_rmw(eth, REG_GDM_LPBK_CFG(2), ++ LPBK_CHAN_MASK | LPBK_MODE_MASK | LPBK_EN_MASK, ++ FIELD_PREP(LPBK_CHAN_MASK, chan) | LPBK_EN_MASK); ++ airoha_fe_rmw(eth, REG_GDM_LEN_CFG(2), ++ GDM_SHORT_LEN_MASK | GDM_LONG_LEN_MASK, ++ FIELD_PREP(GDM_SHORT_LEN_MASK, 60) | ++ FIELD_PREP(GDM_LONG_LEN_MASK, AIROHA_MAX_MTU)); ++ ++ /* Disable VIP and IFC for GDM2 */ ++ airoha_fe_clear(eth, REG_FE_VIP_PORT_EN, BIT(2)); ++ airoha_fe_clear(eth, REG_FE_IFC_PORT_EN, BIT(2)); ++ ++ if (port->id == 3) { ++ /* FIXME: handle XSI_PCE1_PORT */ ++ airoha_fe_wr(eth, REG_PPE_DFT_CPORT0(0), 0x5500); ++ airoha_fe_rmw(eth, REG_FE_WAN_PORT, ++ WAN1_EN_MASK | WAN1_MASK | WAN0_MASK, ++ FIELD_PREP(WAN0_MASK, HSGMII_LAN_PCIE0_SRCPORT)); ++ airoha_fe_rmw(eth, ++ REG_SP_DFT_CPORT(HSGMII_LAN_PCIE0_SRCPORT >> 3), ++ SP_CPORT_PCIE0_MASK, ++ FIELD_PREP(SP_CPORT_PCIE0_MASK, ++ FE_PSE_PORT_CDM2)); ++ } else { ++ /* FIXME: handle XSI_USB_PORT */ ++ airoha_fe_rmw(eth, REG_SRC_PORT_FC_MAP6, ++ FC_ID_OF_SRC_PORT24_MASK, ++ FIELD_PREP(FC_ID_OF_SRC_PORT24_MASK, 2)); ++ airoha_fe_rmw(eth, REG_FE_WAN_PORT, ++ WAN1_EN_MASK | WAN1_MASK | WAN0_MASK, ++ FIELD_PREP(WAN0_MASK, HSGMII_LAN_ETH_SRCPORT)); ++ airoha_fe_rmw(eth, ++ REG_SP_DFT_CPORT(HSGMII_LAN_ETH_SRCPORT >> 3), ++ SP_CPORT_ETH_MASK, ++ FIELD_PREP(SP_CPORT_ETH_MASK, FE_PSE_PORT_CDM2)); ++ } ++} ++ + static int airoha_dev_init(struct net_device *dev) + { + struct airoha_gdm_port *port = netdev_priv(dev); + struct airoha_eth *eth = port->qdma->eth; ++ u32 pse_port; + + airoha_set_macaddr(port, dev->dev_addr); +- airoha_set_gdm_port_fwd_cfg(eth, REG_GDM_FWD_CFG(port->id), +- FE_PSE_PORT_PPE1); ++ ++ switch (port->id) { ++ case 3: ++ case 4: ++ /* If GDM2 is active we can't enable loopback */ ++ if (!eth->ports[1]) ++ airhoha_set_gdm2_loopback(port); ++ fallthrough; ++ case 2: ++ pse_port = FE_PSE_PORT_PPE2; ++ break; ++ default: ++ pse_port = FE_PSE_PORT_PPE1; ++ break; ++ } ++ ++ airoha_set_gdm_port_fwd_cfg(eth, REG_GDM_FWD_CFG(port->id), pse_port); + + return 0; + } +--- a/drivers/net/ethernet/airoha/airoha_eth.h ++++ b/drivers/net/ethernet/airoha/airoha_eth.h +@@ -68,6 +68,13 @@ enum { + }; + + enum { ++ HSGMII_LAN_PCIE0_SRCPORT = 0x16, ++ HSGMII_LAN_PCIE1_SRCPORT, ++ HSGMII_LAN_ETH_SRCPORT, ++ HSGMII_LAN_USB_SRCPORT, ++}; ++ ++enum { + XSI_PCIE0_VIP_PORT_MASK = BIT(22), + XSI_PCIE1_VIP_PORT_MASK = BIT(23), + XSI_USB_VIP_PORT_MASK = BIT(25), +--- a/drivers/net/ethernet/airoha/airoha_ppe.c ++++ b/drivers/net/ethernet/airoha/airoha_ppe.c +@@ -216,7 +216,8 @@ static int airoha_ppe_foe_entry_prepare( + AIROHA_FOE_IB1_BIND_TTL; + hwe->ib1 = val; + +- val = FIELD_PREP(AIROHA_FOE_IB2_PORT_AG, 0x1f); ++ val = FIELD_PREP(AIROHA_FOE_IB2_PORT_AG, 0x1f) | ++ AIROHA_FOE_IB2_PSE_QOS; + if (dsa_port >= 0) + val |= FIELD_PREP(AIROHA_FOE_IB2_NBQ, dsa_port); + +@@ -224,14 +225,13 @@ static int airoha_ppe_foe_entry_prepare( + struct airoha_gdm_port *port = netdev_priv(dev); + u8 pse_port; + +- pse_port = port->id == 4 ? FE_PSE_PORT_GDM4 : port->id; ++ if (dsa_port >= 0) ++ pse_port = port->id == 4 ? FE_PSE_PORT_GDM4 : port->id; ++ else ++ pse_port = 2; /* uplink relies on GDM2 loopback */ + val |= FIELD_PREP(AIROHA_FOE_IB2_PSE_PORT, pse_port); + } + +- /* FIXME: implement QoS support setting pse_port to 2 (loopback) +- * for uplink and setting qos bit in ib2 +- */ +- + if (is_multicast_ether_addr(data->eth.h_dest)) + val |= AIROHA_FOE_IB2_MULTICAST; + +--- a/drivers/net/ethernet/airoha/airoha_regs.h ++++ b/drivers/net/ethernet/airoha/airoha_regs.h +@@ -38,6 +38,12 @@ + #define FE_RST_CORE_MASK BIT(0) + + #define REG_FE_FOE_TS 0x0010 ++ ++#define REG_FE_WAN_PORT 0x0024 ++#define WAN1_EN_MASK BIT(16) ++#define WAN1_MASK GENMASK(12, 8) ++#define WAN0_MASK GENMASK(4, 0) ++ + #define REG_FE_WAN_MAC_H 0x0030 + #define REG_FE_LAN_MAC_H 0x0040 + +@@ -126,6 +132,7 @@ + #define GDM_IP4_CKSUM BIT(22) + #define GDM_TCP_CKSUM BIT(21) + #define GDM_UDP_CKSUM BIT(20) ++#define GDM_STRIP_CRC BIT(16) + #define GDM_UCFQ_MASK GENMASK(15, 12) + #define GDM_BCFQ_MASK GENMASK(11, 8) + #define GDM_MCFQ_MASK GENMASK(7, 4) +@@ -139,6 +146,16 @@ + #define GDM_SHORT_LEN_MASK GENMASK(13, 0) + #define GDM_LONG_LEN_MASK GENMASK(29, 16) + ++#define REG_GDM_LPBK_CFG(_n) (GDM_BASE(_n) + 0x1c) ++#define LPBK_GAP_MASK GENMASK(31, 24) ++#define LPBK_LEN_MASK GENMASK(23, 10) ++#define LPBK_CHAN_MASK GENMASK(8, 4) ++#define LPBK_MODE_MASK GENMASK(3, 1) ++#define LPBK_EN_MASK BIT(0) ++ ++#define REG_GDM_TXCHN_EN(_n) (GDM_BASE(_n) + 0x24) ++#define REG_GDM_RXCHN_EN(_n) (GDM_BASE(_n) + 0x28) ++ + #define REG_FE_CPORT_CFG (GDM1_BASE + 0x40) + #define FE_CPORT_PAD BIT(26) + #define FE_CPORT_PORT_XFC_MASK BIT(25) +@@ -351,6 +368,18 @@ + + #define REG_MC_VLAN_DATA 0x2108 + ++#define REG_SP_DFT_CPORT(_n) (0x20e0 + ((_n) << 2)) ++#define SP_CPORT_PCIE1_MASK GENMASK(31, 28) ++#define SP_CPORT_PCIE0_MASK GENMASK(27, 24) ++#define SP_CPORT_USB_MASK GENMASK(7, 4) ++#define SP_CPORT_ETH_MASK GENMASK(7, 4) ++ ++#define REG_SRC_PORT_FC_MAP6 0x2298 ++#define FC_ID_OF_SRC_PORT27_MASK GENMASK(28, 24) ++#define FC_ID_OF_SRC_PORT26_MASK GENMASK(20, 16) ++#define FC_ID_OF_SRC_PORT25_MASK GENMASK(12, 8) ++#define FC_ID_OF_SRC_PORT24_MASK GENMASK(4, 0) ++ + #define REG_CDM5_RX_OQ1_DROP_CNT 0x29d4 + + /* QDMA */ diff --git a/target/linux/airoha/patches-6.6/048-15-v6.15-net-airoha-Introduce-PPE-debugfs-support.patch b/target/linux/airoha/patches-6.6/048-15-v6.15-net-airoha-Introduce-PPE-debugfs-support.patch new file mode 100644 index 00000000000000..50d7fa12668f9d --- /dev/null +++ b/target/linux/airoha/patches-6.6/048-15-v6.15-net-airoha-Introduce-PPE-debugfs-support.patch @@ -0,0 +1,291 @@ +From 3fe15c640f3808c3faf235553c67c867d1389e5c Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Fri, 28 Feb 2025 11:54:23 +0100 +Subject: [PATCH 15/15] net: airoha: Introduce PPE debugfs support + +Similar to PPE support for Mediatek devices, introduce PPE debugfs +in order to dump binded and unbinded flows. + +Signed-off-by: Lorenzo Bianconi +Signed-off-by: Paolo Abeni +--- + drivers/net/ethernet/airoha/Makefile | 1 + + drivers/net/ethernet/airoha/airoha_eth.h | 14 ++ + drivers/net/ethernet/airoha/airoha_ppe.c | 17 +- + .../net/ethernet/airoha/airoha_ppe_debugfs.c | 181 ++++++++++++++++++ + 4 files changed, 209 insertions(+), 4 deletions(-) + create mode 100644 drivers/net/ethernet/airoha/airoha_ppe_debugfs.c + +--- a/drivers/net/ethernet/airoha/Makefile ++++ b/drivers/net/ethernet/airoha/Makefile +@@ -5,4 +5,5 @@ + + obj-$(CONFIG_NET_AIROHA) += airoha-eth.o + airoha-eth-y := airoha_eth.o airoha_ppe.o ++airoha-eth-$(CONFIG_DEBUG_FS) += airoha_ppe_debugfs.o + obj-$(CONFIG_NET_AIROHA_NPU) += airoha_npu.o +--- a/drivers/net/ethernet/airoha/airoha_eth.h ++++ b/drivers/net/ethernet/airoha/airoha_eth.h +@@ -7,6 +7,7 @@ + #ifndef AIROHA_ETH_H + #define AIROHA_ETH_H + ++#include + #include + #include + #include +@@ -480,6 +481,8 @@ struct airoha_ppe { + + struct hlist_head *foe_flow; + u16 foe_check_time[PPE_NUM_ENTRIES]; ++ ++ struct dentry *debugfs_dir; + }; + + struct airoha_eth { +@@ -533,5 +536,16 @@ int airoha_ppe_setup_tc_block_cb(enum tc + void *cb_priv); + int airoha_ppe_init(struct airoha_eth *eth); + void airoha_ppe_deinit(struct airoha_eth *eth); ++struct airoha_foe_entry *airoha_ppe_foe_get_entry(struct airoha_ppe *ppe, ++ u32 hash); ++ ++#if CONFIG_DEBUG_FS ++int airoha_ppe_debugfs_init(struct airoha_ppe *ppe); ++#else ++static inline int airoha_ppe_debugfs_init(struct airoha_ppe *ppe) ++{ ++ return 0; ++} ++#endif + + #endif /* AIROHA_ETH_H */ +--- a/drivers/net/ethernet/airoha/airoha_ppe.c ++++ b/drivers/net/ethernet/airoha/airoha_ppe.c +@@ -390,8 +390,8 @@ static u32 airoha_ppe_foe_get_entry_hash + return hash; + } + +-static struct airoha_foe_entry * +-airoha_ppe_foe_get_entry(struct airoha_ppe *ppe, u32 hash) ++struct airoha_foe_entry *airoha_ppe_foe_get_entry(struct airoha_ppe *ppe, ++ u32 hash) + { + if (hash < PPE_SRAM_NUM_ENTRIES) { + u32 *hwe = ppe->foe + hash * sizeof(struct airoha_foe_entry); +@@ -861,7 +861,7 @@ void airoha_ppe_check_skb(struct airoha_ + int airoha_ppe_init(struct airoha_eth *eth) + { + struct airoha_ppe *ppe; +- int foe_size; ++ int foe_size, err; + + ppe = devm_kzalloc(eth->dev, sizeof(*ppe), GFP_KERNEL); + if (!ppe) +@@ -882,7 +882,15 @@ int airoha_ppe_init(struct airoha_eth *e + if (!ppe->foe_flow) + return -ENOMEM; + +- return rhashtable_init(ð->flow_table, &airoha_flow_table_params); ++ err = rhashtable_init(ð->flow_table, &airoha_flow_table_params); ++ if (err) ++ return err; ++ ++ err = airoha_ppe_debugfs_init(ppe); ++ if (err) ++ rhashtable_destroy(ð->flow_table); ++ ++ return err; + } + + void airoha_ppe_deinit(struct airoha_eth *eth) +@@ -898,4 +906,5 @@ void airoha_ppe_deinit(struct airoha_eth + rcu_read_unlock(); + + rhashtable_destroy(ð->flow_table); ++ debugfs_remove(eth->ppe->debugfs_dir); + } +--- /dev/null ++++ b/drivers/net/ethernet/airoha/airoha_ppe_debugfs.c +@@ -0,0 +1,181 @@ ++// SPDX-License-Identifier: GPL-2.0-only ++/* ++ * Copyright (c) 2025 AIROHA Inc ++ * Author: Lorenzo Bianconi ++ */ ++ ++#include "airoha_eth.h" ++ ++static void airoha_debugfs_ppe_print_tuple(struct seq_file *m, ++ void *src_addr, void *dest_addr, ++ u16 *src_port, u16 *dest_port, ++ bool ipv6) ++{ ++ __be32 n_addr[IPV6_ADDR_WORDS]; ++ ++ if (ipv6) { ++ ipv6_addr_cpu_to_be32(n_addr, src_addr); ++ seq_printf(m, "%pI6", n_addr); ++ } else { ++ seq_printf(m, "%pI4h", src_addr); ++ } ++ if (src_port) ++ seq_printf(m, ":%d", *src_port); ++ ++ seq_puts(m, "->"); ++ ++ if (ipv6) { ++ ipv6_addr_cpu_to_be32(n_addr, dest_addr); ++ seq_printf(m, "%pI6", n_addr); ++ } else { ++ seq_printf(m, "%pI4h", dest_addr); ++ } ++ if (dest_port) ++ seq_printf(m, ":%d", *dest_port); ++} ++ ++static int airoha_ppe_debugfs_foe_show(struct seq_file *m, void *private, ++ bool bind) ++{ ++ static const char *const ppe_type_str[] = { ++ [PPE_PKT_TYPE_IPV4_HNAPT] = "IPv4 5T", ++ [PPE_PKT_TYPE_IPV4_ROUTE] = "IPv4 3T", ++ [PPE_PKT_TYPE_BRIDGE] = "L2B", ++ [PPE_PKT_TYPE_IPV4_DSLITE] = "DS-LITE", ++ [PPE_PKT_TYPE_IPV6_ROUTE_3T] = "IPv6 3T", ++ [PPE_PKT_TYPE_IPV6_ROUTE_5T] = "IPv6 5T", ++ [PPE_PKT_TYPE_IPV6_6RD] = "6RD", ++ }; ++ static const char *const ppe_state_str[] = { ++ [AIROHA_FOE_STATE_INVALID] = "INV", ++ [AIROHA_FOE_STATE_UNBIND] = "UNB", ++ [AIROHA_FOE_STATE_BIND] = "BND", ++ [AIROHA_FOE_STATE_FIN] = "FIN", ++ }; ++ struct airoha_ppe *ppe = m->private; ++ int i; ++ ++ for (i = 0; i < PPE_NUM_ENTRIES; i++) { ++ const char *state_str, *type_str = "UNKNOWN"; ++ void *src_addr = NULL, *dest_addr = NULL; ++ u16 *src_port = NULL, *dest_port = NULL; ++ struct airoha_foe_mac_info_common *l2; ++ unsigned char h_source[ETH_ALEN] = {}; ++ unsigned char h_dest[ETH_ALEN]; ++ struct airoha_foe_entry *hwe; ++ u32 type, state, ib2, data; ++ bool ipv6 = false; ++ ++ hwe = airoha_ppe_foe_get_entry(ppe, i); ++ if (!hwe) ++ continue; ++ ++ state = FIELD_GET(AIROHA_FOE_IB1_BIND_STATE, hwe->ib1); ++ if (!state) ++ continue; ++ ++ if (bind && state != AIROHA_FOE_STATE_BIND) ++ continue; ++ ++ state_str = ppe_state_str[state % ARRAY_SIZE(ppe_state_str)]; ++ type = FIELD_GET(AIROHA_FOE_IB1_BIND_PACKET_TYPE, hwe->ib1); ++ if (type < ARRAY_SIZE(ppe_type_str) && ppe_type_str[type]) ++ type_str = ppe_type_str[type]; ++ ++ seq_printf(m, "%05x %s %7s", i, state_str, type_str); ++ ++ switch (type) { ++ case PPE_PKT_TYPE_IPV4_HNAPT: ++ case PPE_PKT_TYPE_IPV4_DSLITE: ++ src_port = &hwe->ipv4.orig_tuple.src_port; ++ dest_port = &hwe->ipv4.orig_tuple.dest_port; ++ fallthrough; ++ case PPE_PKT_TYPE_IPV4_ROUTE: ++ src_addr = &hwe->ipv4.orig_tuple.src_ip; ++ dest_addr = &hwe->ipv4.orig_tuple.dest_ip; ++ break; ++ case PPE_PKT_TYPE_IPV6_ROUTE_5T: ++ src_port = &hwe->ipv6.src_port; ++ dest_port = &hwe->ipv6.dest_port; ++ fallthrough; ++ case PPE_PKT_TYPE_IPV6_ROUTE_3T: ++ case PPE_PKT_TYPE_IPV6_6RD: ++ src_addr = &hwe->ipv6.src_ip; ++ dest_addr = &hwe->ipv6.dest_ip; ++ ipv6 = true; ++ break; ++ default: ++ break; ++ } ++ ++ if (src_addr && dest_addr) { ++ seq_puts(m, " orig="); ++ airoha_debugfs_ppe_print_tuple(m, src_addr, dest_addr, ++ src_port, dest_port, ipv6); ++ } ++ ++ switch (type) { ++ case PPE_PKT_TYPE_IPV4_HNAPT: ++ case PPE_PKT_TYPE_IPV4_DSLITE: ++ src_port = &hwe->ipv4.new_tuple.src_port; ++ dest_port = &hwe->ipv4.new_tuple.dest_port; ++ fallthrough; ++ case PPE_PKT_TYPE_IPV4_ROUTE: ++ src_addr = &hwe->ipv4.new_tuple.src_ip; ++ dest_addr = &hwe->ipv4.new_tuple.dest_ip; ++ seq_puts(m, " new="); ++ airoha_debugfs_ppe_print_tuple(m, src_addr, dest_addr, ++ src_port, dest_port, ++ ipv6); ++ break; ++ default: ++ break; ++ } ++ ++ if (type >= PPE_PKT_TYPE_IPV6_ROUTE_3T) { ++ data = hwe->ipv6.data; ++ ib2 = hwe->ipv6.ib2; ++ l2 = &hwe->ipv6.l2; ++ } else { ++ data = hwe->ipv4.data; ++ ib2 = hwe->ipv4.ib2; ++ l2 = &hwe->ipv4.l2.common; ++ *((__be16 *)&h_source[4]) = ++ cpu_to_be16(hwe->ipv4.l2.src_mac_lo); ++ } ++ ++ *((__be32 *)h_dest) = cpu_to_be32(l2->dest_mac_hi); ++ *((__be16 *)&h_dest[4]) = cpu_to_be16(l2->dest_mac_lo); ++ *((__be32 *)h_source) = cpu_to_be32(l2->src_mac_hi); ++ ++ seq_printf(m, " eth=%pM->%pM etype=%04x data=%08x" ++ " vlan=%d,%d ib1=%08x ib2=%08x\n", ++ h_source, h_dest, l2->etype, data, ++ l2->vlan1, l2->vlan2, hwe->ib1, ib2); ++ } ++ ++ return 0; ++} ++ ++static int airoha_ppe_debugfs_foe_all_show(struct seq_file *m, void *private) ++{ ++ return airoha_ppe_debugfs_foe_show(m, private, false); ++} ++DEFINE_SHOW_ATTRIBUTE(airoha_ppe_debugfs_foe_all); ++ ++static int airoha_ppe_debugfs_foe_bind_show(struct seq_file *m, void *private) ++{ ++ return airoha_ppe_debugfs_foe_show(m, private, true); ++} ++DEFINE_SHOW_ATTRIBUTE(airoha_ppe_debugfs_foe_bind); ++ ++int airoha_ppe_debugfs_init(struct airoha_ppe *ppe) ++{ ++ ppe->debugfs_dir = debugfs_create_dir("ppe", NULL); ++ debugfs_create_file("entries", 0444, ppe->debugfs_dir, ppe, ++ &airoha_ppe_debugfs_foe_all_fops); ++ debugfs_create_file("bind", 0444, ppe->debugfs_dir, ppe, ++ &airoha_ppe_debugfs_foe_bind_fops); ++ ++ return 0; ++} diff --git a/target/linux/airoha/patches-6.6/100-cpufreq-airoha-Add-EN7581-Cpufreq-SMC-driver.patch b/target/linux/airoha/patches-6.6/100-cpufreq-airoha-Add-EN7581-Cpufreq-SMC-driver.patch deleted file mode 100644 index 0276a4ee8114cb..00000000000000 --- a/target/linux/airoha/patches-6.6/100-cpufreq-airoha-Add-EN7581-Cpufreq-SMC-driver.patch +++ /dev/null @@ -1,247 +0,0 @@ -From 5296da64f77ef6c809b715cdecf308977a08acb9 Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Wed, 16 Oct 2024 18:00:57 +0200 -Subject: [PATCH] cpufreq: airoha: Add EN7581 Cpufreq SMC driver - -Add simple Cpufreq driver for Airoha EN7581 SoC that control CPU -frequency scaling with SMC APIs. - -All CPU share the same frequency and can't be controlled independently. -Current shared CPU frequency is returned by the related SMC command. - -Add SoC compatible to cpufreq-dt-plat block list as a dedicated cpufreq -driver is needed with OPP v2 nodes declared in DTS. - -Signed-off-by: Christian Marangi ---- - drivers/cpufreq/Kconfig.arm | 8 ++ - drivers/cpufreq/Makefile | 1 + - drivers/cpufreq/airoha-cpufreq.c | 183 +++++++++++++++++++++++++++ - drivers/cpufreq/cpufreq-dt-platdev.c | 2 + - 4 files changed, 194 insertions(+) - create mode 100644 drivers/cpufreq/airoha-cpufreq.c - ---- a/drivers/cpufreq/Kconfig.arm -+++ b/drivers/cpufreq/Kconfig.arm -@@ -41,6 +41,14 @@ config ARM_ALLWINNER_SUN50I_CPUFREQ_NVME - To compile this driver as a module, choose M here: the - module will be called sun50i-cpufreq-nvmem. - -+config ARM_AIROHA_SOC_CPUFREQ -+ tristate "Airoha EN7581 SoC CPUFreq support" -+ depends on ARCH_AIROHA || COMPILE_TEST -+ select PM_OPP -+ default ARCH_AIROHA -+ help -+ This adds the CPUFreq driver for Airoha EN7581 SoCs. -+ - config ARM_APPLE_SOC_CPUFREQ - tristate "Apple Silicon SoC CPUFreq support" - depends on ARCH_APPLE || (COMPILE_TEST && 64BIT) ---- a/drivers/cpufreq/Makefile -+++ b/drivers/cpufreq/Makefile -@@ -52,6 +52,7 @@ obj-$(CONFIG_X86_AMD_FREQ_SENSITIVITY) + - - ################################################################################## - # ARM SoC drivers -+obj-$(CONFIG_ARM_AIROHA_SOC_CPUFREQ) += airoha-cpufreq.o - obj-$(CONFIG_ARM_APPLE_SOC_CPUFREQ) += apple-soc-cpufreq.o - obj-$(CONFIG_ARM_ARMADA_37XX_CPUFREQ) += armada-37xx-cpufreq.o - obj-$(CONFIG_ARM_ARMADA_8K_CPUFREQ) += armada-8k-cpufreq.o ---- /dev/null -+++ b/drivers/cpufreq/airoha-cpufreq.c -@@ -0,0 +1,183 @@ -+// SPDX-License-Identifier: GPL-2.0 -+ -+#include -+#include -+#include -+ -+#define AIROHA_SIP_AVS_HANDLE 0x82000301 -+#define AIROHA_AVS_OP_BASE 0xddddddd0 -+#define AIROHA_AVS_OP_MASK GENMASK(1, 0) -+#define AIROHA_AVS_OP_FREQ_DYN_ADJ (AIROHA_AVS_OP_BASE | \ -+ FIELD_PREP(AIROHA_AVS_OP_MASK, 0x1)) -+#define AIROHA_AVS_OP_GET_FREQ (AIROHA_AVS_OP_BASE | \ -+ FIELD_PREP(AIROHA_AVS_OP_MASK, 0x2)) -+ -+struct airoha_cpufreq_priv { -+ struct list_head list; -+ -+ cpumask_var_t cpus; -+ struct device *cpu_dev; -+ struct cpufreq_frequency_table *freq_table; -+}; -+ -+static LIST_HEAD(priv_list); -+ -+static unsigned int airoha_cpufreq_get(unsigned int cpu) -+{ -+ const struct arm_smccc_1_2_regs args = { -+ .a0 = AIROHA_SIP_AVS_HANDLE, -+ .a1 = AIROHA_AVS_OP_GET_FREQ, -+ }; -+ struct arm_smccc_1_2_regs res; -+ -+ arm_smccc_1_2_smc(&args, &res); -+ -+ return (int)(res.a0 * 1000); -+} -+ -+static int airoha_cpufreq_set_target(struct cpufreq_policy *policy, unsigned int index) -+{ -+ const struct arm_smccc_1_2_regs args = { -+ .a0 = AIROHA_SIP_AVS_HANDLE, -+ .a1 = AIROHA_AVS_OP_FREQ_DYN_ADJ, -+ .a3 = index, -+ }; -+ struct arm_smccc_1_2_regs res; -+ -+ arm_smccc_1_2_smc(&args, &res); -+ -+ /* SMC signal correct apply by unsetting BIT 0 */ -+ return res.a0 & BIT(0) ? -EINVAL : 0; -+} -+ -+static struct airoha_cpufreq_priv *airoha_cpufreq_find_data(int cpu) -+{ -+ struct airoha_cpufreq_priv *priv; -+ -+ list_for_each_entry(priv, &priv_list, list) { -+ if (cpumask_test_cpu(cpu, priv->cpus)) -+ return priv; -+ } -+ -+ return NULL; -+} -+ -+static int airoha_cpufreq_init(struct cpufreq_policy *policy) -+{ -+ struct airoha_cpufreq_priv *priv; -+ struct device *cpu_dev; -+ -+ priv = airoha_cpufreq_find_data(policy->cpu); -+ if (!priv) -+ return -ENODEV; -+ -+ cpu_dev = priv->cpu_dev; -+ cpumask_copy(policy->cpus, priv->cpus); -+ policy->driver_data = priv; -+ policy->freq_table = priv->freq_table; -+ -+ return 0; -+} -+ -+static struct cpufreq_driver airoha_cpufreq_driver = { -+ .flags = CPUFREQ_NEED_INITIAL_FREQ_CHECK | -+ CPUFREQ_IS_COOLING_DEV, -+ .verify = cpufreq_generic_frequency_table_verify, -+ .target_index = airoha_cpufreq_set_target, -+ .get = airoha_cpufreq_get, -+ .init = airoha_cpufreq_init, -+ .attr = cpufreq_generic_attr, -+ .name = "airoha-cpufreq", -+}; -+ -+static int airoha_cpufreq_driver_init_cpu(int cpu) -+{ -+ struct airoha_cpufreq_priv *priv; -+ struct device *cpu_dev; -+ int ret; -+ -+ cpu_dev = get_cpu_device(cpu); -+ if (!cpu_dev) -+ return -EPROBE_DEFER; -+ -+ priv = kzalloc(sizeof(*priv), GFP_KERNEL); -+ if (!priv) -+ return -ENOMEM; -+ -+ if (!zalloc_cpumask_var(&priv->cpus, GFP_KERNEL)) -+ return -ENOMEM; -+ -+ cpumask_set_cpu(cpu, priv->cpus); -+ priv->cpu_dev = cpu_dev; -+ -+ ret = dev_pm_opp_of_get_sharing_cpus(cpu_dev, priv->cpus); -+ if (ret) -+ goto err; -+ -+ ret = dev_pm_opp_of_cpumask_add_table(priv->cpus); -+ if (ret) -+ goto err; -+ -+ ret = dev_pm_opp_init_cpufreq_table(cpu_dev, &priv->freq_table); -+ if (ret) -+ goto err; -+ -+ list_add(&priv->list, &priv_list); -+ -+ return 0; -+ -+err: -+ dev_pm_opp_of_cpumask_remove_table(priv->cpus); -+ free_cpumask_var(priv->cpus); -+ -+ return ret; -+} -+ -+static void airoha_cpufreq_release(void) -+{ -+ struct airoha_cpufreq_priv *priv, *tmp; -+ -+ list_for_each_entry_safe(priv, tmp, &priv_list, list) { -+ dev_pm_opp_free_cpufreq_table(priv->cpu_dev, &priv->freq_table); -+ dev_pm_opp_of_cpumask_remove_table(priv->cpus); -+ free_cpumask_var(priv->cpus); -+ list_del(&priv->list); -+ kfree(priv); -+ } -+} -+ -+static int __init airoha_cpufreq_driver_probe(void) -+{ -+ int cpu, ret; -+ -+ if (!of_machine_is_compatible("airoha,en7581")) -+ return -ENODEV; -+ -+ for_each_possible_cpu(cpu) { -+ ret = airoha_cpufreq_driver_init_cpu(cpu); -+ if (ret) -+ goto err; -+ } -+ -+ ret = cpufreq_register_driver(&airoha_cpufreq_driver); -+ if (ret) -+ goto err; -+ -+ return 0; -+ -+err: -+ airoha_cpufreq_release(); -+ return ret; -+} -+module_init(airoha_cpufreq_driver_probe); -+ -+static void __exit airoha_cpufreq_driver_remove(void) -+{ -+ cpufreq_unregister_driver(&airoha_cpufreq_driver); -+ airoha_cpufreq_release(); -+} -+module_exit(airoha_cpufreq_driver_remove); -+ -+MODULE_AUTHOR("Christian Marangi "); -+MODULE_DESCRIPTION("CPUfreq driver for Airoha SoCs"); -+MODULE_LICENSE("GPL"); ---- a/drivers/cpufreq/cpufreq-dt-platdev.c -+++ b/drivers/cpufreq/cpufreq-dt-platdev.c -@@ -103,6 +103,8 @@ static const struct of_device_id allowli - * platforms using "operating-points-v2" property. - */ - static const struct of_device_id blocklist[] __initconst = { -+ { .compatible = "airoha,en7581", }, -+ - { .compatible = "allwinner,sun50i-h6", }, - - { .compatible = "apple,arm-platform", }, diff --git a/target/linux/airoha/patches-6.6/101-01-thermal-of-Add-devm_thermal_of_zone_register_with_pa.patch b/target/linux/airoha/patches-6.6/101-01-thermal-of-Add-devm_thermal_of_zone_register_with_pa.patch index e69f57d27309c0..d646e05170368a 100644 --- a/target/linux/airoha/patches-6.6/101-01-thermal-of-Add-devm_thermal_of_zone_register_with_pa.patch +++ b/target/linux/airoha/patches-6.6/101-01-thermal-of-Add-devm_thermal_of_zone_register_with_pa.patch @@ -40,7 +40,7 @@ Signed-off-by: Christian Marangi --- a/drivers/thermal/thermal_of.c +++ b/drivers/thermal/thermal_of.c -@@ -249,7 +249,7 @@ static void thermal_of_parameters_init(s +@@ -246,7 +246,7 @@ static void thermal_of_parameters_init(s { int coef[2]; int ncoef = ARRAY_SIZE(coef); @@ -49,7 +49,7 @@ Signed-off-by: Christian Marangi tzp->no_hwmon = true; -@@ -261,14 +261,11 @@ static void thermal_of_parameters_init(s +@@ -258,14 +258,11 @@ static void thermal_of_parameters_init(s * thermal zone. Thus, we are considering only the first two * values as slope and offset. */ @@ -67,7 +67,7 @@ Signed-off-by: Christian Marangi } static struct device_node *thermal_of_zone_get_by_name(struct thermal_zone_device *tz) -@@ -462,10 +459,15 @@ static void thermal_of_zone_unregister(s +@@ -459,10 +456,15 @@ static void thermal_of_zone_unregister(s * zone properties and registers new thermal zone with those * properties. * @@ -83,7 +83,7 @@ Signed-off-by: Christian Marangi * * Return: a valid thermal zone structure pointer on success. * - EINVAL: if the device tree thermal description is malformed -@@ -473,11 +475,11 @@ static void thermal_of_zone_unregister(s +@@ -470,11 +472,11 @@ static void thermal_of_zone_unregister(s * - Other negative errors are returned by the underlying called functions */ static struct thermal_zone_device *thermal_of_zone_register(struct device_node *sensor, int id, void *data, @@ -181,7 +181,7 @@ Signed-off-by: Christian Marangi * @dev: Device for which which resource was allocated. --- a/include/linux/thermal.h +++ b/include/linux/thermal.h -@@ -261,6 +261,10 @@ struct thermal_zone_params { +@@ -263,6 +263,10 @@ struct thermal_zone_params { #ifdef CONFIG_THERMAL_OF struct thermal_zone_device *devm_thermal_of_zone_register(struct device *dev, int id, void *data, const struct thermal_zone_device_ops *ops); @@ -192,7 +192,7 @@ Signed-off-by: Christian Marangi void devm_thermal_of_zone_unregister(struct device *dev, struct thermal_zone_device *tz); -@@ -272,6 +276,15 @@ struct thermal_zone_device *devm_thermal +@@ -274,6 +278,15 @@ struct thermal_zone_device *devm_thermal { return ERR_PTR(-ENOTSUPP); } diff --git a/target/linux/airoha/patches-6.6/105-uart-add-en7523-support.patch b/target/linux/airoha/patches-6.6/105-uart-add-en7523-support.patch index 38611b907ce982..9ea355370bbd45 100644 --- a/target/linux/airoha/patches-6.6/105-uart-add-en7523-support.patch +++ b/target/linux/airoha/patches-6.6/105-uart-add-en7523-support.patch @@ -122,7 +122,7 @@ }; /* Uart divisor latch read */ -@@ -2880,6 +2888,12 @@ serial8250_do_set_termios(struct uart_po +@@ -2888,6 +2896,12 @@ serial8250_do_set_termios(struct uart_po serial8250_set_divisor(port, baud, quot, frac); diff --git a/target/linux/airoha/patches-6.6/108-pwm-airoha-Add-support-for-EN7581-SoC.patch b/target/linux/airoha/patches-6.6/108-pwm-airoha-Add-support-for-EN7581-SoC.patch index 8f83c696c4f558..0b114d5f53b6fe 100644 --- a/target/linux/airoha/patches-6.6/108-pwm-airoha-Add-support-for-EN7581-SoC.patch +++ b/target/linux/airoha/patches-6.6/108-pwm-airoha-Add-support-for-EN7581-SoC.patch @@ -48,7 +48,7 @@ Signed-off-by: Lorenzo Bianconi obj-$(CONFIG_PWM_ATMEL_HLCDC_PWM) += pwm-atmel-hlcdc.o --- /dev/null +++ b/drivers/pwm/pwm-airoha.c -@@ -0,0 +1,400 @@ +@@ -0,0 +1,388 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright 2022 Markus Gothe @@ -414,18 +414,7 @@ Signed-off-by: Lorenzo Bianconi + if (IS_ERR(pc->regmap)) + return PTR_ERR(pc->regmap); + -+ platform_set_drvdata(pdev, pc); -+ -+ return pwmchip_add(&pc->chip); -+} -+ -+static int airoha_pwm_remove(struct platform_device *pdev) -+{ -+ struct airoha_pwm *pc = platform_get_drvdata(pdev); -+ -+ pwmchip_remove(&pc->chip); -+ -+ return 0; ++ return devm_pwmchip_add(&pdev->dev, &pc->chip); +} + +static const struct of_device_id airoha_pwm_of_match[] = { @@ -440,7 +429,6 @@ Signed-off-by: Lorenzo Bianconi + .of_match_table = airoha_pwm_of_match, + }, + .probe = airoha_pwm_probe, -+ .remove = airoha_pwm_remove, +}; +module_platform_driver(airoha_pwm_driver); + diff --git a/target/linux/airoha/patches-6.6/113-net-airoha-Fix-channel-configuration-for-ETS-Qdisc.patch b/target/linux/airoha/patches-6.6/113-net-airoha-Fix-channel-configuration-for-ETS-Qdisc.patch new file mode 100644 index 00000000000000..21896d7fa998a5 --- /dev/null +++ b/target/linux/airoha/patches-6.6/113-net-airoha-Fix-channel-configuration-for-ETS-Qdisc.patch @@ -0,0 +1,104 @@ +From patchwork Tue Jan 7 22:26:28 2025 +Content-Type: text/plain; charset="utf-8" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +X-Patchwork-Submitter: Lorenzo Bianconi +X-Patchwork-Id: 13929634 +X-Patchwork-Delegate: kuba@kernel.org +Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org + [10.30.226.201]) + (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) + (No client certificate requested) + by smtp.subspace.kernel.org (Postfix) with ESMTPS id A82271A3035 + for ; Tue, 7 Jan 2025 22:27:02 +0000 (UTC) +Authentication-Results: smtp.subspace.kernel.org; + arc=none smtp.client-ip=10.30.226.201 +ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; + t=1736288822; cv=none; + b=XZhiaYPBxLiUvOxWeE7zfuFI3fOmu5SLoHdLPFXNXBtvmZWWIohKA8AeGI37v/l+0Du9JwGRKMkb19v/IxDJtMXkyTJXHHKYhXWaNFpj/pFRk9C4WsIa29OCqanfA+yXUQLJyGVopMLsxfcbzznozIANWbaO0NVBHyZZSH9eaYU= +ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; + s=arc-20240116; t=1736288822; c=relaxed/simple; + bh=/BuvRwLGk+7by7QeOu7n+QgJ5Sk03TO9WCsGbgTs3sE=; + h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:To:Cc; + b=jHXwJfD+6o5WvM5xaeL35BI6hshOViNtg+mSqf5q8jH9l3k6FctngCkEYdxJzcYaw9aEEigC8/FZiHoPrIXGyJA29kTWkYSjj7rtagL1aSIWPGAuSJaaAUv2Bj8jxUmIlJxb23wTleEv/Pwnz+1oSf3yZ7g46h9gv4RZaU8yySg= +ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; + dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org + header.b=Gx3FMrdJ; arc=none smtp.client-ip=10.30.226.201 +Authentication-Results: smtp.subspace.kernel.org; + dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org + header.b="Gx3FMrdJ" +Received: by smtp.kernel.org (Postfix) with ESMTPSA id E1A57C4CED6; + Tue, 7 Jan 2025 22:27:01 +0000 (UTC) +DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; + s=k20201202; t=1736288822; + bh=/BuvRwLGk+7by7QeOu7n+QgJ5Sk03TO9WCsGbgTs3sE=; + h=From:Date:Subject:To:Cc:From; + b=Gx3FMrdJH+xaen2jSRnu523A40ZOBBFaj896IwBv1PeosUm+eiUCx+K3Qz9CAisX0 + Bj4ohheTiHZDQHZelhKF3ZFTfVQUyYiLiard4x5QdylW2YZA0cpwJe64TMf7CsHbrT + NHCF7nrJPJUwOhDoS/YVdeTw/bb9DlM95aKGSfyH0cy7Kdmjz55No3Im9bCSKcgyaX + Y/lcRZglFjbLyiC3LS06AtM0KOyhUxQKrH+ZWpx5E/sdOEj3SRTJ/I+K8o3m75Kzsn + wKRft5pBwfhGEIrJXrFR4f73QwnxJ6eSUrfjYV8k4mFQpH3nB0hKLi2DpvYPim5dj/ + ADsdcP6QPwokg== +From: Lorenzo Bianconi +Date: Tue, 07 Jan 2025 23:26:28 +0100 +Subject: [PATCH net-next] net: airoha: Fix channel configuration for ETS + Qdisc +Precedence: bulk +X-Mailing-List: netdev@vger.kernel.org +List-Id: +List-Subscribe: +List-Unsubscribe: +MIME-Version: 1.0 +Message-Id: <20250107-airoha-ets-fix-chan-v1-1-97f66ed3a068@kernel.org> +X-B4-Tracking: v=1; b=H4sIABOqfWcC/x2MSwqAMAwFryJZG6ifVvAq4qLUaLNRaUSE0rsbX + Q5v3mQQSkwCY5Uh0c3Cx67Q1BWE6PeNkBdlaE1rTWMG9JyO6JEuwZUf/CSkzobgw+AW14M+z0S + 6/dVpLuUFNrlCSGUAAAA= +X-Change-ID: 20250107-airoha-ets-fix-chan-e35ccac76d64 +To: Felix Fietkau , Sean Wang , + Mark Lee , Andrew Lunn , + "David S. Miller" , Eric Dumazet , + Jakub Kicinski , Paolo Abeni , + Matthias Brugger , + AngeloGioacchino Del Regno +Cc: linux-arm-kernel@lists.infradead.org, + linux-mediatek@lists.infradead.org, netdev@vger.kernel.org, + Lorenzo Bianconi +X-Mailer: b4 0.14.2 +X-Patchwork-Delegate: kuba@kernel.org + +Limit ETS QoS channel to AIROHA_NUM_QOS_CHANNELS in +airoha_tc_setup_qdisc_ets() in order to align the configured channel to +the value set in airoha_dev_select_queue(). + +Fixes: 20bf7d07c956 ("net: airoha: Add sched ETS offload support") +Signed-off-by: Lorenzo Bianconi +Reviewed-by: Michal Swiatkowski +--- + drivers/net/ethernet/mediatek/airoha_eth.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + + +--- +base-commit: a1942da8a38717ddd9b4c132f59e1657c85c1432 +change-id: 20250107-airoha-ets-fix-chan-e35ccac76d64 + +Best regards, + +--- a/drivers/net/ethernet/airoha/airoha_eth.c ++++ b/drivers/net/ethernet/airoha/airoha_eth.c +@@ -2064,11 +2064,14 @@ static int airoha_qdma_get_tx_ets_stats( + static int airoha_tc_setup_qdisc_ets(struct airoha_gdm_port *port, + struct tc_ets_qopt_offload *opt) + { +- int channel = TC_H_MAJ(opt->handle) >> 16; ++ int channel; + + if (opt->parent == TC_H_ROOT) + return -EINVAL; + ++ channel = TC_H_MAJ(opt->handle) >> 16; ++ channel = channel % AIROHA_NUM_QOS_CHANNELS; ++ + switch (opt->command) { + case TC_ETS_REPLACE: + return airoha_qdma_set_tx_ets_sched(port, channel, opt); diff --git a/target/linux/airoha/patches-6.6/200-spinlock-extend-guard-with-spinlock_bh-variants.patch b/target/linux/airoha/patches-6.6/200-spinlock-extend-guard-with-spinlock_bh-variants.patch index e613b69f81f304..d4905d5fff6fa1 100644 --- a/target/linux/airoha/patches-6.6/200-spinlock-extend-guard-with-spinlock_bh-variants.patch +++ b/target/linux/airoha/patches-6.6/200-spinlock-extend-guard-with-spinlock_bh-variants.patch @@ -12,9 +12,9 @@ Signed-off-by: Christian Marangi --- a/include/linux/spinlock.h +++ b/include/linux/spinlock.h -@@ -515,6 +515,10 @@ DEFINE_LOCK_GUARD_1(raw_spinlock_irq, ra - raw_spin_lock_irq(_T->lock), - raw_spin_unlock_irq(_T->lock)) +@@ -519,6 +519,10 @@ DEFINE_LOCK_GUARD_1(raw_spinlock_irq, ra + + DEFINE_LOCK_GUARD_1_COND(raw_spinlock_irq, _try, raw_spin_trylock_irq(_T->lock)) +DEFINE_LOCK_GUARD_1(raw_spinlock_bh, raw_spinlock_t, + raw_spin_lock_bh(_T->lock), @@ -23,9 +23,9 @@ Signed-off-by: Christian Marangi DEFINE_LOCK_GUARD_1(raw_spinlock_irqsave, raw_spinlock_t, raw_spin_lock_irqsave(_T->lock, _T->flags), raw_spin_unlock_irqrestore(_T->lock, _T->flags), -@@ -528,6 +532,10 @@ DEFINE_LOCK_GUARD_1(spinlock_irq, spinlo - spin_lock_irq(_T->lock), - spin_unlock_irq(_T->lock)) +@@ -540,6 +544,10 @@ DEFINE_LOCK_GUARD_1(spinlock_irq, spinlo + DEFINE_LOCK_GUARD_1_COND(spinlock_irq, _try, + spin_trylock_irq(_T->lock)) +DEFINE_LOCK_GUARD_1(spinlock_bh, spinlock_t, + spin_lock_bh(_T->lock), diff --git a/target/linux/airoha/patches-6.6/901-snand-mtk-bmt-support.patch b/target/linux/airoha/patches-6.6/901-snand-mtk-bmt-support.patch index de8e8806433c60..90619d971ea406 100644 --- a/target/linux/airoha/patches-6.6/901-snand-mtk-bmt-support.patch +++ b/target/linux/airoha/patches-6.6/901-snand-mtk-bmt-support.patch @@ -8,7 +8,7 @@ static int spinand_read_reg_op(struct spinand_device *spinand, u8 reg, u8 *val) { -@@ -1346,6 +1347,7 @@ static int spinand_probe(struct spi_mem +@@ -1352,6 +1353,7 @@ static int spinand_probe(struct spi_mem if (ret) return ret; @@ -16,7 +16,7 @@ ret = mtd_device_register(mtd, NULL, 0); if (ret) goto err_spinand_cleanup; -@@ -1353,6 +1355,7 @@ static int spinand_probe(struct spi_mem +@@ -1359,6 +1361,7 @@ static int spinand_probe(struct spi_mem return 0; err_spinand_cleanup: @@ -24,7 +24,7 @@ spinand_cleanup(spinand); return ret; -@@ -1371,6 +1374,7 @@ static int spinand_remove(struct spi_mem +@@ -1377,6 +1380,7 @@ static int spinand_remove(struct spi_mem if (ret) return ret; diff --git a/target/linux/airoha/patches-6.6/902-mtd-parser-add-support-for-Airoha-parser.patch b/target/linux/airoha/patches-6.6/902-mtd-parser-add-support-for-Airoha-parser.patch deleted file mode 100644 index 590d0d9faa26d4..00000000000000 --- a/target/linux/airoha/patches-6.6/902-mtd-parser-add-support-for-Airoha-parser.patch +++ /dev/null @@ -1,170 +0,0 @@ -From ca46c5834ba3a74595a93d7a491fa9c943be7c30 Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Sun, 28 Jul 2024 12:15:53 +0200 -Subject: [PATCH 3/3] mtd: parser: add support for Airoha parser - -Add support for Airoha parser based on a post parse ofpart function. - -Airoha partition table follow normal fixed-partition implementation -with a special implementation for the ART partition. This is always the -past partition and is placed from the end of the flash - the partition -size. - -To enable this special implementation for ART partition, the relevant -node require the "airoha,dynamic-art" compatible. With that declared, -offset value is ignored and real offset is updated with the calculated -value. - -Due to usage of specific bad block management driver, the MTD size might -vary hence the ART partition offset needs to be dynamically parsed and -can't be declared statically. - -Signed-off-by: Christian Marangi ---- - drivers/mtd/parsers/Kconfig | 10 ++++++ - drivers/mtd/parsers/Makefile | 1 + - drivers/mtd/parsers/ofpart_airoha.c | 56 +++++++++++++++++++++++++++++ - drivers/mtd/parsers/ofpart_airoha.h | 18 ++++++++++ - drivers/mtd/parsers/ofpart_core.c | 6 ++++ - 5 files changed, 91 insertions(+) - create mode 100644 drivers/mtd/parsers/ofpart_airoha.c - create mode 100644 drivers/mtd/parsers/ofpart_airoha.h - ---- a/drivers/mtd/parsers/Kconfig -+++ b/drivers/mtd/parsers/Kconfig -@@ -93,6 +93,16 @@ config MTD_OF_PARTS - flash memory node, as described in - Documentation/devicetree/bindings/mtd/mtd.yaml. - -+config MTD_OF_PARTS_AIROHA -+ bool "Airoha EN7815 partitioning support" -+ depends on MTD_OF_PARTS && (ARCH_AIROHA || COMPILE_TEST) -+ default ARCH_AIROHA -+ help -+ This provides partitions parser for Airoha EN7815 family devices -+ that can have dynamic "ART" partition at the end of the flash. -+ It takes care of finding the correct offset and update property -+ with it. -+ - config MTD_OF_PARTS_BCM4908 - bool "BCM4908 partitioning support" - depends on MTD_OF_PARTS && (ARCH_BCMBCA || COMPILE_TEST) ---- a/drivers/mtd/parsers/Makefile -+++ b/drivers/mtd/parsers/Makefile -@@ -7,6 +7,7 @@ obj-$(CONFIG_MTD_CMDLINE_PARTS) += cmdl - obj-$(CONFIG_MTD_MYLOADER_PARTS) += myloader.o - obj-$(CONFIG_MTD_OF_PARTS) += ofpart.o - ofpart-y += ofpart_core.o -+ofpart-$(CONFIG_MTD_OF_PARTS_AIROHA) += ofpart_airoha.o - ofpart-$(CONFIG_MTD_OF_PARTS_BCM4908) += ofpart_bcm4908.o - ofpart-$(CONFIG_MTD_OF_PARTS_LINKSYS_NS)+= ofpart_linksys_ns.o - obj-$(CONFIG_MTD_PARSER_IMAGETAG) += parser_imagetag.o ---- /dev/null -+++ b/drivers/mtd/parsers/ofpart_airoha.c -@@ -0,0 +1,56 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2024 Christian Marangi -+ */ -+ -+#include -+#include -+ -+#include "ofpart_airoha.h" -+ -+int airoha_partitions_post_parse(struct mtd_info *mtd, -+ struct mtd_partition *parts, -+ int nr_parts) -+{ -+ struct mtd_partition *part; -+ int len, a_cells, s_cells; -+ struct device_node *pp; -+ struct property *prop; -+ const __be32 *reg; -+ __be32 *new_reg; -+ -+ part = &parts[nr_parts - 1]; -+ pp = part->of_node; -+ -+ /* Skip if ART partition have a valid offset instead of a dynamic one */ -+ if (!of_device_is_compatible(pp, "airoha,dynamic-art")) -+ return 0; -+ -+ /* ART partition is set at the end of flash - size */ -+ part->offset = mtd->size - part->size; -+ -+ /* Update the offset with the new calculate value in DT */ -+ prop = kzalloc(sizeof(*prop), GFP_KERNEL); -+ if (!prop) -+ return -ENOMEM; -+ -+ /* Reg already validated by fixed-partition parser */ -+ reg = of_get_property(pp, "reg", &len); -+ -+ /* Fixed partition */ -+ a_cells = of_n_addr_cells(pp); -+ s_cells = of_n_size_cells(pp); -+ -+ prop->name = "reg"; -+ prop->length = (a_cells + s_cells) * sizeof(__be32); -+ prop->value = kmemdup(reg, (a_cells + s_cells) * sizeof(__be32), -+ GFP_KERNEL); -+ new_reg = prop->value; -+ memset(new_reg, 0, a_cells * sizeof(__be32)); -+ new_reg[a_cells - 1] = cpu_to_be32(part->offset); -+ if (a_cells > 1) -+ new_reg[0] = cpu_to_be32(part->offset >> 32); -+ of_update_property(pp, prop); -+ -+ return 0; -+} ---- /dev/null -+++ b/drivers/mtd/parsers/ofpart_airoha.h -@@ -0,0 +1,18 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+#ifndef __OFPART_AIROHA_H -+#define __OFPART_AIROHA_H -+ -+#ifdef CONFIG_MTD_OF_PARTS_AIROHA -+int airoha_partitions_post_parse(struct mtd_info *mtd, -+ struct mtd_partition *parts, -+ int nr_parts); -+#else -+static inline int airoha_partitions_post_parse(struct mtd_info *mtd, -+ struct mtd_partition *parts, -+ int nr_parts) -+{ -+ return -EOPNOTSUPP; -+} -+#endif -+ -+#endif ---- a/drivers/mtd/parsers/ofpart_core.c -+++ b/drivers/mtd/parsers/ofpart_core.c -@@ -16,6 +16,7 @@ - #include - #include - -+#include "ofpart_airoha.h" - #include "ofpart_bcm4908.h" - #include "ofpart_linksys_ns.h" - -@@ -23,6 +24,10 @@ struct fixed_partitions_quirks { - int (*post_parse)(struct mtd_info *mtd, struct mtd_partition *parts, int nr_parts); - }; - -+static struct fixed_partitions_quirks airoha_partitions_quirks = { -+ .post_parse = airoha_partitions_post_parse, -+}; -+ - static struct fixed_partitions_quirks bcm4908_partitions_quirks = { - .post_parse = bcm4908_partitions_post_parse, - }; -@@ -192,6 +197,7 @@ static const struct of_device_id parse_o - /* Generic */ - { .compatible = "fixed-partitions" }, - /* Customized */ -+ { .compatible = "airoha,fixed-partitions", .data = &airoha_partitions_quirks, }, - { .compatible = "brcm,bcm4908-partitions", .data = &bcm4908_partitions_quirks, }, - { .compatible = "linksys,ns-partitions", .data = &linksys_ns_partitions_quirks, }, - {}, diff --git a/target/linux/apm821xx/base-files/etc/uci-defaults/05_fix-compat-version b/target/linux/apm821xx/base-files/etc/uci-defaults/05_fix-compat-version index 00d3954e5f481b..11af63c9e7ce28 100644 --- a/target/linux/apm821xx/base-files/etc/uci-defaults/05_fix-compat-version +++ b/target/linux/apm821xx/base-files/etc/uci-defaults/05_fix-compat-version @@ -2,12 +2,15 @@ case "$(board_name)" in meraki,mx60|\ -netgear,wndap620|\ -netgear,wndap660|\ netgear,wndr4700) uci set system.@system[0].compat_version="3.0" uci commit system ;; +netgear,wndap620|\ +netgear,wndap660) + uci set system.@system[0].compat_version="2.0" + uci commit system + ;; esac exit 0 diff --git a/target/linux/apm821xx/config-6.6 b/target/linux/apm821xx/config-6.6 index 33e586632cd762..a9c9a952c8c50b 100644 --- a/target/linux/apm821xx/config-6.6 +++ b/target/linux/apm821xx/config-6.6 @@ -34,8 +34,6 @@ CONFIG_BOOKE=y CONFIG_BOOKE_OR_40x=y CONFIG_BOOKE_WDT=y # CONFIG_CANYONLANDS is not set -CONFIG_CC_IMPLICIT_FALLTHROUGH="-Wimplicit-fallthrough=5" -CONFIG_CC_NO_ARRAY_BOUNDS=y CONFIG_CLONE_BACKWARDS=y CONFIG_CMDLINE="rootfstype=squashfs noinitrd" CONFIG_CMDLINE_FROM_BOOTLOADER=y @@ -83,7 +81,6 @@ CONFIG_FUNCTION_ALIGNMENT=0 CONFIG_FWNODE_MDIO=y CONFIG_FW_LOADER_PAGED_BUF=y CONFIG_FW_LOADER_SYSFS=y -CONFIG_GCC10_NO_ARRAY_BOUNDS=y CONFIG_GENERIC_ALLOCATOR=y CONFIG_GENERIC_ATOMIC64=y CONFIG_GENERIC_BUG=y diff --git a/target/linux/apm821xx/image/nand.mk b/target/linux/apm821xx/image/nand.mk index 92bdaa87d03372..7b3945183e5baf 100644 --- a/target/linux/apm821xx/image/nand.mk +++ b/target/linux/apm821xx/image/nand.mk @@ -89,9 +89,6 @@ endef TARGET_DEVICES += netgear_wndap660 define Device/netgear_wndr4700 - DEVICE_COMPAT_VERSION := 3.0 - DEVICE_COMPAT_MESSAGE := Network swconfig configuration cannot be upgraded to DSA. \ - Upgrade via sysupgrade mechanism is not possible. DEVICE_VENDOR := NETGEAR DEVICE_MODEL := Centria N900 WNDR4700 DEVICE_ALT0_VENDOR := NETGEAR @@ -123,8 +120,9 @@ define Device/netgear_wndr4700 NETGEAR_HW_ID := 29763875+128+256 UBINIZE_OPTS := -E 5 SUPPORTED_DEVICES += wndr4700 - DEVICE_COMPAT_VERSION := 2.0 + DEVICE_COMPAT_VERSION := 3.0 DEVICE_COMPAT_MESSAGE := kernel and ubi partitions had to be resized. \ + Network swconfig configuration cannot be upgraded to DSA. \ Upgrade via sysupgrade mechanism is not possible. endef TARGET_DEVICES += netgear_wndr4700 diff --git a/target/linux/apm821xx/patches-6.6/900-powerpc-bootwrapper-force-gzip-as-mkimage-s-compress.patch b/target/linux/apm821xx/patches-6.6/900-powerpc-bootwrapper-force-gzip-as-mkimage-s-compress.patch index 3ea4faf20258e7..dcc82546a29972 100644 --- a/target/linux/apm821xx/patches-6.6/900-powerpc-bootwrapper-force-gzip-as-mkimage-s-compress.patch +++ b/target/linux/apm821xx/patches-6.6/900-powerpc-bootwrapper-force-gzip-as-mkimage-s-compress.patch @@ -18,7 +18,7 @@ Signed-off-by: Christian Lamparter --- a/arch/powerpc/boot/Makefile +++ b/arch/powerpc/boot/Makefile -@@ -276,7 +276,7 @@ compressor-$(CONFIG_KERNEL_LZO) := lzo +@@ -277,7 +277,7 @@ compressor-$(CONFIG_KERNEL_LZO) := lzo # args (to if_changed): 1 = (this rule), 2 = platform, 3 = dts 4=dtb 5=initrd quiet_cmd_wrap = WRAP $@ diff --git a/target/linux/archs38/config-6.6 b/target/linux/archs38/config-6.6 index 6298ce9e462c5c..dab1b855b9cb5d 100644 --- a/target/linux/archs38/config-6.6 +++ b/target/linux/archs38/config-6.6 @@ -47,8 +47,6 @@ CONFIG_BLK_DEV_RAM_COUNT=16 CONFIG_BLK_DEV_RAM_SIZE=4096 CONFIG_BLK_DEV_SD=y CONFIG_BUFFER_HEAD=y -CONFIG_CC_IMPLICIT_FALLTHROUGH="-Wimplicit-fallthrough=5" -CONFIG_CC_NO_ARRAY_BOUNDS=y CONFIG_CLK_HSDK=y CONFIG_CLONE_BACKWARDS=y CONFIG_COMMON_CLK=y @@ -103,7 +101,6 @@ CONFIG_FUNCTION_ALIGNMENT=0 CONFIG_FWNODE_MDIO=y CONFIG_FW_LOADER_PAGED_BUF=y CONFIG_FW_LOADER_SYSFS=y -CONFIG_GCC10_NO_ARRAY_BOUNDS=y CONFIG_GENERIC_ALLOCATOR=y CONFIG_GENERIC_CLOCKEVENTS=y CONFIG_GENERIC_CSUM=y diff --git a/target/linux/armsr/README b/target/linux/armsr/README index b4b9012826a2ca..04f01f8e305228 100644 --- a/target/linux/armsr/README +++ b/target/linux/armsr/README @@ -49,7 +49,7 @@ With a EDKII or U-Boot binary for the QEMU ARM virtual machines, you can use the images in EFI mode: 32-bit: -gunzip -c bin/targets/armsr/armv7/openwrt-armsr-armv7-generic-ext4-combined.img.gz > openwrt-arm-32.img +gunzip -c bin/targets/armsr/armv7/openwrt-armsr-armv7-generic-ext4-combined-efi.img.gz > openwrt-arm-32.img qemu-system-arm -nographic \ -cpu cortex-a15 -machine virt \ -bios bin/targets/armsr/armv7/u-boot-qemu_armv7/u-boot.bin \ @@ -60,7 +60,7 @@ qemu-system-arm -nographic \ -netdev user,id=testwan -net nic,netdev=testwan 64-bit: -gunzip -c bin/targets/armsr/armv8/openwrt-armsr-armv8-generic-ext4-combined.img.gz > openwrt-arm-64.img +gunzip -c bin/targets/armsr/armv8/openwrt-armsr-armv8-generic-ext4-combined-efi.img.gz > openwrt-arm-64.img qemu-system-aarch64 -nographic \ -cpu cortex-a53 -machine virt \ -bios bin/targets/armsr/armv8/u-boot-qemu_armv8/u-boot.bin \ diff --git a/target/linux/armsr/image/Makefile b/target/linux/armsr/image/Makefile index 09c37beeec43ec..79173e67dac1be 100644 --- a/target/linux/armsr/image/Makefile +++ b/target/linux/armsr/image/Makefile @@ -12,7 +12,6 @@ GRUB_TERMINAL_CONFIG = GRUB_CONSOLE_CMDLINE = earlycon ifneq ($(CONFIG_GRUB_CONSOLE),) - GRUB_CONSOLE_CMDLINE += console=tty1 GRUB_TERMINALS += console endif @@ -74,18 +73,18 @@ DEVICE_VARS += GRUB2_VARIANT UBOOT define Device/efi-default IMAGE/rootfs.img := append-rootfs | pad-to $(ROOTFS_PARTSIZE) IMAGE/rootfs.img.gz := append-rootfs | pad-to $(ROOTFS_PARTSIZE) | gzip - IMAGE/combined.img := grub-config efi | combined efi | grub-install efi | append-metadata - IMAGE/combined.img.gz := grub-config efi | combined efi | grub-install efi | gzip | append-metadata - IMAGE/combined.vmdk := grub-config efi | combined efi | grub-install efi | qemu-image vmdk + IMAGE/combined-efi.img := grub-config efi | combined efi | grub-install efi | append-metadata + IMAGE/combined-efi.img.gz := grub-config efi | combined efi | grub-install efi | gzip | append-metadata + IMAGE/combined-efi.vmdk := grub-config efi | combined efi | grub-install efi | qemu-image vmdk ifeq ($(CONFIG_TARGET_IMAGES_GZIP),y) IMAGES-y := rootfs.img.gz - IMAGES-y += combined.img.gz + IMAGES-y += combined-efi.img.gz else IMAGES-y := rootfs.img - IMAGES-y += combined.img + IMAGES-y += combined-efi.img endif ifeq ($(CONFIG_VMDK_IMAGES),y) - IMAGES-y += combined.vmdk + IMAGES-y += combined-efi.vmdk endif KERNEL := kernel-bin KERNEL_INSTALL := 1 diff --git a/target/linux/armsr/patches-6.6/300-printk-always-setup-default-consoles.patch b/target/linux/armsr/patches-6.6/300-printk-always-setup-default-consoles.patch new file mode 100644 index 00000000000000..076bfd21dadeca --- /dev/null +++ b/target/linux/armsr/patches-6.6/300-printk-always-setup-default-consoles.patch @@ -0,0 +1,47 @@ +From 0059efbd0f9c291795078fb4e50722641d525f38 Mon Sep 17 00:00:00 2001 +From: Mathew McBride +Date: Thu, 16 Jan 2025 11:48:44 +1100 +Subject: [PATCH] printk: always setup default (tty0 + stdout / SPCR) consoles + when no console= present + +(This is a hack specific to OpenWrt's armsr target) + +This change resolves a difference in behaviour between arm64 ACPI +and DT systems. +Our usecase is to ensure the system console is always present +regardless of display mode (serial port or screen). + +Both ACPI and DT have mechanisms to setup a serial console from +information passed by firmware (SPCR and stdout-path respectively). + +On ACPI systems, the SPCR table is parsed very early on in the kernel +boot which prevents the screen console (tty0) from appearing if it is +not explicitly set. + +We would like to avoid specifying console= arguments as there are many +possible configurations on the serial side (like ttyS0, ttyAMA0, ttymxc0 +etc.). + +If the kernel does not consume the serial port in SPCR/stdout-path, +then the 'default' settings from the firmware (baud rate etc.) are lost. + +If the system administrator explicitly specifies a console= argument, +then the old behaviour is returned. + +Signed-off-by: Mathew McBride +Link: https://github.com/openwrt/openwrt/pull/17012#issuecomment-2591751115 +--- + kernel/printk/printk.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/kernel/printk/printk.c ++++ b/kernel/printk/printk.c +@@ -3515,7 +3515,7 @@ void register_console(struct console *ne + * Note that a console with tty binding will have CON_CONSDEV + * flag set and will be first in the list. + */ +- if (preferred_console < 0) { ++ if (!console_set_on_cmdline) { + if (hlist_empty(&console_list) || !console_first()->device || + console_first()->flags & CON_BOOT) { + try_enable_default_console(newcon); diff --git a/target/linux/at91/sam9x/config-6.6 b/target/linux/at91/sam9x/config-6.6 index d5cfa5f753933f..2631f0feea15f7 100644 --- a/target/linux/at91/sam9x/config-6.6 +++ b/target/linux/at91/sam9x/config-6.6 @@ -44,8 +44,6 @@ CONFIG_BINFMT_FLAT_ARGVP_ENVP_ON_STACK=y CONFIG_BLK_PM=y CONFIG_BUFFER_HEAD=y CONFIG_CC_HAVE_STACKPROTECTOR_TLS=y -CONFIG_CC_IMPLICIT_FALLTHROUGH="-Wimplicit-fallthrough=5" -CONFIG_CC_NO_ARRAY_BOUNDS=y CONFIG_CLONE_BACKWARDS=y CONFIG_COMMON_CLK=y CONFIG_COMMON_CLK_AT91=y @@ -109,7 +107,6 @@ CONFIG_FWNODE_MDIO=y CONFIG_FW_CACHE=y CONFIG_FW_LOADER_PAGED_BUF=y CONFIG_FW_LOADER_SYSFS=y -CONFIG_GCC10_NO_ARRAY_BOUNDS=y CONFIG_GENERIC_ALLOCATOR=y CONFIG_GENERIC_ATOMIC64=y CONFIG_GENERIC_BUG=y diff --git a/target/linux/at91/sama5/config-6.6 b/target/linux/at91/sama5/config-6.6 index 04eee7a210f354..d04e10f9e15849 100644 --- a/target/linux/at91/sama5/config-6.6 +++ b/target/linux/at91/sama5/config-6.6 @@ -54,8 +54,6 @@ CONFIG_BLK_PM=y CONFIG_BUFFER_HEAD=y CONFIG_CACHE_L2X0=y CONFIG_CC_HAVE_STACKPROTECTOR_TLS=y -CONFIG_CC_IMPLICIT_FALLTHROUGH="-Wimplicit-fallthrough=5" -CONFIG_CC_NO_ARRAY_BOUNDS=y CONFIG_CLONE_BACKWARDS=y CONFIG_CMA=y CONFIG_CMA_ALIGNMENT=8 @@ -181,7 +179,6 @@ CONFIG_FWNODE_MDIO=y CONFIG_FW_CACHE=y CONFIG_FW_LOADER_PAGED_BUF=y CONFIG_FW_LOADER_SYSFS=y -CONFIG_GCC10_NO_ARRAY_BOUNDS=y CONFIG_GENERIC_ALLOCATOR=y CONFIG_GENERIC_BUG=y CONFIG_GENERIC_CLOCKEVENTS=y diff --git a/target/linux/at91/sama7/config-6.6 b/target/linux/at91/sama7/config-6.6 index e3455c5e379f27..c69cbdf7671c0e 100644 --- a/target/linux/at91/sama7/config-6.6 +++ b/target/linux/at91/sama7/config-6.6 @@ -45,8 +45,6 @@ CONFIG_BUFFER_HEAD=y # CONFIG_CACHE_L2X0 is not set CONFIG_CAN=y CONFIG_CC_HAVE_STACKPROTECTOR_TLS=y -CONFIG_CC_IMPLICIT_FALLTHROUGH="-Wimplicit-fallthrough=5" -CONFIG_CC_NO_ARRAY_BOUNDS=y CONFIG_CLONE_BACKWARDS=y CONFIG_CMA=y CONFIG_CMA_ALIGNMENT=9 @@ -162,7 +160,6 @@ CONFIG_FUNCTION_ALIGNMENT=0 CONFIG_FWNODE_MDIO=y CONFIG_FW_LOADER_PAGED_BUF=y CONFIG_FW_LOADER_SYSFS=y -CONFIG_GCC10_NO_ARRAY_BOUNDS=y CONFIG_GENERIC_ALLOCATOR=y CONFIG_GENERIC_BUG=y CONFIG_GENERIC_CLOCKEVENTS=y diff --git a/target/linux/ath79/config-6.6 b/target/linux/ath79/config-6.6 index 92057c343c09d1..c43dbfd7194dad 100644 --- a/target/linux/ath79/config-6.6 +++ b/target/linux/ath79/config-6.6 @@ -14,8 +14,6 @@ CONFIG_AT803X_PHY=y CONFIG_ATH79=y CONFIG_ATH79_WDT=y CONFIG_BLK_MQ_PCI=y -CONFIG_CC_IMPLICIT_FALLTHROUGH="-Wimplicit-fallthrough=5" -CONFIG_CC_NO_ARRAY_BOUNDS=y CONFIG_CEVT_R4K=y CONFIG_CLONE_BACKWARDS=y CONFIG_CMDLINE="rootfstype=squashfs,jffs2" @@ -58,7 +56,6 @@ CONFIG_FUNCTION_ALIGNMENT=0 CONFIG_FWNODE_MDIO=y CONFIG_FW_LOADER_PAGED_BUF=y CONFIG_FW_LOADER_SYSFS=y -CONFIG_GCC10_NO_ARRAY_BOUNDS=y CONFIG_GENERIC_ATOMIC64=y CONFIG_GENERIC_CLOCKEVENTS=y CONFIG_GENERIC_CMOS_UPDATE=y diff --git a/target/linux/ath79/dts/ar7240_tplink_tl-wa.dtsi b/target/linux/ath79/dts/ar7240_tplink_tl-wa.dtsi index 1f46e77423cd24..94d2570c6c1e54 100644 --- a/target/linux/ath79/dts/ar7240_tplink_tl-wa.dtsi +++ b/target/linux/ath79/dts/ar7240_tplink_tl-wa.dtsi @@ -17,7 +17,7 @@ }; ð1 { - nvmem-cells = <&macaddr_uboot_1fc00>; + nvmem-cells = <&macaddr_uboot_1fc00 0>; nvmem-cell-names = "mac-address"; }; diff --git a/target/linux/ath79/dts/ar9132_buffalo_wzr-hp-g300nh.dtsi b/target/linux/ath79/dts/ar9132_buffalo_wzr-hp-g300nh.dtsi index a82546c1c1395e..474d0fa80f74cd 100644 --- a/target/linux/ath79/dts/ar9132_buffalo_wzr-hp-g300nh.dtsi +++ b/target/linux/ath79/dts/ar9132_buffalo_wzr-hp-g300nh.dtsi @@ -145,7 +145,7 @@ #size-cells = <1>; cal_art_11000: calibration@11000 { - reg = <0x11000 0x440>; + reg = <0x11000 0xeb8>; }; macaddr_art_1120c: macaddr@1120c { diff --git a/target/linux/ath79/dts/ar9132_tplink_tl-wa901nd-v2.dts b/target/linux/ath79/dts/ar9132_tplink_tl-wa901nd-v2.dts index ed4ca5297e7f5c..3fcc4073fea630 100644 --- a/target/linux/ath79/dts/ar9132_tplink_tl-wa901nd-v2.dts +++ b/target/linux/ath79/dts/ar9132_tplink_tl-wa901nd-v2.dts @@ -104,7 +104,7 @@ #size-cells = <1>; cal_art_1000: calibration@1000 { - reg = <0x1000 0x440>; + reg = <0x1000 0xeb8>; }; }; }; diff --git a/target/linux/ath79/dts/ar9132_tplink_tl-wr1043nd-v1.dts b/target/linux/ath79/dts/ar9132_tplink_tl-wr1043nd-v1.dts index 8958ddd3a83b3f..847d4d4c47def9 100644 --- a/target/linux/ath79/dts/ar9132_tplink_tl-wr1043nd-v1.dts +++ b/target/linux/ath79/dts/ar9132_tplink_tl-wr1043nd-v1.dts @@ -131,7 +131,7 @@ #size-cells = <1>; cal_art_1000: calibration@1000 { - reg = <0x1000 0x440>; + reg = <0x1000 0xeb8>; }; }; }; diff --git a/target/linux/ath79/dts/ar9132_tplink_tl-wr941-v2.dts b/target/linux/ath79/dts/ar9132_tplink_tl-wr941-v2.dts index d3f189479a8b8e..3ad058e9597350 100644 --- a/target/linux/ath79/dts/ar9132_tplink_tl-wr941-v2.dts +++ b/target/linux/ath79/dts/ar9132_tplink_tl-wr941-v2.dts @@ -153,7 +153,7 @@ #size-cells = <1>; cal_art_1000: calibration@1000 { - reg = <0x1000 0x440>; + reg = <0x1000 0xeb8>; }; }; }; diff --git a/target/linux/ath79/dts/ar9331_teltonika_rut230-v1.dts b/target/linux/ath79/dts/ar9331_teltonika_rut230-v1.dts index c2c54b466295cb..73a6cc52ca59cd 100644 --- a/target/linux/ath79/dts/ar9331_teltonika_rut230-v1.dts +++ b/target/linux/ath79/dts/ar9331_teltonika_rut230-v1.dts @@ -36,6 +36,7 @@ sim-tray { label = "sim-tray"; + linux,input-type = ; linux,code = ; gpios = <&gpio 20 GPIO_ACTIVE_LOW>; debounce-interval = <60>; @@ -68,7 +69,7 @@ }; signal-strength-4 { - label = "green:signal-strength4"; + label = "green:signal-strength-4"; gpios = <&gpio 27 GPIO_ACTIVE_HIGH>; }; diff --git a/target/linux/ath79/dts/ar9342_mikrotik_routerboard-911g-xhpnd.dts b/target/linux/ath79/dts/ar9342_mikrotik_routerboard-911g-xhpnd.dts index 5fa44b4412ca78..655c590f8c9bda 100644 --- a/target/linux/ath79/dts/ar9342_mikrotik_routerboard-911g-xhpnd.dts +++ b/target/linux/ath79/dts/ar9342_mikrotik_routerboard-911g-xhpnd.dts @@ -9,3 +9,7 @@ compatible = "mikrotik,routerboard-911g-xhpnd", "qca,ar9342"; model = "MikroTik RouterBOARD 911G-(2,5)HPnD"; }; + +&ref { + clock-frequency = <25000000>; +}; diff --git a/target/linux/ath79/dts/ar9342_mikrotik_routerboard-911g.dtsi b/target/linux/ath79/dts/ar9342_mikrotik_routerboard-911g.dtsi index 0c98a6634ee4b7..3a8c60456f8f8e 100644 --- a/target/linux/ath79/dts/ar9342_mikrotik_routerboard-911g.dtsi +++ b/target/linux/ath79/dts/ar9342_mikrotik_routerboard-911g.dtsi @@ -146,10 +146,6 @@ }; }; -&ref { - clock-frequency = <40000000>; -}; - &spi { status = "okay"; diff --git a/target/linux/ath79/dts/ar9342_mikrotik_routerboard-912uag-2hpnd.dts b/target/linux/ath79/dts/ar9342_mikrotik_routerboard-912uag-2hpnd.dts index 81d7284b3da1e0..4cf62349f5bbd6 100644 --- a/target/linux/ath79/dts/ar9342_mikrotik_routerboard-912uag-2hpnd.dts +++ b/target/linux/ath79/dts/ar9342_mikrotik_routerboard-912uag-2hpnd.dts @@ -10,6 +10,10 @@ model = "MikroTik RouterBOARD 912UAG-(2,5)HPnD"; }; +&ref { + clock-frequency = <40000000>; +}; + &pcie { status = "okay"; }; diff --git a/target/linux/ath79/dts/qca9531_comfast_cf-ew71-v2.dts b/target/linux/ath79/dts/qca9531_comfast_cf-ew71-v2.dts index 22776465001456..0c1e301c512c8a 100644 --- a/target/linux/ath79/dts/qca9531_comfast_cf-ew71-v2.dts +++ b/target/linux/ath79/dts/qca9531_comfast_cf-ew71-v2.dts @@ -32,13 +32,13 @@ led_wan: wan { function = LED_FUNCTION_WAN; color = ; - gpios = <&gpio 11 GPIO_ACTIVE_LOW>; + gpios = <&gpio 0 GPIO_ACTIVE_LOW>; }; wlan { function = LED_FUNCTION_WLAN; color = ; - gpios = <&gpio 14 GPIO_ACTIVE_LOW>; + gpios = <&gpio 12 GPIO_ACTIVE_LOW>; linux,default-trigger = "phy0tpt"; }; }; diff --git a/target/linux/ath79/dts/qca9557_sophos_ap15c.dts b/target/linux/ath79/dts/qca9557_sophos_ap15c.dts new file mode 100644 index 00000000000000..68d02e97a54a14 --- /dev/null +++ b/target/linux/ath79/dts/qca9557_sophos_ap15c.dts @@ -0,0 +1,159 @@ +// SPDX-License-Identifier: GPL-2.0-or-later OR MIT + +#include "qca955x.dtsi" + +#include +#include +#include + +/ { + compatible = "sophos,ap15c", "qca,qca9557"; + model = "Sophos AP15C"; + + aliases { + led-boot = &led_status_green; + led-failsafe = &led_status_yellow; + led-running = &led_status_green; + led-upgrade = &led_status_yellow; + label-mac-device = ð0; + }; + + chosen { + bootargs = "console=ttyS0,115200n8"; + }; + + keys { + compatible = "gpio-keys"; + + reset { + label = "reset"; + linux,code = ; + gpios = <&gpio 18 GPIO_ACTIVE_LOW>; + debounce-interval = <60>; + }; + }; + + leds { + compatible = "gpio-leds"; + + led_status_green: status_green { + function = LED_FUNCTION_STATUS; + color = ; + gpios = <&gpio 13 GPIO_ACTIVE_LOW>; + default-state = "on"; + }; + + led_status_yellow: status_yellow { + function = LED_FUNCTION_STATUS; + color = ; + gpios = <&gpio 14 GPIO_ACTIVE_LOW>; + }; + }; +}; + +&spi { + status = "okay"; + + flash@0 { + compatible = "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <25000000>; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + partition@0 { + label = "u-boot"; + reg = <0x000000 0x040000>; + read-only; + }; + + partition@40000 { + label = "u-boot-env"; + reg = <0x040000 0x010000>; + }; + + partition@50000 { + label = "art"; + reg = <0x050000 0x010000>; + read-only; + + nvmem-layout { + compatible = "fixed-layout"; + #address-cells = <1>; + #size-cells = <1>; + + cal_art_1000: calibration@1000 { + reg = <0x1000 0x440>; + }; + }; + }; + + partition@60000 { + label = "config"; + reg = <0x060000 0x010000>; + read-only; + + nvmem-layout { + compatible = "fixed-layout"; + #address-cells = <1>; + #size-cells = <1>; + + macaddr_config_201a: macaddr@201a { + reg = <0x201a 0x6>; + }; + }; + }; + + partition@70000 { + compatible = "denx,uimage"; + label = "firmware"; + reg = <0x070000 0xf90000>; + }; + }; + }; +}; + +&mdio0 { + status = "okay"; + + phy-mask = <0x10>; + + phy4: ethernet-phy@4 { + reg = <4>; + eee-broken-100tx; + eee-broken-1000t; + }; +}; + +ð0 { + status = "okay"; + + pll-data = <0xa6000000 0xa0000101 0xa0001313>; + + nvmem-cells = <&macaddr_config_201a>; + nvmem-cell-names = "mac-address"; + + phy-mode = "rgmii-id"; + phy-handle = <&phy4>; + + gmac_config: gmac-config { + device = <&gmac>; + + rgmii-enabled = <1>; + + rxdv-delay = <3>; + rxd-delay = <3>; + txen-delay = <3>; + txd-delay = <3>; + }; +}; + +&wmac { + status = "okay"; + + nvmem-cells = <&cal_art_1000>; + nvmem-cell-names = "calibration"; +}; diff --git a/target/linux/ath79/dts/qca9558_buffalo_wzr-450hp2.dts b/target/linux/ath79/dts/qca9558_buffalo_wzr-450hp2.dts new file mode 100644 index 00000000000000..8f19907dfeea9d --- /dev/null +++ b/target/linux/ath79/dts/qca9558_buffalo_wzr-450hp2.dts @@ -0,0 +1,179 @@ +// SPDX-License-Identifier: GPL-2.0-or-later OR MIT + +#include "qca955x.dtsi" + +#include +#include +#include + +/ { + compatible = "buffalo,wzr-450hp2", "qca,qca9558"; + model = "Buffalo WZR-450HP2/WZR-450HP2D"; + + aliases { + led-boot = &led_status_green; + led-failsafe = &led_status_green; + led-running = &led_status_green; + led-upgrade = &led_status_green; + label-mac-device = ð0; + }; + + leds { + compatible = "gpio-leds"; + + led_status_green: status_green { + function = LED_FUNCTION_STATUS; + color = ; + gpios = <&gpio 20 GPIO_ACTIVE_LOW>; + default-state = "on"; + }; + + led_wlan_green: wlan_green { + function = LED_FUNCTION_WLAN; + color = ; + gpios = <&gpio 18 GPIO_ACTIVE_LOW>; + linux,default-trigger = "phy0tpt"; + }; + + led_wps_green: wps_green { + function = LED_FUNCTION_WPS; + color = ; + gpios = <&gpio 3 GPIO_ACTIVE_LOW>; + }; + }; + + keys { + compatible = "gpio-keys"; + + reset { + label = "Reset button"; + linux,code = ; + gpios = <&gpio 17 GPIO_ACTIVE_LOW>; + debounce-interval = <60>; + }; + + rfkill { + label = "RFKILL button"; + linux,code = ; + gpios = <&gpio 21 GPIO_ACTIVE_LOW>; + debounce-interval = <60>; + }; + }; +}; + +&spi { + status = "okay"; + + flash@0 { + compatible = "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <25000000>; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + partition@0 { + label = "u-boot"; + reg = <0x0 0x40000>; + read-only; + }; + + partition@40000 { + reg = <0x40000 0x10000>; + label = "u-boot-env"; + }; + + partition@50000 { + compatible = "denx,uimage"; + reg = <0x50000 0xf90000>; + label = "firmware"; + }; + + partition@fe0000 { + reg = <0xfe0000 0x10000>; + label = "user_property"; + read-only; + }; + + art: partition@ff0000 { + label = "art"; + reg = <0xff0000 0x10000>; + read-only; + + nvmem-layout { + compatible = "fixed-layout"; + #address-cells = <1>; + #size-cells = <1>; + + macaddr_wan: macaddr@0 { + reg = <0x0 0x6>; + }; + + macaddr_lan: macaddr@6 { + reg = <0x6 0x6>; + }; + + cal_ath9k: cal_ath9k@1000 { + reg = <0x1000 0x440>; + }; + }; + }; + }; + }; +}; + +&mdio0 { + status = "okay"; + + phy0: ethernet-phy@0 { + reg = <0>; + + qca,ar8327-initvals = < + 0x04 0x07600000 /* PORT0 PAD MODE CTRL: RGMII, to eth0 */ + 0x0c 0x00080080 /* PORT6 PAD MODE CTRL: SGMII, to eth1 */ + 0x10 0x81000080 /* POWER ON STRAP */ + 0x50 0xcc35cc35 /* LED_CTRL0 */ + 0x54 0xca35ca35 /* LED_CTRL1 */ + 0x58 0xc935c935 /* LED_CTRL2 */ + 0x5c 0x03ffff00 /* LED_CTRL3 */ + 0x7c 0x0000007e /* PORT0_STATUS */ + 0x94 0x0000007e /* PORT6_STATUS */ + >; + }; +}; + +ð0 { + status = "okay"; + + nvmem-cells = <&macaddr_wan>; + nvmem-cell-names = "mac-address"; + phy-handle = <&phy0>; + pll-data = <0x56000000 0x00000101 0x00001616>; + + gmac-config { + device = <&gmac>; + rgmii-enabled = <1>; + }; +}; + +ð1 { + status = "okay"; + + nvmem-cells = <&macaddr_lan>; + nvmem-cell-names = "mac-address"; + pll-data = <0x03000101 0x00000101 0x00001616>; + + fixed-link { + speed = <1000>; + full-duplex; + }; +}; + +&wmac { + status = "okay"; + + nvmem-cells = <&cal_ath9k>; + nvmem-cell-names = "calibration"; +}; diff --git a/target/linux/ath79/dts/qca9558_linksys_ea4500-v3.dts b/target/linux/ath79/dts/qca9558_linksys_ea4500-v3.dts index 6c799efe33a54e..1da46d72145b10 100644 --- a/target/linux/ath79/dts/qca9558_linksys_ea4500-v3.dts +++ b/target/linux/ath79/dts/qca9558_linksys_ea4500-v3.dts @@ -123,7 +123,7 @@ partition@2c0000 { label = "firmware"; - reg = <0x2c0000 0x5000000>; + reg = <0x2c0000 0x7d40000>; compatible = "fixed-partitions"; #address-cells = <1>; @@ -136,7 +136,7 @@ partition@400000 { label = "ubi"; - reg = <0x400000 0x4c00000>; + reg = <0x400000 0x7940000>; }; /* Original layout for secondary partitions */ @@ -151,11 +151,11 @@ }; */ }; - partition@52c0000 { + /* Original layout for user data partition */ + /* partition@52c0000 { label = "syscfg"; reg = <0x52c0000 0x2d40000>; - read-only; - }; + }; */ }; }; diff --git a/target/linux/ath79/dts/qca9558_mikrotik_routerboard-96x.dtsi b/target/linux/ath79/dts/qca9558_mikrotik_routerboard-96x.dtsi index 684ca8632a4852..4e219d167c1dba 100644 --- a/target/linux/ath79/dts/qca9558_mikrotik_routerboard-96x.dtsi +++ b/target/linux/ath79/dts/qca9558_mikrotik_routerboard-96x.dtsi @@ -44,7 +44,7 @@ usb_power { gpio-export,name = "usb-power"; - gpio-export,output = <0>; + gpio-export,output = <1>; gpios = <&gpio 13 GPIO_ACTIVE_HIGH>; }; }; diff --git a/target/linux/ath79/dts/qca955x_elecom_wab.dtsi b/target/linux/ath79/dts/qca955x_elecom_wab.dtsi index 53bb5b0141254b..43e34c6029182d 100644 --- a/target/linux/ath79/dts/qca955x_elecom_wab.dtsi +++ b/target/linux/ath79/dts/qca955x_elecom_wab.dtsi @@ -8,7 +8,6 @@ / { aliases { - label-mac-device = ð0; led-boot = &led_status; led-failsafe = &led_status; led-upgrade = &led_status; @@ -108,9 +107,6 @@ phy-mode = "rgmii-rxid"; pll-data = <0xae000000 0x80000101 0x80001313>; - nvmem-cells = <&macaddr_uboot_ethaddr 0>; - nvmem-cell-names = "mac-address"; - gmac-config { device = <&gmac>; @@ -148,8 +144,8 @@ wifi@0,0 { compatible = "qcom,ath10k"; reg = <0x0000 0 0 0 0>; - nvmem-cells = <&cal_art_5000>, <&macaddr_uboot_ethaddr 1>; - nvmem-cell-names = "calibration", "mac-address"; + nvmem-cells = <&cal_art_5000>; + nvmem-cell-names = "calibration"; }; }; @@ -173,14 +169,9 @@ }; partition@40000 { - compatible = "u-boot,env"; label = "u-boot-env"; reg = <0x40000 0x10000>; read-only; - - macaddr_uboot_ethaddr: ethaddr { - #nvmem-cell-cells = <1>; - }; }; partition@50000 { @@ -261,6 +252,6 @@ &wmac { status = "okay"; - nvmem-cells = <&cal_art_1000>, <&macaddr_uboot_ethaddr 0>; - nvmem-cell-names = "calibration", "mac-address"; + nvmem-cells = <&cal_art_1000>; + nvmem-cell-names = "calibration"; }; diff --git a/target/linux/ath79/dts/qca9563_kuwfi_n650.dts b/target/linux/ath79/dts/qca9563_kuwfi_n650.dts new file mode 100644 index 00000000000000..03801dabb3ed6c --- /dev/null +++ b/target/linux/ath79/dts/qca9563_kuwfi_n650.dts @@ -0,0 +1,178 @@ +// SPDX-License-Identifier: GPL-2.0-or-later OR MIT + +#include "qca956x.dtsi" + +#include +#include +#include +#include + +/ { + model = "KuWFi N650"; + compatible = "kuwfi,n650", "qca,qca9563"; + + aliases { + label-mac-device = ð0; + led-boot = &led_green; + led-running = &led_green; + led-failsafe = &led_blue; + led-upgrade = &led_blue; + }; + + virtual_flash { + compatible = "mtd-concat"; + devices = <&fwconcat0 &fwconcat1>; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + partition@0 { + reg = <0x0 0x0>; + label = "firmware"; + compatible = "openwrt,uimage", "denx,uimage"; + openwrt,ih-magic = ; + }; + }; + }; + + keys { + compatible = "gpio-keys"; + + reset { + label = "Reset button"; + linux,code = ; + gpios = <&gpio 2 GPIO_ACTIVE_LOW>; + debounce-interval = <60>; + }; + }; + + leds { + compatible = "gpio-leds"; + + led_blue: blue { + function = LED_FUNCTION_DEBUG; + color = ; + gpios = <&gpio 7 GPIO_ACTIVE_LOW>; + }; + + led_green: green { + function = LED_FUNCTION_POWER; + color = ; + gpios = <&gpio 8 GPIO_ACTIVE_LOW>; + }; + }; +}; + +&spi { + status = "okay"; + + flash@0 { + compatible = "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <25000000>; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + partition@0 { + label = "u-boot"; + reg = <0x000000 0x030000>; + read-only; + }; + + partition@30000 { + label = "u-boot-env"; + reg = <0x030000 0x010000>; + }; + + fwconcat0: partition@40000 { + label = "fwconcat0"; + reg = <0x040000 0xd40000>; + }; + + partition@d80000 { + label = "loader"; + reg = <0xd80000 0x10000>; + }; + + fwconcat1: partition@d90000 { + label = "fwconcat1"; + reg = <0xd90000 0x160000>; + }; + + partition@ef0000 { + label = "log"; + reg = <0xef0000 0x0f0000>; + read-only; + }; + + partition@fe0000 { + label = "nvram"; + reg = <0xfe0000 0x010000>; + read-only; + }; + + partition@ff0000 { + label = "art"; + reg = <0xff0000 0x10000>; + read-only; + + nvmem-layout { + compatible = "fixed-layout"; + #address-cells = <1>; + #size-cells = <1>; + + macaddr_art_0: macaddr@0 { + compatible = "mac-base"; + reg = <0x0 0x6>; + #nvmem-cell-cells = <1>; + }; + + precal_art_5000: pre-calibration@5000 { + reg = <0x5000 0x2f20>; + }; + }; + }; + }; + }; +}; + +&mdio0 { + status = "okay"; + + phy0: ethernet-phy@0 { + reg = <0>; + phy-mode = "sgmii"; + reset-gpios = <&gpio 11 GPIO_ACTIVE_LOW>; + qca,mib-poll-interval = <500>; + + qca,ar8327-initvals = < + 0x04 0x00080080 /* PORT0 PAD MODE CTRL */ + 0x7c 0x0000007e /* PORT0_STATUS */ + >; + }; +}; + +ð0 { + status = "okay"; + + nvmem-cells = <&macaddr_art_0 0>; + nvmem-cell-names = "mac-address"; + phy-handle = <&phy0>; + phy-mode = "sgmii"; +}; + +&pcie { + status = "okay"; + + wifi@0,0 { + compatible = "pci168c,0056"; + reg = <0x0000 0 0 0 0>; + nvmem-cells = <&precal_art_5000>, <&macaddr_art_0 1>; + nvmem-cell-names = "pre-calibration", "mac-address"; + }; +}; diff --git a/target/linux/ath79/dts/qca9563_tplink_archer-c6-v2.dts b/target/linux/ath79/dts/qca9563_tplink_archer-c6-v2.dts index 66ae2d1ffd52c7..36281f4caa137e 100644 --- a/target/linux/ath79/dts/qca9563_tplink_archer-c6-v2.dts +++ b/target/linux/ath79/dts/qca9563_tplink_archer-c6-v2.dts @@ -89,6 +89,7 @@ reg = <0x0000 0 0 0 0>; nvmem-cells = <&precal_art_5000>, <&macaddr_info_8 (-1)>; nvmem-cell-names = "pre-calibration", "mac-address"; + qcom,ath10k-calibration-variant = "TP-Link-Archer-c6-v2"; }; }; diff --git a/target/linux/ath79/dts/qca9563_tplink_cpe710-v1.dts b/target/linux/ath79/dts/qca9563_tplink_cpe710-v1.dts index 6d1b58f95fae48..31e04232ab6c5a 100644 --- a/target/linux/ath79/dts/qca9563_tplink_cpe710-v1.dts +++ b/target/linux/ath79/dts/qca9563_tplink_cpe710-v1.dts @@ -1,151 +1,13 @@ // SPDX-License-Identifier: GPL-2.0-or-later OR MIT -#include "qca956x.dtsi" - -#include -#include -#include +#include "qca9563_tplink_cpe710.dtsi" / { model = "TP-Link CPE710 v1"; compatible = "tplink,cpe710-v1", "qca,qca9563"; - - aliases { - label-mac-device = ð0; - led-boot = &led_lan; - led-failsafe = &led_lan; - led-upgrade = &led_lan; - }; - - leds { - compatible = "gpio-leds"; - - led_lan: lan { - function = LED_FUNCTION_LAN; - color = ; - gpios = <&gpio 5 GPIO_ACTIVE_LOW>; - }; - - wlan5g { - label = "blue:wlan5g"; - gpios = <&gpio 1 GPIO_ACTIVE_LOW>; - linux,default-trigger = "phy0tpt"; - }; - }; - - keys { - compatible = "gpio-keys"; - - reset { - label = "Reset button"; - linux,code = ; - gpios = <&gpio 2 GPIO_ACTIVE_LOW>; - debounce-interval = <60>; - }; - }; -}; - -&pcie { - status = "okay"; - - wifi@0,0 { - compatible = "qcom,ath10k"; - reg = <0x0000 0 0 0 0>; - nvmem-cells = <&precal_art_5000>, <&macaddr_info_8>; - nvmem-cell-names = "pre-calibration", "mac-address"; - }; -}; - -&spi { - status = "okay"; - - flash@0 { - compatible = "jedec,spi-nor"; - reg = <0>; - spi-max-frequency = <40000000>; - - partitions { - compatible = "fixed-partitions"; - #address-cells = <1>; - #size-cells = <1>; - - partition@0 { - label = "u-boot"; - reg = <0x000000 0x040000>; - read-only; - }; - - partition@40000 { - label = "u-boot-env"; - reg = <0x040000 0x010000>; - }; - - partition@50000 { - label = "partition-table"; - reg = <0x050000 0x010000>; - read-only; - }; - - info: partition@60000 { - label = "info"; - reg = <0x060000 0x010000>; - read-only; - - nvmem-layout { - compatible = "fixed-layout"; - #address-cells = <1>; - #size-cells = <1>; - - macaddr_info_8: macaddr@8 { - reg = <0x8 0x6>; - }; - }; - }; - - partition@70000 { - compatible = "denx,uimage"; - label = "firmware"; - reg = <0x070000 0xf50000>; - }; - - partition@fc0000 { - label = "config"; - reg = <0xfc0000 0x030000>; - read-only; - }; - - partition@ff0000 { - label = "art"; - reg = <0xff0000 0x010000>; - read-only; - - nvmem-layout { - compatible = "fixed-layout"; - #address-cells = <1>; - #size-cells = <1>; - - precal_art_5000: pre-calibration@5000 { - reg = <0x5000 0x2f20>; - }; - }; - }; - }; - }; -}; - -&pinmux { - mdio_pins: mdio_pins { - /* GPIO 10 as MDIO(0x20), GPIO 8 as MDC(0x21) */ - pinctrl-single,bits = <0x8 0x00200021 0x00ff00ff>; - }; }; &mdio0 { - status = "okay"; - - pinctrl-names = "default"; - pinctrl-0 = <&mdio_pins>; - phy4: ethernet-phy@4 { reg = <4>; reset-gpios = <&gpio 11 GPIO_ACTIVE_LOW>; @@ -153,17 +15,6 @@ }; ð0 { - status = "okay"; - phy-handle = <&phy4>; phy-mode = "sgmii"; - - nvmem-cells = <&macaddr_info_8>; - nvmem-cell-names = "mac-address"; - - qca956x-serdes-fixup; - - gmac-config { - device = <&gmac>; - }; }; diff --git a/target/linux/ath79/dts/qca9563_tplink_cpe710-v2.dts b/target/linux/ath79/dts/qca9563_tplink_cpe710-v2.dts new file mode 100644 index 00000000000000..fe277fc549d5b5 --- /dev/null +++ b/target/linux/ath79/dts/qca9563_tplink_cpe710-v2.dts @@ -0,0 +1,20 @@ +// SPDX-License-Identifier: GPL-2.0-or-later OR MIT + +#include "qca9563_tplink_cpe710.dtsi" + +/ { + model = "TP-Link CPE710 v2"; + compatible = "tplink,cpe710-v2", "qca,qca9563"; +}; + +&mdio0 { + phy0: ethernet-phy@0 { + reg = <0>; + reset-gpios = <&gpio 11 GPIO_ACTIVE_LOW>; + }; +}; + +ð0 { + phy-handle = <&phy0>; + phy-mode = "sgmii"; +}; diff --git a/target/linux/ath79/dts/qca9563_tplink_cpe710.dtsi b/target/linux/ath79/dts/qca9563_tplink_cpe710.dtsi new file mode 100644 index 00000000000000..9de36f3b6635f5 --- /dev/null +++ b/target/linux/ath79/dts/qca9563_tplink_cpe710.dtsi @@ -0,0 +1,160 @@ +// SPDX-License-Identifier: GPL-2.0-or-later OR MIT + +#include "qca956x.dtsi" + +#include +#include +#include + +/ { + aliases { + led-boot = &led_lan; + led-failsafe = &led_lan; + led-upgrade = &led_lan; + label-mac-device = ð0; + }; + + leds { + compatible = "gpio-leds"; + + led_lan: lan { + function = LED_FUNCTION_LAN; + color = ; + gpios = <&gpio 5 GPIO_ACTIVE_LOW>; + }; + + wlan5g { + color = ; + function = LED_FUNCTION_WLAN_5GHZ; + gpios = <&gpio 1 GPIO_ACTIVE_LOW>; + linux,default-trigger = "phy0tpt"; + }; + }; + + keys { + compatible = "gpio-keys"; + + reset { + label = "Reset button"; + linux,code = ; + gpios = <&gpio 2 GPIO_ACTIVE_LOW>; + debounce-interval = <60>; + }; + }; +}; + +&pcie { + status = "okay"; + + wifi@0,0 { + compatible = "qcom,ath10k"; + reg = <0x0000 0 0 0 0>; + nvmem-cells = <&precal_art_5000>, <&macaddr_info_8>; + nvmem-cell-names = "pre-calibration", "mac-address"; + }; +}; + +&spi { + status = "okay"; + + flash@0 { + compatible = "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <40000000>; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + partition@0 { + label = "u-boot"; + reg = <0x000000 0x040000>; + read-only; + }; + + partition@40000 { + label = "u-boot-env"; + reg = <0x040000 0x010000>; + read-only; + }; + + partition@50000 { + label = "partition-table"; + reg = <0x050000 0x010000>; + read-only; + }; + + partition@60000 { + label = "info"; + reg = <0x060000 0x010000>; + read-only; + + nvmem-layout { + compatible = "fixed-layout"; + #address-cells = <1>; + #size-cells = <1>; + + macaddr_info_8: macaddr@8 { + reg = <0x8 0x6>; + }; + }; + }; + + partition@70000 { + compatible = "denx,uimage"; + label = "firmware"; + reg = <0x070000 0xf50000>; + }; + + partition@fc0000 { + label = "config"; + reg = <0xfc0000 0x030000>; + read-only; + }; + + partition@ff0000 { + label = "art"; + reg = <0xff0000 0x010000>; + read-only; + + nvmem-layout { + compatible = "fixed-layout"; + #address-cells = <1>; + #size-cells = <1>; + + precal_art_5000: pre-calibration@5000 { + reg = <0x5000 0x2f20>; + }; + }; + }; + }; + }; +}; + +&pinmux { + mdio_pins: mdio_pins { + /* GPIO 10 as MDIO(0x20), GPIO 8 as MDC(0x21) */ + pinctrl-single,bits = <0x8 0x00200021 0x00ff00ff>; + }; +}; + +&mdio0 { + status = "okay"; + + pinctrl-names = "default"; + pinctrl-0 = <&mdio_pins>; +}; + +ð0 { + status = "okay"; + + nvmem-cells = <&macaddr_info_8>; + nvmem-cell-names = "mac-address"; + + qca956x-serdes-fixup; + + gmac-config { + device = <&gmac>; + }; +}; diff --git a/target/linux/ath79/dts/qca9563_xiaomi_aiot-ac2350.dts b/target/linux/ath79/dts/qca9563_xiaomi_aiot-ac2350.dts index cff567e497f413..69d75e9b553743 100644 --- a/target/linux/ath79/dts/qca9563_xiaomi_aiot-ac2350.dts +++ b/target/linux/ath79/dts/qca9563_xiaomi_aiot-ac2350.dts @@ -201,5 +201,6 @@ reg = <0x0000 0 0 0 0>; nvmem-cells = <&precal_art_5000>; nvmem-cell-names = "pre-calibration"; + qcom,ath10k-calibration-variant = "Xiaomi-AIoT-AC2350"; }; }; diff --git a/target/linux/ath79/files/drivers/gpio/gpio-latch-mikrotik.c b/target/linux/ath79/files/drivers/gpio/gpio-latch-mikrotik.c index 6e3f0f9690e75c..a0759fe9e37172 100644 --- a/target/linux/ath79/files/drivers/gpio/gpio-latch-mikrotik.c +++ b/target/linux/ath79/files/drivers/gpio/gpio-latch-mikrotik.c @@ -28,11 +28,6 @@ struct gpio_latch_chip { struct gpio_desc *gpios[GPIO_LATCH_LINES]; }; -static inline struct gpio_latch_chip *to_gpio_latch_chip(struct gpio_chip *gc) -{ - return container_of(gc, struct gpio_latch_chip, gc); -} - static void gpio_latch_lock(struct gpio_latch_chip *glc, bool enable) { mutex_lock(&glc->mutex); @@ -58,7 +53,7 @@ static void gpio_latch_unlock(struct gpio_latch_chip *glc, bool disable) static int gpio_latch_get(struct gpio_chip *gc, unsigned offset) { - struct gpio_latch_chip *glc = to_gpio_latch_chip(gc); + struct gpio_latch_chip *glc = gpiochip_get_data(gc); int ret; gpio_latch_lock(glc, false); @@ -71,7 +66,7 @@ gpio_latch_get(struct gpio_chip *gc, unsigned offset) static void gpio_latch_set(struct gpio_chip *gc, unsigned offset, int value) { - struct gpio_latch_chip *glc = to_gpio_latch_chip(gc); + struct gpio_latch_chip *glc = gpiochip_get_data(gc); bool enable_latch = false; bool disable_latch = false; @@ -88,7 +83,7 @@ gpio_latch_set(struct gpio_chip *gc, unsigned offset, int value) static int gpio_latch_direction_output(struct gpio_chip *gc, unsigned offset, int value) { - struct gpio_latch_chip *glc = to_gpio_latch_chip(gc); + struct gpio_latch_chip *glc = gpiochip_get_data(gc); bool enable_latch = false; bool disable_latch = false; int ret; @@ -173,7 +168,6 @@ static struct platform_driver gpio_latch_driver = { .probe = gpio_latch_probe, .driver = { .name = GPIO_LATCH_DRIVER_NAME, - .owner = THIS_MODULE, .of_match_table = gpio_latch_match, }, }; diff --git a/target/linux/ath79/files/drivers/gpio/gpio-rb91x-key.c b/target/linux/ath79/files/drivers/gpio/gpio-rb91x-key.c index b2c8e633051f52..d83b690afeccfd 100644 --- a/target/linux/ath79/files/drivers/gpio/gpio-rb91x-key.c +++ b/target/linux/ath79/files/drivers/gpio/gpio-rb91x-key.c @@ -41,14 +41,9 @@ struct gpio_rb91x_key { struct gpio_desc *gpio; }; -static inline struct gpio_rb91x_key *to_gpio_rb91x_key(struct gpio_chip *gc) -{ - return container_of(gc, struct gpio_rb91x_key, gc); -} - static int gpio_rb91x_key_get(struct gpio_chip *gc, unsigned offset) { - struct gpio_rb91x_key *drvdata = to_gpio_rb91x_key(gc); + struct gpio_rb91x_key *drvdata = gpiochip_get_data(gc); struct gpio_desc *gpio = drvdata->gpio; int val, bak_val; @@ -97,7 +92,7 @@ static int gpio_rb91x_key_direction_input(struct gpio_chip *gc, unsigned offset) static void gpio_rb91x_key_set(struct gpio_chip *gc, unsigned offset, int value) { - struct gpio_rb91x_key *drvdata = to_gpio_rb91x_key(gc); + struct gpio_rb91x_key *drvdata = gpiochip_get_data(gc); struct gpio_desc *gpio = drvdata->gpio; mutex_lock(&drvdata->mutex); @@ -187,7 +182,6 @@ static struct platform_driver gpio_rb91x_key_driver = { .probe = gpio_rb91x_key_probe, .driver = { .name = GPIO_RB91X_KEY_DRIVER_NAME, - .owner = THIS_MODULE, .of_match_table = gpio_rb91x_key_match, }, }; diff --git a/target/linux/ath79/files/drivers/mtd/nand/raw/ar934x_nand.c b/target/linux/ath79/files/drivers/mtd/nand/raw/ar934x_nand.c index d0d9e2090ba802..029142ca618abd 100644 --- a/target/linux/ath79/files/drivers/mtd/nand/raw/ar934x_nand.c +++ b/target/linux/ath79/files/drivers/mtd/nand/raw/ar934x_nand.c @@ -1478,7 +1478,6 @@ static struct platform_driver ar934x_nfc_driver = { .remove = ar934x_nfc_remove, .driver = { .name = AR934X_NFC_DRIVER_NAME, - .owner = THIS_MODULE, .of_match_table = ar934x_nfc_match, }, }; diff --git a/target/linux/ath79/files/drivers/mtd/nand/raw/rb91x_nand.c b/target/linux/ath79/files/drivers/mtd/nand/raw/rb91x_nand.c index 092cd85d82e117..cf2809bfa36678 100644 --- a/target/linux/ath79/files/drivers/mtd/nand/raw/rb91x_nand.c +++ b/target/linux/ath79/files/drivers/mtd/nand/raw/rb91x_nand.c @@ -356,7 +356,6 @@ static struct platform_driver rb91x_nand_driver = { .remove = rb91x_nand_remove, .driver = { .name = "rb91x-nand", - .owner = THIS_MODULE, .of_match_table = rb91x_nand_match, }, }; diff --git a/target/linux/ath79/generic/base-files/etc/board.d/01_leds b/target/linux/ath79/generic/base-files/etc/board.d/01_leds index 0e5731dd743186..6409adb78ad825 100644 --- a/target/linux/ath79/generic/base-files/etc/board.d/01_leds +++ b/target/linux/ath79/generic/base-files/etc/board.d/01_leds @@ -222,7 +222,8 @@ openmesh,mr900-v1|\ openmesh,mr900-v2|\ openmesh,mr1750-v1|\ openmesh,mr1750-v2|\ -tplink,cpe710-v1) +tplink,cpe710-v1|\ +tplink,cpe710-v2) ucidef_set_led_netdev "lan" "LAN" "blue:lan" "eth0" ;; compex,wpj344-16m|\ diff --git a/target/linux/ath79/generic/base-files/etc/board.d/02_network b/target/linux/ath79/generic/base-files/etc/board.d/02_network index 8474c1c4c2df00..dedbaf05b8014a 100644 --- a/target/linux/ath79/generic/base-files/etc/board.d/02_network +++ b/target/linux/ath79/generic/base-files/etc/board.d/02_network @@ -76,6 +76,7 @@ ath79_setup_interfaces() ruckus,zf7351|\ siemens,ws-ap3610|\ sophos,ap15|\ + sophos,ap15c|\ sophos,ap55|\ sophos,ap55c|\ sophos,ap100|\ @@ -88,6 +89,7 @@ ath79_setup_interfaces() tplink,cpe610-v1|\ tplink,cpe610-v2|\ tplink,cpe710-v1|\ + tplink,cpe710-v2|\ tplink,eap225-outdoor-v1|\ tplink,eap225-outdoor-v3|\ tplink,eap225-v1|\ @@ -211,6 +213,10 @@ ath79_setup_interfaces() ucidef_add_switch "switch0" \ "0@eth1" "1:lan" "2:lan" "3:lan" "4:lan" "5:wan" "6@eth0" ;; + buffalo,wzr-450hp2) + ucidef_add_switch "switch0" \ + "6@eth1" "1:lan" "2:lan" "3:lan" "4:lan" "5:wan" "0@eth0" + ;; buffalo,wzr-600dhp|\ buffalo,wzr-hp-ag300h|\ tplink,archer-c25-v1|\ @@ -399,6 +405,10 @@ ath79_setup_interfaces() ucidef_add_switch "switch0" \ "0@eth0" "1:lan:2" "4:lan:1" ;; + kuwfi,n650) + ucidef_add_switch "switch0" \ + "0@eth0" "2:lan:1" "3:lan:2" + ;; letv,lba-047-ch) ucidef_set_interface_wan "eth0" ucidef_add_switch "switch0" \ @@ -715,6 +725,9 @@ ath79_setup_macs() lan_mac=$(mtd_get_mac_ascii devdata "lanmac") wan_mac=$(mtd_get_mac_ascii devdata "wanmac") ;; + elecom,wab-i1750-ps|\ + elecom,wab-s1167-ps|\ + elecom,wab-s600-ps|\ engenius,ecb1200|\ engenius,ecb1750) lan_mac=$(mtd_get_mac_ascii u-boot-env ethaddr) diff --git a/target/linux/ath79/generic/base-files/etc/hotplug.d/ieee80211/10_fix_wifi_mac b/target/linux/ath79/generic/base-files/etc/hotplug.d/ieee80211/10_fix_wifi_mac index 6676e4d509873f..5155d240a825ac 100644 --- a/target/linux/ath79/generic/base-files/etc/hotplug.d/ieee80211/10_fix_wifi_mac +++ b/target/linux/ath79/generic/base-files/etc/hotplug.d/ieee80211/10_fix_wifi_mac @@ -42,6 +42,16 @@ case "$board" in [ "$PHYNBR" -eq 1 ] && \ mtd_get_mac_ascii bdcfg "wlanmac" > /sys${DEVPATH}/macaddress ;; + elecom,wab-i1750-ps|\ + elecom,wab-s1167-ps|\ + elecom,wab-s600-ps) + # set the 5G MAC address (= ethaddr + 1) + [ "$PHYNBR" -eq 0 ] && \ + macaddr_add "$(mtd_get_mac_ascii u-boot-env ethaddr)" 1 > /sys${DEVPATH}/macaddress + # set the 2.4G MAC address (= ethaddr) + [ "$PHYNBR" -eq 1 ] && \ + mtd_get_mac_ascii u-boot-env "ethaddr" > /sys${DEVPATH}/macaddress + ;; engenius,ecb1200|\ engenius,ecb1750) [ "$PHYNBR" -eq 0 ] && \ diff --git a/target/linux/ath79/image/Makefile b/target/linux/ath79/image/Makefile index 5647200b4ba04c..1918a8a4318dfb 100644 --- a/target/linux/ath79/image/Makefile +++ b/target/linux/ath79/image/Makefile @@ -4,7 +4,7 @@ include $(INCLUDE_DIR)/image.mk KERNEL_LOADADDR = 0x80060000 DEVICE_VARS += LOADER_FLASH_OFFS LOADER_TYPE -DEVICE_VARS += LOADER_FLASH_MAX LOADER_KERNEL_MAGIC +DEVICE_VARS += LOADER_FLASH_MAX LOADER_KERNEL_MAGIC LZMA_TEXT_START DEVICE_VARS += NETGEAR_BOARD_ID NETGEAR_HW_ID DEVICE_VARS += RAS_BOARD RAS_ROOTFS_SIZE RAS_VERSION DEVICE_VARS += SEAMA_SIGNATURE SEAMA_MTDBLOCK @@ -14,6 +14,7 @@ define Build/loader-common $(MAKE) -C lzma-loader \ PKG_BUILD_DIR="$@.src" \ TARGET_DIR="$(dir $@)" LOADER_NAME="$(notdir $@)" \ + LZMA_TEXT_START=$(LZMA_TEXT_START) \ $(1) compile loader.$(LOADER_TYPE) mv "$@.$(LOADER_TYPE)" "$@" rm -rf $@.src @@ -74,6 +75,7 @@ define Device/Default LOADER_FLASH_MAX := LOADER_FLASH_OFFS := LOADER_TYPE := + LZMA_TEXT_START := 0x81800000 COMPILE := IMAGES := sysupgrade.bin IMAGE/sysupgrade.bin = append-kernel | pad-to $$$$(BLOCKSIZE) | \ diff --git a/target/linux/ath79/image/common-nec.mk b/target/linux/ath79/image/common-nec.mk index 7981a72d8eed5c..23671e215de8d1 100644 --- a/target/linux/ath79/image/common-nec.mk +++ b/target/linux/ath79/image/common-nec.mk @@ -8,6 +8,7 @@ endef define Device/nec-netbsd-aterm DEVICE_VENDOR := NEC LOADER_TYPE := bin + LZMA_TEXT_START := 0x82800000 KERNEL := kernel-bin | append-dtb | lzma | loader-kernel | uImage none KERNEL_INITRAMFS := kernel-bin | append-dtb | lzma | loader-kernel | uImage none ARTIFACTS := uboot.bin diff --git a/target/linux/ath79/image/generic-tp-link.mk b/target/linux/ath79/image/generic-tp-link.mk index 643de76f7c2ba7..9c1cf90a9196ca 100644 --- a/target/linux/ath79/image/generic-tp-link.mk +++ b/target/linux/ath79/image/generic-tp-link.mk @@ -104,7 +104,7 @@ define Device/tplink_archer-c6-v2 DEVICE_MODEL := Archer C6 DEVICE_VARIANT := v2 (EU/RU/JP) TPLINK_BOARD_ID := ARCHER-C6-V2 - DEVICE_PACKAGES := kmod-ath10k-ct ath10k-firmware-qca9888-ct + DEVICE_PACKAGES := kmod-ath10k-ct ath10k-firmware-qca9888-ct -ath10k-board-qca9888 ipq-wifi-tplink_archer-c6-v2 endef TARGET_DEVICES += tplink_archer-c6-v2 @@ -391,6 +391,17 @@ define Device/tplink_cpe710-v1 endef TARGET_DEVICES += tplink_cpe710-v1 +define Device/tplink_cpe710-v2 + $(Device/tplink-safeloader-uimage) + SOC := qca9563 + IMAGE_SIZE := 15680k + DEVICE_MODEL := CPE710 + DEVICE_VARIANT := v2 + DEVICE_PACKAGES := kmod-ath10k-ct ath10k-firmware-qca9888-ct + TPLINK_BOARD_ID := CPE710V2 +endef +TARGET_DEVICES += tplink_cpe710-v2 + define Device/tplink-eap2x5 $(Device/tplink-safeloader) LOADER_TYPE := elf diff --git a/target/linux/ath79/image/generic.mk b/target/linux/ath79/image/generic.mk index c075f050db2298..e7aed14bd3e7ab 100644 --- a/target/linux/ath79/image/generic.mk +++ b/target/linux/ath79/image/generic.mk @@ -759,6 +759,18 @@ define Device/buffalo_wzr-hp-g450h endef TARGET_DEVICES += buffalo_wzr-hp-g450h +define Device/buffalo_wzr-450hp2 + $(Device/buffalo_common) + SOC := qca9558 + DEVICE_MODEL := WZR-450HP2 + DEVICE_ALT0_VENDOR := Buffalo + DEVICE_ALT0_MODEL := WZR-450HP2D + BUFFALO_PRODUCT := WZR-450HP2 + IMAGE_SIZE := 15936k + SUPPORTED_DEVICES += wzr-450hp2 +endef +TARGET_DEVICES += buffalo_wzr-450hp2 + define Device/comfast_cf-e110n-v2 SOC := qca9533 DEVICE_VENDOR := COMFAST @@ -1963,6 +1975,25 @@ define Device/kuwfi_c910 endef TARGET_DEVICES += kuwfi_c910 +define Device/kuwfi_n650 + $(Device/loader-okli-uimage) + SOC := qca9563 + DEVICE_VENDOR := KuWFi + DEVICE_MODEL := N650 + DEVICE_PACKAGES += kmod-ath10k-ct ath10k-firmware-qca9888-ct + FACTORY_SIZE := 13632k + LOADER_FLASH_OFFS := 0x40000 + KERNEL := kernel-bin | append-dtb | lzma | uImage lzma -M 0x4f4b4c49 + IMAGE_SIZE := 15040k + IMAGES += factory.bin + IMAGE/factory.bin := append-kernel | pad-to $$$$(BLOCKSIZE) | \ + append-rootfs | pad-rootfs | check-size | pad-to 13568k | \ + append-loader-okli-uimage $(1) | pad-to 64k | check-size $$$$(FACTORY_SIZE) + ARTIFACTS := loader.bin + ARTIFACT/loader.bin := append-loader-okli-uimage $(1) | pad-to 64k +endef +TARGET_DEVICES += kuwfi_n650 + define Device/letv_lba-047-ch $(Device/loader-okli-uimage) SOC := qca9531 @@ -2972,6 +3003,14 @@ define Device/sophos_ap15 endef TARGET_DEVICES += sophos_ap15 +define Device/sophos_ap15c + SOC := qca9557 + DEVICE_VENDOR := Sophos + DEVICE_MODEL := AP15C + IMAGE_SIZE := 15936k +endef +TARGET_DEVICES += sophos_ap15c + define Device/sophos_ap55 SOC := qca9558 DEVICE_VENDOR := Sophos @@ -3224,7 +3263,7 @@ define Device/xiaomi_aiot-ac2350 SOC := qca9563 DEVICE_VENDOR := Xiaomi DEVICE_MODEL := AIoT AC2350 - DEVICE_PACKAGES := kmod-ath10k-ct ath10k-firmware-qca9984-ct + DEVICE_PACKAGES := kmod-ath10k-ct ath10k-firmware-qca9984-ct ipq-wifi-xiaomi_aiot-ac2350 IMAGE_SIZE := 14336k endef TARGET_DEVICES += xiaomi_aiot-ac2350 diff --git a/target/linux/ath79/image/lzma-loader/src/board.c b/target/linux/ath79/image/lzma-loader/src/board.c index 14451085085ce1..294ca307d5d797 100644 --- a/target/linux/ath79/image/lzma-loader/src/board.c +++ b/target/linux/ath79/image/lzma-loader/src/board.c @@ -209,7 +209,7 @@ static inline void huawei_ap_init(void) #if defined(CONFIG_BOARD_HUAWEI_AP5030DN) WRITEREG(gpiobase + AR934X_GPIO_REG_OUT_FUNC3, reg | (QCA955X_GPIO_OUTSEL_CLK_OBS5 << 24)); -#else if defined(CONFIG_BOARD_HUAWEI_AP6010DN) +#elif defined(CONFIG_BOARD_HUAWEI_AP6010DN) WRITEREG(gpiobase + AR934X_GPIO_REG_OUT_FUNC3, reg | (AR934X_GPIO_OUTSEL_CLK_OBS4 << 24)); #endif diff --git a/target/linux/ath79/image/nand.mk b/target/linux/ath79/image/nand.mk index a3bdedaf6d53d5..68cb5431872f23 100644 --- a/target/linux/ath79/image/nand.mk +++ b/target/linux/ath79/image/nand.mk @@ -281,6 +281,12 @@ TARGET_DEVICES += glinet_gl-x1200-nor define Device/linksys_ea4500-v3 SOC := qca9558 + DEVICE_COMPAT_VERSION := 1.1 + DEVICE_COMPAT_MESSAGE := Partition table has been changed. Please \ + install kmod-mtd-rw and erase mtd8 (syscfg) before upgrade \ + to keep configures, or forcibly flash factory image to mtd5 \ + (firmware) partition with mtd tool to discard configures but \ + claim additional space immediately. DEVICE_VENDOR := Linksys DEVICE_MODEL := EA4500 DEVICE_VARIANT := v3 @@ -288,7 +294,7 @@ define Device/linksys_ea4500-v3 BLOCKSIZE := 128k PAGESIZE := 2048 KERNEL_SIZE := 4096k - IMAGE_SIZE := 81920k + IMAGE_SIZE := 128256k IMAGE/sysupgrade.bin := sysupgrade-tar | append-metadata LINKSYS_HWNAME := EA4500V3 IMAGES += factory.img @@ -307,10 +313,9 @@ define Device/meraki_mr18 BLOCKSIZE := 128k PAGESIZE := 2048 LOADER_TYPE := bin + LZMA_TEXT_START := 0x82800000 KERNEL := kernel-bin | append-dtb | lzma | loader-kernel | meraki-header MR18 -# Initramfs-build fails due to size issues -# KERNEL_INITRAMFS := $$(KERNEL) - KERNEL_INITRAMFS := + KERNEL_INITRAMFS := $$(KERNEL) IMAGE/sysupgrade.bin := sysupgrade-tar | append-metadata SUPPORTED_DEVICES += mr18 endef @@ -436,6 +441,10 @@ define Device/zte_mf28x_common DEVICE_PACKAGES := kmod-usb2 kmod-ath10k-ct BLOCKSIZE := 128k PAGESIZE := 2048 + LOADER_TYPE := bin + LZMA_TEXT_START := 0x82800000 + KERNEL := kernel-bin | append-dtb | lzma | loader-kernel | uImage none + KERNEL_INITRAMFS := $$(KERNEL) KERNEL_SIZE := 4096k IMAGE/sysupgrade.bin := sysupgrade-tar | append-metadata endef diff --git a/target/linux/ath79/image/tiny-tp-link.mk b/target/linux/ath79/image/tiny-tp-link.mk index 93cbc7d148cfd3..70c3ab4c7b5d54 100644 --- a/target/linux/ath79/image/tiny-tp-link.mk +++ b/target/linux/ath79/image/tiny-tp-link.mk @@ -481,6 +481,7 @@ define Device/tplink_tl-wr941-v2 $(Device/tplink-4m) SOC := ar9132 DEVICE_MODEL := TL-WR941ND + DEVICE_PACKAGES := kmod-dsa-mv88e6060 DEVICE_VARIANT := v2/v3 DEVICE_ALT0_VENDOR := TP-Link DEVICE_ALT0_MODEL := TL-WR941N diff --git a/target/linux/ath79/nand/base-files/etc/board.d/05_compat-version b/target/linux/ath79/nand/base-files/etc/board.d/05_compat-version index 238927aa7b474c..4d826d978d62ad 100644 --- a/target/linux/ath79/nand/base-files/etc/board.d/05_compat-version +++ b/target/linux/ath79/nand/base-files/etc/board.d/05_compat-version @@ -4,6 +4,7 @@ board_config_update case "$(board_name)" in + linksys,ea4500-v3|\ netgear,wndr4300-v2|\ netgear,wndr4500-v3) ucidef_set_compat_version "1.1" diff --git a/target/linux/ath79/patches-6.6/101-reset-ath79-reset-ETH-switch-for-AR9344.patch b/target/linux/ath79/patches-6.6/101-reset-ath79-reset-ETH-switch-for-AR9344.patch new file mode 100644 index 00000000000000..5d9daf1c1ce681 --- /dev/null +++ b/target/linux/ath79/patches-6.6/101-reset-ath79-reset-ETH-switch-for-AR9344.patch @@ -0,0 +1,105 @@ +From: David Bauer +Date: Tue, 2 Jan 2025 19:22:40 +0100 +Subject: [PATCH] reset: ath79: reset ETH switch for AR9344 + +According to datasheet, on AR9344 the switch and switch analog need to +be reset first before initiating a full reset. + +Resetting these systems fixes spurious reset hangs on Atheros AR9344 +SoCs. + +Link: https://github.com/freifunk-gluon/gluon/issues/2904 + +Signed-off-by: David Bauer + +--- a/drivers/reset/reset-ath79.c ++++ b/drivers/reset/reset-ath79.c +@@ -12,8 +12,11 @@ + #include + #include + #include ++#include ++#include + + struct ath79_reset { ++ struct platform_device *pdev; + struct reset_controller_dev rcdev; + struct notifier_block restart_nb; + void __iomem *base; +@@ -21,16 +24,13 @@ struct ath79_reset { + }; + + #define FULL_CHIP_RESET 24 ++#define ETH_SWITCH_RESET 8 ++#define ETH_SWITCH_ARESET 12 + +-static int ath79_reset_update(struct reset_controller_dev *rcdev, ++static void __ath79_reset_update_unlocked(struct ath79_reset *ath79_reset, + unsigned long id, bool assert) + { +- struct ath79_reset *ath79_reset = +- container_of(rcdev, struct ath79_reset, rcdev); +- unsigned long flags; + u32 val; +- +- spin_lock_irqsave(&ath79_reset->lock, flags); + val = readl(ath79_reset->base); + if (assert) + val |= BIT(id); +@@ -39,6 +39,17 @@ static int ath79_reset_update(struct res + writel(val, ath79_reset->base); + /* Flush cache */ + readl(ath79_reset->base); ++} ++ ++static int ath79_reset_update(struct reset_controller_dev *rcdev, ++ unsigned long id, bool assert) ++{ ++ struct ath79_reset *ath79_reset = ++ container_of(rcdev, struct ath79_reset, rcdev); ++ unsigned long flags; ++ ++ spin_lock_irqsave(&ath79_reset->lock, flags); ++ __ath79_reset_update_unlocked(ath79_reset, id, assert); + spin_unlock_irqrestore(&ath79_reset->lock, flags); + + return 0; +@@ -79,8 +90,28 @@ static int ath79_reset_restart_handler(s + { + struct ath79_reset *ath79_reset = + container_of(nb, struct ath79_reset, restart_nb); ++ unsigned long flags; + +- ath79_reset_assert(&ath79_reset->rcdev, FULL_CHIP_RESET); ++ spin_lock_irqsave(&ath79_reset->lock, flags); ++ ++ if (of_device_is_compatible(ath79_reset->pdev->dev.of_node, "qca,ar9340-reset")) { ++ /** ++ * AR9344 has been observed to hang on reboot in rare cases. ++ * ++ * Datasheet states to reset the ETH switch systems before asserting ++ * full chip reset. See page 111 of the AR9344 datasheet. ++ */ ++ __ath79_reset_update_unlocked(ath79_reset, ETH_SWITCH_RESET, true); ++ mdelay(1); ++ __ath79_reset_update_unlocked(ath79_reset, ETH_SWITCH_ARESET, true); ++ mdelay(1); ++ __ath79_reset_update_unlocked(ath79_reset, FULL_CHIP_RESET, true); ++ mdelay(10); ++ } else { ++ __ath79_reset_update_unlocked(ath79_reset, FULL_CHIP_RESET, true); ++ } ++ ++ spin_unlock_irqrestore(&ath79_reset->lock, flags); + + return NOTIFY_DONE; + } +@@ -95,6 +126,8 @@ static int ath79_reset_probe(struct plat + if (!ath79_reset) + return -ENOMEM; + ++ ath79_reset->pdev = pdev; ++ + ath79_reset->base = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(ath79_reset->base)) + return PTR_ERR(ath79_reset->base); diff --git a/target/linux/ath79/patches-6.6/810-ath79-ignore-the-abused-interrupt-map-on-pcie-node.patch b/target/linux/ath79/patches-6.6/810-ath79-ignore-the-abused-interrupt-map-on-pcie-node.patch index 330c0d139b33f8..b53461e37f65d0 100644 --- a/target/linux/ath79/patches-6.6/810-ath79-ignore-the-abused-interrupt-map-on-pcie-node.patch +++ b/target/linux/ath79/patches-6.6/810-ath79-ignore-the-abused-interrupt-map-on-pcie-node.patch @@ -22,7 +22,7 @@ Signed-off-by: Shiji Yang --- a/drivers/of/irq.c +++ b/drivers/of/irq.c -@@ -89,6 +89,8 @@ EXPORT_SYMBOL_GPL(of_irq_find_parent); +@@ -94,6 +94,8 @@ EXPORT_SYMBOL_GPL(of_irq_find_parent); * drawing board. */ static const char * const of_irq_imap_abusers[] = { diff --git a/target/linux/ath79/patches-6.6/820-mfd-syscon-support-skip-reset-control-for-syscon-devices.patch b/target/linux/ath79/patches-6.6/820-mfd-syscon-support-skip-reset-control-for-syscon-devices.patch index c73c8443b9f3eb..3bdc2faf3ff81a 100644 --- a/target/linux/ath79/patches-6.6/820-mfd-syscon-support-skip-reset-control-for-syscon-devices.patch +++ b/target/linux/ath79/patches-6.6/820-mfd-syscon-support-skip-reset-control-for-syscon-devices.patch @@ -16,16 +16,16 @@ Signed-off-by: Shiji Yang --- a/drivers/mfd/syscon.c +++ b/drivers/mfd/syscon.c -@@ -52,7 +52,7 @@ static struct syscon *of_syscon_register +@@ -53,7 +53,7 @@ static struct syscon *of_syscon_register int ret; struct regmap_config syscon_config = syscon_regmap_config; struct resource res; - struct reset_control *reset; + struct reset_control *reset = NULL; - syscon = kzalloc(sizeof(*syscon), GFP_KERNEL); - if (!syscon) -@@ -134,7 +134,8 @@ static struct syscon *of_syscon_register + WARN_ON(!mutex_is_locked(&syscon_list_lock)); + +@@ -133,7 +133,8 @@ static struct syscon *of_syscon_register goto err_attach_clk; } diff --git a/target/linux/ath79/patches-6.6/900-unaligned_access_hacks.patch b/target/linux/ath79/patches-6.6/900-unaligned_access_hacks.patch index c5b01b7daddfc4..2e574740bebdcf 100644 --- a/target/linux/ath79/patches-6.6/900-unaligned_access_hacks.patch +++ b/target/linux/ath79/patches-6.6/900-unaligned_access_hacks.patch @@ -259,7 +259,7 @@ SVN-Revision: 35130 #include #include #include -@@ -893,10 +894,10 @@ static void tcp_v6_send_response(const s +@@ -891,10 +892,10 @@ static void tcp_v6_send_response(const s topt = (__be32 *)(t1 + 1); if (tsecr) { @@ -323,7 +323,7 @@ SVN-Revision: 35130 SKB_DROP_REASON_IP_INHDR); --- a/include/linux/types.h +++ b/include/linux/types.h -@@ -244,5 +244,11 @@ typedef void (*swap_func_t)(void *a, voi +@@ -245,5 +245,11 @@ typedef void (*swap_func_t)(void *a, voi typedef int (*cmp_r_func_t)(const void *a, const void *b, const void *priv); typedef int (*cmp_func_t)(const void *a, const void *b); @@ -337,7 +337,7 @@ SVN-Revision: 35130 #endif /* _LINUX_TYPES_H */ --- a/net/ipv4/af_inet.c +++ b/net/ipv4/af_inet.c -@@ -1508,8 +1508,8 @@ struct sk_buff *inet_gro_receive(struct +@@ -1506,8 +1506,8 @@ struct sk_buff *inet_gro_receive(struct goto out; NAPI_GRO_CB(skb)->proto = proto; @@ -350,7 +350,7 @@ SVN-Revision: 35130 list_for_each_entry(p, head, list) { --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c -@@ -622,48 +622,53 @@ static void tcp_options_write(struct tcp +@@ -625,48 +625,53 @@ static void tcp_options_write(struct tcp u16 options = opts->options; /* mungable copy */ if (unlikely(OPTION_MD5 & options)) { @@ -427,7 +427,7 @@ SVN-Revision: 35130 } if (unlikely(opts->num_sack_blocks)) { -@@ -671,16 +676,17 @@ static void tcp_options_write(struct tcp +@@ -674,16 +679,17 @@ static void tcp_options_write(struct tcp tp->duplicate_sack : tp->selective_acks; int this_sack; @@ -451,7 +451,7 @@ SVN-Revision: 35130 } tp->rx_opt.dsack = 0; -@@ -693,13 +699,14 @@ static void tcp_options_write(struct tcp +@@ -696,13 +702,14 @@ static void tcp_options_write(struct tcp if (foc->exp) { len = TCPOLEN_EXP_FASTOPEN_BASE + foc->len; @@ -557,7 +557,7 @@ SVN-Revision: 35130 static inline struct neighbour *__ipv6_neigh_lookup_noref(struct net_device *dev, const void *pkey) --- a/net/sched/cls_u32.c +++ b/net/sched/cls_u32.c -@@ -157,7 +157,7 @@ next_knode: +@@ -167,7 +167,7 @@ next_knode: data = skb_header_pointer(skb, toff, 4, &hdata); if (!data) goto out; @@ -566,7 +566,7 @@ SVN-Revision: 35130 n = rcu_dereference_bh(n->next); goto next_knode; } -@@ -208,8 +208,8 @@ check_terminal: +@@ -218,8 +218,8 @@ check_terminal: &hdata); if (!data) goto out; @@ -579,7 +579,7 @@ SVN-Revision: 35130 goto next_ht; --- a/net/ipv6/ip6_offload.c +++ b/net/ipv6/ip6_offload.c -@@ -273,7 +273,7 @@ INDIRECT_CALLABLE_SCOPE struct sk_buff * +@@ -275,7 +275,7 @@ INDIRECT_CALLABLE_SCOPE struct sk_buff * continue; iph2 = (struct ipv6hdr *)(p->data + off); @@ -751,7 +751,7 @@ SVN-Revision: 35130 EXPORT_SYMBOL(xfrm_parse_spi); --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c -@@ -4262,14 +4262,16 @@ static bool tcp_parse_aligned_timestamp( +@@ -4283,14 +4283,16 @@ static bool tcp_parse_aligned_timestamp( { const __be32 *ptr = (const __be32 *)(th + 1); @@ -785,7 +785,7 @@ SVN-Revision: 35130 --- a/include/net/neighbour.h +++ b/include/net/neighbour.h -@@ -286,8 +286,10 @@ static inline bool neigh_key_eq128(const +@@ -287,8 +287,10 @@ static inline bool neigh_key_eq128(const const u32 *n32 = (const u32 *)n->primary_key; const u32 *p32 = pkey; @@ -858,7 +858,7 @@ SVN-Revision: 35130 --- a/net/ipv4/tcp_offload.c +++ b/net/ipv4/tcp_offload.c -@@ -63,7 +63,7 @@ static struct sk_buff *__tcpv4_gso_segme +@@ -66,7 +66,7 @@ static struct sk_buff *__tcpv4_gso_segme th2 = tcp_hdr(seg->next); iph2 = ip_hdr(seg->next); @@ -867,7 +867,7 @@ SVN-Revision: 35130 iph->daddr == iph2->daddr && iph->saddr == iph2->saddr) return segs; -@@ -264,7 +264,7 @@ struct sk_buff *tcp_gro_lookup(struct li +@@ -267,7 +267,7 @@ struct sk_buff *tcp_gro_lookup(struct li continue; th2 = tcp_hdr(p); @@ -876,7 +876,7 @@ SVN-Revision: 35130 NAPI_GRO_CB(p)->same_flow = 0; continue; } -@@ -330,8 +330,8 @@ struct sk_buff *tcp_gro_receive(struct l +@@ -333,8 +333,8 @@ struct sk_buff *tcp_gro_receive(struct l ~(TCP_FLAG_CWR | TCP_FLAG_FIN | TCP_FLAG_PSH)); flush |= (__force int)(th->ack_seq ^ th2->ack_seq); for (i = sizeof(*th); i < thlen; i += 4) diff --git a/target/linux/ath79/tiny/config-default b/target/linux/ath79/tiny/config-default index e47260df82056f..38fbe1b5228be3 100644 --- a/target/linux/ath79/tiny/config-default +++ b/target/linux/ath79/tiny/config-default @@ -1,9 +1,6 @@ CONFIG_GRO_CELLS=y CONFIG_MTD_SPI_NOR_USE_4K_SECTORS=y CONFIG_NET_DEVLINK=y -CONFIG_NET_DSA=y -CONFIG_NET_DSA_MV88E6060=y -CONFIG_NET_DSA_TAG_TRAILER=y CONFIG_NET_SWITCHDEV=y CONFIG_NVMEM_SYSFS=y CONFIG_NVMEM_U_BOOT_ENV=y diff --git a/target/linux/bcm27xx/base-files/etc/board.d/02_network b/target/linux/bcm27xx/base-files/etc/board.d/02_network index f246139c385bd8..e05c369d642db2 100644 --- a/target/linux/bcm27xx/base-files/etc/board.d/02_network +++ b/target/linux/bcm27xx/base-files/etc/board.d/02_network @@ -17,6 +17,8 @@ raspberrypi,3-model-b-plus |\ raspberrypi,400 |\ raspberrypi,4-compute-module |\ raspberrypi,4-model-b |\ +raspberrypi,500 |\ +raspberrypi,5-compute-module |\ raspberrypi,5-model-b |\ raspberrypi,model-b |\ raspberrypi,model-b-plus |\ diff --git a/target/linux/bcm27xx/base-files/lib/preinit/05_set_preinit_iface_brcm2708 b/target/linux/bcm27xx/base-files/lib/preinit/05_set_preinit_iface_brcm2708 index 120475b55dcda6..bce75d7119b29a 100644 --- a/target/linux/bcm27xx/base-files/lib/preinit/05_set_preinit_iface_brcm2708 +++ b/target/linux/bcm27xx/base-files/lib/preinit/05_set_preinit_iface_brcm2708 @@ -12,6 +12,8 @@ set_preinit_iface() { raspberrypi,400 |\ raspberrypi,4-compute-module |\ raspberrypi,4-model-b |\ + raspberrypi,500 |\ + raspberrypi,5-compute-module |\ raspberrypi,5-model-b |\ raspberrypi,model-b |\ raspberrypi,model-b-plus |\ diff --git a/target/linux/bcm27xx/bcm2708/config-6.6 b/target/linux/bcm27xx/bcm2708/config-6.6 index 4872e44642f8f0..84be5f8d27365e 100644 --- a/target/linux/bcm27xx/bcm2708/config-6.6 +++ b/target/linux/bcm27xx/bcm2708/config-6.6 @@ -55,8 +55,6 @@ CONFIG_BRCM_CHAR_DRIVERS=y CONFIG_BUFFER_HEAD=y # CONFIG_CACHE_L2X0 is not set CONFIG_CC_HAVE_STACKPROTECTOR_TLS=y -CONFIG_CC_IMPLICIT_FALLTHROUGH="-Wimplicit-fallthrough=5" -CONFIG_CC_NO_ARRAY_BOUNDS=y CONFIG_CLKSRC_MMIO=y CONFIG_CLK_BCM2711_DVP=y CONFIG_CLK_BCM2835=y @@ -172,7 +170,6 @@ CONFIG_FWNODE_MDIO=y CONFIG_FW_CACHE=y CONFIG_FW_LOADER_PAGED_BUF=y CONFIG_FW_LOADER_SYSFS=y -CONFIG_GCC10_NO_ARRAY_BOUNDS=y CONFIG_GENERIC_ALLOCATOR=y CONFIG_GENERIC_BUG=y CONFIG_GENERIC_CLOCKEVENTS=y @@ -252,11 +249,11 @@ CONFIG_MFD_SYSCON=y CONFIG_MIGHT_HAVE_CACHE_L2X0=y CONFIG_MIGRATION=y CONFIG_MMC=y -# CONFIG_MMC_BCM2835 is not set +CONFIG_MMC_BCM2835=y CONFIG_MMC_BCM2835_DMA=y CONFIG_MMC_BCM2835_MMC=y CONFIG_MMC_BCM2835_PIO_DMA_BARRIER=2 -CONFIG_MMC_BCM2835_SDHOST=y +# CONFIG_MMC_BCM2835_SDHOST is not set CONFIG_MMC_BLOCK=y CONFIG_MMC_BLOCK_MINORS=32 CONFIG_MMC_HSQ=y @@ -317,6 +314,7 @@ CONFIG_PRINTK_TIME=y CONFIG_PTP_1588_CLOCK_OPTIONAL=y CONFIG_PWM=y CONFIG_PWM_BCM2835=y +CONFIG_PWM_GPIO=y CONFIG_PWM_SYSFS=y CONFIG_RANDSTRUCT_NONE=y CONFIG_RASPBERRYPI_FIRMWARE=y @@ -349,6 +347,7 @@ CONFIG_SERIAL_DEV_BUS=y # CONFIG_SERIAL_DEV_CTRL_TTYPORT is not set CONFIG_SERIAL_MCTRL_GPIO=y CONFIG_SERIAL_OF_PLATFORM=y +CONFIG_SERIAL_RPI_FW=y CONFIG_SG_POOL=y CONFIG_SMSC_PHY=y CONFIG_SOFTIRQ_ON_OWN_STACK=y diff --git a/target/linux/bcm27xx/bcm2709/config-6.6 b/target/linux/bcm27xx/bcm2709/config-6.6 index 23e93241dfe3f5..747e3a6684e810 100644 --- a/target/linux/bcm27xx/bcm2709/config-6.6 +++ b/target/linux/bcm27xx/bcm2709/config-6.6 @@ -69,8 +69,6 @@ CONFIG_BROADCOM_PHY=y CONFIG_BUFFER_HEAD=y # CONFIG_CACHE_L2X0 is not set CONFIG_CC_HAVE_STACKPROTECTOR_TLS=y -CONFIG_CC_IMPLICIT_FALLTHROUGH="-Wimplicit-fallthrough=5" -CONFIG_CC_NO_ARRAY_BOUNDS=y CONFIG_CLKSRC_MMIO=y CONFIG_CLK_BCM2711_DVP=y CONFIG_CLK_BCM2835=y @@ -211,7 +209,6 @@ CONFIG_FWNODE_MDIO=y CONFIG_FW_CACHE=y CONFIG_FW_LOADER_PAGED_BUF=y CONFIG_FW_LOADER_SYSFS=y -CONFIG_GCC10_NO_ARRAY_BOUNDS=y CONFIG_GENERIC_ALLOCATOR=y CONFIG_GENERIC_ARCH_TOPOLOGY=y CONFIG_GENERIC_BUG=y @@ -315,11 +312,11 @@ CONFIG_MICROCHIP_PHY=y CONFIG_MIGHT_HAVE_CACHE_L2X0=y CONFIG_MIGRATION=y CONFIG_MMC=y -# CONFIG_MMC_BCM2835 is not set +CONFIG_MMC_BCM2835=y CONFIG_MMC_BCM2835_DMA=y CONFIG_MMC_BCM2835_MMC=y CONFIG_MMC_BCM2835_PIO_DMA_BARRIER=2 -CONFIG_MMC_BCM2835_SDHOST=y +# CONFIG_MMC_BCM2835_SDHOST is not set CONFIG_MMC_BLOCK=y CONFIG_MMC_BLOCK_MINORS=32 CONFIG_MMC_HSQ=y @@ -401,6 +398,7 @@ CONFIG_PTP_1588_CLOCK=y CONFIG_PTP_1588_CLOCK_OPTIONAL=y CONFIG_PWM=y CONFIG_PWM_BCM2835=y +CONFIG_PWM_GPIO=y CONFIG_PWM_SYSFS=y CONFIG_RANDSTRUCT_NONE=y CONFIG_RAS=y @@ -438,6 +436,7 @@ CONFIG_SERIAL_DEV_BUS=y # CONFIG_SERIAL_DEV_CTRL_TTYPORT is not set CONFIG_SERIAL_MCTRL_GPIO=y CONFIG_SERIAL_OF_PLATFORM=y +CONFIG_SERIAL_RPI_FW=y CONFIG_SG_POOL=y CONFIG_SMP=y CONFIG_SMP_ON_UP=y diff --git a/target/linux/bcm27xx/bcm2710/config-6.6 b/target/linux/bcm27xx/bcm2710/config-6.6 index 5b7d6ae4f1032b..26565cd237a463 100644 --- a/target/linux/bcm27xx/bcm2710/config-6.6 +++ b/target/linux/bcm27xx/bcm2710/config-6.6 @@ -85,8 +85,6 @@ CONFIG_CAVIUM_ERRATUM_23154=y CONFIG_CAVIUM_ERRATUM_27456=y CONFIG_CC_HAVE_SHADOW_CALL_STACK=y CONFIG_CC_HAVE_STACKPROTECTOR_SYSREG=y -CONFIG_CC_IMPLICIT_FALLTHROUGH="-Wimplicit-fallthrough=5" -CONFIG_CC_NO_ARRAY_BOUNDS=y CONFIG_CLKSRC_MMIO=y CONFIG_CLK_BCM2711_DVP=y CONFIG_CLK_BCM2835=y @@ -218,7 +216,6 @@ CONFIG_FWNODE_MDIO=y CONFIG_FW_CACHE=y CONFIG_FW_LOADER_PAGED_BUF=y CONFIG_FW_LOADER_SYSFS=y -CONFIG_GCC10_NO_ARRAY_BOUNDS=y CONFIG_GCC_SUPPORTS_DYNAMIC_FTRACE_WITH_ARGS=y CONFIG_GENERIC_ALLOCATOR=y CONFIG_GENERIC_ARCH_TOPOLOGY=y @@ -313,11 +310,11 @@ CONFIG_MICROCHIP_PHY=y CONFIG_MIGRATION=y # CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY is not set CONFIG_MMC=y -# CONFIG_MMC_BCM2835 is not set +CONFIG_MMC_BCM2835=y CONFIG_MMC_BCM2835_DMA=y CONFIG_MMC_BCM2835_MMC=y CONFIG_MMC_BCM2835_PIO_DMA_BARRIER=2 -CONFIG_MMC_BCM2835_SDHOST=y +# CONFIG_MMC_BCM2835_SDHOST is not set CONFIG_MMC_BLOCK=y CONFIG_MMC_BLOCK_MINORS=32 CONFIG_MMC_HSQ=y @@ -392,6 +389,7 @@ CONFIG_PRINTK_TIME=y CONFIG_PTP_1588_CLOCK_OPTIONAL=y CONFIG_PWM=y CONFIG_PWM_BCM2835=y +CONFIG_PWM_GPIO=y CONFIG_PWM_SYSFS=y CONFIG_QUEUED_RWLOCKS=y CONFIG_QUEUED_SPINLOCKS=y @@ -431,6 +429,7 @@ CONFIG_SERIAL_DEV_BUS=y # CONFIG_SERIAL_DEV_CTRL_TTYPORT is not set CONFIG_SERIAL_MCTRL_GPIO=y CONFIG_SERIAL_OF_PLATFORM=y +CONFIG_SERIAL_RPI_FW=y CONFIG_SG_POOL=y CONFIG_SMP=y CONFIG_SMSC_PHY=y diff --git a/target/linux/bcm27xx/bcm2711/config-6.6 b/target/linux/bcm27xx/bcm2711/config-6.6 index 270763549a199e..7b37b67fb31b03 100644 --- a/target/linux/bcm27xx/bcm2711/config-6.6 +++ b/target/linux/bcm27xx/bcm2711/config-6.6 @@ -84,8 +84,6 @@ CONFIG_CAVIUM_ERRATUM_23154=y CONFIG_CAVIUM_ERRATUM_27456=y CONFIG_CC_HAVE_SHADOW_CALL_STACK=y CONFIG_CC_HAVE_STACKPROTECTOR_SYSREG=y -CONFIG_CC_IMPLICIT_FALLTHROUGH="-Wimplicit-fallthrough=5" -CONFIG_CC_NO_ARRAY_BOUNDS=y CONFIG_CLKSRC_MMIO=y CONFIG_CLK_BCM2711_DVP=y CONFIG_CLK_BCM2835=y @@ -219,7 +217,6 @@ CONFIG_FWNODE_MDIO=y CONFIG_FW_CACHE=y CONFIG_FW_LOADER_PAGED_BUF=y CONFIG_FW_LOADER_SYSFS=y -CONFIG_GCC10_NO_ARRAY_BOUNDS=y CONFIG_GCC_SUPPORTS_DYNAMIC_FTRACE_WITH_ARGS=y CONFIG_GENERIC_ALLOCATOR=y CONFIG_GENERIC_ARCH_NUMA=y @@ -316,11 +313,11 @@ CONFIG_MFD_CORE=y CONFIG_MFD_SYSCON=y CONFIG_MIGRATION=y CONFIG_MMC=y -# CONFIG_MMC_BCM2835 is not set +CONFIG_MMC_BCM2835=y CONFIG_MMC_BCM2835_DMA=y CONFIG_MMC_BCM2835_MMC=y CONFIG_MMC_BCM2835_PIO_DMA_BARRIER=2 -CONFIG_MMC_BCM2835_SDHOST=y +# CONFIG_MMC_BCM2835_SDHOST is not set CONFIG_MMC_BLOCK=y CONFIG_MMC_BLOCK_MINORS=32 CONFIG_MMC_HSQ=y @@ -408,6 +405,7 @@ CONFIG_PTP_1588_CLOCK=y CONFIG_PTP_1588_CLOCK_OPTIONAL=y CONFIG_PWM=y CONFIG_PWM_BCM2835=y +CONFIG_PWM_GPIO=y CONFIG_PWM_SYSFS=y CONFIG_QUEUED_RWLOCKS=y CONFIG_QUEUED_SPINLOCKS=y @@ -448,6 +446,7 @@ CONFIG_SERIAL_DEV_BUS=y # CONFIG_SERIAL_DEV_CTRL_TTYPORT is not set CONFIG_SERIAL_MCTRL_GPIO=y CONFIG_SERIAL_OF_PLATFORM=y +CONFIG_SERIAL_RPI_FW=y CONFIG_SG_POOL=y CONFIG_SMP=y CONFIG_SOCK_RX_QUEUE_MAPPING=y diff --git a/target/linux/bcm27xx/bcm2712/config-6.6 b/target/linux/bcm27xx/bcm2712/config-6.6 index a5eb6c4d0e1f12..24f59326ae733d 100644 --- a/target/linux/bcm27xx/bcm2712/config-6.6 +++ b/target/linux/bcm27xx/bcm2712/config-6.6 @@ -110,8 +110,6 @@ CONFIG_BUFFER_HEAD=y CONFIG_BUILTIN_RETURN_ADDRESS_STRIPS_PAC=y CONFIG_CC_HAVE_SHADOW_CALL_STACK=y CONFIG_CC_HAVE_STACKPROTECTOR_SYSREG=y -CONFIG_CC_IMPLICIT_FALLTHROUGH="-Wimplicit-fallthrough=5" -CONFIG_CC_NO_ARRAY_BOUNDS=y CONFIG_CLKSRC_MMIO=y CONFIG_CLK_BCM2711_DVP=y CONFIG_CLK_BCM2835=y @@ -130,7 +128,7 @@ CONFIG_CMA_SIZE_SEL_MBYTES=y # CONFIG_CMA_SYSFS is not set CONFIG_COMMON_CLK=y CONFIG_COMMON_CLK_RP1=y -# CONFIG_COMMON_CLK_RP1_SDIO is not set +CONFIG_COMMON_CLK_RP1_SDIO=y CONFIG_COMMON_CLK_XGENE=y CONFIG_COMPACT_UNEVICTABLE_DEFAULT=1 # CONFIG_COMPAT_32BIT_TIME is not set @@ -241,6 +239,7 @@ CONFIG_FB_DEVICE=y CONFIG_FB_IOMEM_FOPS=y CONFIG_FB_IOMEM_HELPERS=y CONFIG_FB_SIMPLE=y +# CONFIG_FIRMWARE_RP1 is not set CONFIG_FIXED_PHY=y CONFIG_FIX_EARLYCON_MEM=y CONFIG_FONT_8x16=y @@ -262,7 +261,6 @@ CONFIG_FWNODE_MDIO=y CONFIG_FW_CACHE=y CONFIG_FW_LOADER_PAGED_BUF=y CONFIG_FW_LOADER_SYSFS=y -CONFIG_GCC10_NO_ARRAY_BOUNDS=y CONFIG_GCC_SUPPORTS_DYNAMIC_FTRACE_WITH_ARGS=y CONFIG_GENERIC_ALLOCATOR=y CONFIG_GENERIC_ARCH_NUMA=y @@ -322,13 +320,8 @@ CONFIG_HW_CONSOLE=y CONFIG_HW_RANDOM=y CONFIG_HW_RANDOM_IPROC_RNG200=y CONFIG_I2C=y -CONFIG_I2C_ALGOBIT=y # CONFIG_I2C_BCM2708 is not set -CONFIG_I2C_BCM2835=y CONFIG_I2C_BOARDINFO=y -CONFIG_I2C_BRCMSTB=y -CONFIG_I2C_DESIGNWARE_CORE=y -CONFIG_I2C_DESIGNWARE_PLATFORM=y CONFIG_ILLEGAL_POINTER_VALUE=0xdead000000000000 CONFIG_INPUT=y CONFIG_INPUT_MOUSEDEV=y @@ -374,6 +367,7 @@ CONFIG_MAGIC_SYSRQ=y CONFIG_MAGIC_SYSRQ_DEFAULT_ENABLE=0x1f6 CONFIG_MAILBOX=y # CONFIG_MAILBOX_TEST is not set +# CONFIG_MBOX_RP1 is not set CONFIG_MDIO_BCM_UNIMAC=y CONFIG_MDIO_BUS=y CONFIG_MDIO_DEVICE=y @@ -392,11 +386,11 @@ CONFIG_MFD_SYSCON=y CONFIG_MICROCHIP_PHY=y CONFIG_MIGRATION=y CONFIG_MMC=y -# CONFIG_MMC_BCM2835 is not set +CONFIG_MMC_BCM2835=y CONFIG_MMC_BCM2835_DMA=y CONFIG_MMC_BCM2835_MMC=y CONFIG_MMC_BCM2835_PIO_DMA_BARRIER=2 -CONFIG_MMC_BCM2835_SDHOST=y +# CONFIG_MMC_BCM2835_SDHOST is not set CONFIG_MMC_BLOCK=y CONFIG_MMC_BLOCK_MINORS=32 CONFIG_MMC_CQHCI=y @@ -514,6 +508,7 @@ CONFIG_PTP_1588_CLOCK_OPTIONAL=y CONFIG_PWM=y CONFIG_PWM_BCM2835=y CONFIG_PWM_BRCMSTB=y +CONFIG_PWM_GPIO=y CONFIG_PWM_RP1=y CONFIG_PWM_SYSFS=y CONFIG_QUEUED_RWLOCKS=y @@ -537,6 +532,7 @@ CONFIG_RESET_RASPBERRYPI=y CONFIG_RESET_SIMPLE=y CONFIG_RFS_ACCEL=y CONFIG_RODATA_FULL_DEFAULT_ENABLED=y +# CONFIG_RP1_PIO is not set # CONFIG_RPI_POE_POWER is not set CONFIG_RPS=y CONFIG_RTC_CLASS=y @@ -549,7 +545,7 @@ CONFIG_SCSI_COMMON=y # CONFIG_SCSI_LOWLEVEL is not set # CONFIG_SCSI_PROC_FS is not set CONFIG_SENSORS_RASPBERRYPI_HWMON=y -CONFIG_SENSORS_RP1_ADC=y +# CONFIG_SENSORS_RP1_ADC is not set CONFIG_SERIAL_8250_BCM2835AUX=y CONFIG_SERIAL_8250_BCM7271=y # CONFIG_SERIAL_8250_DMA is not set @@ -577,6 +573,7 @@ CONFIG_SPARSEMEM_VMEMMAP=y CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y CONFIG_SPARSE_IRQ=y CONFIG_SQUASHFS_DECOMP_MULTI_PERCPU=y +CONFIG_SRAM=y # CONFIG_STRIP_ASM_SYMS is not set CONFIG_SUSPEND=y CONFIG_SUSPEND_FREEZER=y diff --git a/target/linux/bcm27xx/config-6.6 b/target/linux/bcm27xx/config-6.6 index b44aa9f8a9b35d..e69dbf5d74584d 100644 --- a/target/linux/bcm27xx/config-6.6 +++ b/target/linux/bcm27xx/config-6.6 @@ -1,6 +1,7 @@ # CONFIG_BACKLIGHT_RPI is not set # CONFIG_BCM2712_MIP is not set # CONFIG_COMMON_CLK_RP1 is not set +# CONFIG_COMMON_CLK_RP1_SDIO is not set # CONFIG_COMMON_CLK_RP1_SDIO is not set # CONFIG_DRM_PANEL_ILITEK_ILI9806E is not set # CONFIG_DRM_PANEL_TPO_Y17P is not set @@ -9,8 +10,10 @@ # CONFIG_DRM_RP1_DSI is not set # CONFIG_DRM_RP1_VEC is not set # CONFIG_FB_RPISENSE is not set +# CONFIG_FIRMWARE_RP1 is not set # CONFIG_GPIO_PWM is not set # CONFIG_INPUT_RASPBERRYPI_BUTTON is not set +# CONFIG_MBOX_RP1 is not set # CONFIG_MEDIA_PCI_HAILO is not set # CONFIG_MFD_PM8921_CORE is not set # CONFIG_MFD_RASPBERRYPI_POE_HAT is not set @@ -19,10 +22,14 @@ # CONFIG_PHY_CADENCE_DP is not set # CONFIG_PINCTRL_BCM2712 is not set # CONFIG_PINCTRL_RP1 is not set +# CONFIG_PWM_PIO_RP1 is not set # CONFIG_PWM_RP1 is not set # CONFIG_RASPBERRYPI_GPIOMEM is not set # CONFIG_REGULATOR_RASPBERRYPI_TOUCHSCREEN_V2 is not set +# CONFIG_RP1_PIO is not set # CONFIG_SENSORS_RP1_ADC is not set +# CONFIG_SERIAL_RPI_FW is not set +# CONFIG_SND_PIMIDI is not set # CONFIG_SPI_RP2040_GPIO_BRIDGE is not set # CONFIG_VIDEO_AD5398 is not set # CONFIG_VIDEO_ARDUCAM_64MP is not set @@ -39,3 +46,4 @@ # CONFIG_VIDEO_OV64A40 is not set # CONFIG_VIDEO_RASPBERRYPI_PISP_BE is not set # CONFIG_VIDEO_RP1_CFE is not set +# CONFIG_WS2812_PIO_RP1 is not set diff --git a/target/linux/bcm27xx/image/Makefile b/target/linux/bcm27xx/image/Makefile index 23bc3a35c9edd8..8320855573a455 100644 --- a/target/linux/bcm27xx/image/Makefile +++ b/target/linux/bcm27xx/image/Makefile @@ -88,7 +88,9 @@ define Device/rpi DEVICE_PACKAGES := \ cypress-firmware-43430-sdio \ brcmfmac-nvram-43430-sdio \ - kmod-brcmfmac wpad-basic-mbedtls + kmod-brcmfmac wpad-basic-mbedtls \ + kmod-i2c-bcm2835 kmod-spi-bcm2835 \ + kmod-spi-bcm2835-aux endef ifeq ($(SUBTARGET),bcm2708) TARGET_DEVICES += rpi @@ -127,7 +129,9 @@ define Device/rpi-2 brcmfmac-nvram-43430-sdio \ cypress-firmware-43455-sdio \ brcmfmac-nvram-43455-sdio \ - kmod-brcmfmac wpad-basic-mbedtls + kmod-brcmfmac wpad-basic-mbedtls \ + kmod-i2c-bcm2835 kmod-spi-bcm2835 \ + kmod-spi-bcm2835-aux IMAGE/sysupgrade.img.gz := boot-common | boot-2708 | boot-2711 | sdcard-img | gzip | append-metadata IMAGE/factory.img.gz := boot-common | boot-2708 | boot-2711 | sdcard-img | gzip endef @@ -161,7 +165,9 @@ define Device/rpi-3 brcmfmac-nvram-43430-sdio \ cypress-firmware-43455-sdio \ brcmfmac-nvram-43455-sdio \ - kmod-brcmfmac wpad-basic-mbedtls + kmod-brcmfmac wpad-basic-mbedtls \ + kmod-i2c-bcm2835 kmod-spi-bcm2835 \ + kmod-spi-bcm2835-aux endef ifeq ($(SUBTARGET),bcm2710) TARGET_DEVICES += rpi-3 @@ -183,6 +189,9 @@ define Device/rpi-4 cypress-firmware-43455-sdio \ brcmfmac-nvram-43455-sdio \ kmod-brcmfmac wpad-basic-mbedtls \ + kmod-i2c-bcm2835 kmod-spi-bcm2835 \ + kmod-spi-bcm2835-aux \ + kmod-i2c-brcmstb \ kmod-usb-net-lan78xx \ kmod-r8169 IMAGE/sysupgrade.img.gz := boot-common | boot-2711 | sdcard-img | gzip | append-metadata @@ -193,14 +202,26 @@ ifeq ($(SUBTARGET),bcm2711) endif define Device/rpi-5 - DEVICE_MODEL := 5 + DEVICE_MODEL := 5/500/CM5 KERNEL_IMG := kernel_2712.img - DEVICE_DTS := broadcom/bcm2712-rpi-5-b - SUPPORTED_DEVICES := raspberrypi,5-model-b + DEVICE_DTS := \ + broadcom/bcm2712-rpi-5-b \ + broadcom/bcm2712-rpi-cm5-cm4io \ + broadcom/bcm2712-rpi-cm5-cm5io \ + broadcom/bcm2712-rpi-cm5l-cm4io \ + broadcom/bcm2712-rpi-cm5l-cm5io \ + broadcom/bcm2712d0-rpi-5-b + SUPPORTED_DEVICES := \ + raspberrypi,500 \ + raspberrypi,5-compute-module \ + raspberrypi,5-model-b DEVICE_PACKAGES := \ cypress-firmware-43455-sdio \ brcmfmac-nvram-43455-sdio \ kmod-brcmfmac wpad-basic-mbedtls \ + kmod-i2c-bcm2835 kmod-spi-bcm2835 \ + kmod-i2c-brcmstb \ + kmod-i2c-designware-platform kmod-spi-dw-mmio \ kmod-hwmon-pwmfan kmod-thermal IMAGE/sysupgrade.img.gz := boot-common | sdcard-img | gzip | append-metadata IMAGE/factory.img.gz := boot-common | sdcard-img | gzip diff --git a/target/linux/bcm27xx/modules/hwmon.mk b/target/linux/bcm27xx/modules/hwmon.mk index 0f1547cd4f802c..320b11708f9221 100644 --- a/target/linux/bcm27xx/modules/hwmon.mk +++ b/target/linux/bcm27xx/modules/hwmon.mk @@ -2,6 +2,23 @@ # # Copyright (C) 2019 OpenWrt.org +define KernelPackage/rp1-adc + SUBMENU:=$(OTHER_MENU) + TITLE:=RP1 ADC and temperature sensor driver + KCONFIG:=CONFIG_SENSORS_RP1_ADC + FILES:=$(LINUX_DIR)/drivers/hwmon/rp1-adc.ko + AUTOLOAD:=$(call AutoLoad,21,rp1-adc) + DEPENDS:=@TARGET_bcm27xx_bcm2712 +endef + +define KernelPackage/rp1-adc/description + Kernel module for RP1 silicon providing ADC and + temperature monitoring. +endef + +$(eval $(call KernelPackage,rp1-adc)) + + define KernelPackage/hwmon-raspberrypi TITLE:=Raspberry Pi voltage monitor KCONFIG:=CONFIG_SENSORS_RASPBERRYPI_HWMON diff --git a/target/linux/bcm27xx/modules/i2c.mk b/target/linux/bcm27xx/modules/i2c.mk index ba266b29f29bf9..0d44f1febcf49e 100644 --- a/target/linux/bcm27xx/modules/i2c.mk +++ b/target/linux/bcm27xx/modules/i2c.mk @@ -16,3 +16,19 @@ define KernelPackage/i2c-bcm2835/description endef $(eval $(call KernelPackage,i2c-bcm2835)) + + +I2C_BRCMSTB_MODULES:=\ + CONFIG_I2C_BRCMSTB:drivers/i2c/busses/i2c-brcmstb + +define KernelPackage/i2c-brcmstb + $(call i2c_defaults,$(I2C_BRCMSTB_MODULES),59) + TITLE:=Broadcom BRCMSTB I2C master controller driver + DEPENDS:=@TARGET_bcm27xx +kmod-i2c-core +endef + +define KernelPackage/i2c-brcmstb/description + This package contains the BRCM Settop/DSL I2C master controller driver +endef + +$(eval $(call KernelPackage,i2c-brcmstb)) diff --git a/target/linux/bcm27xx/modules/other.mk b/target/linux/bcm27xx/modules/other.mk index 99b71d4d695af1..7ec35c95f0b21c 100644 --- a/target/linux/bcm27xx/modules/other.mk +++ b/target/linux/bcm27xx/modules/other.mk @@ -53,3 +53,89 @@ define KernelPackage/smi-bcm2835-dev/description endef $(eval $(call KernelPackage,smi-bcm2835-dev)) + + +define KernelPackage/rp1 + SUBMENU:=$(OTHER_MENU) + TITLE:=RP1 firmware + KCONFIG:=CONFIG_FIRMWARE_RP1 + FILES:=$(LINUX_DIR)/drivers/firmware/rp1.ko + AUTOLOAD:=$(call AutoLoad,21,rp1) + DEPENDS:=@TARGET_bcm27xx_bcm2712 +endef + +define KernelPackage/rp1/description + This driver provides a firmware interface to the RP1 processor using shared + memory and a mailbox. +endef + +$(eval $(call KernelPackage,rp1)) + + +define KernelPackage/rp1-pio + SUBMENU:=$(OTHER_MENU) + TITLE:=RP1 PIO block support + KCONFIG:=CONFIG_RP1_PIO + FILES:=$(LINUX_DIR)/drivers/misc/rp1-pio.ko + AUTOLOAD:=$(call AutoLoad,21,rp1-pio) + DEPENDS:=@TARGET_bcm27xx_bcm2712 +kmod-rp1 +endef + +define KernelPackage/rp1-pio/description + Driver providing control of the Raspberry Pi PIO block, as found in RP1 +endef + +$(eval $(call KernelPackage,rp1-pio)) + + +define KernelPackage/pwm-pio-rp1 + SUBMENU:=$(OTHER_MENU) + TITLE:=RP1 PWM support + KCONFIG:=CONFIG_PWM_PIO_RP1 + FILES:=$(LINUX_DIR)/drivers/pwm/pwm-pio-rp1.ko + AUTOLOAD:=$(call AutoLoad,21,pwm-pio-rp1) + DEPENDS:=@TARGET_bcm27xx_bcm2712 +kmod-rp1-pio +endef + +define KernelPackage/pwm-pio-rp1/description + Enables precise control of PWM signals for tasks like motor control, + LED dimming, and audio signal generation. Leveraging PIO allows for + higher accuracy and flexibility in PWM signal generation compared + to traditional hardware timers. +endef + +$(eval $(call KernelPackage,pwm-pio-rp1)) + + +define KernelPackage/ws2812-pio-rp1 + SUBMENU:=$(OTHER_MENU) + TITLE:=RP1 PIO-base WS2812 driver + KCONFIG:=CONFIG_WS2812_PIO_RP1 + FILES:=$(LINUX_DIR)/drivers/misc/ws2812-pio-rp1.ko + AUTOLOAD:=$(call AutoLoad,21,ws2812-pio-rp1) + DEPENDS:=@TARGET_bcm27xx_bcm2712 +kmod-rp1-pio +endef + +define KernelPackage/ws2812-pio-rp1/description + Driver for the WS2812 (NeoPixel) LEDs using the RP1 PIO hardware. + The driver creates a character device to which rgbw pixels may be + written. Single-byte writes to offset 0 set the brightness at runtime. +endef + +$(eval $(call KernelPackage,ws2812-pio-rp1)) + + +define KernelPackage/rp1-mailbox + SUBMENU:=$(OTHER_MENU) + TITLE:=RP1 mailbox IPC driver + KCONFIG:=CONFIG_MBOX_RP1 + FILES:=$(LINUX_DIR)/drivers/mailbox/rp1-mailbox.ko + AUTOLOAD:=$(call AutoLoad,21,rp1-mailbox) + DEPENDS:=@TARGET_bcm27xx_bcm2712 +endef + +define KernelPackage/rp1-mailbox/description + This is a RP1 mailbox IPC driver. +endef + +$(eval $(call KernelPackage,rp1-mailbox)) diff --git a/target/linux/bcm27xx/modules/video.mk b/target/linux/bcm27xx/modules/video.mk index b9af0b3e0f8603..f8b39c71c4497c 100644 --- a/target/linux/bcm27xx/modules/video.mk +++ b/target/linux/bcm27xx/modules/video.mk @@ -115,3 +115,81 @@ define KernelPackage/vchiq-mmal-bcm2835/description endef $(eval $(call KernelPackage,vchiq-mmal-bcm2835)) + + +define KernelPackage/drm-rp1-dsi + SUBMENU:=$(VIDEO_MENU) + TITLE:=RP1 Display Serial Interface for Video + KCONFIG:= \ + CONFIG_DRM_RP1_DSI \ + CONFIG_DRM_GEM_DMA_HELPER \ + CONFIG_DRM_KMS_HELPER \ + CONFIG_DRM_MIPI_DSI=y \ + CONFIG_DRM_VRAM_HELPER=n \ + CONFIG_DRM_TTM=n \ + CONFIG_DRM_TTM_HELPER=n \ + CONFIG_GENERIC_PHY_MIPI_DPHY=n \ + CONFIG_DRM_WERROR=n + FILES:=$(LINUX_DIR)/drivers/gpu/drm/rp1/rp1-dsi/drm-rp1-dsi.ko + AUTOLOAD:=$(call AutoLoad,67,drm-rp1-dsi) + DEPENDS:=@TARGET_bcm27xx_bcm2712 +kmod-drm-vc4 +endef + +define KernelPackage/drm-rp1-dsi/description + This module manages the DSI for driving high-resolution LCD panels + such as the official Raspberry Pi displays or other screens that + use the DSI interface. +endef + +$(eval $(call KernelPackage,drm-rp1-dsi)) + + +define KernelPackage/drm-rp1-dpi + SUBMENU:=$(VIDEO_MENU) + TITLE:=RP1 Display Parallel Interface for Video + KCONFIG:= \ + CONFIG_DRM_RP1_DPI \ + CONFIG_DRM_GEM_DMA_HELPER \ + CONFIG_DRM_KMS_HELPER \ + CONFIG_DRM_VRAM_HELPER=n \ + CONFIG_DRM_TTM=n \ + CONFIG_DRM_TTM_HELPER=n + FILES:=$(LINUX_DIR)/drivers/gpu/drm/rp1/rp1-dpi/drm-rp1-dpi.ko + AUTOLOAD:=$(call AutoLoad,67,drm-rp1-dpi) + DEPENDS:=@TARGET_bcm27xx_bcm2712 +kmod-drm-vc4 +kmod-rp1-pio +endef + +define KernelPackage/drm-rp1-dpi/description + This module is or driving displays using the DPI standard. + Useful for interfacing with custom or low-level LCD panels + that require parallel RGB signals. Provides direct control + over the timing and signal driving of raw LCD panels. + Typically used in maker projects or with non-HDMI displays. +endef + +$(eval $(call KernelPackage,drm-rp1-dpi)) + + +define KernelPackage/drm-rp1-vec + SUBMENU:=$(VIDEO_MENU) + TITLE:=RP1 Display Composite Video + KCONFIG:= \ + CONFIG_DRM_RP1_VEC \ + CONFIG_DRM_GEM_DMA_HELPER \ + CONFIG_DRM_KMS_HELPER \ + CONFIG_DRM_VRAM_HELPER=n \ + CONFIG_DRM_TTM=n \ + CONFIG_DRM_TTM_HELPER=n + FILES:=$(LINUX_DIR)/drivers/gpu/drm/rp1/rp1-vec/drm-rp1-vec.ko + AUTOLOAD:=$(call AutoLoad,67,drm-rp1-vec) + DEPENDS:=@TARGET_bcm27xx_bcm2712 +kmod-drm-vc4 +endef + +define KernelPackage/drm-rp1-vec/description + This module is used for composite video output, which is typically + transmitted through the RCA jack. Primary use is onnecting older + TVs or monitors that rely on analog signals via a composite interface. + Handles standard-definition analog signals in NTSC and PAL. +endef + +$(eval $(call KernelPackage,drm-rp1-vec)) diff --git a/target/linux/bcm27xx/patches-6.6/950-0007-drm-vc4-Add-firmware-kms-mode.patch b/target/linux/bcm27xx/patches-6.6/950-0007-drm-vc4-Add-firmware-kms-mode.patch index c755e8143598e1..468420bdee0eac 100644 --- a/target/linux/bcm27xx/patches-6.6/950-0007-drm-vc4-Add-firmware-kms-mode.patch +++ b/target/linux/bcm27xx/patches-6.6/950-0007-drm-vc4-Add-firmware-kms-mode.patch @@ -220,7 +220,7 @@ Signed-off-by: Dave Stevenson struct vc4_hang_state *hang_state; -@@ -963,6 +967,9 @@ extern struct platform_driver vc4_dsi_dr +@@ -964,6 +968,9 @@ extern struct platform_driver vc4_dsi_dr /* vc4_fence.c */ extern const struct dma_fence_ops vc4_fence_ops; diff --git a/target/linux/bcm27xx/patches-6.6/950-0008-drm-vc4-Add-support-for-gamma-on-BCM2711.patch b/target/linux/bcm27xx/patches-6.6/950-0008-drm-vc4-Add-support-for-gamma-on-BCM2711.patch index a4712310f2b7b2..10a09eb2c0c155 100644 --- a/target/linux/bcm27xx/patches-6.6/950-0008-drm-vc4-Add-support-for-gamma-on-BCM2711.patch +++ b/target/linux/bcm27xx/patches-6.6/950-0008-drm-vc4-Add-support-for-gamma-on-BCM2711.patch @@ -83,7 +83,7 @@ Signed-off-by: Maxime Ripard struct drm_device; struct drm_gem_object; -@@ -494,6 +495,17 @@ struct drm_encoder *vc4_find_encoder_by_ +@@ -495,6 +496,17 @@ struct drm_encoder *vc4_find_encoder_by_ return NULL; } @@ -101,7 +101,7 @@ Signed-off-by: Maxime Ripard struct vc4_crtc_data { const char *name; -@@ -538,9 +550,19 @@ struct vc4_crtc { +@@ -539,9 +551,19 @@ struct vc4_crtc { /* Timestamp at start of vblank irq - unaffected by lock delays. */ ktime_t t_vblank; @@ -126,7 +126,7 @@ Signed-off-by: Maxime Ripard --- a/drivers/gpu/drm/vc4/vc4_hvs.c +++ b/drivers/gpu/drm/vc4/vc4_hvs.c -@@ -243,7 +243,8 @@ static void vc4_hvs_lut_load(struct vc4_ +@@ -248,7 +248,8 @@ static void vc4_hvs_lut_load(struct vc4_ static void vc4_hvs_update_gamma_lut(struct vc4_hvs *hvs, struct vc4_crtc *vc4_crtc) { @@ -136,7 +136,7 @@ Signed-off-by: Maxime Ripard struct drm_color_lut *lut = crtc_state->gamma_lut->data; u32 length = drm_color_lut_size(crtc_state->gamma_lut); u32 i; -@@ -257,6 +258,81 @@ static void vc4_hvs_update_gamma_lut(str +@@ -262,6 +263,81 @@ static void vc4_hvs_update_gamma_lut(str vc4_hvs_lut_load(hvs, vc4_crtc); } @@ -218,7 +218,7 @@ Signed-off-by: Maxime Ripard u8 vc4_hvs_get_fifo_frame_count(struct vc4_hvs *hvs, unsigned int fifo) { struct drm_device *drm = &hvs->vc4->base; -@@ -400,7 +476,10 @@ static int vc4_hvs_init_channel(struct v +@@ -405,7 +481,10 @@ static int vc4_hvs_init_channel(struct v /* Reload the LUT, since the SRAMs would have been disabled if * all CRTCs had SCALER_DISPBKGND_GAMMA unset at once. */ @@ -230,7 +230,7 @@ Signed-off-by: Maxime Ripard drm_dev_exit(idx); -@@ -646,7 +725,11 @@ void vc4_hvs_atomic_flush(struct drm_crt +@@ -649,7 +728,11 @@ void vc4_hvs_atomic_flush(struct drm_crt u32 dispbkgndx = HVS_READ(SCALER_DISPBKGNDX(channel)); if (crtc->state->gamma_lut) { diff --git a/target/linux/bcm27xx/patches-6.6/950-0009-drm-vc4-Add-debugfs-node-that-dumps-the-vc5-gamma-PW.patch b/target/linux/bcm27xx/patches-6.6/950-0009-drm-vc4-Add-debugfs-node-that-dumps-the-vc5-gamma-PW.patch index 24d0cd90f6e2f9..863ad82432d5df 100644 --- a/target/linux/bcm27xx/patches-6.6/950-0009-drm-vc4-Add-debugfs-node-that-dumps-the-vc5-gamma-PW.patch +++ b/target/linux/bcm27xx/patches-6.6/950-0009-drm-vc4-Add-debugfs-node-that-dumps-the-vc5-gamma-PW.patch @@ -17,7 +17,7 @@ Signed-off-by: Maxime Ripard --- a/drivers/gpu/drm/vc4/vc4_hvs.c +++ b/drivers/gpu/drm/vc4/vc4_hvs.c -@@ -143,6 +143,85 @@ static int vc4_hvs_debugfs_dlist(struct +@@ -145,6 +145,85 @@ static int vc4_hvs_debugfs_dlist(struct return 0; } @@ -103,7 +103,7 @@ Signed-off-by: Maxime Ripard /* The filter kernel is composed of dwords each containing 3 9-bit * signed integers packed next to each other. */ -@@ -850,11 +929,15 @@ int vc4_hvs_debugfs_init(struct drm_mino +@@ -854,11 +933,15 @@ int vc4_hvs_debugfs_init(struct drm_mino if (!vc4->hvs) return -ENODEV; diff --git a/target/linux/bcm27xx/patches-6.6/950-0010-drm-vc4-hvs-Force-modeset-on-gamma-lut-change.patch b/target/linux/bcm27xx/patches-6.6/950-0010-drm-vc4-hvs-Force-modeset-on-gamma-lut-change.patch index f49122dec27a11..b8847230af0841 100644 --- a/target/linux/bcm27xx/patches-6.6/950-0010-drm-vc4-hvs-Force-modeset-on-gamma-lut-change.patch +++ b/target/linux/bcm27xx/patches-6.6/950-0010-drm-vc4-hvs-Force-modeset-on-gamma-lut-change.patch @@ -45,7 +45,7 @@ Signed-off-by: Maxime Ripard struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc); --- a/drivers/gpu/drm/vc4/vc4_drv.h +++ b/drivers/gpu/drm/vc4/vc4_drv.h -@@ -613,6 +613,9 @@ vc4_crtc_to_vc4_pv_data(const struct vc4 +@@ -614,6 +614,9 @@ vc4_crtc_to_vc4_pv_data(const struct vc4 return container_of_const(data, struct vc4_pv_data, base); } @@ -57,7 +57,7 @@ Signed-off-by: Maxime Ripard --- a/drivers/gpu/drm/vc4/vc4_hvs.c +++ b/drivers/gpu/drm/vc4/vc4_hvs.c -@@ -596,6 +596,36 @@ out: +@@ -599,6 +599,36 @@ out: drm_dev_exit(idx); } @@ -94,7 +94,7 @@ Signed-off-by: Maxime Ripard int vc4_hvs_atomic_check(struct drm_crtc *crtc, struct drm_atomic_state *state) { struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state, crtc); -@@ -626,7 +656,7 @@ int vc4_hvs_atomic_check(struct drm_crtc +@@ -629,7 +659,7 @@ int vc4_hvs_atomic_check(struct drm_crtc if (ret) return ret; diff --git a/target/linux/bcm27xx/patches-6.6/950-0014-drm-vc4-Enable-gamma-block-only-when-required.patch b/target/linux/bcm27xx/patches-6.6/950-0014-drm-vc4-Enable-gamma-block-only-when-required.patch index 76647cbd48889b..061b37797de7c8 100644 --- a/target/linux/bcm27xx/patches-6.6/950-0014-drm-vc4-Enable-gamma-block-only-when-required.patch +++ b/target/linux/bcm27xx/patches-6.6/950-0014-drm-vc4-Enable-gamma-block-only-when-required.patch @@ -20,7 +20,7 @@ Signed-off-by: Dave Stevenson --- a/drivers/gpu/drm/vc4/vc4_hvs.c +++ b/drivers/gpu/drm/vc4/vc4_hvs.c -@@ -548,8 +548,11 @@ static int vc4_hvs_init_channel(struct v +@@ -553,8 +553,11 @@ static int vc4_hvs_init_channel(struct v dispbkgndx &= ~SCALER_DISPBKGND_GAMMA; dispbkgndx &= ~SCALER_DISPBKGND_INTERLACE; @@ -33,7 +33,7 @@ Signed-off-by: Dave Stevenson (interlace ? SCALER_DISPBKGND_INTERLACE : 0)); /* Reload the LUT, since the SRAMs would have been disabled if -@@ -834,18 +837,25 @@ void vc4_hvs_atomic_flush(struct drm_crt +@@ -837,18 +840,25 @@ void vc4_hvs_atomic_flush(struct drm_crt u32 dispbkgndx = HVS_READ(SCALER_DISPBKGNDX(channel)); if (crtc->state->gamma_lut) { diff --git a/target/linux/bcm27xx/patches-6.6/950-0016-drm-vc4-Validate-the-size-of-the-gamma_lut.patch b/target/linux/bcm27xx/patches-6.6/950-0016-drm-vc4-Validate-the-size-of-the-gamma_lut.patch index fd0823aa136c89..7280b6e30c4a87 100644 --- a/target/linux/bcm27xx/patches-6.6/950-0016-drm-vc4-Validate-the-size-of-the-gamma_lut.patch +++ b/target/linux/bcm27xx/patches-6.6/950-0016-drm-vc4-Validate-the-size-of-the-gamma_lut.patch @@ -13,7 +13,7 @@ Signed-off-by: Dave Stevenson --- a/drivers/gpu/drm/vc4/vc4_hvs.c +++ b/drivers/gpu/drm/vc4/vc4_hvs.c -@@ -614,6 +614,16 @@ static int vc4_hvs_gamma_check(struct dr +@@ -617,6 +617,16 @@ static int vc4_hvs_gamma_check(struct dr if (!crtc_state->color_mgmt_changed) return 0; diff --git a/target/linux/bcm27xx/patches-6.6/950-0020-vc4-drm-vc4_plane-Keep-fractional-source-coords-insi.patch b/target/linux/bcm27xx/patches-6.6/950-0020-vc4-drm-vc4_plane-Keep-fractional-source-coords-insi.patch index 46a72e4ed92cbd..17dd4433e1ac47 100644 --- a/target/linux/bcm27xx/patches-6.6/950-0020-vc4-drm-vc4_plane-Keep-fractional-source-coords-insi.patch +++ b/target/linux/bcm27xx/patches-6.6/950-0020-vc4-drm-vc4_plane-Keep-fractional-source-coords-insi.patch @@ -12,7 +12,7 @@ Signed-off-by: Dom Cobley --- a/drivers/gpu/drm/vc4/vc4_drv.h +++ b/drivers/gpu/drm/vc4/vc4_drv.h -@@ -408,7 +408,7 @@ struct vc4_plane_state { +@@ -409,7 +409,7 @@ struct vc4_plane_state { /* Clipped coordinates of the plane on the display. */ int crtc_x, crtc_y, crtc_w, crtc_h; diff --git a/target/linux/bcm27xx/patches-6.6/950-0024-drm-vc4-Force-trigger-of-dlist-update-on-margins-cha.patch b/target/linux/bcm27xx/patches-6.6/950-0024-drm-vc4-Force-trigger-of-dlist-update-on-margins-cha.patch index 9779cd512c0078..06cb7094985b1f 100644 --- a/target/linux/bcm27xx/patches-6.6/950-0024-drm-vc4-Force-trigger-of-dlist-update-on-margins-cha.patch +++ b/target/linux/bcm27xx/patches-6.6/950-0024-drm-vc4-Force-trigger-of-dlist-update-on-margins-cha.patch @@ -42,7 +42,7 @@ Signed-off-by: Dave Stevenson --- a/drivers/gpu/drm/vc4/vc4_drv.h +++ b/drivers/gpu/drm/vc4/vc4_drv.h -@@ -626,12 +626,7 @@ struct vc4_crtc_state { +@@ -627,12 +627,7 @@ struct vc4_crtc_state { bool txp_armed; unsigned int assigned_channel; diff --git a/target/linux/bcm27xx/patches-6.6/950-0025-drm-atomic-helpers-remove-legacy_cursor_update-hacks.patch b/target/linux/bcm27xx/patches-6.6/950-0025-drm-atomic-helpers-remove-legacy_cursor_update-hacks.patch index 97bc25b565ef9a..6655920b1ee13d 100644 --- a/target/linux/bcm27xx/patches-6.6/950-0025-drm-atomic-helpers-remove-legacy_cursor_update-hacks.patch +++ b/target/linux/bcm27xx/patches-6.6/950-0025-drm-atomic-helpers-remove-legacy_cursor_update-hacks.patch @@ -60,7 +60,7 @@ Signed-off-by: Maxime Ripard --- a/drivers/gpu/drm/drm_atomic_helper.c +++ b/drivers/gpu/drm/drm_atomic_helper.c -@@ -1653,13 +1653,6 @@ drm_atomic_helper_wait_for_vblanks(struc +@@ -1681,13 +1681,6 @@ drm_atomic_helper_wait_for_vblanks(struc int i, ret; unsigned int crtc_mask = 0; @@ -74,7 +74,7 @@ Signed-off-by: Maxime Ripard for_each_oldnew_crtc_in_state(old_state, crtc, old_crtc_state, new_crtc_state, i) { if (!new_crtc_state->active) continue; -@@ -2309,12 +2302,6 @@ int drm_atomic_helper_setup_commit(struc +@@ -2337,12 +2330,6 @@ int drm_atomic_helper_setup_commit(struc complete_all(&commit->flip_done); continue; } @@ -89,7 +89,7 @@ Signed-off-by: Maxime Ripard commit->event = kzalloc(sizeof(*commit->event), --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c -@@ -7280,6 +7280,19 @@ int intel_atomic_commit(struct drm_devic +@@ -7297,6 +7297,19 @@ int intel_atomic_commit(struct drm_devic state->base.legacy_cursor_update = false; } diff --git a/target/linux/bcm27xx/patches-6.6/950-0027-drm-vc4-hvs-Skip-DebugFS-Registration-for-FKMS.patch b/target/linux/bcm27xx/patches-6.6/950-0027-drm-vc4-hvs-Skip-DebugFS-Registration-for-FKMS.patch index ba03cfb7b92fc9..fb8abd20caf596 100644 --- a/target/linux/bcm27xx/patches-6.6/950-0027-drm-vc4-hvs-Skip-DebugFS-Registration-for-FKMS.patch +++ b/target/linux/bcm27xx/patches-6.6/950-0027-drm-vc4-hvs-Skip-DebugFS-Registration-for-FKMS.patch @@ -13,7 +13,7 @@ Signed-off-by: Maxime Ripard --- a/drivers/gpu/drm/vc4/vc4_hvs.c +++ b/drivers/gpu/drm/vc4/vc4_hvs.c -@@ -976,6 +976,9 @@ int vc4_hvs_debugfs_init(struct drm_mino +@@ -980,6 +980,9 @@ int vc4_hvs_debugfs_init(struct drm_mino struct vc4_dev *vc4 = to_vc4_dev(drm); struct vc4_hvs *hvs = vc4->hvs; diff --git a/target/linux/bcm27xx/patches-6.6/950-0028-drm-vc4_hdmi-Allow-hotplug-detect-to-be-forced.patch b/target/linux/bcm27xx/patches-6.6/950-0028-drm-vc4_hdmi-Allow-hotplug-detect-to-be-forced.patch index 95b3ec7a248de5..5785fbf667b28b 100644 --- a/target/linux/bcm27xx/patches-6.6/950-0028-drm-vc4_hdmi-Allow-hotplug-detect-to-be-forced.patch +++ b/target/linux/bcm27xx/patches-6.6/950-0028-drm-vc4_hdmi-Allow-hotplug-detect-to-be-forced.patch @@ -45,7 +45,7 @@ Signed-off-by: Dom Cobley static const char * const output_format_str[] = { [VC4_HDMI_OUTPUT_RGB] = "RGB", [VC4_HDMI_OUTPUT_YUV420] = "YUV 4:2:0", -@@ -478,7 +484,9 @@ static int vc4_hdmi_connector_detect_ctx +@@ -482,7 +488,9 @@ static int vc4_hdmi_connector_detect_ctx return connector_status_unknown; } diff --git a/target/linux/bcm27xx/patches-6.6/950-0029-vc4_hdmi-Avoid-log-spam-for-audio-start-failure.patch b/target/linux/bcm27xx/patches-6.6/950-0029-vc4_hdmi-Avoid-log-spam-for-audio-start-failure.patch deleted file mode 100644 index 0baf803edf8d5f..00000000000000 --- a/target/linux/bcm27xx/patches-6.6/950-0029-vc4_hdmi-Avoid-log-spam-for-audio-start-failure.patch +++ /dev/null @@ -1,41 +0,0 @@ -From 7508b889b8c8058e53ceeec90a1e3cc998897e16 Mon Sep 17 00:00:00 2001 -From: Dom Cobley -Date: Tue, 6 Dec 2022 15:05:56 +0000 -Subject: [PATCH 0029/1085] vc4_hdmi: Avoid log spam for audio start failure - -We regularly get dmesg error reports of: -[ 18.184066] hdmi-audio-codec hdmi-audio-codec.3.auto: ASoC: error at snd_soc_dai_startup on i2s-hifi: -19 -[ 18.184098] MAI: soc_pcm_open() failed (-19) - -Currently I get 30 of these when booting to desktop. -We always say, ignore they are harmless, but removing them would be good. - -A bit of investigation shows, for me, the errors are all generated by second, unused hdmi interface. - -It shows as an alsa device, and pulseaudio attempts to open it (numerous times), generating a kernel -error message each time. - -systemctl --user restart pulseaudio.service generates 6 additional error messages. - -The error messages all come through: -https://github.com/raspberrypi/linux/blob/a009a9c0d79dfec114ee5102ec3d3325a172c952/sound/soc/soc-pcm.c#L39 - -which suggests returning ENOTSUPP, rather that ENODEV will be quiet. And indeed it is. - -Note: earlier kernels do not have the quiet ENOTSUPP, so additional cherry-picks will be needed to backport -Signed-off-by: Dom Cobley ---- - drivers/gpu/drm/vc4/vc4_hdmi.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/gpu/drm/vc4/vc4_hdmi.c -+++ b/drivers/gpu/drm/vc4/vc4_hdmi.c -@@ -2400,7 +2400,7 @@ static int vc4_hdmi_audio_startup(struct - } - - if (!vc4_hdmi_audio_can_stream(vc4_hdmi)) { -- ret = -ENODEV; -+ ret = -ENOTSUPP; - goto out_dev_exit; - } - diff --git a/target/linux/bcm27xx/patches-6.6/950-0030-drm-vc4-hvs-Defer-dlist-slots-deallocation.patch b/target/linux/bcm27xx/patches-6.6/950-0030-drm-vc4-hvs-Defer-dlist-slots-deallocation.patch index a53dd1fa637e02..0d052868638180 100644 --- a/target/linux/bcm27xx/patches-6.6/950-0030-drm-vc4-hvs-Defer-dlist-slots-deallocation.patch +++ b/target/linux/bcm27xx/patches-6.6/950-0030-drm-vc4-hvs-Defer-dlist-slots-deallocation.patch @@ -98,7 +98,7 @@ Signed-off-by: Maxime Ripard } --- a/drivers/gpu/drm/vc4/vc4_drv.h +++ b/drivers/gpu/drm/vc4/vc4_drv.h -@@ -332,6 +332,9 @@ struct vc4_hvs { +@@ -333,6 +333,9 @@ struct vc4_hvs { struct drm_mm lbm_mm; spinlock_t mm_lock; @@ -108,7 +108,7 @@ Signed-off-by: Maxime Ripard struct drm_mm_node mitchell_netravali_filter; struct debugfs_regset32 regset; -@@ -619,10 +622,16 @@ struct drm_connector *vc4_get_crtc_conne +@@ -620,10 +623,16 @@ struct drm_connector *vc4_get_crtc_conne struct drm_encoder *vc4_get_crtc_encoder(struct drm_crtc *crtc, struct drm_crtc_state *state); @@ -127,7 +127,7 @@ Signed-off-by: Maxime Ripard bool txp_armed; unsigned int assigned_channel; -@@ -1032,6 +1041,8 @@ struct vc4_hvs *__vc4_hvs_alloc(struct v +@@ -1033,6 +1042,8 @@ struct vc4_hvs *__vc4_hvs_alloc(struct v void vc4_hvs_stop_channel(struct vc4_hvs *hvs, unsigned int output); int vc4_hvs_get_fifo_from_output(struct vc4_hvs *hvs, unsigned int output); u8 vc4_hvs_get_fifo_frame_count(struct vc4_hvs *hvs, unsigned int fifo); @@ -138,7 +138,7 @@ Signed-off-by: Maxime Ripard void vc4_hvs_atomic_enable(struct drm_crtc *crtc, struct drm_atomic_state *state); --- a/drivers/gpu/drm/vc4/vc4_hvs.c +++ b/drivers/gpu/drm/vc4/vc4_hvs.c -@@ -412,6 +412,152 @@ static void vc5_hvs_update_gamma_lut(str +@@ -417,6 +417,152 @@ static void vc5_hvs_update_gamma_lut(str vc5_hvs_lut_load(hvs, vc4_crtc); } @@ -291,7 +291,7 @@ Signed-off-by: Maxime Ripard u8 vc4_hvs_get_fifo_frame_count(struct vc4_hvs *hvs, unsigned int fifo) { struct drm_device *drm = &hvs->vc4->base; -@@ -643,13 +789,12 @@ int vc4_hvs_atomic_check(struct drm_crtc +@@ -646,13 +792,12 @@ int vc4_hvs_atomic_check(struct drm_crtc { struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state, crtc); struct vc4_crtc_state *vc4_state = to_vc4_crtc_state(crtc_state); @@ -306,7 +306,7 @@ Signed-off-by: Maxime Ripard /* The pixelvalve can only feed one encoder (and encoders are * 1:1 with connectors.) -@@ -662,12 +807,11 @@ int vc4_hvs_atomic_check(struct drm_crtc +@@ -665,12 +810,11 @@ int vc4_hvs_atomic_check(struct drm_crtc dlist_count++; /* Account for SCALER_CTL0_END. */ @@ -324,7 +324,7 @@ Signed-off-by: Maxime Ripard return vc4_hvs_gamma_check(crtc, state); } -@@ -683,8 +827,9 @@ static void vc4_hvs_install_dlist(struct +@@ -686,8 +830,9 @@ static void vc4_hvs_install_dlist(struct if (!drm_dev_enter(dev, &idx)) return; @@ -335,7 +335,7 @@ Signed-off-by: Maxime Ripard drm_dev_exit(idx); } -@@ -711,8 +856,10 @@ static void vc4_hvs_update_dlist(struct +@@ -714,8 +859,10 @@ static void vc4_hvs_update_dlist(struct spin_unlock_irqrestore(&dev->event_lock, flags); } @@ -347,7 +347,7 @@ Signed-off-by: Maxime Ripard spin_unlock_irqrestore(&vc4_crtc->irq_lock, flags); } -@@ -769,8 +916,7 @@ void vc4_hvs_atomic_flush(struct drm_crt +@@ -772,8 +919,7 @@ void vc4_hvs_atomic_flush(struct drm_crt struct vc4_plane_state *vc4_plane_state; bool debug_dump_regs = false; bool enable_bg_fill = false; @@ -357,7 +357,7 @@ Signed-off-by: Maxime Ripard unsigned int zpos = 0; bool found = false; int idx; -@@ -788,6 +934,9 @@ void vc4_hvs_atomic_flush(struct drm_crt +@@ -791,6 +937,9 @@ void vc4_hvs_atomic_flush(struct drm_crt vc4_hvs_dump_state(hvs); } @@ -367,7 +367,7 @@ Signed-off-by: Maxime Ripard /* Copy all the active planes' dlist contents to the hardware dlist. */ do { found = false; -@@ -821,7 +970,8 @@ void vc4_hvs_atomic_flush(struct drm_crt +@@ -824,7 +973,8 @@ void vc4_hvs_atomic_flush(struct drm_crt writel(SCALER_CTL0_END, dlist_next); dlist_next++; @@ -377,7 +377,7 @@ Signed-off-by: Maxime Ripard if (enable_bg_fill) /* This sets a black background color fill, as is the case -@@ -960,6 +1110,11 @@ static irqreturn_t vc4_hvs_irq_handler(i +@@ -964,6 +1114,11 @@ static irqreturn_t vc4_hvs_irq_handler(i irqret = IRQ_HANDLED; } @@ -389,7 +389,7 @@ Signed-off-by: Maxime Ripard } /* Clear every per-channel interrupt flag. */ -@@ -1014,6 +1169,9 @@ struct vc4_hvs *__vc4_hvs_alloc(struct v +@@ -1018,6 +1173,9 @@ struct vc4_hvs *__vc4_hvs_alloc(struct v spin_lock_init(&hvs->mm_lock); diff --git a/target/linux/bcm27xx/patches-6.6/950-0031-drm-vc4-hvs-Initialize-the-dlist-allocation-list-ent.patch b/target/linux/bcm27xx/patches-6.6/950-0031-drm-vc4-hvs-Initialize-the-dlist-allocation-list-ent.patch index d250dd4e1e15bf..2fd7aa573de881 100644 --- a/target/linux/bcm27xx/patches-6.6/950-0031-drm-vc4-hvs-Initialize-the-dlist-allocation-list-ent.patch +++ b/target/linux/bcm27xx/patches-6.6/950-0031-drm-vc4-hvs-Initialize-the-dlist-allocation-list-ent.patch @@ -19,7 +19,7 @@ Signed-off-by: Maxime Ripard --- a/drivers/gpu/drm/vc4/vc4_hvs.c +++ b/drivers/gpu/drm/vc4/vc4_hvs.c -@@ -452,6 +452,8 @@ vc4_hvs_alloc_dlist_entry(struct vc4_hvs +@@ -457,6 +457,8 @@ vc4_hvs_alloc_dlist_entry(struct vc4_hvs if (!alloc) return ERR_PTR(-ENOMEM); diff --git a/target/linux/bcm27xx/patches-6.6/950-0032-drm-vc4-hvs-Move-the-dlist-allocation-destruction-to.patch b/target/linux/bcm27xx/patches-6.6/950-0032-drm-vc4-hvs-Move-the-dlist-allocation-destruction-to.patch index f6fe9e1a4c20b2..07fb255e66109f 100644 --- a/target/linux/bcm27xx/patches-6.6/950-0032-drm-vc4-hvs-Move-the-dlist-allocation-destruction-to.patch +++ b/target/linux/bcm27xx/patches-6.6/950-0032-drm-vc4-hvs-Move-the-dlist-allocation-destruction-to.patch @@ -14,7 +14,7 @@ Signed-off-by: Maxime Ripard --- a/drivers/gpu/drm/vc4/vc4_hvs.c +++ b/drivers/gpu/drm/vc4/vc4_hvs.c -@@ -466,6 +466,18 @@ vc4_hvs_alloc_dlist_entry(struct vc4_hvs +@@ -471,6 +471,18 @@ vc4_hvs_alloc_dlist_entry(struct vc4_hvs return alloc; } @@ -33,7 +33,7 @@ Signed-off-by: Maxime Ripard void vc4_hvs_mark_dlist_entry_stale(struct vc4_hvs *hvs, struct vc4_hvs_dlist_allocation *alloc) { -@@ -553,9 +565,7 @@ static void vc4_hvs_dlist_free_work(stru +@@ -558,9 +570,7 @@ static void vc4_hvs_dlist_free_work(stru if (!vc4_hvs_frcnt_lte(cur->target_frame_count, frcnt)) continue; diff --git a/target/linux/bcm27xx/patches-6.6/950-0033-drm-vc4-hvs-Destroy-dlist-allocations-immediately-wh.patch b/target/linux/bcm27xx/patches-6.6/950-0033-drm-vc4-hvs-Destroy-dlist-allocations-immediately-wh.patch index 6c8689e169cb46..ecfabf63b92a59 100644 --- a/target/linux/bcm27xx/patches-6.6/950-0033-drm-vc4-hvs-Destroy-dlist-allocations-immediately-wh.patch +++ b/target/linux/bcm27xx/patches-6.6/950-0033-drm-vc4-hvs-Destroy-dlist-allocations-immediately-wh.patch @@ -27,7 +27,7 @@ Signed-off-by: Maxime Ripard --- a/drivers/gpu/drm/vc4/vc4_hvs.c +++ b/drivers/gpu/drm/vc4/vc4_hvs.c -@@ -490,6 +490,18 @@ void vc4_hvs_mark_dlist_entry_stale(stru +@@ -495,6 +495,18 @@ void vc4_hvs_mark_dlist_entry_stale(stru if (!drm_mm_node_allocated(&alloc->mm_node)) return; diff --git a/target/linux/bcm27xx/patches-6.6/950-0035-drm-vc4-Calculate-bpc-based-on-max_requested_bpc.patch b/target/linux/bcm27xx/patches-6.6/950-0035-drm-vc4-Calculate-bpc-based-on-max_requested_bpc.patch index f0fb3eb7d47eee..fbaa2619aa52b2 100644 --- a/target/linux/bcm27xx/patches-6.6/950-0035-drm-vc4-Calculate-bpc-based-on-max_requested_bpc.patch +++ b/target/linux/bcm27xx/patches-6.6/950-0035-drm-vc4-Calculate-bpc-based-on-max_requested_bpc.patch @@ -18,7 +18,7 @@ Signed-off-by: Matthias Reichl --- a/drivers/gpu/drm/vc4/vc4_hdmi.c +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c -@@ -2132,7 +2132,7 @@ vc4_hdmi_encoder_compute_config(const st +@@ -2136,7 +2136,7 @@ vc4_hdmi_encoder_compute_config(const st { struct drm_device *dev = vc4_hdmi->connector.dev; struct drm_connector_state *conn_state = &vc4_state->base; diff --git a/target/linux/bcm27xx/patches-6.6/950-0036-drm-vc4-Set-AXI-panic-modes-for-the-HVS.patch b/target/linux/bcm27xx/patches-6.6/950-0036-drm-vc4-Set-AXI-panic-modes-for-the-HVS.patch index 996094739581f7..3ecea01fcd56a6 100644 --- a/target/linux/bcm27xx/patches-6.6/950-0036-drm-vc4-Set-AXI-panic-modes-for-the-HVS.patch +++ b/target/linux/bcm27xx/patches-6.6/950-0036-drm-vc4-Set-AXI-panic-modes-for-the-HVS.patch @@ -19,7 +19,7 @@ Signed-off-by: Dave Stevenson --- a/drivers/gpu/drm/vc4/vc4_hvs.c +++ b/drivers/gpu/drm/vc4/vc4_hvs.c -@@ -1363,6 +1363,17 @@ static int vc4_hvs_bind(struct device *d +@@ -1379,6 +1379,17 @@ static int vc4_hvs_bind(struct device *d dispctrl |= VC4_SET_FIELD(2, SCALER_DISPCTRL_PANIC1); dispctrl |= VC4_SET_FIELD(2, SCALER_DISPCTRL_PANIC2); diff --git a/target/linux/bcm27xx/patches-6.6/950-0037-drm-vc4-drop-unnecessary-and-harmful-HDMI-RGB-format.patch b/target/linux/bcm27xx/patches-6.6/950-0037-drm-vc4-drop-unnecessary-and-harmful-HDMI-RGB-format.patch index b9fba16f695737..18b5b63b547870 100644 --- a/target/linux/bcm27xx/patches-6.6/950-0037-drm-vc4-drop-unnecessary-and-harmful-HDMI-RGB-format.patch +++ b/target/linux/bcm27xx/patches-6.6/950-0037-drm-vc4-drop-unnecessary-and-harmful-HDMI-RGB-format.patch @@ -25,7 +25,7 @@ Signed-off-by: Matthias Reichl --- a/drivers/gpu/drm/vc4/vc4_hdmi.c +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c -@@ -1958,9 +1958,6 @@ vc4_hdmi_sink_supports_format_bpc(const +@@ -1962,9 +1962,6 @@ vc4_hdmi_sink_supports_format_bpc(const case VC4_HDMI_OUTPUT_RGB: drm_dbg(dev, "RGB Format, checking the constraints.\n"); diff --git a/target/linux/bcm27xx/patches-6.6/950-0038-drm-vc4-Limit-max_bpc-to-8-on-Pi0-3.patch b/target/linux/bcm27xx/patches-6.6/950-0038-drm-vc4-Limit-max_bpc-to-8-on-Pi0-3.patch index 2b86f419529670..b3b1c3d9e4348c 100644 --- a/target/linux/bcm27xx/patches-6.6/950-0038-drm-vc4-Limit-max_bpc-to-8-on-Pi0-3.patch +++ b/target/linux/bcm27xx/patches-6.6/950-0038-drm-vc4-Limit-max_bpc-to-8-on-Pi0-3.patch @@ -13,7 +13,7 @@ Signed-off-by: Dave Stevenson --- a/drivers/gpu/drm/vc4/vc4_hdmi.c +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c -@@ -762,7 +762,6 @@ static int vc4_hdmi_connector_init(struc +@@ -766,7 +766,6 @@ static int vc4_hdmi_connector_init(struc drm_connector_attach_colorspace_property(connector); drm_connector_attach_tv_margin_properties(connector); @@ -21,7 +21,7 @@ Signed-off-by: Dave Stevenson connector->polled = (DRM_CONNECTOR_POLL_CONNECT | DRM_CONNECTOR_POLL_DISCONNECT); -@@ -771,8 +770,12 @@ static int vc4_hdmi_connector_init(struc +@@ -775,8 +774,12 @@ static int vc4_hdmi_connector_init(struc connector->doublescan_allowed = 0; connector->stereo_allowed = 1; diff --git a/target/linux/bcm27xx/patches-6.6/950-0039-arm64-setup-Fix-build-warning.patch b/target/linux/bcm27xx/patches-6.6/950-0039-arm64-setup-Fix-build-warning.patch index a53c896daaaf65..75e552a7ef036c 100644 --- a/target/linux/bcm27xx/patches-6.6/950-0039-arm64-setup-Fix-build-warning.patch +++ b/target/linux/bcm27xx/patches-6.6/950-0039-arm64-setup-Fix-build-warning.patch @@ -10,7 +10,7 @@ Signed-off-by: Maxime Ripard --- a/arch/arm64/kernel/setup.c +++ b/arch/arm64/kernel/setup.c -@@ -225,9 +225,9 @@ static void __init request_standard_reso +@@ -229,9 +229,9 @@ static void __init request_standard_reso size_t res_size; kernel_code.start = __pa_symbol(_stext); diff --git a/target/linux/bcm27xx/patches-6.6/950-0061-Revert-Revert-xhci-add-quirk-for-host-controllers-th.patch b/target/linux/bcm27xx/patches-6.6/950-0061-Revert-Revert-xhci-add-quirk-for-host-controllers-th.patch index 1135b31d4f6222..3dce8aa62158b5 100644 --- a/target/linux/bcm27xx/patches-6.6/950-0061-Revert-Revert-xhci-add-quirk-for-host-controllers-th.patch +++ b/target/linux/bcm27xx/patches-6.6/950-0061-Revert-Revert-xhci-add-quirk-for-host-controllers-th.patch @@ -14,21 +14,17 @@ We don't agree with upstream revert so undo it. --- a/drivers/usb/host/xhci-pci.c +++ b/drivers/usb/host/xhci-pci.c -@@ -490,8 +490,10 @@ static void xhci_pci_quirks(struct devic - pdev->device == 0x3432) - xhci->quirks |= XHCI_BROKEN_STREAMS; - -- if (pdev->vendor == PCI_VENDOR_ID_VIA && pdev->device == 0x3483) -+ if (pdev->vendor == PCI_VENDOR_ID_VIA && pdev->device == 0x3483) { +@@ -510,6 +510,7 @@ static void xhci_pci_quirks(struct devic + if (pdev->vendor == PCI_VENDOR_ID_VIA && pdev->device == PCI_DEVICE_ID_VIA_VL805) { xhci->quirks |= XHCI_LPM_SUPPORT; + xhci->quirks |= XHCI_TRB_OVERFETCH; + xhci->quirks |= XHCI_EP_CTX_BROKEN_DCS; -+ } + } if (pdev->vendor == PCI_VENDOR_ID_ASMEDIA && - pdev->device == PCI_DEVICE_ID_ASMEDIA_1042_XHCI) { --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c -@@ -633,8 +633,11 @@ static int xhci_move_dequeue_past_td(str +@@ -635,8 +635,11 @@ static int xhci_move_dequeue_past_td(str struct xhci_ring *ep_ring; struct xhci_command *cmd; struct xhci_segment *new_seg; @@ -40,7 +36,7 @@ We don't agree with upstream revert so undo it. dma_addr_t addr; u64 hw_dequeue; bool cycle_found = false; -@@ -672,7 +675,27 @@ static int xhci_move_dequeue_past_td(str +@@ -674,7 +677,27 @@ static int xhci_move_dequeue_past_td(str hw_dequeue = xhci_get_hw_deq(xhci, dev, ep_index, stream_id); new_seg = ep_ring->deq_seg; new_deq = ep_ring->dequeue; diff --git a/target/linux/bcm27xx/patches-6.6/950-0065-cgroup-Disable-cgroup-memory-by-default.patch b/target/linux/bcm27xx/patches-6.6/950-0065-cgroup-Disable-cgroup-memory-by-default.patch index 8a06ec387e6ef6..5600e857341644 100644 --- a/target/linux/bcm27xx/patches-6.6/950-0065-cgroup-Disable-cgroup-memory-by-default.patch +++ b/target/linux/bcm27xx/patches-6.6/950-0065-cgroup-Disable-cgroup-memory-by-default.patch @@ -17,7 +17,7 @@ Signed-off-by: Phil Elwell --- a/kernel/cgroup/cgroup.c +++ b/kernel/cgroup/cgroup.c -@@ -6060,6 +6060,9 @@ int __init cgroup_init_early(void) +@@ -6059,6 +6059,9 @@ int __init cgroup_init_early(void) return 0; } @@ -27,7 +27,7 @@ Signed-off-by: Phil Elwell /** * cgroup_init - cgroup initialization * -@@ -6093,6 +6096,12 @@ int __init cgroup_init(void) +@@ -6092,6 +6095,12 @@ int __init cgroup_init(void) cgroup_unlock(); @@ -40,7 +40,7 @@ Signed-off-by: Phil Elwell for_each_subsys(ss, ssid) { if (ss->early_init) { struct cgroup_subsys_state *css = -@@ -6733,6 +6742,10 @@ static int __init cgroup_disable(char *s +@@ -6740,6 +6749,10 @@ static int __init cgroup_disable(char *s strcmp(token, ss->legacy_name)) continue; @@ -51,7 +51,7 @@ Signed-off-by: Phil Elwell static_branch_disable(cgroup_subsys_enabled_key[i]); pr_info("Disabling %s control group subsystem\n", ss->name); -@@ -6751,6 +6764,31 @@ static int __init cgroup_disable(char *s +@@ -6758,6 +6771,31 @@ static int __init cgroup_disable(char *s } __setup("cgroup_disable=", cgroup_disable); diff --git a/target/linux/bcm27xx/patches-6.6/950-0077-sound-Demote-deferral-errors-to-INFO-level.patch b/target/linux/bcm27xx/patches-6.6/950-0077-sound-Demote-deferral-errors-to-INFO-level.patch index 623c859a43f69c..9255c4480f7886 100644 --- a/target/linux/bcm27xx/patches-6.6/950-0077-sound-Demote-deferral-errors-to-INFO-level.patch +++ b/target/linux/bcm27xx/patches-6.6/950-0077-sound-Demote-deferral-errors-to-INFO-level.patch @@ -15,7 +15,7 @@ Signed-off-by: Phil Elwell --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c -@@ -1080,7 +1080,7 @@ static int snd_soc_add_pcm_runtime(struc +@@ -1083,7 +1083,7 @@ static int snd_soc_add_pcm_runtime(struc for_each_link_cpus(dai_link, i, cpu) { asoc_rtd_to_cpu(rtd, i) = snd_soc_find_dai(cpu); if (!asoc_rtd_to_cpu(rtd, i)) { @@ -24,7 +24,7 @@ Signed-off-by: Phil Elwell cpu->dai_name); goto _err_defer; } -@@ -1091,7 +1091,7 @@ static int snd_soc_add_pcm_runtime(struc +@@ -1094,7 +1094,7 @@ static int snd_soc_add_pcm_runtime(struc for_each_link_codecs(dai_link, i, codec) { asoc_rtd_to_codec(rtd, i) = snd_soc_find_dai(codec); if (!asoc_rtd_to_codec(rtd, i)) { diff --git a/target/linux/bcm27xx/patches-6.6/950-0081-lan78xx-Enable-LEDs-and-auto-negotiation.patch b/target/linux/bcm27xx/patches-6.6/950-0081-lan78xx-Enable-LEDs-and-auto-negotiation.patch index 8735b0617017ad..fb248b08892ddb 100644 --- a/target/linux/bcm27xx/patches-6.6/950-0081-lan78xx-Enable-LEDs-and-auto-negotiation.patch +++ b/target/linux/bcm27xx/patches-6.6/950-0081-lan78xx-Enable-LEDs-and-auto-negotiation.patch @@ -14,7 +14,7 @@ Signed-off-by: Phil Elwell --- a/drivers/net/usb/lan78xx.c +++ b/drivers/net/usb/lan78xx.c -@@ -2883,6 +2883,11 @@ static int lan78xx_reset(struct lan78xx_ +@@ -2884,6 +2884,11 @@ static int lan78xx_reset(struct lan78xx_ int ret; u32 buf; u8 sig; @@ -26,7 +26,7 @@ Signed-off-by: Phil Elwell ret = lan78xx_read_reg(dev, HW_CFG, &buf); if (ret < 0) -@@ -2947,6 +2952,10 @@ static int lan78xx_reset(struct lan78xx_ +@@ -2948,6 +2953,10 @@ static int lan78xx_reset(struct lan78xx_ buf |= HW_CFG_MEF_; @@ -37,7 +37,7 @@ Signed-off-by: Phil Elwell ret = lan78xx_write_reg(dev, HW_CFG, buf); if (ret < 0) return ret; -@@ -3046,6 +3055,9 @@ static int lan78xx_reset(struct lan78xx_ +@@ -3047,6 +3056,9 @@ static int lan78xx_reset(struct lan78xx_ buf |= MAC_CR_AUTO_DUPLEX_ | MAC_CR_AUTO_SPEED_; } } diff --git a/target/linux/bcm27xx/patches-6.6/950-0083-amba_pl011-Add-cts-event-workaround-DT-property.patch b/target/linux/bcm27xx/patches-6.6/950-0083-amba_pl011-Add-cts-event-workaround-DT-property.patch index 58910b861198a3..efee03dc801a74 100644 --- a/target/linux/bcm27xx/patches-6.6/950-0083-amba_pl011-Add-cts-event-workaround-DT-property.patch +++ b/target/linux/bcm27xx/patches-6.6/950-0083-amba_pl011-Add-cts-event-workaround-DT-property.patch @@ -36,7 +36,7 @@ Signed-off-by: Phil Elwell - reg --- a/drivers/tty/serial/amba-pl011.c +++ b/drivers/tty/serial/amba-pl011.c -@@ -2808,6 +2808,11 @@ static int pl011_probe(struct amba_devic +@@ -2815,6 +2815,11 @@ static int pl011_probe(struct amba_devic if (IS_ERR(uap->clk)) return PTR_ERR(uap->clk); diff --git a/target/linux/bcm27xx/patches-6.6/950-0087-Add-dwc_otg-driver.patch b/target/linux/bcm27xx/patches-6.6/950-0087-Add-dwc_otg-driver.patch index cb9fd4442a3481..0dd0c034003d85 100644 --- a/target/linux/bcm27xx/patches-6.6/950-0087-Add-dwc_otg-driver.patch +++ b/target/linux/bcm27xx/patches-6.6/950-0087-Add-dwc_otg-driver.patch @@ -1189,7 +1189,7 @@ Signed-off-by: Alexander Winkowski } --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c -@@ -5710,7 +5710,7 @@ static void port_event(struct usb_hub *h +@@ -5751,7 +5751,7 @@ static void port_event(struct usb_hub *h port_dev->over_current_count++; port_over_current_notify(port_dev); diff --git a/target/linux/bcm27xx/patches-6.6/950-0092-MMC-added-alternative-MMC-driver.patch b/target/linux/bcm27xx/patches-6.6/950-0092-MMC-added-alternative-MMC-driver.patch index aebb491f32af30..6dddd80026ac15 100644 --- a/target/linux/bcm27xx/patches-6.6/950-0092-MMC-added-alternative-MMC-driver.patch +++ b/target/linux/bcm27xx/patches-6.6/950-0092-MMC-added-alternative-MMC-driver.patch @@ -344,7 +344,7 @@ Signed-off-by: Phil Elwell } --- a/drivers/mmc/core/quirks.h +++ b/drivers/mmc/core/quirks.h -@@ -134,6 +134,14 @@ static const struct mmc_fixup __maybe_un +@@ -50,6 +50,14 @@ static const struct mmc_fixup __maybe_un MMC_FIXUP(CID_NAME_ANY, CID_MANFID_SANDISK_SD, 0x5344, add_quirk_sd, MMC_QUIRK_BROKEN_SD_DISCARD), @@ -2013,10 +2013,10 @@ Signed-off-by: Phil Elwell sdhci_dumpregs(host); --- a/include/linux/mmc/card.h +++ b/include/linux/mmc/card.h -@@ -296,6 +296,7 @@ struct mmc_card { - #define MMC_QUIRK_BROKEN_SD_DISCARD (1<<14) /* Disable broken SD discard support */ - #define MMC_QUIRK_BROKEN_SD_CACHE (1<<15) /* Disable broken SD cache support */ +@@ -298,6 +298,7 @@ struct mmc_card { #define MMC_QUIRK_BROKEN_CACHE_FLUSH (1<<16) /* Don't flush cache until the write has occurred */ + #define MMC_QUIRK_BROKEN_SD_POWEROFF_NOTIFY (1<<17) /* Disable broken SD poweroff notify support */ + #define MMC_QUIRK_NO_UHS_DDR50_TUNING (1<<18) /* Disable DDR50 tuning */ +#define MMC_QUIRK_ERASE_BROKEN (1<<31) /* Skip erase */ bool written_flag; /* Indicates eMMC has been written since power on */ diff --git a/target/linux/bcm27xx/patches-6.6/950-0106-Add-support-for-all-the-downstream-rpi-sound-card-dr.patch b/target/linux/bcm27xx/patches-6.6/950-0106-Add-support-for-all-the-downstream-rpi-sound-card-dr.patch index 8685508ddf6af7..58aa9440874d4d 100644 --- a/target/linux/bcm27xx/patches-6.6/950-0106-Add-support-for-all-the-downstream-rpi-sound-card-dr.patch +++ b/target/linux/bcm27xx/patches-6.6/950-0106-Add-support-for-all-the-downstream-rpi-sound-card-dr.patch @@ -14927,7 +14927,7 @@ Signed-off-by: Phil Elwell config SND_SOC_TFA989X tristate "NXP/Goodix TFA989X (TFA1) amplifiers" depends on I2C -@@ -2404,4 +2422,8 @@ config SND_SOC_LPASS_TX_MACRO +@@ -2405,4 +2423,8 @@ config SND_SOC_LPASS_TX_MACRO select SND_SOC_LPASS_MACRO_COMMON tristate "Qualcomm TX Macro in LPASS(Low Power Audio SubSystem)" @@ -17546,7 +17546,7 @@ Signed-off-by: Phil Elwell +#endif /* _TAS5713_H */ --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c -@@ -1316,7 +1316,15 @@ int snd_soc_runtime_set_dai_fmt(struct s +@@ -1319,7 +1319,15 @@ int snd_soc_runtime_set_dai_fmt(struct s return 0; for_each_rtd_codec_dais(rtd, i, codec_dai) { @@ -17583,7 +17583,7 @@ Signed-off-by: Phil Elwell * For devices with more than one control interface, we assume the --- a/sound/usb/quirks.c +++ b/sound/usb/quirks.c -@@ -2195,6 +2195,8 @@ static const struct usb_audio_quirk_flag +@@ -2260,6 +2260,8 @@ static const struct usb_audio_quirk_flag QUIRK_FLAG_ALIGN_TRANSFER), DEVICE_FLG(0x534d, 0x2109, /* MacroSilicon MS2109 */ QUIRK_FLAG_ALIGN_TRANSFER), diff --git a/target/linux/bcm27xx/patches-6.6/950-0120-lan78xx-Read-initial-EEE-status-from-DT.patch b/target/linux/bcm27xx/patches-6.6/950-0120-lan78xx-Read-initial-EEE-status-from-DT.patch index 296ceae6c70c3a..7aa05b0abc4225 100644 --- a/target/linux/bcm27xx/patches-6.6/950-0120-lan78xx-Read-initial-EEE-status-from-DT.patch +++ b/target/linux/bcm27xx/patches-6.6/950-0120-lan78xx-Read-initial-EEE-status-from-DT.patch @@ -15,7 +15,7 @@ Signed-off-by: Phil Elwell --- a/drivers/net/usb/lan78xx.c +++ b/drivers/net/usb/lan78xx.c -@@ -3111,6 +3111,22 @@ static int lan78xx_open(struct net_devic +@@ -3112,6 +3112,22 @@ static int lan78xx_open(struct net_devic netif_dbg(dev, ifup, dev->net, "phy initialised successfully"); diff --git a/target/linux/bcm27xx/patches-6.6/950-0121-hid-Reduce-default-mouse-polling-interval-to-60Hz.patch b/target/linux/bcm27xx/patches-6.6/950-0121-hid-Reduce-default-mouse-polling-interval-to-60Hz.patch index c3563ba402c85b..1584a946c533d6 100644 --- a/target/linux/bcm27xx/patches-6.6/950-0121-hid-Reduce-default-mouse-polling-interval-to-60Hz.patch +++ b/target/linux/bcm27xx/patches-6.6/950-0121-hid-Reduce-default-mouse-polling-interval-to-60Hz.patch @@ -19,7 +19,7 @@ Reduces overhead when using X module_param_named(mousepoll, hid_mousepoll_interval, uint, 0644); MODULE_PARM_DESC(mousepoll, "Polling interval of mice"); -@@ -1112,7 +1112,9 @@ static int usbhid_start(struct hid_devic +@@ -1115,7 +1115,9 @@ static int usbhid_start(struct hid_devic */ switch (hid->collection->usage) { case HID_GD_MOUSE: diff --git a/target/linux/bcm27xx/patches-6.6/950-0125-net-lan78xx-Disable-TCP-Segmentation-Offload-TSO.patch b/target/linux/bcm27xx/patches-6.6/950-0125-net-lan78xx-Disable-TCP-Segmentation-Offload-TSO.patch index 7738bdb8da8688..1b6643508b38cc 100644 --- a/target/linux/bcm27xx/patches-6.6/950-0125-net-lan78xx-Disable-TCP-Segmentation-Offload-TSO.patch +++ b/target/linux/bcm27xx/patches-6.6/950-0125-net-lan78xx-Disable-TCP-Segmentation-Offload-TSO.patch @@ -38,7 +38,7 @@ Signed-off-by: Dave Stevenson static int lan78xx_read_reg(struct lan78xx_net *dev, u32 index, u32 *data) { u32 *buf; -@@ -3471,8 +3480,14 @@ static int lan78xx_bind(struct lan78xx_n +@@ -3472,8 +3481,14 @@ static int lan78xx_bind(struct lan78xx_n if (DEFAULT_RX_CSUM_ENABLE) dev->net->features |= NETIF_F_RXCSUM; diff --git a/target/linux/bcm27xx/patches-6.6/950-0127-lan78xx-Move-enabling-of-EEE-into-PHY-init-code.patch b/target/linux/bcm27xx/patches-6.6/950-0127-lan78xx-Move-enabling-of-EEE-into-PHY-init-code.patch index f73106ab4bd8b4..f98d2c7dd63c18 100644 --- a/target/linux/bcm27xx/patches-6.6/950-0127-lan78xx-Move-enabling-of-EEE-into-PHY-init-code.patch +++ b/target/linux/bcm27xx/patches-6.6/950-0127-lan78xx-Move-enabling-of-EEE-into-PHY-init-code.patch @@ -16,7 +16,7 @@ Signed-off-by: Phil Elwell --- a/drivers/net/usb/lan78xx.c +++ b/drivers/net/usb/lan78xx.c -@@ -2419,6 +2419,22 @@ static int lan78xx_phy_init(struct lan78 +@@ -2420,6 +2420,22 @@ static int lan78xx_phy_init(struct lan78 mii_adv_to_linkmode_adv_t(fc, mii_adv); linkmode_or(phydev->advertising, fc, phydev->advertising); @@ -39,7 +39,7 @@ Signed-off-by: Phil Elwell if (phydev->mdio.dev.of_node) { u32 reg; int len; -@@ -3120,22 +3136,6 @@ static int lan78xx_open(struct net_devic +@@ -3121,22 +3137,6 @@ static int lan78xx_open(struct net_devic netif_dbg(dev, ifup, dev->net, "phy initialised successfully"); diff --git a/target/linux/bcm27xx/patches-6.6/950-0130-serial-sc16is7xx-Don-t-spin-if-no-data-received.patch b/target/linux/bcm27xx/patches-6.6/950-0130-serial-sc16is7xx-Don-t-spin-if-no-data-received.patch index eceba53aabdaa7..4ef34aeffc0b6a 100644 --- a/target/linux/bcm27xx/patches-6.6/950-0130-serial-sc16is7xx-Don-t-spin-if-no-data-received.patch +++ b/target/linux/bcm27xx/patches-6.6/950-0130-serial-sc16is7xx-Don-t-spin-if-no-data-received.patch @@ -15,7 +15,7 @@ Signed-off-by: Phil Elwell --- a/drivers/tty/serial/sc16is7xx.c +++ b/drivers/tty/serial/sc16is7xx.c -@@ -773,6 +773,8 @@ static bool sc16is7xx_port_irq(struct sc +@@ -777,6 +777,8 @@ static bool sc16is7xx_port_irq(struct sc if (rxlen) sc16is7xx_handle_rx(port, rxlen, iir); diff --git a/target/linux/bcm27xx/patches-6.6/950-0131-net-lan78xx-Support-auto-downshift-to-100Mb-s.patch b/target/linux/bcm27xx/patches-6.6/950-0131-net-lan78xx-Support-auto-downshift-to-100Mb-s.patch index acc0d7f3e86f59..0c6145ae51c71b 100644 --- a/target/linux/bcm27xx/patches-6.6/950-0131-net-lan78xx-Support-auto-downshift-to-100Mb-s.patch +++ b/target/linux/bcm27xx/patches-6.6/950-0131-net-lan78xx-Support-auto-downshift-to-100Mb-s.patch @@ -31,7 +31,7 @@ Signed-off-by: Phil Elwell --- a/drivers/net/phy/microchip.c +++ b/drivers/net/phy/microchip.c -@@ -233,6 +233,7 @@ static int lan88xx_probe(struct phy_devi +@@ -192,6 +192,7 @@ static int lan88xx_probe(struct phy_devi struct device *dev = &phydev->mdio.dev; struct lan88xx_priv *priv; u32 led_modes[4]; @@ -39,7 +39,7 @@ Signed-off-by: Phil Elwell int len; priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); -@@ -262,6 +263,32 @@ static int lan88xx_probe(struct phy_devi +@@ -221,6 +222,32 @@ static int lan88xx_probe(struct phy_devi return -EINVAL; } diff --git a/target/linux/bcm27xx/patches-6.6/950-0133-lan78xx-Debounce-link-events-to-minimize-poll-storm.patch b/target/linux/bcm27xx/patches-6.6/950-0133-lan78xx-Debounce-link-events-to-minimize-poll-storm.patch index dc411233dfa2ff..46bfe50f1aa490 100644 --- a/target/linux/bcm27xx/patches-6.6/950-0133-lan78xx-Debounce-link-events-to-minimize-poll-storm.patch +++ b/target/linux/bcm27xx/patches-6.6/950-0133-lan78xx-Debounce-link-events-to-minimize-poll-storm.patch @@ -29,7 +29,7 @@ See: https://github.com/raspberrypi/linux/issues/2447 static int lan78xx_read_reg(struct lan78xx_net *dev, u32 index, u32 *data) { u32 *buf; -@@ -4455,7 +4460,13 @@ static int lan78xx_probe(struct usb_inte +@@ -4456,7 +4461,13 @@ static int lan78xx_probe(struct usb_inte if (ret < 0) goto out4; @@ -42,5 +42,5 @@ See: https://github.com/raspberrypi/linux/issues/2447 + netif_notice(dev, probe, netdev, "int urb period %d\n", period); + maxp = usb_maxpacket(dev->udev, dev->pipe_intr); - buf = kmalloc(maxp, GFP_KERNEL); - if (!buf) { + + dev->urb_intr = usb_alloc_urb(0, GFP_KERNEL); diff --git a/target/linux/bcm27xx/patches-6.6/950-0134-lan78xx-EEE-support-is-now-a-PHY-property.patch b/target/linux/bcm27xx/patches-6.6/950-0134-lan78xx-EEE-support-is-now-a-PHY-property.patch index df6c7e687fd7d3..b5e0095d97c01d 100644 --- a/target/linux/bcm27xx/patches-6.6/950-0134-lan78xx-EEE-support-is-now-a-PHY-property.patch +++ b/target/linux/bcm27xx/patches-6.6/950-0134-lan78xx-EEE-support-is-now-a-PHY-property.patch @@ -15,7 +15,7 @@ Signed-off-by: Phil Elwell --- a/drivers/net/usb/lan78xx.c +++ b/drivers/net/usb/lan78xx.c -@@ -2424,7 +2424,7 @@ static int lan78xx_phy_init(struct lan78 +@@ -2425,7 +2425,7 @@ static int lan78xx_phy_init(struct lan78 mii_adv_to_linkmode_adv_t(fc, mii_adv); linkmode_or(phydev->advertising, fc, phydev->advertising); diff --git a/target/linux/bcm27xx/patches-6.6/950-0135-media-tc358743-Increase-FIFO-level-to-374.patch b/target/linux/bcm27xx/patches-6.6/950-0135-media-tc358743-Increase-FIFO-level-to-374.patch deleted file mode 100644 index 79c13d562399ca..00000000000000 --- a/target/linux/bcm27xx/patches-6.6/950-0135-media-tc358743-Increase-FIFO-level-to-374.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 1026232b9a7af3439c2d9cc9a793240028fbf9a4 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Wed, 31 Oct 2018 14:56:59 +0000 -Subject: [PATCH 0135/1085] media: tc358743: Increase FIFO level to 374. - -The existing fixed value of 16 worked for UYVY 720P60 over -2 lanes at 594MHz, or UYVY 1080P60 over 4 lanes. (RGB888 -1080P60 needs 6 lanes at 594MHz). -It doesn't allow for lower resolutions to work as the FIFO -underflows. - -374 is required for 1080P24-30 UYVY over 2 lanes @ 972Mbit/s, but ->374 means that the FIFO underflows on 1080P50 UYVY over 2 lanes -@ 972Mbit/s. - -Signed-off-by: Dave Stevenson ---- - drivers/media/i2c/tc358743.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/media/i2c/tc358743.c -+++ b/drivers/media/i2c/tc358743.c -@@ -1933,7 +1933,7 @@ static int tc358743_probe_of(struct tc35 - state->pdata.ddc5v_delay = DDC5V_DELAY_100_MS; - state->pdata.enable_hdcp = false; - /* A FIFO level of 16 should be enough for 2-lane 720p60 at 594 MHz. */ -- state->pdata.fifo_level = 16; -+ state->pdata.fifo_level = 374; - /* - * The PLL input clock is obtained by dividing refclk by pll_prd. - * It must be between 6 MHz and 40 MHz, lower frequency is better. diff --git a/target/linux/bcm27xx/patches-6.6/950-0136-media-tc358743-Add-support-for-972Mbit-s-link-freq.patch b/target/linux/bcm27xx/patches-6.6/950-0136-media-tc358743-Add-support-for-972Mbit-s-link-freq.patch index 01337f7703a975..14955b948908c1 100644 --- a/target/linux/bcm27xx/patches-6.6/950-0136-media-tc358743-Add-support-for-972Mbit-s-link-freq.patch +++ b/target/linux/bcm27xx/patches-6.6/950-0136-media-tc358743-Add-support-for-972Mbit-s-link-freq.patch @@ -14,7 +14,7 @@ Signed-off-by: Dave Stevenson --- a/drivers/media/i2c/tc358743.c +++ b/drivers/media/i2c/tc358743.c -@@ -1953,6 +1953,7 @@ static int tc358743_probe_of(struct tc35 +@@ -1971,6 +1971,7 @@ static int tc358743_probe_of(struct tc35 /* * The CSI bps per lane must be between 62.5 Mbps and 1 Gbps. * The default is 594 Mbps for 4-lane 1080p60 or 2-lane 720p60. @@ -22,7 +22,7 @@ Signed-off-by: Dave Stevenson */ bps_pr_lane = 2 * endpoint.link_frequencies[0]; if (bps_pr_lane < 62500000U || bps_pr_lane > 1000000000U) { -@@ -1966,23 +1967,41 @@ static int tc358743_probe_of(struct tc35 +@@ -1984,23 +1985,41 @@ static int tc358743_probe_of(struct tc35 state->pdata.refclk_hz * state->pdata.pll_prd; /* diff --git a/target/linux/bcm27xx/patches-6.6/950-0137-media-tc358743-Check-I2C-succeeded-during-probe.patch b/target/linux/bcm27xx/patches-6.6/950-0137-media-tc358743-Check-I2C-succeeded-during-probe.patch deleted file mode 100644 index 710c72f897d6fe..00000000000000 --- a/target/linux/bcm27xx/patches-6.6/950-0137-media-tc358743-Check-I2C-succeeded-during-probe.patch +++ /dev/null @@ -1,98 +0,0 @@ -From 1bf7f627d378f9ef0d056d4a1f925bba810db6c7 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Wed, 31 Oct 2018 14:57:34 +0000 -Subject: [PATCH 0137/1085] media: tc358743: Check I2C succeeded during probe. - -The probe for the TC358743 reads the CHIPID register from -the device and compares it to the expected value of 0. -If the I2C request fails then that also returns 0, so -the driver loads thinking that the device is there. - -Generally I2C communications are reliable so there is -limited need to check the return value on every transfer, -therefore only amend the one read during probe to check -for I2C errors. - -Signed-off-by: Dave Stevenson ---- - drivers/media/i2c/tc358743.c | 27 +++++++++++++++++++++++---- - 1 file changed, 23 insertions(+), 4 deletions(-) - ---- a/drivers/media/i2c/tc358743.c -+++ b/drivers/media/i2c/tc358743.c -@@ -110,7 +110,7 @@ static inline struct tc358743_state *to_ - - /* --------------- I2C --------------- */ - --static void i2c_rd(struct v4l2_subdev *sd, u16 reg, u8 *values, u32 n) -+static int i2c_rd(struct v4l2_subdev *sd, u16 reg, u8 *values, u32 n) - { - struct tc358743_state *state = to_state(sd); - struct i2c_client *client = state->i2c_client; -@@ -136,6 +136,7 @@ static void i2c_rd(struct v4l2_subdev *s - v4l2_err(sd, "%s: reading register 0x%x from 0x%x failed: %d\n", - __func__, reg, client->addr, err); - } -+ return err != ARRAY_SIZE(msgs); - } - - static void i2c_wr(struct v4l2_subdev *sd, u16 reg, u8 *values, u32 n) -@@ -192,15 +193,24 @@ static void i2c_wr(struct v4l2_subdev *s - } - } - --static noinline u32 i2c_rdreg(struct v4l2_subdev *sd, u16 reg, u32 n) -+static noinline u32 i2c_rdreg_err(struct v4l2_subdev *sd, u16 reg, u32 n, -+ int *err) - { -+ int error; - __le32 val = 0; - -- i2c_rd(sd, reg, (u8 __force *)&val, n); -+ error = i2c_rd(sd, reg, (u8 __force *)&val, n); -+ if (err) -+ *err = error; - - return le32_to_cpu(val); - } - -+static inline u32 i2c_rdreg(struct v4l2_subdev *sd, u16 reg, u32 n) -+{ -+ return i2c_rdreg_err(sd, reg, n, NULL); -+} -+ - static noinline void i2c_wrreg(struct v4l2_subdev *sd, u16 reg, u32 val, u32 n) - { - __le32 raw = cpu_to_le32(val); -@@ -229,6 +239,13 @@ static u16 i2c_rd16(struct v4l2_subdev * - return i2c_rdreg(sd, reg, 2); - } - -+static int i2c_rd16_err(struct v4l2_subdev *sd, u16 reg, u16 *value) -+{ -+ int err; -+ *value = i2c_rdreg_err(sd, reg, 2, &err); -+ return err; -+} -+ - static void i2c_wr16(struct v4l2_subdev *sd, u16 reg, u16 val) - { - i2c_wrreg(sd, reg, val, 2); -@@ -2040,6 +2057,7 @@ static int tc358743_probe(struct i2c_cli - struct tc358743_platform_data *pdata = client->dev.platform_data; - struct v4l2_subdev *sd; - u16 irq_mask = MASK_HDMI_MSK | MASK_CSI_MSK; -+ u16 chipid; - int err; - - if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) -@@ -2071,7 +2089,8 @@ static int tc358743_probe(struct i2c_cli - sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE | V4L2_SUBDEV_FL_HAS_EVENTS; - - /* i2c access */ -- if ((i2c_rd16(sd, CHIPID) & MASK_CHIPID) != 0) { -+ if (i2c_rd16_err(sd, CHIPID, &chipid) || -+ (chipid & MASK_CHIPID) != 0) { - v4l2_info(sd, "not a TC358743 on address 0x%x\n", - client->addr << 1); - return -ENODEV; diff --git a/target/linux/bcm27xx/patches-6.6/950-0138-media-adv7180-Default-to-the-first-valid-input.patch b/target/linux/bcm27xx/patches-6.6/950-0138-media-adv7180-Default-to-the-first-valid-input.patch index 7669317e602295..181b69b807ec97 100644 --- a/target/linux/bcm27xx/patches-6.6/950-0138-media-adv7180-Default-to-the-first-valid-input.patch +++ b/target/linux/bcm27xx/patches-6.6/950-0138-media-adv7180-Default-to-the-first-valid-input.patch @@ -16,7 +16,7 @@ Signed-off-by: Dave Stevenson --- a/drivers/media/i2c/adv7180.c +++ b/drivers/media/i2c/adv7180.c -@@ -1340,6 +1340,7 @@ static const struct adv7180_chip_info ad +@@ -1350,6 +1350,7 @@ static const struct adv7180_chip_info ad static int init_device(struct adv7180_state *state) { int ret; @@ -24,7 +24,7 @@ Signed-off-by: Dave Stevenson mutex_lock(&state->mutex); -@@ -1387,6 +1388,18 @@ static int init_device(struct adv7180_st +@@ -1397,6 +1398,18 @@ static int init_device(struct adv7180_st goto out_unlock; } diff --git a/target/linux/bcm27xx/patches-6.6/950-0139-media-adv7180-Add-YPrPb-support-for-ADV7282M.patch b/target/linux/bcm27xx/patches-6.6/950-0139-media-adv7180-Add-YPrPb-support-for-ADV7282M.patch index faaf79f2ae0dd7..caa83f409f870f 100644 --- a/target/linux/bcm27xx/patches-6.6/950-0139-media-adv7180-Add-YPrPb-support-for-ADV7282M.patch +++ b/target/linux/bcm27xx/patches-6.6/950-0139-media-adv7180-Add-YPrPb-support-for-ADV7282M.patch @@ -14,7 +14,7 @@ Signed-off-by: Dave Stevenson --- a/drivers/media/i2c/adv7180.c +++ b/drivers/media/i2c/adv7180.c -@@ -1329,6 +1329,7 @@ static const struct adv7180_chip_info ad +@@ -1339,6 +1339,7 @@ static const struct adv7180_chip_info ad BIT(ADV7182_INPUT_SVIDEO_AIN1_AIN2) | BIT(ADV7182_INPUT_SVIDEO_AIN3_AIN4) | BIT(ADV7182_INPUT_SVIDEO_AIN7_AIN8) | diff --git a/target/linux/bcm27xx/patches-6.6/950-0143-media-tc358743-Return-an-appropriate-colorspace-from.patch b/target/linux/bcm27xx/patches-6.6/950-0143-media-tc358743-Return-an-appropriate-colorspace-from.patch deleted file mode 100644 index ca00c809491e77..00000000000000 --- a/target/linux/bcm27xx/patches-6.6/950-0143-media-tc358743-Return-an-appropriate-colorspace-from.patch +++ /dev/null @@ -1,98 +0,0 @@ -From a44571c8bd6d63caf3744d3e95a3a7492df15b6c Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Thu, 22 Nov 2018 17:31:06 +0000 -Subject: [PATCH 0143/1085] media: tc358743: Return an appropriate colorspace - from tc358743_set_fmt - -When calling tc358743_set_fmt, the code was calling tc358743_get_fmt -to choose a valid format. However that sets the colorspace -based on what was read back from the chip. When you set the format, -then the driver would choose and program the colorspace based -on the format code. - -The result was that if you called try or set format for UYVY -when the current format was RGB3 then you would get told sRGB, -and try RGB3 when current was UYVY and you would get told -SMPTE170M. - -The value programmed into the chip is determined by this driver, -therefore there is no need to read back the value. Return the -colorspace based on the format set/tried instead. - -Signed-off-by: Dave Stevenson ---- - drivers/media/i2c/tc358743.c | 40 +++++++++++++----------------------- - 1 file changed, 14 insertions(+), 26 deletions(-) - ---- a/drivers/media/i2c/tc358743.c -+++ b/drivers/media/i2c/tc358743.c -@@ -1668,12 +1668,23 @@ static int tc358743_enum_mbus_code(struc - return 0; - } - -+static u32 tc358743_g_colorspace(u32 code) -+{ -+ switch (code) { -+ case MEDIA_BUS_FMT_RGB888_1X24: -+ return V4L2_COLORSPACE_SRGB; -+ case MEDIA_BUS_FMT_UYVY8_1X16: -+ return V4L2_COLORSPACE_SMPTE170M; -+ default: -+ return 0; -+ } -+} -+ - static int tc358743_get_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_state *sd_state, - struct v4l2_subdev_format *format) - { - struct tc358743_state *state = to_state(sd); -- u8 vi_rep = i2c_rd8(sd, VI_REP); - - if (format->pad != 0) - return -EINVAL; -@@ -1683,23 +1694,7 @@ static int tc358743_get_fmt(struct v4l2_ - format->format.height = state->timings.bt.height; - format->format.field = V4L2_FIELD_NONE; - -- switch (vi_rep & MASK_VOUT_COLOR_SEL) { -- case MASK_VOUT_COLOR_RGB_FULL: -- case MASK_VOUT_COLOR_RGB_LIMITED: -- format->format.colorspace = V4L2_COLORSPACE_SRGB; -- break; -- case MASK_VOUT_COLOR_601_YCBCR_LIMITED: -- case MASK_VOUT_COLOR_601_YCBCR_FULL: -- format->format.colorspace = V4L2_COLORSPACE_SMPTE170M; -- break; -- case MASK_VOUT_COLOR_709_YCBCR_FULL: -- case MASK_VOUT_COLOR_709_YCBCR_LIMITED: -- format->format.colorspace = V4L2_COLORSPACE_REC709; -- break; -- default: -- format->format.colorspace = 0; -- break; -- } -+ format->format.colorspace = tc358743_g_colorspace(format->format.code); - - return 0; - } -@@ -1714,18 +1709,11 @@ static int tc358743_set_fmt(struct v4l2_ - int ret = tc358743_get_fmt(sd, sd_state, format); - - format->format.code = code; -+ format->format.colorspace = tc358743_g_colorspace(code); - - if (ret) - return ret; - -- switch (code) { -- case MEDIA_BUS_FMT_RGB888_1X24: -- case MEDIA_BUS_FMT_UYVY8_1X16: -- break; -- default: -- return -EINVAL; -- } -- - if (format->which == V4L2_SUBDEV_FORMAT_TRY) - return 0; - diff --git a/target/linux/bcm27xx/patches-6.6/950-0161-xhci-implement-xhci_fixup_endpoint-for-interval-adju.patch b/target/linux/bcm27xx/patches-6.6/950-0161-xhci-implement-xhci_fixup_endpoint-for-interval-adju.patch index f5eea9b47df860..2cf32f792b0cfb 100644 --- a/target/linux/bcm27xx/patches-6.6/950-0161-xhci-implement-xhci_fixup_endpoint-for-interval-adju.patch +++ b/target/linux/bcm27xx/patches-6.6/950-0161-xhci-implement-xhci_fixup_endpoint-for-interval-adju.patch @@ -15,7 +15,7 @@ Signed-off-by: Jonathan Bell --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c -@@ -1497,6 +1497,109 @@ command_cleanup: +@@ -1526,6 +1526,109 @@ command_cleanup: } /* @@ -125,7 +125,7 @@ Signed-off-by: Jonathan Bell * non-error returns are a promise to giveback() the urb later * we drop ownership so next owner (or urb unlink) can get it */ -@@ -5328,6 +5431,7 @@ static const struct hc_driver xhci_hc_dr +@@ -5395,6 +5498,7 @@ static const struct hc_driver xhci_hc_dr .endpoint_reset = xhci_endpoint_reset, .check_bandwidth = xhci_check_bandwidth, .reset_bandwidth = xhci_reset_bandwidth, diff --git a/target/linux/bcm27xx/patches-6.6/950-0162-usb-xhci-workaround-for-bogus-SET_DEQ_PENDING-endpoi.patch b/target/linux/bcm27xx/patches-6.6/950-0162-usb-xhci-workaround-for-bogus-SET_DEQ_PENDING-endpoi.patch index 32681a1bc4b041..9d22d745101c4b 100644 --- a/target/linux/bcm27xx/patches-6.6/950-0162-usb-xhci-workaround-for-bogus-SET_DEQ_PENDING-endpoi.patch +++ b/target/linux/bcm27xx/patches-6.6/950-0162-usb-xhci-workaround-for-bogus-SET_DEQ_PENDING-endpoi.patch @@ -26,7 +26,7 @@ Signed-off-by: Jonathan Bell --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c -@@ -738,9 +738,9 @@ deq_found: +@@ -740,9 +740,9 @@ deq_found: } if ((ep->ep_state & SET_DEQ_PENDING)) { diff --git a/target/linux/bcm27xx/patches-6.6/950-0163-usb-xhci-drop-and-add-the-endpoint-context-in-xhci_f.patch b/target/linux/bcm27xx/patches-6.6/950-0163-usb-xhci-drop-and-add-the-endpoint-context-in-xhci_f.patch index 1e5bb6059d2762..b162b37cf48752 100644 --- a/target/linux/bcm27xx/patches-6.6/950-0163-usb-xhci-drop-and-add-the-endpoint-context-in-xhci_f.patch +++ b/target/linux/bcm27xx/patches-6.6/950-0163-usb-xhci-drop-and-add-the-endpoint-context-in-xhci_f.patch @@ -19,7 +19,7 @@ Signed-off-by: Jonathan Bell --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c -@@ -1586,7 +1586,7 @@ static void xhci_fixup_endpoint(struct u +@@ -1615,7 +1615,7 @@ static void xhci_fixup_endpoint(struct u return; } ctrl_ctx->add_flags = xhci_get_endpoint_flag_from_index(ep_index); diff --git a/target/linux/bcm27xx/patches-6.6/950-0164-usbhid-call-usb_fixup_endpoint-after-mangling-interv.patch b/target/linux/bcm27xx/patches-6.6/950-0164-usbhid-call-usb_fixup_endpoint-after-mangling-interv.patch index 3755d9116996ea..2f14a56f8e48fc 100644 --- a/target/linux/bcm27xx/patches-6.6/950-0164-usbhid-call-usb_fixup_endpoint-after-mangling-interv.patch +++ b/target/linux/bcm27xx/patches-6.6/950-0164-usbhid-call-usb_fixup_endpoint-after-mangling-interv.patch @@ -13,7 +13,7 @@ Signed-off-by: Jonathan Bell --- a/drivers/hid/usbhid/hid-core.c +++ b/drivers/hid/usbhid/hid-core.c -@@ -1126,6 +1126,7 @@ static int usbhid_start(struct hid_devic +@@ -1129,6 +1129,7 @@ static int usbhid_start(struct hid_devic interval = hid_kbpoll_interval; break; } diff --git a/target/linux/bcm27xx/patches-6.6/950-0167-drm-v3d-Clock-V3D-down-when-not-in-use.patch b/target/linux/bcm27xx/patches-6.6/950-0167-drm-v3d-Clock-V3D-down-when-not-in-use.patch index 031d8ab6b23db9..099cf75a817599 100644 --- a/target/linux/bcm27xx/patches-6.6/950-0167-drm-v3d-Clock-V3D-down-when-not-in-use.patch +++ b/target/linux/bcm27xx/patches-6.6/950-0167-drm-v3d-Clock-V3D-down-when-not-in-use.patch @@ -25,7 +25,7 @@ Signed-off-by: Phil Elwell --- a/drivers/gpu/drm/v3d/v3d_drv.c +++ b/drivers/gpu/drm/v3d/v3d_drv.c -@@ -256,6 +256,21 @@ static int v3d_platform_drm_probe(struct +@@ -266,6 +266,21 @@ static int v3d_platform_drm_probe(struct } } @@ -47,7 +47,7 @@ Signed-off-by: Phil Elwell if (v3d->ver < 41) { ret = map_regs(v3d, &v3d->gca_regs, "gca"); if (ret) -@@ -281,6 +296,9 @@ static int v3d_platform_drm_probe(struct +@@ -292,6 +307,9 @@ static int v3d_platform_drm_probe(struct if (ret) goto irq_disable; @@ -59,7 +59,7 @@ Signed-off-by: Phil Elwell irq_disable: --- a/drivers/gpu/drm/v3d/v3d_drv.h +++ b/drivers/gpu/drm/v3d/v3d_drv.h -@@ -76,6 +76,12 @@ struct v3d_dev { +@@ -84,6 +84,12 @@ struct v3d_dev { void __iomem *bridge_regs; void __iomem *gca_regs; struct clk *clk; @@ -130,7 +130,7 @@ Signed-off-by: Phil Elwell v3d_init_core(struct v3d_dev *v3d, int core) { /* Set OVRTMUOUT, which means that the texture sampler uniform -@@ -318,6 +360,7 @@ static void +@@ -320,6 +362,7 @@ static void v3d_job_free(struct kref *ref) { struct v3d_job *job = container_of(ref, struct v3d_job, refcount); @@ -138,7 +138,7 @@ Signed-off-by: Phil Elwell int i; if (job->bo) { -@@ -329,6 +372,8 @@ v3d_job_free(struct kref *ref) +@@ -331,6 +374,8 @@ v3d_job_free(struct kref *ref) dma_fence_put(job->irq_fence); dma_fence_put(job->done_fence); @@ -147,7 +147,7 @@ Signed-off-by: Phil Elwell if (job->perfmon) v3d_perfmon_put(job->perfmon); -@@ -448,6 +493,7 @@ v3d_job_init(struct v3d_dev *v3d, struct +@@ -450,6 +495,7 @@ v3d_job_init(struct v3d_dev *v3d, struct goto fail_deps; } @@ -155,7 +155,7 @@ Signed-off-by: Phil Elwell kref_init(&job->refcount); return 0; -@@ -1031,6 +1077,9 @@ v3d_gem_init(struct drm_device *dev) +@@ -1033,6 +1079,9 @@ v3d_gem_init(struct drm_device *dev) if (ret) return ret; diff --git a/target/linux/bcm27xx/patches-6.6/950-0169-hid-usb-Add-device-quirks-for-Freeway-Airmouse-T3-an.patch b/target/linux/bcm27xx/patches-6.6/950-0169-hid-usb-Add-device-quirks-for-Freeway-Airmouse-T3-an.patch index 5301066196f53b..96c04d52c7cdf0 100644 --- a/target/linux/bcm27xx/patches-6.6/950-0169-hid-usb-Add-device-quirks-for-Freeway-Airmouse-T3-an.patch +++ b/target/linux/bcm27xx/patches-6.6/950-0169-hid-usb-Add-device-quirks-for-Freeway-Airmouse-T3-an.patch @@ -23,7 +23,7 @@ Signed-off-by: Jonathan Bell --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h -@@ -242,6 +242,9 @@ +@@ -248,6 +248,9 @@ #define USB_VENDOR_ID_BAANTO 0x2453 #define USB_DEVICE_ID_BAANTO_MT_190W2 0x0100 @@ -33,7 +33,7 @@ Signed-off-by: Jonathan Bell #define USB_VENDOR_ID_BELKIN 0x050d #define USB_DEVICE_ID_FLIP_KVM 0x3201 -@@ -1404,6 +1407,9 @@ +@@ -1449,6 +1452,9 @@ #define USB_VENDOR_ID_XIAOMI 0x2717 #define USB_DEVICE_ID_MI_SILENT_MOUSE 0x5014 @@ -45,7 +45,7 @@ Signed-off-by: Jonathan Bell #define USB_DEVICE_ID_THT_2P_ARCADE 0x75e1 --- a/drivers/hid/hid-quirks.c +++ b/drivers/hid/hid-quirks.c -@@ -42,6 +42,7 @@ static const struct hid_device_id hid_qu +@@ -44,6 +44,7 @@ static const struct hid_device_id hid_qu { HID_USB_DEVICE(USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_CS682), HID_QUIRK_NOGET }, { HID_USB_DEVICE(USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_CS692), HID_QUIRK_NOGET }, { HID_USB_DEVICE(USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_UC100KM), HID_QUIRK_NOGET }, @@ -53,7 +53,7 @@ Signed-off-by: Jonathan Bell { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_MULTI_TOUCH), HID_QUIRK_MULTI_INPUT }, { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_PIXART_USB_OPTICAL_MOUSE), HID_QUIRK_ALWAYS_POLL }, { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_PIXART_USB_OPTICAL_MOUSE2), HID_QUIRK_ALWAYS_POLL }, -@@ -209,6 +210,7 @@ static const struct hid_device_id hid_qu +@@ -213,6 +214,7 @@ static const struct hid_device_id hid_qu { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_QUAD_USB_JOYPAD), HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT }, { HID_USB_DEVICE(USB_VENDOR_ID_XIN_MO, USB_DEVICE_ID_XIN_MO_DUAL_ARCADE), HID_QUIRK_MULTI_INPUT }, { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_GROUP_AUDIO), HID_QUIRK_NOGET }, diff --git a/target/linux/bcm27xx/patches-6.6/950-0173-media-i2c-imx477-Support-for-the-Sony-IMX477-sensor.patch b/target/linux/bcm27xx/patches-6.6/950-0173-media-i2c-imx477-Support-for-the-Sony-IMX477-sensor.patch index 03af7a9cb9e33f..264b3ca376ac59 100644 --- a/target/linux/bcm27xx/patches-6.6/950-0173-media-i2c-imx477-Support-for-the-Sony-IMX477-sensor.patch +++ b/target/linux/bcm27xx/patches-6.6/950-0173-media-i2c-imx477-Support-for-the-Sony-IMX477-sensor.patch @@ -343,7 +343,7 @@ Signed-off-by: Naushir Patuck +... --- a/MAINTAINERS +++ b/MAINTAINERS -@@ -20057,6 +20057,14 @@ T: git git://linuxtv.org/media_tree.git +@@ -20058,6 +20058,14 @@ T: git git://linuxtv.org/media_tree.git F: Documentation/devicetree/bindings/media/i2c/sony,imx415.yaml F: drivers/media/i2c/imx415.c diff --git a/target/linux/bcm27xx/patches-6.6/950-0174-media-i2c-imx519-Support-for-the-Sony-IMX519-sensor.patch b/target/linux/bcm27xx/patches-6.6/950-0174-media-i2c-imx519-Support-for-the-Sony-IMX519-sensor.patch index 3dbfea8813957b..2ba00932c27735 100644 --- a/target/linux/bcm27xx/patches-6.6/950-0174-media-i2c-imx519-Support-for-the-Sony-IMX519-sensor.patch +++ b/target/linux/bcm27xx/patches-6.6/950-0174-media-i2c-imx519-Support-for-the-Sony-IMX519-sensor.patch @@ -177,7 +177,7 @@ Signed-off-by: Phil Elwell +... --- a/MAINTAINERS +++ b/MAINTAINERS -@@ -20065,6 +20065,14 @@ T: git git://linuxtv.org/media_tree.git +@@ -20066,6 +20066,14 @@ T: git git://linuxtv.org/media_tree.git F: Documentation/devicetree/bindings/media/i2c/imx477.yaml F: drivers/media/i2c/imx477.c diff --git a/target/linux/bcm27xx/patches-6.6/950-0175-Documentation-devicetree-Add-documentation-for-imx37.patch b/target/linux/bcm27xx/patches-6.6/950-0175-Documentation-devicetree-Add-documentation-for-imx37.patch index b6df79f250563c..019ca418aebb1d 100644 --- a/target/linux/bcm27xx/patches-6.6/950-0175-Documentation-devicetree-Add-documentation-for-imx37.patch +++ b/target/linux/bcm27xx/patches-6.6/950-0175-Documentation-devicetree-Add-documentation-for-imx37.patch @@ -132,7 +132,7 @@ Signed-off-by: David Plowman +... --- a/MAINTAINERS +++ b/MAINTAINERS -@@ -20062,6 +20062,7 @@ M: Raspberry Pi Kernel Maintenance --- a/drivers/gpu/drm/v3d/v3d_irq.c +++ b/drivers/gpu/drm/v3d/v3d_irq.c -@@ -177,6 +177,7 @@ v3d_hub_irq(int irq, void *arg) +@@ -189,6 +189,7 @@ v3d_hub_irq(int irq, void *arg) "GMP", }; const char *client = "?"; @@ -21,7 +21,7 @@ Signed-off-by: Phil Elwell V3D_WRITE(V3D_MMU_CTL, V3D_READ(V3D_MMU_CTL)); -@@ -186,6 +187,7 @@ v3d_hub_irq(int irq, void *arg) +@@ -198,6 +199,7 @@ v3d_hub_irq(int irq, void *arg) client = v3d41_axi_ids[axi_id]; } @@ -29,7 +29,7 @@ Signed-off-by: Phil Elwell dev_err(v3d->drm.dev, "MMU error from client %s (%d) at 0x%llx%s%s%s\n", client, axi_id, (long long)vio_addr, ((intsts & V3D_HUB_INT_MMU_WRV) ? -@@ -194,6 +196,7 @@ v3d_hub_irq(int irq, void *arg) +@@ -206,6 +208,7 @@ v3d_hub_irq(int irq, void *arg) ", pte invalid" : ""), ((intsts & V3D_HUB_INT_MMU_CAP) ? ", cap exceeded" : "")); diff --git a/target/linux/bcm27xx/patches-6.6/950-0184-staging-vchiq_arm-Register-vcsm-cma-as-a-platform-dr.patch b/target/linux/bcm27xx/patches-6.6/950-0184-staging-vchiq_arm-Register-vcsm-cma-as-a-platform-dr.patch index 102931650446f4..6daa690dff2138 100644 --- a/target/linux/bcm27xx/patches-6.6/950-0184-staging-vchiq_arm-Register-vcsm-cma-as-a-platform-dr.patch +++ b/target/linux/bcm27xx/patches-6.6/950-0184-staging-vchiq_arm-Register-vcsm-cma-as-a-platform-dr.patch @@ -22,7 +22,7 @@ Signed-off-by: Dave Stevenson struct vchiq_drvdata { const unsigned int cache_line_size; -@@ -1838,6 +1839,7 @@ static int vchiq_probe(struct platform_d +@@ -1824,6 +1825,7 @@ static int vchiq_probe(struct platform_d goto error_exit; } @@ -30,7 +30,7 @@ Signed-off-by: Dave Stevenson bcm2835_camera = vchiq_register_child(pdev, "bcm2835-camera"); bcm2835_audio = vchiq_register_child(pdev, "bcm2835_audio"); -@@ -1853,6 +1855,7 @@ static void vchiq_remove(struct platform +@@ -1839,6 +1841,7 @@ static void vchiq_remove(struct platform { platform_device_unregister(bcm2835_audio); platform_device_unregister(bcm2835_camera); diff --git a/target/linux/bcm27xx/patches-6.6/950-0185-staging-vchiq_arm-Register-bcm2835-codec-as-a-platfo.patch b/target/linux/bcm27xx/patches-6.6/950-0185-staging-vchiq_arm-Register-bcm2835-codec-as-a-platfo.patch index ab4fb514d6dd28..5adc8c75afe0d0 100644 --- a/target/linux/bcm27xx/patches-6.6/950-0185-staging-vchiq_arm-Register-bcm2835-codec-as-a-platfo.patch +++ b/target/linux/bcm27xx/patches-6.6/950-0185-staging-vchiq_arm-Register-bcm2835-codec-as-a-platfo.patch @@ -22,7 +22,7 @@ Signed-off-by: Dave Stevenson static struct platform_device *vcsm_cma; struct vchiq_drvdata { -@@ -1840,6 +1841,7 @@ static int vchiq_probe(struct platform_d +@@ -1826,6 +1827,7 @@ static int vchiq_probe(struct platform_d } vcsm_cma = vchiq_register_child(pdev, "vcsm-cma"); @@ -30,7 +30,7 @@ Signed-off-by: Dave Stevenson bcm2835_camera = vchiq_register_child(pdev, "bcm2835-camera"); bcm2835_audio = vchiq_register_child(pdev, "bcm2835_audio"); -@@ -1855,6 +1857,7 @@ static void vchiq_remove(struct platform +@@ -1841,6 +1843,7 @@ static void vchiq_remove(struct platform { platform_device_unregister(bcm2835_audio); platform_device_unregister(bcm2835_camera); diff --git a/target/linux/bcm27xx/patches-6.6/950-0187-v3d_drv-Handle-missing-clock-more-gracefully.patch b/target/linux/bcm27xx/patches-6.6/950-0187-v3d_drv-Handle-missing-clock-more-gracefully.patch index d8a7c28bd673f1..dc601a66979858 100644 --- a/target/linux/bcm27xx/patches-6.6/950-0187-v3d_drv-Handle-missing-clock-more-gracefully.patch +++ b/target/linux/bcm27xx/patches-6.6/950-0187-v3d_drv-Handle-missing-clock-more-gracefully.patch @@ -10,7 +10,7 @@ Signed-off-by: popcornmix --- a/drivers/gpu/drm/v3d/v3d_drv.c +++ b/drivers/gpu/drm/v3d/v3d_drv.c -@@ -257,10 +257,10 @@ static int v3d_platform_drm_probe(struct +@@ -267,10 +267,10 @@ static int v3d_platform_drm_probe(struct } v3d->clk = devm_clk_get(dev, NULL); diff --git a/target/linux/bcm27xx/patches-6.6/950-0188-v3d_gem-Kick-the-clock-so-firmware-knows-we-are-usin.patch b/target/linux/bcm27xx/patches-6.6/950-0188-v3d_gem-Kick-the-clock-so-firmware-knows-we-are-usin.patch index 19c0ddaf3e671e..7850e796fc311d 100644 --- a/target/linux/bcm27xx/patches-6.6/950-0188-v3d_gem-Kick-the-clock-so-firmware-knows-we-are-usin.patch +++ b/target/linux/bcm27xx/patches-6.6/950-0188-v3d_gem-Kick-the-clock-so-firmware-knows-we-are-usin.patch @@ -14,7 +14,7 @@ Signed-off-by: popcornmix --- a/drivers/gpu/drm/v3d/v3d_gem.c +++ b/drivers/gpu/drm/v3d/v3d_gem.c -@@ -1080,6 +1080,10 @@ v3d_gem_init(struct drm_device *dev) +@@ -1082,6 +1082,10 @@ v3d_gem_init(struct drm_device *dev) mutex_init(&v3d->clk_lock); INIT_DELAYED_WORK(&v3d->clk_down_work, v3d_clock_down_work); diff --git a/target/linux/bcm27xx/patches-6.6/950-0190-staging-vchiq_arm-Set-up-dma-ranges-on-child-devices.patch b/target/linux/bcm27xx/patches-6.6/950-0190-staging-vchiq_arm-Set-up-dma-ranges-on-child-devices.patch index b008f909468268..525cb835e68df2 100644 --- a/target/linux/bcm27xx/patches-6.6/950-0190-staging-vchiq_arm-Set-up-dma-ranges-on-child-devices.patch +++ b/target/linux/bcm27xx/patches-6.6/950-0190-staging-vchiq_arm-Set-up-dma-ranges-on-child-devices.patch @@ -18,7 +18,7 @@ Signed-off-by: Dave Stevenson --- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c +++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c -@@ -1790,6 +1790,12 @@ vchiq_register_child(struct platform_dev +@@ -1776,6 +1776,12 @@ vchiq_register_child(struct platform_dev child = NULL; } diff --git a/target/linux/bcm27xx/patches-6.6/950-0191-staging-vchiq-Use-the-old-dma-controller-for-OF-conf.patch b/target/linux/bcm27xx/patches-6.6/950-0191-staging-vchiq-Use-the-old-dma-controller-for-OF-conf.patch index 85d1174a60e553..5613a4100a9a1a 100644 --- a/target/linux/bcm27xx/patches-6.6/950-0191-staging-vchiq-Use-the-old-dma-controller-for-OF-conf.patch +++ b/target/linux/bcm27xx/patches-6.6/950-0191-staging-vchiq-Use-the-old-dma-controller-for-OF-conf.patch @@ -17,7 +17,7 @@ Signed-off-by: Dave Stevenson --- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c +++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c -@@ -1776,6 +1776,7 @@ vchiq_register_child(struct platform_dev +@@ -1762,6 +1762,7 @@ vchiq_register_child(struct platform_dev { struct platform_device_info pdevinfo; struct platform_device *child; @@ -25,7 +25,7 @@ Signed-off-by: Dave Stevenson memset(&pdevinfo, 0, sizeof(pdevinfo)); -@@ -1791,10 +1792,20 @@ vchiq_register_child(struct platform_dev +@@ -1777,10 +1778,20 @@ vchiq_register_child(struct platform_dev } /* diff --git a/target/linux/bcm27xx/patches-6.6/950-0194-staging-vchiq_arm-Give-vchiq-children-DT-nodes.patch b/target/linux/bcm27xx/patches-6.6/950-0194-staging-vchiq_arm-Give-vchiq-children-DT-nodes.patch index eab0710367f632..a75bd3da561d79 100644 --- a/target/linux/bcm27xx/patches-6.6/950-0194-staging-vchiq_arm-Give-vchiq-children-DT-nodes.patch +++ b/target/linux/bcm27xx/patches-6.6/950-0194-staging-vchiq_arm-Give-vchiq-children-DT-nodes.patch @@ -16,7 +16,7 @@ Signed-off-by: Phil Elwell --- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c +++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c -@@ -1785,12 +1785,20 @@ vchiq_register_child(struct platform_dev +@@ -1771,12 +1771,20 @@ vchiq_register_child(struct platform_dev pdevinfo.id = PLATFORM_DEVID_NONE; pdevinfo.dma_mask = DMA_BIT_MASK(32); diff --git a/target/linux/bcm27xx/patches-6.6/950-0204-spi-Force-CS_HIGH-if-GPIO-descriptors-are-used.patch b/target/linux/bcm27xx/patches-6.6/950-0204-spi-Force-CS_HIGH-if-GPIO-descriptors-are-used.patch index 5398d85ef3e23a..7cbbeebf6de146 100644 --- a/target/linux/bcm27xx/patches-6.6/950-0204-spi-Force-CS_HIGH-if-GPIO-descriptors-are-used.patch +++ b/target/linux/bcm27xx/patches-6.6/950-0204-spi-Force-CS_HIGH-if-GPIO-descriptors-are-used.patch @@ -32,7 +32,7 @@ Signed-off-by: Phil Elwell --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c -@@ -3740,6 +3740,7 @@ static int spi_set_cs_timing(struct spi_ +@@ -3747,6 +3747,7 @@ static int spi_set_cs_timing(struct spi_ */ int spi_setup(struct spi_device *spi) { @@ -40,7 +40,7 @@ Signed-off-by: Phil Elwell unsigned bad_bits, ugly_bits; int status = 0; -@@ -3760,6 +3761,14 @@ int spi_setup(struct spi_device *spi) +@@ -3767,6 +3768,14 @@ int spi_setup(struct spi_device *spi) (SPI_TX_DUAL | SPI_TX_QUAD | SPI_TX_OCTAL | SPI_RX_DUAL | SPI_RX_QUAD | SPI_RX_OCTAL))) return -EINVAL; diff --git a/target/linux/bcm27xx/patches-6.6/950-0209-staging-vchiq-Load-bcm2835_isp-driver-from-vchiq.patch b/target/linux/bcm27xx/patches-6.6/950-0209-staging-vchiq-Load-bcm2835_isp-driver-from-vchiq.patch index a33b39967f857f..5c1b37bfd95102 100644 --- a/target/linux/bcm27xx/patches-6.6/950-0209-staging-vchiq-Load-bcm2835_isp-driver-from-vchiq.patch +++ b/target/linux/bcm27xx/patches-6.6/950-0209-staging-vchiq-Load-bcm2835_isp-driver-from-vchiq.patch @@ -21,7 +21,7 @@ Signed-off-by: Naushir Patuck struct vchiq_drvdata { const unsigned int cache_line_size; -@@ -1869,6 +1870,7 @@ static int vchiq_probe(struct platform_d +@@ -1855,6 +1856,7 @@ static int vchiq_probe(struct platform_d bcm2835_codec = vchiq_register_child(pdev, "bcm2835-codec"); bcm2835_camera = vchiq_register_child(pdev, "bcm2835-camera"); bcm2835_audio = vchiq_register_child(pdev, "bcm2835_audio"); @@ -29,7 +29,7 @@ Signed-off-by: Naushir Patuck return 0; -@@ -1880,6 +1882,7 @@ error_exit: +@@ -1866,6 +1868,7 @@ error_exit: static void vchiq_remove(struct platform_device *pdev) { diff --git a/target/linux/bcm27xx/patches-6.6/950-0210-media-i2c-tc358743-Fix-fallthrough-warning.patch b/target/linux/bcm27xx/patches-6.6/950-0210-media-i2c-tc358743-Fix-fallthrough-warning.patch index 265e0c6cecf0fd..6b0296c5a5139d 100644 --- a/target/linux/bcm27xx/patches-6.6/950-0210-media-i2c-tc358743-Fix-fallthrough-warning.patch +++ b/target/linux/bcm27xx/patches-6.6/950-0210-media-i2c-tc358743-Fix-fallthrough-warning.patch @@ -10,7 +10,7 @@ Signed-off-by: Jacko Dirks --- a/drivers/media/i2c/tc358743.c +++ b/drivers/media/i2c/tc358743.c -@@ -1980,6 +1980,7 @@ static int tc358743_probe_of(struct tc35 +@@ -1993,6 +1993,7 @@ static int tc358743_probe_of(struct tc35 switch (bps_pr_lane) { default: dev_warn(dev, "untested bps per lane: %u bps\n", bps_pr_lane); diff --git a/target/linux/bcm27xx/patches-6.6/950-0215-PCI-brcmstb-Add-DT-property-to-control-L1SS.patch b/target/linux/bcm27xx/patches-6.6/950-0215-PCI-brcmstb-Add-DT-property-to-control-L1SS.patch index f29ecab0712880..c6a5810fade4d2 100644 --- a/target/linux/bcm27xx/patches-6.6/950-0215-PCI-brcmstb-Add-DT-property-to-control-L1SS.patch +++ b/target/linux/bcm27xx/patches-6.6/950-0215-PCI-brcmstb-Add-DT-property-to-control-L1SS.patch @@ -65,7 +65,7 @@ Signed-off-by: Phil Elwell writel(tmp, base + PCIE_MISC_HARD_PCIE_HARD_DEBUG); return 0; -@@ -1536,6 +1551,7 @@ static int brcm_pcie_probe(struct platfo +@@ -1537,6 +1552,7 @@ static int brcm_pcie_probe(struct platfo pcie->gen = (ret < 0) ? 0 : ret; pcie->ssc = of_property_read_bool(np, "brcm,enable-ssc"); diff --git a/target/linux/bcm27xx/patches-6.6/950-0237-media-i2c-tc358743-Only-allow-supported-pixel-fmts-i.patch b/target/linux/bcm27xx/patches-6.6/950-0237-media-i2c-tc358743-Only-allow-supported-pixel-fmts-i.patch deleted file mode 100644 index a8c881e732c001..00000000000000 --- a/target/linux/bcm27xx/patches-6.6/950-0237-media-i2c-tc358743-Only-allow-supported-pixel-fmts-i.patch +++ /dev/null @@ -1,30 +0,0 @@ -From dd2f62c0c0e9b0d882b50b7a1dbe8da680adb824 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Fri, 10 Jul 2020 12:40:50 +0100 -Subject: [PATCH 0237/1085] media: i2c: tc358743: Only allow supported pixel - fmts in set_fmt - -Fix commit "media: tc358743: Return an appropriate colorspace from -tc358743_set_fmt" to ensure that the format passed in to set_fmt -is checked to be valid, and reset to the current format if not. - -Signed-off-by: Dave Stevenson ---- - drivers/media/i2c/tc358743.c | 6 ++++-- - 1 file changed, 4 insertions(+), 2 deletions(-) - ---- a/drivers/media/i2c/tc358743.c -+++ b/drivers/media/i2c/tc358743.c -@@ -1708,8 +1708,10 @@ static int tc358743_set_fmt(struct v4l2_ - u32 code = format->format.code; /* is overwritten by get_fmt */ - int ret = tc358743_get_fmt(sd, sd_state, format); - -- format->format.code = code; -- format->format.colorspace = tc358743_g_colorspace(code); -+ if (code == MEDIA_BUS_FMT_RGB888_1X24 || -+ code == MEDIA_BUS_FMT_UYVY8_1X16) -+ format->format.code = code; -+ format->format.colorspace = tc358743_g_colorspace(format->format.code); - - if (ret) - return ret; diff --git a/target/linux/bcm27xx/patches-6.6/950-0243-staging-fbtft-Add-support-for-display-variants.patch b/target/linux/bcm27xx/patches-6.6/950-0243-staging-fbtft-Add-support-for-display-variants.patch index f49c9a2b56a34c..fad8eb5a11c369 100644 --- a/target/linux/bcm27xx/patches-6.6/950-0243-staging-fbtft-Add-support-for-display-variants.patch +++ b/target/linux/bcm27xx/patches-6.6/950-0243-staging-fbtft-Add-support-for-display-variants.patch @@ -95,7 +95,7 @@ Signed-off-by: Phil Elwell #include