Merge Official Source
Signed-off-by: Tianling Shen <cnsztl@immortalwrt.org>
This commit is contained in:
+5
-1
@@ -898,9 +898,13 @@ define Device/Build
|
||||
$$(call Device/Build/compile,$$(compile),$(1))))
|
||||
|
||||
$$(eval $$(foreach image,$$(IMAGES), \
|
||||
$$(foreach fs,$$(filter $(TARGET_FILESYSTEMS),$$(FILESYSTEMS)), \
|
||||
$$(foreach fs,$$(filter $$(filter-out targz,$(TARGET_FILESYSTEMS)),$$(FILESYSTEMS)), \
|
||||
$$(call Device/Build/image,$$(fs),$$(image),$(1)))))
|
||||
|
||||
$(if $(CONFIG_TARGET_ROOTFS_TARGZ), \
|
||||
IMAGE/rootfs.tar.gz := append-rootfs
|
||||
$$(eval $$(call Device/Build/image,targz,rootfs.tar.gz,$(1))))
|
||||
|
||||
$$(eval $$(foreach artifact,$$(ARTIFACTS), \
|
||||
$$(call Device/Build/artifact,$$(artifact),$(1))))
|
||||
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
#
|
||||
# Copyright (C) 2026 Martin Schiller <ms@dev.tdt.de>
|
||||
#
|
||||
# This is free software, licensed under the GNU General Public License v2.
|
||||
# See /LICENSE for more information.
|
||||
#
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_VERSION:=2.14.0
|
||||
PKG_RELEASE:=1
|
||||
|
||||
PKG_HASH:=b2a3bc360307c929714ffd8e7f1441c4888cd5d80531276e809c2de54db5dc16
|
||||
|
||||
PKG_MAINTAINER:=Martin Schiller <ms@dev.tdt.de>
|
||||
|
||||
include $(INCLUDE_DIR)/kernel.mk
|
||||
include $(INCLUDE_DIR)/trusted-firmware-a.mk
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
|
||||
define Trusted-Firmware-A/Default
|
||||
BUILD_TARGET:=imx
|
||||
BUILD_SUBTARGET:=cortexa53
|
||||
endef
|
||||
|
||||
define Trusted-Firmware-A/imx8mp
|
||||
NAME:=NXP i.MX8MP
|
||||
PLAT:=imx8mp
|
||||
endef
|
||||
|
||||
TFA_TARGETS:= \
|
||||
imx8mp
|
||||
|
||||
TFA_MAKE_FLAGS += \
|
||||
IMX_BOOT_UART_BASE="auto"
|
||||
|
||||
define Package/trusted-firmware-a/install
|
||||
$(INSTALL_DIR) $(STAGING_DIR_IMAGE)
|
||||
$(INSTALL_DATA) $(PKG_BUILD_DIR)/build/$(PLAT)/release/bl31.bin $(STAGING_DIR_IMAGE)/bl31_$(BUILD_VARIANT).bin
|
||||
endef
|
||||
|
||||
$(eval $(call BuildPackage/Trusted-Firmware-A))
|
||||
@@ -7,10 +7,10 @@
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_VERSION:=2022.01
|
||||
PKG_RELEASE:=5
|
||||
PKG_VERSION:=2026.04
|
||||
PKG_RELEASE:=1
|
||||
|
||||
PKG_HASH:=81b4543227db228c03f8a1bf5ddbc813b0bb8f6555ce46064ef721a6fc680413
|
||||
PKG_HASH:=ac7c04b8b7004923b00a4e5d6699c5df4d21233bac9fda690d8cfbc209fff2fd
|
||||
|
||||
include $(INCLUDE_DIR)/u-boot.mk
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
@@ -28,6 +28,15 @@ define U-Boot/apalis_imx6
|
||||
BUILD_DEVICES:=toradex_apalis
|
||||
endef
|
||||
|
||||
define U-Boot/kontron-osm-s-mx8mp
|
||||
NAME:=Kontron OSM-S/BL i.MX8MP
|
||||
DEPENDS:=+firmware-imx +trusted-firmware-a-imx8mp
|
||||
ATF:=bl31_imx8mp.bin
|
||||
UBOOT_IMAGE:=flash.bin
|
||||
BUILD_SUBTARGET:=cortexa53
|
||||
BUILD_DEVICES:=kontron_osm-s-imx8mp
|
||||
endef
|
||||
|
||||
define U-Boot/mx6cuboxi
|
||||
NAME:=SolidRun Cubox-i boards
|
||||
UBOOT_IMAGE:=SPL u-boot-dtb.img
|
||||
@@ -52,11 +61,18 @@ endef
|
||||
|
||||
UBOOT_TARGETS := \
|
||||
apalis_imx6 \
|
||||
kontron-osm-s-mx8mp \
|
||||
mx6cuboxi \
|
||||
pico-pi-imx7d \
|
||||
wandboard
|
||||
|
||||
ifneq ($(SUBTARGET),cortexa53)
|
||||
UBOOT_MAKE_FLAGS += u-boot.imx
|
||||
else
|
||||
UBOOT_MAKE_FLAGS += \
|
||||
BL31=$(STAGING_DIR_IMAGE)/$(ATF) \
|
||||
BINMAN_INDIRS="$(STAGING_DIR_IMAGE)/firmware-imx $(STAGING_DIR_IMAGE)"
|
||||
endif
|
||||
|
||||
define Build/InstallDev
|
||||
$(INSTALL_DIR) $(STAGING_DIR_IMAGE)
|
||||
@@ -65,4 +81,7 @@ define Build/InstallDev
|
||||
)
|
||||
endef
|
||||
|
||||
define Package/u-boot/install/default
|
||||
endef
|
||||
|
||||
$(eval $(call BuildPackage/U-Boot))
|
||||
|
||||
+1
-1
@@ -16,7 +16,7 @@ Signed-off-by: Petr Štetiar <ynezz@true.cz>
|
||||
|
||||
--- a/configs/apalis_imx6_defconfig
|
||||
+++ b/configs/apalis_imx6_defconfig
|
||||
@@ -60,6 +60,7 @@ CONFIG_CMD_CACHE=y
|
||||
@@ -66,6 +66,7 @@ CONFIG_CMD_CACHE=y
|
||||
CONFIG_CMD_TIME=y
|
||||
CONFIG_CMD_PMIC=y
|
||||
CONFIG_CMD_REGULATOR=y
|
||||
|
||||
+3
-4
@@ -13,7 +13,7 @@ Signed-off-by: Zoltan HERPAI <wigyori@uid0.hu>
|
||||
create mode 100644 configs/mangopi_mqdual_t113_defconfig
|
||||
|
||||
--- /dev/null
|
||||
+++ b/arch/arm/dts/sun8i-t113s-mangopi-mqdual-t113.dts
|
||||
+++ b/dts/upstream/src/arm/allwinner/sun8i-t113s-mangopi-mqdual-t113.dts
|
||||
@@ -0,0 +1,50 @@
|
||||
+// SPDX-License-Identifier: (GPL-2.0+ or MIT)
|
||||
+// Copyright (C) 2022 Arm Ltd.
|
||||
@@ -67,10 +67,10 @@ Signed-off-by: Zoltan HERPAI <wigyori@uid0.hu>
|
||||
+};
|
||||
--- /dev/null
|
||||
+++ b/configs/mangopi_mqdual_t113_defconfig
|
||||
@@ -0,0 +1,18 @@
|
||||
@@ -0,0 +1,17 @@
|
||||
+CONFIG_ARM=y
|
||||
+CONFIG_ARCH_SUNXI=y
|
||||
+CONFIG_DEFAULT_DEVICE_TREE="sun8i-t113s-mangopi-mqdual-t113"
|
||||
+CONFIG_DEFAULT_DEVICE_TREE="allwinner/sun8i-t113s-mangopi-mqdual-t113"
|
||||
+CONFIG_SUNXI_MINIMUM_DRAM_MB=128
|
||||
+CONFIG_SPL=y
|
||||
+CONFIG_MACH_SUN8I_R528=y
|
||||
@@ -85,4 +85,3 @@ Signed-off-by: Zoltan HERPAI <wigyori@uid0.hu>
|
||||
+CONFIG_DRAM_SUNXI_TPR11=0x340000
|
||||
+CONFIG_DRAM_SUNXI_TPR12=0x46
|
||||
+CONFIG_DRAM_SUNXI_TPR13=0x34000100
|
||||
+# CONFIG_OF_UPSTREAM is not set
|
||||
|
||||
+77
-79
@@ -1,5 +1,79 @@
|
||||
--- /dev/null
|
||||
+++ b/arch/arm/dts/sun8i-t113s-myir-myd-yt113x-emmc.dts
|
||||
+++ b/configs/myir_myd_t113x-emmc_defconfig
|
||||
@@ -0,0 +1,29 @@
|
||||
+CONFIG_ARM=y
|
||||
+CONFIG_ARCH_SUNXI=y
|
||||
+CONFIG_DEFAULT_DEVICE_TREE="allwinner/sun8i-t113s-myir-myd-yt113x-emmc"
|
||||
+CONFIG_SUNXI_MINIMUM_DRAM_MB=128
|
||||
+CONFIG_SPL=y
|
||||
+CONFIG_MACH_SUN8I_R528=y
|
||||
+CONFIG_CONS_INDEX=6
|
||||
+CONFIG_MMC0_CD_PIN="PF6"
|
||||
+CONFIG_MMC_SUNXI_SLOT_EXTRA=2
|
||||
+# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
|
||||
+CONFIG_SYS_MONITOR_LEN=786432
|
||||
+CONFIG_DRAM_CLK=792
|
||||
+CONFIG_DRAM_ZQ=8092667
|
||||
+CONFIG_DRAM_SUNXI_ODT_EN=0
|
||||
+CONFIG_DRAM_SUNXI_TPR0=0x004a2195
|
||||
+CONFIG_DRAM_SUNXI_TPR11=0x340000
|
||||
+CONFIG_DRAM_SUNXI_TPR12=0x46
|
||||
+CONFIG_DRAM_SUNXI_TPR13=0x34000100
|
||||
+CONFIG_USB_EHCI_HCD=y
|
||||
+CONFIG_USB_OHCI_HCD=y
|
||||
+CONFIG_PHY_MOTORCOMM=y
|
||||
+CONFIG_SUN8I_EMAC=y
|
||||
+CONFIG_RGMII=y
|
||||
+CONFIG_RMII=y
|
||||
+CONFIG_SUPPORT_EMMC_BOOT=y
|
||||
+CONFIG_MMC_IO_VOLTAGE=y
|
||||
+CONFIG_SPL_MMC_IO_VOLTAGE=y
|
||||
+CONFIG_MMC_HS200_SUPPORT=y
|
||||
+CONFIG_SPL_MMC_HS200_SUPPORT=y
|
||||
--- /dev/null
|
||||
+++ b/configs/myir_myd_t113x-spi_defconfig
|
||||
@@ -0,0 +1,39 @@
|
||||
+CONFIG_ARM=y
|
||||
+CONFIG_ARCH_SUNXI=y
|
||||
+CONFIG_DEFAULT_DEVICE_TREE="allwinner/sun8i-t113s-myir-myd-yt113x-spi"
|
||||
+CONFIG_SUNXI_MINIMUM_DRAM_MB=128
|
||||
+CONFIG_SPL=y
|
||||
+CONFIG_SPL_SPI_SUNXI=y
|
||||
+CONFIG_MTD_SPI_NAND=y
|
||||
+CONFIG_MACH_SUN8I_R528=y
|
||||
+CONFIG_CONS_INDEX=6
|
||||
+CONFIG_MMC0_CD_PIN="PF6"
|
||||
+# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
|
||||
+CONFIG_SYS_MONITOR_LEN=786432
|
||||
+CONFIG_DRAM_CLK=792
|
||||
+CONFIG_DRAM_ZQ=8092667
|
||||
+CONFIG_DRAM_SUNXI_ODT_EN=0
|
||||
+CONFIG_DRAM_SUNXI_TPR0=0x004a2195
|
||||
+CONFIG_DRAM_SUNXI_TPR11=0x340000
|
||||
+CONFIG_DRAM_SUNXI_TPR12=0x46
|
||||
+CONFIG_DRAM_SUNXI_TPR13=0x34000100
|
||||
+CONFIG_CLK_SUN20I_D1=y
|
||||
+CONFIG_PHY_MOTORCOMM=y
|
||||
+CONFIG_SUN8I_EMAC=y
|
||||
+CONFIG_RGMII=y
|
||||
+CONFIG_RMII=y
|
||||
+CONFIG_MTD=y
|
||||
+CONFIG_DM_MTD=y
|
||||
+CONFIG_SYS_MTDPARTS_RUNTIME=y
|
||||
+CONFIG_NAND_STM32_FMC2=y
|
||||
+CONFIG_SYS_NAND_ONFI_DETECTION=y
|
||||
+CONFIG_MTD_SPI_NAND=y
|
||||
+CONFIG_DM_SPI_FLASH=y
|
||||
+CONFIG_SPI_FLASH_MACRONIX=y
|
||||
+CONFIG_SPI_FLASH_SPANSION=y
|
||||
+CONFIG_SPI_FLASH_STMICRO=y
|
||||
+CONFIG_SPI_FLASH_WINBOND=y
|
||||
+# CONFIG_SPI_FLASH_USE_4K_SECTORS is not set
|
||||
+CONFIG_SPI_FLASH_MTD=y
|
||||
+CONFIG_SPI=y
|
||||
+CONFIG_MTD_UBI_FASTMAP=y
|
||||
--- /dev/null
|
||||
+++ b/dts/upstream/src/arm/allwinner/sun8i-t113s-myir-myd-yt113x-emmc.dts
|
||||
@@ -0,0 +1,32 @@
|
||||
+// SPDX-License-Identifier: (GPL-2.0+ or MIT)
|
||||
+// Copyright (C) 2022 Arm Ltd.
|
||||
@@ -34,7 +108,7 @@
|
||||
+ };
|
||||
+};
|
||||
--- /dev/null
|
||||
+++ b/arch/arm/dts/sun8i-t113s-myir-myd-yt113x-spi.dts
|
||||
+++ b/dts/upstream/src/arm/allwinner/sun8i-t113s-myir-myd-yt113x-spi.dts
|
||||
@@ -0,0 +1,50 @@
|
||||
+// SPDX-License-Identifier: (GPL-2.0+ or MIT)
|
||||
+// Copyright (C) 2025 Zoltan HERPAI <wigyori@uid0.hu>
|
||||
@@ -87,83 +161,7 @@
|
||||
+ };
|
||||
+};
|
||||
--- /dev/null
|
||||
+++ b/configs/myir_myd_t113x-emmc_defconfig
|
||||
@@ -0,0 +1,30 @@
|
||||
+CONFIG_ARM=y
|
||||
+CONFIG_ARCH_SUNXI=y
|
||||
+CONFIG_DEFAULT_DEVICE_TREE="sun8i-t113s-myir-myd-yt113x-emmc"
|
||||
+CONFIG_SUNXI_MINIMUM_DRAM_MB=128
|
||||
+CONFIG_SPL=y
|
||||
+CONFIG_MACH_SUN8I_R528=y
|
||||
+CONFIG_CONS_INDEX=6
|
||||
+CONFIG_MMC0_CD_PIN="PF6"
|
||||
+CONFIG_MMC_SUNXI_SLOT_EXTRA=2
|
||||
+# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
|
||||
+CONFIG_SYS_MONITOR_LEN=786432
|
||||
+CONFIG_DRAM_CLK=792
|
||||
+CONFIG_DRAM_ZQ=8092667
|
||||
+CONFIG_DRAM_SUNXI_ODT_EN=0
|
||||
+CONFIG_DRAM_SUNXI_TPR0=0x004a2195
|
||||
+CONFIG_DRAM_SUNXI_TPR11=0x340000
|
||||
+CONFIG_DRAM_SUNXI_TPR12=0x46
|
||||
+CONFIG_DRAM_SUNXI_TPR13=0x34000100
|
||||
+CONFIG_USB_EHCI_HCD=y
|
||||
+CONFIG_USB_OHCI_HCD=y
|
||||
+CONFIG_PHY_MOTORCOMM=y
|
||||
+CONFIG_SUN8I_EMAC=y
|
||||
+CONFIG_RGMII=y
|
||||
+CONFIG_RMII=y
|
||||
+CONFIG_SUPPORT_EMMC_BOOT=y
|
||||
+CONFIG_MMC_IO_VOLTAGE=y
|
||||
+CONFIG_SPL_MMC_IO_VOLTAGE=y
|
||||
+CONFIG_MMC_HS200_SUPPORT=y
|
||||
+CONFIG_SPL_MMC_HS200_SUPPORT=y
|
||||
+# CONFIG_OF_UPSTREAM is not set
|
||||
--- /dev/null
|
||||
+++ b/configs/myir_myd_t113x-spi_defconfig
|
||||
@@ -0,0 +1,40 @@
|
||||
+CONFIG_ARM=y
|
||||
+CONFIG_ARCH_SUNXI=y
|
||||
+CONFIG_DEFAULT_DEVICE_TREE="sun8i-t113s-myir-myd-yt113x-spi"
|
||||
+CONFIG_SUNXI_MINIMUM_DRAM_MB=128
|
||||
+CONFIG_SPL=y
|
||||
+CONFIG_SPL_SPI_SUNXI=y
|
||||
+CONFIG_MTD_SPI_NAND=y
|
||||
+CONFIG_MACH_SUN8I_R528=y
|
||||
+CONFIG_CONS_INDEX=6
|
||||
+CONFIG_MMC0_CD_PIN="PF6"
|
||||
+# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
|
||||
+CONFIG_SYS_MONITOR_LEN=786432
|
||||
+CONFIG_DRAM_CLK=792
|
||||
+CONFIG_DRAM_ZQ=8092667
|
||||
+CONFIG_DRAM_SUNXI_ODT_EN=0
|
||||
+CONFIG_DRAM_SUNXI_TPR0=0x004a2195
|
||||
+CONFIG_DRAM_SUNXI_TPR11=0x340000
|
||||
+CONFIG_DRAM_SUNXI_TPR12=0x46
|
||||
+CONFIG_DRAM_SUNXI_TPR13=0x34000100
|
||||
+CONFIG_CLK_SUN20I_D1=y
|
||||
+CONFIG_PHY_MOTORCOMM=y
|
||||
+CONFIG_SUN8I_EMAC=y
|
||||
+CONFIG_RGMII=y
|
||||
+CONFIG_RMII=y
|
||||
+CONFIG_MTD=y
|
||||
+CONFIG_DM_MTD=y
|
||||
+CONFIG_SYS_MTDPARTS_RUNTIME=y
|
||||
+CONFIG_NAND_STM32_FMC2=y
|
||||
+CONFIG_SYS_NAND_ONFI_DETECTION=y
|
||||
+CONFIG_MTD_SPI_NAND=y
|
||||
+CONFIG_DM_SPI_FLASH=y
|
||||
+CONFIG_SPI_FLASH_MACRONIX=y
|
||||
+CONFIG_SPI_FLASH_SPANSION=y
|
||||
+CONFIG_SPI_FLASH_STMICRO=y
|
||||
+CONFIG_SPI_FLASH_WINBOND=y
|
||||
+# CONFIG_SPI_FLASH_USE_4K_SECTORS is not set
|
||||
+CONFIG_SPI_FLASH_MTD=y
|
||||
+CONFIG_SPI=y
|
||||
+CONFIG_MTD_UBI_FASTMAP=y
|
||||
+# CONFIG_OF_UPSTREAM is not set
|
||||
--- /dev/null
|
||||
+++ b/arch/arm/dts/sun8i-t113s-myir-myd-yt113x.dtsi
|
||||
+++ b/dts/upstream/src/arm/allwinner/sun8i-t113s-myir-myd-yt113x.dtsi
|
||||
@@ -0,0 +1,144 @@
|
||||
+// SPDX-License-Identifier: (GPL-2.0+ or MIT)
|
||||
+// Copyright (C) 2025 Zoltan HERPAI <wigyori@uid0.hu>
|
||||
|
||||
+3
-4
@@ -13,7 +13,7 @@ Signed-off-by: Zoltan HERPAI <wigyori@uid0.hu>
|
||||
create mode 100644 configs/rongpin_rp_t113_defconfig
|
||||
|
||||
--- /dev/null
|
||||
+++ b/arch/arm/dts/sun8i-t113s-rongpin-rp-t113.dts
|
||||
+++ b/dts/upstream/src/arm/allwinner/sun8i-t113s-rongpin-rp-t113.dts
|
||||
@@ -0,0 +1,99 @@
|
||||
+// SPDX-License-Identifier: (GPL-2.0+ or MIT)
|
||||
+// Copyright (C) 2022 Arm Ltd.
|
||||
@@ -116,10 +116,10 @@ Signed-off-by: Zoltan HERPAI <wigyori@uid0.hu>
|
||||
+};
|
||||
--- /dev/null
|
||||
+++ b/configs/rongpin_rp_t113_defconfig
|
||||
@@ -0,0 +1,19 @@
|
||||
@@ -0,0 +1,18 @@
|
||||
+CONFIG_ARM=y
|
||||
+CONFIG_ARCH_SUNXI=y
|
||||
+CONFIG_DEFAULT_DEVICE_TREE="sun8i-t113s-rongpin-rp-t113"
|
||||
+CONFIG_DEFAULT_DEVICE_TREE="allwinner/sun8i-t113s-rongpin-rp-t113"
|
||||
+CONFIG_SUNXI_MINIMUM_DRAM_MB=128
|
||||
+CONFIG_SPL=y
|
||||
+CONFIG_MACH_SUN8I_R528=y
|
||||
@@ -135,4 +135,3 @@ Signed-off-by: Zoltan HERPAI <wigyori@uid0.hu>
|
||||
+CONFIG_DRAM_SUNXI_TPR12=0x46
|
||||
+CONFIG_DRAM_SUNXI_TPR13=0x34000100
|
||||
+CONFIG_UART3_PINS_PE=y
|
||||
+# CONFIG_OF_UPSTREAM is not set
|
||||
|
||||
@@ -27,8 +27,8 @@ Signed-off-by: Zoltan HERPAI <wigyori@uid0.hu>
|
||||
configs/rongpin_rp_t113_defconfig | 3 +++
|
||||
2 files changed, 31 insertions(+)
|
||||
|
||||
--- a/arch/arm/dts/sun8i-t113s-rongpin-rp-t113.dts
|
||||
+++ b/arch/arm/dts/sun8i-t113s-rongpin-rp-t113.dts
|
||||
--- a/dts/upstream/src/arm/allwinner/sun8i-t113s-rongpin-rp-t113.dts
|
||||
+++ b/dts/upstream/src/arm/allwinner/sun8i-t113s-rongpin-rp-t113.dts
|
||||
@@ -55,6 +55,16 @@
|
||||
regulator-max-microvolt = <2800000>;
|
||||
vin-supply = <®_3v3>;
|
||||
@@ -77,10 +77,10 @@ Signed-off-by: Zoltan HERPAI <wigyori@uid0.hu>
|
||||
+};
|
||||
--- a/configs/rongpin_rp_t113_defconfig
|
||||
+++ b/configs/rongpin_rp_t113_defconfig
|
||||
@@ -17,3 +17,6 @@ CONFIG_DRAM_SUNXI_TPR12=0x46
|
||||
@@ -16,3 +16,6 @@ CONFIG_DRAM_SUNXI_TPR11=0x340000
|
||||
CONFIG_DRAM_SUNXI_TPR12=0x46
|
||||
CONFIG_DRAM_SUNXI_TPR13=0x34000100
|
||||
CONFIG_UART3_PINS_PE=y
|
||||
# CONFIG_OF_UPSTREAM is not set
|
||||
+CONFIG_SUN8I_EMAC=y
|
||||
+CONFIG_PHY_ICPLUS=y
|
||||
+CONFIG_RMII=y
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
--- /dev/null
|
||||
+++ b/arch/arm/dts/sun8i-t113s-olinuxino.dts
|
||||
+++ b/dts/upstream/src/arm/allwinner/sun8i-t113s-olinuxino.dts
|
||||
@@ -0,0 +1,193 @@
|
||||
+// SPDX-License-Identifier: (GPL-2.0+ or MIT)
|
||||
+// Copyright (C) 2022 Arm Ltd.
|
||||
@@ -196,10 +196,10 @@
|
||||
+};
|
||||
--- /dev/null
|
||||
+++ b/configs/olimex_olinuxino_defconfig
|
||||
@@ -0,0 +1,42 @@
|
||||
@@ -0,0 +1,41 @@
|
||||
+CONFIG_ARM=y
|
||||
+CONFIG_ARCH_SUNXI=y
|
||||
+CONFIG_DEFAULT_DEVICE_TREE="sun8i-t113s-olinuxino"
|
||||
+CONFIG_DEFAULT_DEVICE_TREE="allwinner/sun8i-t113s-olinuxino"
|
||||
+CONFIG_SUNXI_MINIMUM_DRAM_MB=128
|
||||
+CONFIG_SPL=y
|
||||
+CONFIG_MACH_SUN8I_R528=y
|
||||
@@ -238,4 +238,3 @@
|
||||
+CONFIG_SPL_SPI_FLASH_MTD=y
|
||||
+CONFIG_SPL_SPI_SUNXI=y
|
||||
+CONFIG_SPI=y
|
||||
+# CONFIG_OF_UPSTREAM is not set
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
#
|
||||
# Copyright 2022-2025 NXP
|
||||
#
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=firmware-imx
|
||||
PKG_VERSION:=8.28-994fa14
|
||||
PKG_RELEASE:=1
|
||||
|
||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).bin
|
||||
PKG_SOURCE_URL:=https://www.nxp.com/lgfiles/NMG/MAD/YOCTO/
|
||||
PKG_HASH:=55996f340e87825685a00cd309901189066ec9545ee607734f942c3cde4d69dc
|
||||
|
||||
PKG_LICENSE:=LA_OPT_NXP_Software_License
|
||||
PKG_LICENSE_FILES:=COPYING
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
|
||||
define Package/firmware-imx
|
||||
SECTION:=firmware
|
||||
CATEGORY:=Firmware
|
||||
TITLE:=NXP firmware for i.MX SoC
|
||||
DEPENDS:=@TARGET_imx_cortexa53
|
||||
endef
|
||||
|
||||
UNPACK_CMD:=
|
||||
define Build/Compile
|
||||
$(PKG_UNPACK)
|
||||
$(CP) $(DL_DIR)/$(PKG_SOURCE) $(PKG_BUILD_DIR)
|
||||
chmod a+x $(PKG_BUILD_DIR)/$(PKG_SOURCE)
|
||||
cd $(PKG_BUILD_DIR) && ./$(PKG_SOURCE) --auto-accept
|
||||
endef
|
||||
|
||||
define Build/InstallDev
|
||||
$(INSTALL_DIR) $(STAGING_DIR_IMAGE)/firmware-imx
|
||||
$(CP) $(PKG_BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)/firmware/ddr/synopsys/* \
|
||||
$(STAGING_DIR_IMAGE)/firmware-imx/
|
||||
$(CP) $(PKG_BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)/firmware/hdmi/cadence/* \
|
||||
$(STAGING_DIR_IMAGE)/firmware-imx/
|
||||
endef
|
||||
|
||||
$(eval $(call BuildPackage,firmware-imx))
|
||||
@@ -8,12 +8,12 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=linux-firmware
|
||||
PKG_VERSION:=20260410
|
||||
PKG_VERSION:=20260519
|
||||
PKG_RELEASE:=1
|
||||
|
||||
PKG_SOURCE_URL:=@KERNEL/linux/kernel/firmware
|
||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
|
||||
PKG_HASH:=b7812ed6d59f6b09ecceddaa0be842a7e82a79cc0e46ca60478a4ebf02f1e178
|
||||
PKG_HASH:=b14e7197a290a7e5569f5ef790cde289bddc47e32126f2eb262a8e677fc39727
|
||||
|
||||
PKG_MAINTAINER:=Felix Fietkau <nbd@nbd.name>
|
||||
|
||||
@@ -32,6 +32,7 @@ define Package/firmware-default
|
||||
DEPENDS:=$(2)
|
||||
LICENSE_FILES:=$(3)
|
||||
LICENSE:=$(4)
|
||||
$(if $(5),PKGFLAGS:=$(5))
|
||||
endef
|
||||
|
||||
define Build/Compile
|
||||
|
||||
@@ -97,7 +97,7 @@ define Package/mt7986-wo-firmware/install
|
||||
endef
|
||||
$(eval $(call BuildPackage,mt7986-wo-firmware))
|
||||
|
||||
Package/mt7987-2p5g-phy-firmware = $(call Package/firmware-default,MT7987 built-in 2.5G Ethernet PHY firmware,+LINUX_6_18:kmod-phy-mediatek-2p5g,LICENCE.mediatek)
|
||||
Package/mt7987-2p5g-phy-firmware = $(call Package/firmware-default,MT7987 built-in 2.5G Ethernet PHY firmware,@TARGET_mediatek_filogic +LINUX_6_18:kmod-phy-mediatek-2p5g,LICENCE.mediatek,,nonshared)
|
||||
define Package/mt7987-2p5g-phy-firmware/install
|
||||
$(INSTALL_DIR) $(1)/lib/firmware/mediatek/mt7987
|
||||
$(INSTALL_DATA) \
|
||||
@@ -107,7 +107,7 @@ define Package/mt7987-2p5g-phy-firmware/install
|
||||
endef
|
||||
$(eval $(call BuildPackage,mt7987-2p5g-phy-firmware))
|
||||
|
||||
Package/mt7988-2p5g-phy-firmware = $(call Package/firmware-default,MT7988 built-in 2.5G Ethernet PHY firmware,+LINUX_6_18:kmod-phy-mediatek-2p5g,LICENCE.mediatek)
|
||||
Package/mt7988-2p5g-phy-firmware = $(call Package/firmware-default,MT7988 built-in 2.5G Ethernet PHY firmware,@TARGET_mediatek_filogic +LINUX_6_18:kmod-phy-mediatek-2p5g,LICENCE.mediatek,,nonshared)
|
||||
define Package/mt7988-2p5g-phy-firmware/install
|
||||
$(INSTALL_DIR) $(1)/lib/firmware/mediatek/mt7988
|
||||
$(INSTALL_DATA) \
|
||||
|
||||
@@ -365,6 +365,7 @@ gpio_keys_get_devtree_pdata(struct device *dev)
|
||||
{
|
||||
struct device_node *node = dev->of_node;
|
||||
struct gpio_keys_platform_data *pdata;
|
||||
struct gpio_keys_button *buttons;
|
||||
int nbuttons;
|
||||
int i = 0;
|
||||
|
||||
@@ -372,21 +373,12 @@ gpio_keys_get_devtree_pdata(struct device *dev)
|
||||
if (nbuttons == 0)
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
||||
pdata = devm_kzalloc(dev, sizeof(struct gpio_keys_platform_data), GFP_KERNEL);
|
||||
if (!pdata)
|
||||
buttons = devm_kmalloc_array(dev, nbuttons, sizeof(struct gpio_keys_button), GFP_KERNEL);
|
||||
if (!buttons)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
pdata->buttons = devm_kmalloc_array(dev, nbuttons, sizeof(struct gpio_keys_button), GFP_KERNEL);
|
||||
if (!pdata->buttons)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
pdata->nbuttons = nbuttons;
|
||||
|
||||
pdata->rep = of_property_present(node, "autorepeat");
|
||||
of_property_read_u32(node, "poll-interval", &pdata->poll_interval);
|
||||
|
||||
for_each_available_child_of_node_scoped(node, pp) {
|
||||
struct gpio_keys_button *button = (struct gpio_keys_button *)&pdata->buttons[i++];
|
||||
struct gpio_keys_button *button = &buttons[i++];
|
||||
|
||||
if (of_property_read_u32(pp, "linux,code", &button->code)) {
|
||||
dev_err(dev, "Button node '%s' without keycode\n",
|
||||
@@ -409,6 +401,15 @@ gpio_keys_get_devtree_pdata(struct device *dev)
|
||||
button->gpio = -ENOENT; /* mark this as device-tree */
|
||||
}
|
||||
|
||||
pdata = devm_kzalloc(dev, sizeof(struct gpio_keys_platform_data), GFP_KERNEL);
|
||||
if (!pdata)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
pdata->nbuttons = nbuttons;
|
||||
pdata->buttons = buttons;
|
||||
pdata->rep = of_property_present(node, "autorepeat");
|
||||
of_property_read_u32(node, "poll-interval", &pdata->poll_interval);
|
||||
|
||||
return pdata;
|
||||
}
|
||||
|
||||
|
||||
@@ -1133,8 +1133,8 @@ define KernelPackage/crypto-sha512/arm
|
||||
endef
|
||||
|
||||
define KernelPackage/crypto-sha512/aarch64
|
||||
FILES+=$(LINUX_DIR)/arch/arm64/crypto/sha512-arm64.ko
|
||||
AUTOLOAD+=$(call AutoLoad,09,sha512-arm64)
|
||||
FILES+=$(LINUX_DIR)/arch/arm64/crypto/sha512-arm64.ko@lt6.18
|
||||
AUTOLOAD+=$(call AutoLoad,09,!LINUX_6_18:sha512-arm64)
|
||||
endef
|
||||
|
||||
KernelPackage/crypto-sha512/imx/cortexa7=$(KernelPackage/crypto-sha512/arm)
|
||||
|
||||
@@ -221,6 +221,23 @@ endef
|
||||
|
||||
$(eval $(call KernelPackage,rtc-rs5c372a))
|
||||
|
||||
define KernelPackage/rtc-rv3028
|
||||
SUBMENU:=$(RTC_MENU)
|
||||
TITLE:=Micro Crystal RV3028
|
||||
DEFAULT:=m if ALL_KMODS && RTC_SUPPORT
|
||||
DEPENDS:=+kmod-i2c-core +kmod-regmap-i2c
|
||||
KCONFIG:=CONFIG_RTC_DRV_RV3028 \
|
||||
CONFIG_RTC_CLASS=y
|
||||
FILES:=$(LINUX_DIR)/drivers/rtc/rtc-rv3028.ko
|
||||
AUTOLOAD:=$(call AutoLoad,50,rtc-rv3028,1)
|
||||
endef
|
||||
|
||||
define KernelPackage/rtc-rv3028/description
|
||||
Kernel module for Micro Crystal RV3028 I2C RTC chip
|
||||
endef
|
||||
|
||||
$(eval $(call KernelPackage,rtc-rv3028))
|
||||
|
||||
define KernelPackage/rtc-rx8025
|
||||
SUBMENU:=$(RTC_MENU)
|
||||
TITLE:=Epson RX-8025 / RX-8035
|
||||
|
||||
+59
@@ -0,0 +1,59 @@
|
||||
From: Felix Fietkau <nbd@nbd.name>
|
||||
Date: Mon, 23 Mar 2026 10:14:22 +0000
|
||||
Subject: [PATCH] wifi: mac80211: add ieee80211_txq_aql_pending()
|
||||
|
||||
Add a function to allow drivers to query the pending AQL airtime
|
||||
for a given txq, for both unicast and broadcast.
|
||||
This will be used for mt76 to limit buffering in AP mode for power-save
|
||||
stations.
|
||||
|
||||
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
---
|
||||
|
||||
--- a/include/net/mac80211.h
|
||||
+++ b/include/net/mac80211.h
|
||||
@@ -6603,6 +6603,17 @@ bool
|
||||
ieee80211_txq_airtime_check(struct ieee80211_hw *hw, struct ieee80211_txq *txq);
|
||||
|
||||
/**
|
||||
+ * ieee80211_txq_aql_pending - get pending AQL airtime for a txq
|
||||
+ *
|
||||
+ * @hw: pointer obtained from ieee80211_alloc_hw()
|
||||
+ * @txq: pointer obtained from station or virtual interface
|
||||
+ *
|
||||
+ * Return: pending airtime (in usec) for the given txq.
|
||||
+ */
|
||||
+u32 ieee80211_txq_aql_pending(struct ieee80211_hw *hw,
|
||||
+ struct ieee80211_txq *txq);
|
||||
+
|
||||
+/**
|
||||
* ieee80211_iter_keys - iterate keys programmed into the device
|
||||
* @hw: pointer obtained from ieee80211_alloc_hw()
|
||||
* @vif: virtual interface to iterate, may be %NULL for all
|
||||
--- a/net/mac80211/tx.c
|
||||
+++ b/net/mac80211/tx.c
|
||||
@@ -4185,6 +4185,24 @@ bool ieee80211_txq_airtime_check(struct
|
||||
}
|
||||
EXPORT_SYMBOL(ieee80211_txq_airtime_check);
|
||||
|
||||
+u32 ieee80211_txq_aql_pending(struct ieee80211_hw *hw,
|
||||
+ struct ieee80211_txq *txq)
|
||||
+{
|
||||
+ struct ieee80211_local *local = hw_to_local(hw);
|
||||
+ struct sta_info *sta;
|
||||
+
|
||||
+ if (!txq->sta)
|
||||
+ return atomic_read(&local->aql_bc_pending_airtime);
|
||||
+
|
||||
+ sta = container_of(txq->sta, struct sta_info, sta);
|
||||
+
|
||||
+ if (unlikely(txq->tid == IEEE80211_NUM_TIDS))
|
||||
+ return 0;
|
||||
+
|
||||
+ return atomic_read(&sta->airtime[txq->ac].aql_tx_pending);
|
||||
+}
|
||||
+EXPORT_SYMBOL(ieee80211_txq_aql_pending);
|
||||
+
|
||||
static bool
|
||||
ieee80211_txq_schedule_airtime_check(struct ieee80211_local *local, u8 ac)
|
||||
{
|
||||
@@ -535,6 +535,28 @@ menu "Resource limits"
|
||||
Possible values: 1 to 80 (from src/sysoptions.h)
|
||||
Default: 10
|
||||
|
||||
config DROPBEAR_MAX_PUBKEY_QUERIES
|
||||
int "Max. public key queries per session"
|
||||
range 1 80
|
||||
default 15
|
||||
help
|
||||
Default maximum number of public key queries per session (server option).
|
||||
|
||||
Public key queries aren't a risk for brute forcing authentication,
|
||||
but can be a user enumeration/privacy concern if an attacker
|
||||
attempts to iterate known public keys such as those published by GitHub.
|
||||
|
||||
This limit has a trade-off. Having a smaller limit reduces the number
|
||||
of legitimate public keys that can be presented by a client/ssh agent.
|
||||
|
||||
That is still a risk against a single host,
|
||||
but this limit may deter internet-wide scanning.
|
||||
|
||||
If -T argument or DROPBEAR_MAX_AUTH_TRIES is larger that will be used instead.
|
||||
|
||||
Possible values: 1 to 80 (same as for DROPBEAR_MAX_AUTH_TRIES)
|
||||
Default: 15
|
||||
|
||||
config DROPBEAR_UNAUTH_CLOSE_DELAY
|
||||
int "Delay closing unauth. connections (seconds)"
|
||||
range 0 3600
|
||||
@@ -640,6 +662,21 @@ menu "Resource limits"
|
||||
Possible values: 0 to 604800 (7 days)
|
||||
Default: 0 (disabled).
|
||||
|
||||
config DROPBEAR_DEFAULT_MAX_DURATION
|
||||
int "Default max. session duration (seconds)"
|
||||
range 0 604800
|
||||
default 0
|
||||
help
|
||||
If session duration exceeds specified limit, disconnect.
|
||||
Applies to both server and client.
|
||||
|
||||
Note: values below 30 seconds are not recommended.
|
||||
|
||||
This can be changed at run-time with the -M argument.
|
||||
|
||||
Possible values: 0 to 604800 (7 days)
|
||||
Default: 0 (disabled).
|
||||
|
||||
endmenu
|
||||
## </RESOURCE LIMITS>
|
||||
|
||||
@@ -985,7 +1022,7 @@ menu "Encryption options"
|
||||
|
||||
Post-quantum KEM can avoid harvest-now-decrypt-later style attacks.
|
||||
|
||||
Default: enabled, except devices with very small flash.
|
||||
Default: disabled.
|
||||
|
||||
config DROPBEAR_SNTRUP761
|
||||
bool "sntrup761 [POST-QUANTUM]"
|
||||
|
||||
@@ -8,14 +8,14 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=dropbear
|
||||
PKG_VERSION:=2025.89
|
||||
PKG_VERSION:=2026.91
|
||||
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:=0d1f7ca711cfc336dc8a85e672cab9cfd8223a02fe2da0a4a7aeb58c9e113634
|
||||
PKG_HASH:=defa924475abf6bc1e74abc00173e46bfdc804bd47caafa14f5a4ef0cc76da34
|
||||
|
||||
PKG_LICENSE:=MIT
|
||||
PKG_LICENSE_FILES:=LICENSE libtomcrypt/LICENSE libtommath/LICENSE
|
||||
@@ -32,7 +32,7 @@ PKG_CONFIG_DEPENDS:= \
|
||||
CONFIG_DROPBEAR_DO_HOST_LOOKUP CONFIG_DROPBEAR_SVR_PUBKEY_OPTIONS CONFIG_DROPBEAR_LASTLOG CONFIG_DROPBEAR_LASTLOG_PATH CONFIG_DROPBEAR_WTMP CONFIG_DROPBEAR_WTMP_PATH CONFIG_DROPBEAR_UTMP CONFIG_DROPBEAR_UTMP_PATH CONFIG_DROPBEAR_PUTUTLINE CONFIG_DROPBEAR_LOGINFUNC \
|
||||
CONFIG_DROPBEAR_REEXEC CONFIG_DROPBEAR_ZLIB CONFIG_DROPBEAR_DELAY_HOSTKEY CONFIG_DROPBEAR_SVR_AGENTFWD CONFIG_DROPBEAR_SVR_REMOTETCPFWD CONFIG_DROPBEAR_SVR_LOCALTCPFWD CONFIG_DROPBEAR_SVR_LOCALSTREAMFWD CONFIG_DROPBEAR_X11FWD CONFIG_DROPBEAR_SCP CONFIG_DROPBEAR_SFTPSERVER \
|
||||
CONFIG_DROPBEAR_DBCLIENT CONFIG_DROPBEAR_USER_ALGO_LIST CONFIG_DROPBEAR_USE_SSH_CONFIG CONFIG_DROPBEAR_CLI_IMMEDIATE_AUTH CONFIG_DROPBEAR_USE_PASSWORD_ENV CONFIG_DROPBEAR_CLI_ASKPASS_HELPER CONFIG_DROPBEAR_CLI_AGENTFWD CONFIG_DROPBEAR_CLI_LOCALTCPFWD CONFIG_DROPBEAR_CLI_REMOTETCPFWD CONFIG_DROPBEAR_CLI_PROXYCMD CONFIG_DROPBEAR_CLI_NETCAT CONFIG_DROPBEAR_CLI_MULTIHOP \
|
||||
CONFIG_DROPBEAR_KEX_REKEY_TIMEOUT CONFIG_DROPBEAR_KEX_REKEY_DATA CONFIG_DROPBEAR_AUTH_TIMEOUT CONFIG_DROPBEAR_MAX_AUTH_TRIES CONFIG_DROPBEAR_UNAUTH_CLOSE_DELAY CONFIG_DROPBEAR_MAX_UNAUTH_PER_IP CONFIG_DROPBEAR_MAX_UNAUTH_CLIENTS CONFIG_DROPBEAR_DEFAULT_RECV_WINDOW CONFIG_DROPBEAR_DEFAULT_KEEPALIVE CONFIG_DROPBEAR_DEFAULT_KEEPALIVE_LIMIT CONFIG_DROPBEAR_DEFAULT_IDLE_TIMEOUT \
|
||||
CONFIG_DROPBEAR_KEX_REKEY_TIMEOUT CONFIG_DROPBEAR_KEX_REKEY_DATA CONFIG_DROPBEAR_AUTH_TIMEOUT CONFIG_DROPBEAR_MAX_AUTH_TRIES CONFIG_DROPBEAR_UNAUTH_CLOSE_DELAY CONFIG_DROPBEAR_MAX_UNAUTH_PER_IP CONFIG_DROPBEAR_MAX_UNAUTH_CLIENTS CONFIG_DROPBEAR_DEFAULT_RECV_WINDOW CONFIG_DROPBEAR_DEFAULT_KEEPALIVE CONFIG_DROPBEAR_DEFAULT_KEEPALIVE_LIMIT CONFIG_DROPBEAR_DEFAULT_IDLE_TIMEOUT CONFIG_DROPBEAR_MAX_PUBKEY_QUERIES CONFIG_DROPBEAR_DEFAULT_MAX_DURATION \
|
||||
CONFIG_DROPBEAR_3DES CONFIG_DROPBEAR_AES128 CONFIG_DROPBEAR_AES256 CONFIG_DROPBEAR_CHACHA20POLY1305 \
|
||||
CONFIG_DROPBEAR_ENABLE_CTR_MODE CONFIG_DROPBEAR_ENABLE_CBC_MODE CONFIG_DROPBEAR_ENABLE_GCM_MODE \
|
||||
CONFIG_DROPBEAR_SHA1_96_HMAC CONFIG_DROPBEAR_SHA1_HMAC CONFIG_DROPBEAR_SHA2_256_HMAC CONFIG_DROPBEAR_SHA2_512_HMAC \
|
||||
@@ -130,10 +130,12 @@ DB_OPT_COMMON = \
|
||||
DEFAULT_IDLE_TIMEOUT,$(CONFIG_DROPBEAR_DEFAULT_IDLE_TIMEOUT) \
|
||||
DEFAULT_KEEPALIVE_LIMIT,$(CONFIG_DROPBEAR_DEFAULT_KEEPALIVE_LIMIT) \
|
||||
DEFAULT_KEEPALIVE,$(CONFIG_DROPBEAR_DEFAULT_KEEPALIVE) \
|
||||
DEFAULT_MAX_DURATION,$(CONFIG_DROPBEAR_DEFAULT_MAX_DURATION) \
|
||||
DEFAULT_RECV_WINDOW,$(CONFIG_DROPBEAR_DEFAULT_RECV_WINDOW) \
|
||||
KEX_REKEY_DATA,$(CONFIG_DROPBEAR_KEX_REKEY_DATA) \
|
||||
KEX_REKEY_TIMEOUT,$(CONFIG_DROPBEAR_KEX_REKEY_TIMEOUT) \
|
||||
MAX_AUTH_TRIES,$(CONFIG_DROPBEAR_MAX_AUTH_TRIES) \
|
||||
MAX_PUBKEY_QUERIES,$(CONFIG_DROPBEAR_MAX_PUBKEY_QUERIES) \
|
||||
MAX_UNAUTH_CLIENTS,$(CONFIG_DROPBEAR_MAX_UNAUTH_CLIENTS) \
|
||||
MAX_UNAUTH_PER_IP,$(CONFIG_DROPBEAR_MAX_UNAUTH_PER_IP) \
|
||||
UNAUTH_CLOSE_DELAY,$(CONFIG_DROPBEAR_UNAUTH_CLOSE_DELAY) \
|
||||
|
||||
@@ -1,61 +1,83 @@
|
||||
#!/bin/sh
|
||||
|
||||
_dropbear()
|
||||
{
|
||||
/usr/sbin/dropbear "$@" </dev/null >/dev/null 2>&1
|
||||
db_key_quiet() { dropbearkey "$@" </dev/null >/dev/null 2>&1 ; }
|
||||
db_key_types_int() {
|
||||
dropbearkey -h </dev/null 2>&1 \
|
||||
| sed -En '/^\s*-t/,/^\s*-/p' \
|
||||
| sed -En '/^\s*-/n;p'
|
||||
}
|
||||
db_key_types() {
|
||||
normalize_list "$(db_key_types_int)"
|
||||
}
|
||||
|
||||
_dropbearkey()
|
||||
db_key_ensure()
|
||||
{
|
||||
/usr/bin/dropbearkey "$@" </dev/null >/dev/null 2>&1
|
||||
}
|
||||
|
||||
_ensurekey()
|
||||
{
|
||||
_dropbearkey -y -f "$1" && return
|
||||
db_key_quiet -y -f "$1" && return
|
||||
rm -f "$1"
|
||||
_dropbearkey -f "$@" || {
|
||||
db_key_quiet -f "$@" || {
|
||||
rm -f "$1"
|
||||
return 1
|
||||
}
|
||||
}
|
||||
|
||||
ktype_all='ed25519 ecdsa rsa'
|
||||
# $1 - list with whitespace-separated elements
|
||||
normalize_list()
|
||||
{
|
||||
printf '%s' "$1" | tr -s ' \r\n\t' ' ' | sed -E 's/^ //;s/ $//'
|
||||
}
|
||||
|
||||
failsafe_dropbear () {
|
||||
local kargs kcount ktype tkey
|
||||
failsafe_dropbear() {
|
||||
local ktype_all kargs kcount ktype tkey
|
||||
|
||||
# don't hardcode supported algorithm list until things go wrong
|
||||
ktype_all=$(db_key_types)
|
||||
[ -n "${ktype_all}" ] || {
|
||||
echo "dropbear: unable to correctly retrieve supported hostkey algorithms!" >&2
|
||||
|
||||
ktype_all='rsa ecdsa ed25519'
|
||||
}
|
||||
|
||||
kargs=
|
||||
kcount=0
|
||||
for ktype in ${ktype_all} ; do
|
||||
tkey="/tmp/dropbear_failsafe_${ktype}_host_key"
|
||||
|
||||
case "${ktype}" in
|
||||
ed25519) _ensurekey "${tkey}" -t ed25519 ;;
|
||||
ecdsa) _ensurekey "${tkey}" -t ecdsa -s 256 ;;
|
||||
rsa) _ensurekey "${tkey}" -t rsa -s 1024 ;;
|
||||
*)
|
||||
echo "unknown key type: ${ktype}" >&2
|
||||
continue
|
||||
rsa ) ;; # skip (see below)
|
||||
* )
|
||||
tkey="/tmp/dropbear_failsafe_${ktype}_host_key"
|
||||
|
||||
db_key_ensure "${tkey}" -t "${ktype}" || :
|
||||
if [ -s "${tkey}" ] ; then
|
||||
chmod 0400 "${tkey}"
|
||||
kargs="${kargs} -r ${tkey}"
|
||||
kcount=$((kcount+1))
|
||||
else
|
||||
rm -f "${tkey}" "${tkey}.pub"
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
[ -s "${tkey}" ] || {
|
||||
rm -f "${tkey}"
|
||||
continue
|
||||
}
|
||||
|
||||
chmod 0400 "${tkey}"
|
||||
kargs="${kargs}${kargs:+ }-r ${tkey}"
|
||||
kcount=$((kcount+1))
|
||||
done
|
||||
|
||||
# use RSA only if none of the modern algorithms is supported
|
||||
if [ "${kcount}" = 0 ] ; then
|
||||
ktype=rsa
|
||||
tkey="/tmp/dropbear_failsafe_${ktype}_host_key"
|
||||
|
||||
db_key_ensure "${tkey}" -t "${ktype}" || :
|
||||
if [ -s "${tkey}" ] ; then
|
||||
chmod 0400 "${tkey}"
|
||||
kargs="${kargs} -r ${tkey}"
|
||||
kcount=$((kcount+1))
|
||||
else
|
||||
rm -f "${tkey}" "${tkey}.pub"
|
||||
fi
|
||||
fi
|
||||
|
||||
[ "${kcount}" != 0 ] || {
|
||||
echo 'DROPBEAR IS BROKEN' >&2
|
||||
return 1
|
||||
}
|
||||
|
||||
_dropbear ${kargs}
|
||||
dropbear ${kargs} </dev/null >/dev/null 2>&1
|
||||
}
|
||||
|
||||
boot_hook_add failsafe failsafe_dropbear
|
||||
|
||||
@@ -18,9 +18,14 @@ dumb_stat() { ls -Ldln "$1" | tr -s '\t ' ' ' ; }
|
||||
stat_perm() { real_stat -c '%A' "$1" || dumb_stat "$1" | cut -d ' ' -f 1 ; }
|
||||
stat_owner() { real_stat -c '%u' "$1" || dumb_stat "$1" | cut -d ' ' -f 3 ; }
|
||||
|
||||
_dropbearkey()
|
||||
{
|
||||
/usr/bin/dropbearkey "$@" </dev/null >/dev/null 2>&1
|
||||
db_key_quiet() { dropbearkey "$@" </dev/null >/dev/null 2>&1 ; }
|
||||
db_key_types_int() {
|
||||
dropbearkey -h </dev/null 2>&1 \
|
||||
| sed -En '/^\s*-t/,/^\s*-/p' \
|
||||
| sed -En '/^\s*-/n;p'
|
||||
}
|
||||
db_key_types() {
|
||||
normalize_list "$(db_key_types_int)"
|
||||
}
|
||||
|
||||
# $1 - file name (host key or config)
|
||||
@@ -43,7 +48,7 @@ file_verify()
|
||||
[ -z "$2" ] || return 0
|
||||
# checking file contents (finally)
|
||||
[ -s "$1" ] || return 4
|
||||
_dropbearkey -y -f "$1" || return 5
|
||||
db_key_quiet -y -f "$1" || return 5
|
||||
return 0
|
||||
}
|
||||
|
||||
@@ -79,22 +84,32 @@ hk_config()
|
||||
# $1 - host key file name
|
||||
hk_config__keyfile() { hk_config keyfile "$1" ; }
|
||||
|
||||
ktype_all='ed25519 ecdsa rsa'
|
||||
|
||||
hk_generate_as_needed()
|
||||
{
|
||||
local hk_cfg_dir kgen ktype kfile hk_tmp_dir
|
||||
local hk_cfg_dir ktype_all kgen ktype kfile hk_tmp_dir
|
||||
hk_cfg_dir='/etc/dropbear'
|
||||
|
||||
[ -d "${hk_cfg_dir}" ] || mkdir -p "${hk_cfg_dir}"
|
||||
|
||||
# don't hardcode supported algorithm list until things go wrong
|
||||
ktype_all=$(db_key_types)
|
||||
[ -n "${ktype_all}" ] || {
|
||||
logger -t "${NAME}" -p daemon.warn \
|
||||
"unable to correctly retrieve supported hostkey algorithms!"
|
||||
|
||||
ktype_all='rsa ecdsa ed25519'
|
||||
}
|
||||
|
||||
kgen=
|
||||
for ktype in ${ktype_all} ; do
|
||||
kfile="${hk_cfg_dir}/dropbear_${ktype}_host_key"
|
||||
|
||||
if file_verify "${kfile}" ; then continue ; fi
|
||||
|
||||
kgen="${kgen}${kgen:+ }${ktype}"
|
||||
# cleanup empty files (if any)
|
||||
[ -s "${kfile}" ] || rm -f "${kfile}"
|
||||
|
||||
kgen="${kgen} ${ktype}"
|
||||
done
|
||||
|
||||
# all keys are sane?
|
||||
@@ -103,28 +118,27 @@ hk_generate_as_needed()
|
||||
hk_tmp_dir=$(mktemp -d)
|
||||
# system in bad state?
|
||||
[ -n "${hk_tmp_dir}" ] || return 1
|
||||
|
||||
chmod 0700 "${hk_tmp_dir}"
|
||||
|
||||
for ktype in ${kgen} ; do
|
||||
kfile="${hk_tmp_dir}/dropbear_${ktype}_host_key"
|
||||
|
||||
if ! _dropbearkey -t ${ktype} -f "${kfile}" ; then
|
||||
if ! db_key_quiet -t "${ktype}" -f "${kfile}" ; then
|
||||
# unsupported key type
|
||||
rm -f "${kfile}"
|
||||
rm -f "${kfile}" "${kfile}.pub"
|
||||
continue
|
||||
fi
|
||||
|
||||
chmod 0600 "${kfile}"
|
||||
# unused file
|
||||
rm -f "${kfile}.pub"
|
||||
done
|
||||
|
||||
kgen=
|
||||
for ktype in ${ktype_all} ; do
|
||||
kfile="${hk_tmp_dir}/dropbear_${ktype}_host_key"
|
||||
|
||||
[ -s "${kfile}" ] || continue
|
||||
|
||||
kgen="${kgen}${kgen:+ }${ktype}"
|
||||
kgen="${kgen} ${ktype}"
|
||||
done
|
||||
|
||||
if [ -n "${kgen}" ] ; then
|
||||
@@ -136,13 +150,6 @@ hk_generate_as_needed()
|
||||
fi
|
||||
|
||||
rm -rf "${hk_tmp_dir}"
|
||||
|
||||
# cleanup empty files
|
||||
for ktype in ${ktype_all} ; do
|
||||
kfile="${hk_cfg_dir}/dropbear_${ktype}_host_key"
|
||||
|
||||
[ -s "${kfile}" ] || rm -f "${kfile}"
|
||||
done
|
||||
}
|
||||
|
||||
# $1 - list with whitespace-separated elements
|
||||
@@ -176,6 +183,7 @@ validate_section_dropbear()
|
||||
'Port:port:22' \
|
||||
'SSHKeepAlive:uinteger:300' \
|
||||
'IdleTimeout:uinteger:0' \
|
||||
'MaxSessionDuration:uinteger:0' \
|
||||
'MaxAuthTries:uinteger:3' \
|
||||
'RecvWindowSize:uinteger:0' \
|
||||
'LocalPortForward:bool:1' \
|
||||
@@ -336,6 +344,7 @@ dropbear_instance()
|
||||
fi
|
||||
[ -n "${BannerFile}" ] && procd_append_param command -b "${BannerFile}"
|
||||
[ "${IdleTimeout}" -ne 0 ] && procd_append_param command -I "${IdleTimeout}"
|
||||
[ "${MaxSessionDuration}" -ne 0 ] && procd_append_param command -M "${MaxSessionDuration}"
|
||||
[ "${SSHKeepAlive}" -ne 0 ] && procd_append_param command -K "${SSHKeepAlive}"
|
||||
[ "${MaxAuthTries}" -ne 0 ] && procd_append_param command -T "${MaxAuthTries}"
|
||||
[ "${RecvWindowSize}" -gt 0 ] && {
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
From b487b111d0cf735c640e6668aa888f7da4e78b3c Mon Sep 17 00:00:00 2001
|
||||
From: Matt Johnston <matt@ucc.asn.au>
|
||||
Date: Mon, 11 May 2026 20:43:50 +0800
|
||||
Subject: sntrup: Fix 64-bit literals
|
||||
|
||||
Avoids warning on 32-bit platform
|
||||
|
||||
src/sntrup761.c:1643: warning: integer constant is too large for 'long' type
|
||||
---
|
||||
src/sntrup761.c | 6 +++---
|
||||
1 file changed, 3 insertions(+), 3 deletions(-)
|
||||
|
||||
--- a/src/sntrup761.c
|
||||
+++ b/src/sntrup761.c
|
||||
@@ -1640,9 +1640,9 @@ __attribute__((unused))
|
||||
static inline
|
||||
int crypto_int64_ones_num(crypto_int64 crypto_int64_x) {
|
||||
crypto_int64_unsigned crypto_int64_y = crypto_int64_x;
|
||||
- const crypto_int64 C0 = 0x5555555555555555;
|
||||
- const crypto_int64 C1 = 0x3333333333333333;
|
||||
- const crypto_int64 C2 = 0x0f0f0f0f0f0f0f0f;
|
||||
+ const crypto_int64 C0 = INT64_C(0x5555555555555555);
|
||||
+ const crypto_int64 C1 = INT64_C(0x3333333333333333);
|
||||
+ const crypto_int64 C2 = INT64_C(0x0f0f0f0f0f0f0f0f);
|
||||
crypto_int64_y -= ((crypto_int64_y >> 1) & C0);
|
||||
crypto_int64_y = (crypto_int64_y & C1) + ((crypto_int64_y >> 2) & C1);
|
||||
crypto_int64_y = (crypto_int64_y + (crypto_int64_y >> 4)) & C2;
|
||||
@@ -0,0 +1,23 @@
|
||||
From a05569c6124006bd9b4823db30e824953c5024de Mon Sep 17 00:00:00 2001
|
||||
From: Matt Johnston <matt@ucc.asn.au>
|
||||
Date: Wed, 13 May 2026 08:40:17 +0800
|
||||
Subject: Increase MAX_HOSTKEYS to 6
|
||||
|
||||
This allows all key types to be loaded at once, including different
|
||||
ecdsa sizes.
|
||||
Suggested by Darren Tucker.
|
||||
---
|
||||
src/sysoptions.h | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
--- a/src/sysoptions.h
|
||||
+++ b/src/sysoptions.h
|
||||
@@ -283,7 +283,7 @@
|
||||
#define MAX_KEX_PARTS 1000
|
||||
#endif
|
||||
|
||||
-#define MAX_HOSTKEYS 4
|
||||
+#define MAX_HOSTKEYS 6
|
||||
|
||||
/* The maximum size of the bignum portion of the kexhash buffer */
|
||||
/* K_S + Q_C + Q_S + K */
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
From ee65bff1567576a223febcdd5ae552326a4da4b1 Mon Sep 17 00:00:00 2001
|
||||
From: Matt Johnston <matt@ucc.asn.au>
|
||||
Date: Tue, 19 May 2026 19:03:39 +0800
|
||||
Subject: Fix too-low pubkey key query count
|
||||
|
||||
Dropbear 2026.90 added a limit to the number of queries that could be
|
||||
made to a server when determining usable keys. This was intended to be
|
||||
set to 15 (MAX_PUBKEY_QUERIES) but the logic was incorrect (and also
|
||||
debug code was accidentally committed). This meant only 10 (default
|
||||
MAX_AUTH_TRIES/-T) tried keys would be allowed - not a huge difference.
|
||||
|
||||
Reported by Rui Salvaterra
|
||||
|
||||
Fixes: db0d3fd0a9e9 ("Limit server number of public key queries")
|
||||
---
|
||||
src/svr-authpubkey.c | 6 +++---
|
||||
1 file changed, 3 insertions(+), 3 deletions(-)
|
||||
|
||||
--- a/src/svr-authpubkey.c
|
||||
+++ b/src/svr-authpubkey.c
|
||||
@@ -173,9 +173,9 @@ void svr_auth_pubkey(int valid_user) {
|
||||
* Start counting failures (incrfail) only when it's reaching
|
||||
* the limit.
|
||||
*/
|
||||
- unsigned int free_query_limit = 0;
|
||||
- MAX(0, (int)svr_opts.maxauthtries - MAX_PUBKEY_QUERIES);
|
||||
- int incrfail = ses.authstate.serv_pubkey_query_count > free_query_limit;
|
||||
+ unsigned int free_query_limit =
|
||||
+ MAX(0, MAX_PUBKEY_QUERIES - (int)svr_opts.maxauthtries);
|
||||
+ int incrfail = ses.authstate.serv_pubkey_query_count >= free_query_limit;
|
||||
send_msg_userauth_failure(0, incrfail);
|
||||
ses.authstate.serv_pubkey_query_count++;
|
||||
goto out;
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
--- a/src/svr-authpubkey.c
|
||||
+++ b/src/svr-authpubkey.c
|
||||
@@ -79,6 +79,39 @@ static void send_msg_userauth_pk_ok(cons
|
||||
@@ -80,6 +80,39 @@ static void send_msg_userauth_pk_ok(cons
|
||||
const unsigned char* keyblob, unsigned int keybloblen);
|
||||
static int checkfileperm(char * filename);
|
||||
|
||||
@@ -43,7 +43,7 @@
|
||||
/* process a pubkey auth request, sending success or failure message as
|
||||
* appropriate */
|
||||
void svr_auth_pubkey(int valid_user) {
|
||||
@@ -439,16 +472,22 @@ out:
|
||||
@@ -459,16 +492,22 @@ out:
|
||||
static char *authorized_keys_filepath() {
|
||||
size_t len = 0;
|
||||
char *pathname = NULL, *dir = NULL;
|
||||
@@ -69,7 +69,7 @@
|
||||
m_free(dir);
|
||||
return pathname;
|
||||
}
|
||||
@@ -549,11 +588,23 @@ out:
|
||||
@@ -572,11 +611,23 @@ out:
|
||||
* When this path is inside the user's home dir it checks up to and including
|
||||
* the home dir, otherwise it checks every path component. */
|
||||
static int checkpubkeyperms() {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
--- a/src/svr-auth.c
|
||||
+++ b/src/svr-auth.c
|
||||
@@ -510,9 +510,9 @@ void svr_switch_user(void) {
|
||||
@@ -504,9 +504,9 @@ void svr_switch_user(void) {
|
||||
/* We can only change uid/gid as root ... */
|
||||
if (getuid() == 0) {
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
dropbear_exit("Error changing user group");
|
||||
}
|
||||
|
||||
@@ -534,7 +534,7 @@ void svr_switch_user(void) {
|
||||
@@ -528,7 +528,7 @@ void svr_switch_user(void) {
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
--- a/src/cli-runopts.c
|
||||
+++ b/src/cli-runopts.c
|
||||
@@ -340,6 +340,10 @@ void cli_getopts(int argc, char ** argv)
|
||||
@@ -352,6 +352,10 @@ void cli_getopts(int argc, char ** argv)
|
||||
case 'z':
|
||||
opts.disable_ip_tos = 1;
|
||||
break;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
--- a/src/svr-auth.c
|
||||
+++ b/src/svr-auth.c
|
||||
@@ -124,7 +124,7 @@ void recv_msg_userauth_request() {
|
||||
@@ -122,7 +122,7 @@ void recv_msg_userauth_request() {
|
||||
AUTH_METHOD_NONE_LEN) == 0) {
|
||||
TRACE(("recv_msg_userauth_request: 'none' request"))
|
||||
if (valid_user
|
||||
|
||||
@@ -8,12 +8,12 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=lldpd
|
||||
PKG_VERSION:=1.0.20
|
||||
PKG_VERSION:=1.0.22
|
||||
PKG_RELEASE:=1
|
||||
|
||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
|
||||
PKG_SOURCE_URL:=https://github.com/lldpd/lldpd/releases/download/$(PKG_VERSION)/
|
||||
PKG_HASH:=c851ce102444b932b691f0d00142520333030822709fc4566ef20c651ae1714f
|
||||
PKG_HASH:=552baa55118bccbcd1e61c51db438930a36ce04e0abd84c4c0b7b20633ca2b5a
|
||||
|
||||
PKG_MAINTAINER:=Stijn Tintel <stijn@linux-ipv6.be>
|
||||
PKG_LICENSE:=ISC
|
||||
|
||||
@@ -12,9 +12,9 @@ PKG_RELEASE:=1
|
||||
|
||||
PKG_SOURCE_URL=$(PROJECT_GIT)/project/ustp.git
|
||||
PKG_SOURCE_PROTO:=git
|
||||
PKG_SOURCE_DATE:=2023-05-29
|
||||
PKG_SOURCE_VERSION:=a85a5bc83bde5b485319ca12b6e32c4b7f0b120f
|
||||
PKG_MIRROR_HASH:=b907b91989320eb8916e719ced9bdce96b8c5db6abefcee35e25fb112ad5b27f
|
||||
PKG_SOURCE_DATE:=2026-05-27
|
||||
PKG_SOURCE_VERSION:=17c36bebada116b98784a6a17412005537bdf8ac
|
||||
PKG_MIRROR_HASH:=04498fb8886082dd78bb11bda5e05fbbe6aacb4dc782f425bbdb193fbbc54620
|
||||
|
||||
PKG_MAINTAINER:=Felix Fietkau <nbd@nbd.name>
|
||||
PKG_LICENSE:=GPL-2.0
|
||||
|
||||
@@ -8,13 +8,13 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=ethtool
|
||||
PKG_VERSION:=6.19
|
||||
PKG_RELEASE:=2
|
||||
PKG_VERSION:=7.0
|
||||
PKG_RELEASE:=1
|
||||
|
||||
PKG_MAINTAINER:=Felix Fietkau <nbd@nbd.name>
|
||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
|
||||
PKG_SOURCE_URL:=@KERNEL/software/network/ethtool
|
||||
PKG_HASH:=1c2114ab6e0c0d2aa67d699960eb11df4f341e2403139cdf28ae9da858a6025f
|
||||
PKG_HASH:=660bf9725a7871343a0d232068a7634fbcfb69b6c2f8eff455827faefb0cd162
|
||||
|
||||
PKG_LICENSE:=GPL-2.0
|
||||
PKG_LICENSE_FILES:=COPYING
|
||||
|
||||
@@ -242,6 +242,10 @@ int mtd_replace_jffs2(const char *mtd, int fd, int ofs, const char *filename)
|
||||
mtdofs = ofs;
|
||||
|
||||
buf = malloc(erasesize);
|
||||
if (!buf) {
|
||||
fprintf(stderr, "Out of memory!\n");
|
||||
return -1;
|
||||
}
|
||||
target_ino = 1;
|
||||
if (!last_ino)
|
||||
last_ino = 1;
|
||||
|
||||
@@ -79,32 +79,14 @@ CONFIG_CPU_MITIGATIONS=y
|
||||
CONFIG_CPU_RMAP=y
|
||||
CONFIG_CRC16=y
|
||||
CONFIG_CRC_CCITT=y
|
||||
CONFIG_CRYPTO_CBC=y
|
||||
CONFIG_CRYPTO_CRC32C=y
|
||||
CONFIG_CRYPTO_DEFLATE=y
|
||||
CONFIG_CRYPTO_DRBG=y
|
||||
CONFIG_CRYPTO_DRBG_HMAC=y
|
||||
CONFIG_CRYPTO_DRBG_MENU=y
|
||||
CONFIG_CRYPTO_ECB=y
|
||||
CONFIG_CRYPTO_ECHAINIV=y
|
||||
CONFIG_CRYPTO_GENIV=y
|
||||
CONFIG_CRYPTO_HASH_INFO=y
|
||||
CONFIG_CRYPTO_HMAC=y
|
||||
CONFIG_CRYPTO_JITTERENTROPY=y
|
||||
CONFIG_CRYPTO_JITTERENTROPY_MEMORY_BLOCKS=64
|
||||
CONFIG_CRYPTO_JITTERENTROPY_MEMORY_BLOCKSIZE=32
|
||||
CONFIG_CRYPTO_JITTERENTROPY_OSR=1
|
||||
CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y
|
||||
CONFIG_CRYPTO_LIB_GF128MUL=y
|
||||
CONFIG_CRYPTO_LIB_SHA256=y
|
||||
CONFIG_CRYPTO_LIB_UTILS=y
|
||||
CONFIG_CRYPTO_LZO=y
|
||||
CONFIG_CRYPTO_RNG=y
|
||||
CONFIG_CRYPTO_RNG_DEFAULT=y
|
||||
CONFIG_CRYPTO_SEQIV=y
|
||||
CONFIG_CRYPTO_SHA256=y
|
||||
CONFIG_CRYPTO_SHA3=y
|
||||
CONFIG_CRYPTO_SHA512=y
|
||||
CONFIG_CRYPTO_ZSTD=y
|
||||
CONFIG_DCACHE_WORD_ACCESS=y
|
||||
CONFIG_DEBUG_INFO=y
|
||||
|
||||
@@ -84,26 +84,14 @@ CONFIG_CRC_CCITT=y
|
||||
CONFIG_CRYPTO_CRC32C=y
|
||||
CONFIG_CRYPTO_DEFLATE=y
|
||||
CONFIG_CRYPTO_DEV_EIP93=y
|
||||
CONFIG_CRYPTO_DRBG=y
|
||||
CONFIG_CRYPTO_DRBG_HMAC=y
|
||||
CONFIG_CRYPTO_DRBG_MENU=y
|
||||
CONFIG_CRYPTO_ECB=y
|
||||
CONFIG_CRYPTO_HASH_INFO=y
|
||||
CONFIG_CRYPTO_HMAC=y
|
||||
CONFIG_CRYPTO_JITTERENTROPY=y
|
||||
CONFIG_CRYPTO_JITTERENTROPY_MEMORY_BLOCKS=64
|
||||
CONFIG_CRYPTO_JITTERENTROPY_MEMORY_BLOCKSIZE=32
|
||||
CONFIG_CRYPTO_JITTERENTROPY_OSR=1
|
||||
CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y
|
||||
CONFIG_CRYPTO_LIB_GF128MUL=y
|
||||
CONFIG_CRYPTO_LIB_SHA256=y
|
||||
CONFIG_CRYPTO_LIB_UTILS=y
|
||||
CONFIG_CRYPTO_LZO=y
|
||||
CONFIG_CRYPTO_RNG=y
|
||||
CONFIG_CRYPTO_RNG_DEFAULT=y
|
||||
CONFIG_CRYPTO_SHA256=y
|
||||
CONFIG_CRYPTO_SHA3=y
|
||||
CONFIG_CRYPTO_SHA512=y
|
||||
CONFIG_CRYPTO_ZSTD=y
|
||||
CONFIG_DCACHE_WORD_ACCESS=y
|
||||
CONFIG_DEBUG_MISC=y
|
||||
|
||||
@@ -174,33 +174,51 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
} else { /* scattered frame */
|
||||
struct skb_shared_info *shinfo = skb_shinfo(q->skb);
|
||||
int nr_frags = shinfo->nr_frags;
|
||||
@@ -743,12 +869,13 @@ static int airoha_qdma_rx_napi_poll(stru
|
||||
@@ -743,12 +869,10 @@ static int airoha_qdma_rx_napi_poll(stru
|
||||
static int airoha_qdma_init_rx_queue(struct airoha_queue *q,
|
||||
struct airoha_qdma *qdma, int ndesc)
|
||||
{
|
||||
+ int pp_order = airoha_qdma_is_lro_queue(q) ? AIROHA_LRO_PAGE_ORDER : 0;
|
||||
const struct page_pool_params pp_params = {
|
||||
- const struct page_pool_params pp_params = {
|
||||
- .order = 0,
|
||||
+ .order = pp_order,
|
||||
+ struct page_pool_params pp_params = {
|
||||
.pool_size = 256,
|
||||
.flags = PP_FLAG_DMA_MAP | PP_FLAG_DMA_SYNC_DEV,
|
||||
.dma_dir = DMA_FROM_DEVICE,
|
||||
- .max_len = PAGE_SIZE,
|
||||
+ .max_len = PAGE_SIZE << pp_order,
|
||||
.nid = NUMA_NO_NODE,
|
||||
.dev = qdma->eth->dev,
|
||||
.napi = &q->napi,
|
||||
@@ -757,7 +884,8 @@ static int airoha_qdma_init_rx_queue(str
|
||||
@@ -756,9 +880,10 @@ static int airoha_qdma_init_rx_queue(str
|
||||
struct airoha_eth *eth = qdma->eth;
|
||||
int qid = q - &qdma->q_rx[0], thr;
|
||||
dma_addr_t dma_addr;
|
||||
+ bool lro_q;
|
||||
|
||||
- q->buf_size = PAGE_SIZE / 2;
|
||||
+ q->buf_size = airoha_qdma_is_lro_queue(q) ? pp_params.max_len
|
||||
+ : pp_params.max_len / 2;
|
||||
q->qdma = qdma;
|
||||
+ lro_q = airoha_qdma_is_lro_queue(q);
|
||||
|
||||
q->entry = devm_kzalloc(eth->dev, ndesc * sizeof(*q->entry),
|
||||
@@ -2034,6 +2162,67 @@ int airoha_get_fe_port(struct airoha_gdm
|
||||
GFP_KERNEL);
|
||||
@@ -770,6 +895,9 @@ static int airoha_qdma_init_rx_queue(str
|
||||
if (!q->desc)
|
||||
return -ENOMEM;
|
||||
|
||||
+ pp_params.order = lro_q ? AIROHA_LRO_PAGE_ORDER : 0;
|
||||
+ pp_params.max_len = PAGE_SIZE << pp_params.order;
|
||||
+
|
||||
q->page_pool = page_pool_create(&pp_params);
|
||||
if (IS_ERR(q->page_pool)) {
|
||||
int err = PTR_ERR(q->page_pool);
|
||||
@@ -778,6 +906,7 @@ static int airoha_qdma_init_rx_queue(str
|
||||
return err;
|
||||
}
|
||||
|
||||
+ q->buf_size = lro_q ? pp_params.max_len : pp_params.max_len / 2;
|
||||
q->ndesc = ndesc;
|
||||
netif_napi_add(eth->napi_dev, &q->napi, airoha_qdma_rx_napi_poll);
|
||||
|
||||
@@ -2034,6 +2163,67 @@ int airoha_get_fe_port(struct airoha_gdm
|
||||
}
|
||||
}
|
||||
|
||||
@@ -268,7 +286,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
static netdev_tx_t airoha_dev_xmit(struct sk_buff *skb,
|
||||
struct net_device *dev)
|
||||
{
|
||||
@@ -2933,6 +3122,7 @@ static const struct net_device_ops airoh
|
||||
@@ -2933,6 +3123,7 @@ static const struct net_device_ops airoh
|
||||
.ndo_stop = airoha_dev_stop,
|
||||
.ndo_change_mtu = airoha_dev_change_mtu,
|
||||
.ndo_select_queue = airoha_dev_select_queue,
|
||||
@@ -276,7 +294,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
.ndo_start_xmit = airoha_dev_xmit,
|
||||
.ndo_get_stats64 = airoha_dev_get_stats64,
|
||||
.ndo_set_mac_address = airoha_dev_set_macaddr,
|
||||
@@ -3150,12 +3340,9 @@ static int airoha_alloc_gdm_port(struct
|
||||
@@ -3150,12 +3341,9 @@ static int airoha_alloc_gdm_port(struct
|
||||
dev->ethtool_ops = &airoha_ethtool_ops;
|
||||
dev->max_mtu = AIROHA_MAX_MTU;
|
||||
dev->watchdog_timeo = 5 * HZ;
|
||||
|
||||
+35
-35
@@ -70,7 +70,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
/* 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
|
||||
@@ -992,6 +997,7 @@ static void airoha_qdma_wake_netdev_txqs
|
||||
@@ -993,6 +998,7 @@ static void airoha_qdma_wake_netdev_txqs
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(eth->ports); i++) {
|
||||
struct airoha_gdm_port *port = eth->ports[i];
|
||||
@@ -78,7 +78,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
int j;
|
||||
|
||||
if (!port)
|
||||
@@ -1000,11 +1006,12 @@ static void airoha_qdma_wake_netdev_txqs
|
||||
@@ -1001,11 +1007,12 @@ static void airoha_qdma_wake_netdev_txqs
|
||||
if (port->qdma != qdma)
|
||||
continue;
|
||||
|
||||
@@ -93,7 +93,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
}
|
||||
}
|
||||
q->txq_stopped = false;
|
||||
@@ -1848,33 +1855,34 @@ static void airoha_update_hw_stats(struc
|
||||
@@ -1849,33 +1856,34 @@ static void airoha_update_hw_stats(struc
|
||||
spin_unlock(&port->stats.lock);
|
||||
}
|
||||
|
||||
@@ -136,7 +136,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
airoha_fe_set(qdma->eth, REG_GDM_INGRESS_CFG(port->id),
|
||||
GDM_STAG_EN_MASK);
|
||||
else
|
||||
@@ -1902,16 +1910,17 @@ static int airoha_dev_open(struct net_de
|
||||
@@ -1903,16 +1911,17 @@ static int airoha_dev_open(struct net_de
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -159,7 +159,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
|
||||
airoha_set_gdm_port_fwd_cfg(qdma->eth, REG_GDM_FWD_CFG(port->id),
|
||||
FE_PSE_PORT_DROP);
|
||||
@@ -1931,24 +1940,25 @@ static int airoha_dev_stop(struct net_de
|
||||
@@ -1932,24 +1941,25 @@ static int airoha_dev_stop(struct net_de
|
||||
|
||||
#if defined(CONFIG_PCS_AIROHA)
|
||||
if (airhoa_is_phy_external(port)) {
|
||||
@@ -191,7 +191,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -2014,16 +2024,17 @@ static int airoha_set_gdm2_loopback(stru
|
||||
@@ -2015,16 +2025,17 @@ static int airoha_set_gdm2_loopback(stru
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -214,7 +214,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
|
||||
switch (port->id) {
|
||||
case AIROHA_GDM3_IDX:
|
||||
@@ -2048,10 +2059,11 @@ static int airoha_dev_init(struct net_de
|
||||
@@ -2049,10 +2060,11 @@ static int airoha_dev_init(struct net_de
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -228,7 +228,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
unsigned int start;
|
||||
|
||||
airoha_update_hw_stats(port);
|
||||
@@ -2070,36 +2082,39 @@ static void airoha_dev_get_stats64(struc
|
||||
@@ -2071,36 +2083,39 @@ static void airoha_dev_get_stats64(struc
|
||||
} while (u64_stats_fetch_retry(&port->stats.syncp, start));
|
||||
}
|
||||
|
||||
@@ -275,7 +275,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
}
|
||||
|
||||
static u32 airoha_get_dsa_tag(struct sk_buff *skb, struct net_device *dev)
|
||||
@@ -2162,11 +2177,12 @@ int airoha_get_fe_port(struct airoha_gdm
|
||||
@@ -2163,11 +2178,12 @@ int airoha_get_fe_port(struct airoha_gdm
|
||||
}
|
||||
}
|
||||
|
||||
@@ -291,7 +291,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
struct airoha_qdma *qdma = port->qdma;
|
||||
struct airoha_eth *eth = qdma->eth;
|
||||
int qdma_id = qdma - ð->qdma[0];
|
||||
@@ -2175,7 +2191,7 @@ static int airoha_dev_set_features(struc
|
||||
@@ -2176,7 +2192,7 @@ static int airoha_dev_set_features(struc
|
||||
if (!(diff & NETIF_F_LRO))
|
||||
return 0;
|
||||
|
||||
@@ -300,7 +300,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
return -EBUSY;
|
||||
|
||||
/* reset LRO configuration */
|
||||
@@ -2204,6 +2220,7 @@ static int airoha_dev_set_features(struc
|
||||
@@ -2205,6 +2221,7 @@ static int airoha_dev_set_features(struc
|
||||
} else {
|
||||
for (i = 0; i < ARRAY_SIZE(eth->ports); i++) {
|
||||
struct airoha_gdm_port *p = eth->ports[i];
|
||||
@@ -308,7 +308,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
|
||||
if (!p)
|
||||
continue;
|
||||
@@ -2211,10 +2228,11 @@ static int airoha_dev_set_features(struc
|
||||
@@ -2212,10 +2229,11 @@ static int airoha_dev_set_features(struc
|
||||
if (p->qdma != qdma)
|
||||
continue;
|
||||
|
||||
@@ -322,7 +322,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
return 0;
|
||||
}
|
||||
airoha_fe_lro_disable(eth, qdma_id);
|
||||
@@ -2224,9 +2242,10 @@ static int airoha_dev_set_features(struc
|
||||
@@ -2225,9 +2243,10 @@ static int airoha_dev_set_features(struc
|
||||
}
|
||||
|
||||
static netdev_tx_t airoha_dev_xmit(struct sk_buff *skb,
|
||||
@@ -335,7 +335,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
struct airoha_qdma *qdma = port->qdma;
|
||||
u32 nr_frags, tag, msg0, msg1, len;
|
||||
struct airoha_queue_entry *e;
|
||||
@@ -2239,7 +2258,7 @@ static netdev_tx_t airoha_dev_xmit(struc
|
||||
@@ -2240,7 +2259,7 @@ static netdev_tx_t airoha_dev_xmit(struc
|
||||
u8 fport;
|
||||
|
||||
qid = airoha_qdma_get_txq(qdma, skb_get_queue_mapping(skb));
|
||||
@@ -344,7 +344,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
|
||||
msg0 = FIELD_PREP(QDMA_ETH_TXMSG_CHAN_MASK,
|
||||
qid / AIROHA_NUM_QOS_QUEUES) |
|
||||
@@ -2275,7 +2294,7 @@ static netdev_tx_t airoha_dev_xmit(struc
|
||||
@@ -2276,7 +2295,7 @@ static netdev_tx_t airoha_dev_xmit(struc
|
||||
|
||||
spin_lock_bh(&q->lock);
|
||||
|
||||
@@ -353,7 +353,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
nr_frags = 1 + skb_shinfo(skb)->nr_frags;
|
||||
|
||||
if (q->queued + nr_frags >= q->ndesc) {
|
||||
@@ -2299,9 +2318,9 @@ static netdev_tx_t airoha_dev_xmit(struc
|
||||
@@ -2300,9 +2319,9 @@ static netdev_tx_t airoha_dev_xmit(struc
|
||||
dma_addr_t addr;
|
||||
u32 val;
|
||||
|
||||
@@ -365,7 +365,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
goto error_unmap;
|
||||
|
||||
list_move_tail(&e->list, &tx_list);
|
||||
@@ -2350,7 +2369,7 @@ static netdev_tx_t airoha_dev_xmit(struc
|
||||
@@ -2351,7 +2370,7 @@ static netdev_tx_t airoha_dev_xmit(struc
|
||||
|
||||
error_unmap:
|
||||
list_for_each_entry(e, &tx_list, list) {
|
||||
@@ -374,7 +374,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
DMA_TO_DEVICE);
|
||||
e->dma_addr = 0;
|
||||
}
|
||||
@@ -2359,25 +2378,27 @@ error_unmap:
|
||||
@@ -2360,25 +2379,27 @@ error_unmap:
|
||||
spin_unlock_bh(&q->lock);
|
||||
error:
|
||||
dev_kfree_skb_any(skb);
|
||||
@@ -407,7 +407,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
unsigned int start;
|
||||
|
||||
airoha_update_hw_stats(port);
|
||||
@@ -2405,11 +2426,12 @@ static const struct ethtool_rmon_hist_ra
|
||||
@@ -2406,11 +2427,12 @@ static const struct ethtool_rmon_hist_ra
|
||||
};
|
||||
|
||||
static void
|
||||
@@ -422,7 +422,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
struct airoha_hw_stats *hw_stats = &port->stats;
|
||||
unsigned int start;
|
||||
|
||||
@@ -2434,11 +2456,12 @@ airoha_ethtool_get_rmon_stats(struct net
|
||||
@@ -2435,11 +2457,12 @@ airoha_ethtool_get_rmon_stats(struct net
|
||||
} while (u64_stats_fetch_retry(&port->stats.syncp, start));
|
||||
}
|
||||
|
||||
@@ -437,7 +437,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
int i;
|
||||
|
||||
for (i = 0; i < AIROHA_NUM_TX_RING; i++)
|
||||
@@ -2523,10 +2546,12 @@ static int airoha_qdma_set_tx_ets_sched(
|
||||
@@ -2524,10 +2547,12 @@ static int airoha_qdma_set_tx_ets_sched(
|
||||
ARRAY_SIZE(w));
|
||||
}
|
||||
|
||||
@@ -452,7 +452,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
u64 cpu_tx_packets = airoha_qdma_rr(port->qdma,
|
||||
REG_CNTR_VAL(channel << 1));
|
||||
u64 fwd_tx_packets = airoha_qdma_rr(port->qdma,
|
||||
@@ -2788,11 +2813,12 @@ static int airoha_qdma_set_trtcm_token_b
|
||||
@@ -2789,11 +2814,12 @@ static int airoha_qdma_set_trtcm_token_b
|
||||
mode, val);
|
||||
}
|
||||
|
||||
@@ -467,7 +467,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
int i, err;
|
||||
|
||||
for (i = 0; i <= TRTCM_PEAK_MODE; i++) {
|
||||
@@ -2812,20 +2838,22 @@ static int airoha_qdma_set_tx_rate_limit
|
||||
@@ -2813,20 +2839,22 @@ static int airoha_qdma_set_tx_rate_limit
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -494,7 +494,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
if (err) {
|
||||
NL_SET_ERR_MSG_MOD(opt->extack,
|
||||
"failed configuring htb offload");
|
||||
@@ -2835,9 +2863,10 @@ static int airoha_tc_htb_alloc_leaf_queu
|
||||
@@ -2836,9 +2864,10 @@ static int airoha_tc_htb_alloc_leaf_queu
|
||||
if (opt->command == TC_HTB_NODE_MODIFY)
|
||||
return 0;
|
||||
|
||||
@@ -507,7 +507,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
NL_SET_ERR_MSG_MOD(opt->extack,
|
||||
"failed setting real_num_tx_queues");
|
||||
return err;
|
||||
@@ -2927,11 +2956,12 @@ static int airoha_tc_matchall_act_valida
|
||||
@@ -2928,11 +2957,12 @@ static int airoha_tc_matchall_act_valida
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -522,7 +522,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
u32 rate = 0, bucket_size = 0;
|
||||
|
||||
switch (f->command) {
|
||||
@@ -2966,18 +2996,19 @@ static int airoha_dev_tc_matchall(struct
|
||||
@@ -2967,18 +2997,19 @@ static int airoha_dev_tc_matchall(struct
|
||||
static int airoha_dev_setup_tc_block_cb(enum tc_setup_type type,
|
||||
void *type_data, void *cb_priv)
|
||||
{
|
||||
@@ -546,7 +546,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
default:
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
@@ -3024,47 +3055,51 @@ static int airoha_dev_setup_tc_block(str
|
||||
@@ -3025,47 +3056,51 @@ static int airoha_dev_setup_tc_block(str
|
||||
}
|
||||
}
|
||||
|
||||
@@ -610,7 +610,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
|
||||
if (!test_bit(channel, port->qos_sq_bmap)) {
|
||||
NL_SET_ERR_MSG_MOD(opt->extack, "invalid queue id");
|
||||
@@ -3100,8 +3135,8 @@ static int airoha_tc_setup_qdisc_htb(str
|
||||
@@ -3101,8 +3136,8 @@ static int airoha_tc_setup_qdisc_htb(str
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -621,7 +621,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
{
|
||||
switch (type) {
|
||||
case TC_SETUP_QDISC_ETS:
|
||||
@@ -3173,13 +3208,18 @@ static void airoha_metadata_dst_free(str
|
||||
@@ -3174,13 +3209,18 @@ static void airoha_metadata_dst_free(str
|
||||
}
|
||||
}
|
||||
|
||||
@@ -643,7 +643,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -3191,8 +3231,9 @@ static void airoha_mac_link_up(struct ph
|
||||
@@ -3192,8 +3232,9 @@ static void airoha_mac_link_up(struct ph
|
||||
unsigned int mode, phy_interface_t interface,
|
||||
int speed, int duplex, bool tx_pause, bool rx_pause)
|
||||
{
|
||||
@@ -655,7 +655,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
struct airoha_qdma *qdma = port->qdma;
|
||||
struct airoha_eth *eth = qdma->eth;
|
||||
u32 frag_size_tx, frag_size_rx;
|
||||
@@ -3248,65 +3289,122 @@ static int airoha_fill_available_pcs(str
|
||||
@@ -3249,65 +3290,122 @@ static int airoha_fill_available_pcs(str
|
||||
&num_available_pcs);
|
||||
}
|
||||
|
||||
@@ -800,7 +800,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
int err, p;
|
||||
u32 id;
|
||||
|
||||
@@ -3328,58 +3426,22 @@ static int airoha_alloc_gdm_port(struct
|
||||
@@ -3329,58 +3427,22 @@ static int airoha_alloc_gdm_port(struct
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@@ -865,7 +865,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
}
|
||||
|
||||
static int airoha_register_gdm_devices(struct airoha_eth *eth)
|
||||
@@ -3393,7 +3455,7 @@ static int airoha_register_gdm_devices(s
|
||||
@@ -3394,7 +3456,7 @@ static int airoha_register_gdm_devices(s
|
||||
if (!port)
|
||||
continue;
|
||||
|
||||
@@ -874,7 +874,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
@@ -3502,16 +3564,18 @@ error_napi_stop:
|
||||
@@ -3503,16 +3565,18 @@ error_napi_stop:
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(eth->ports); i++) {
|
||||
struct airoha_gdm_port *port = eth->ports[i];
|
||||
@@ -896,7 +896,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
}
|
||||
airoha_metadata_dst_free(port);
|
||||
}
|
||||
@@ -3533,15 +3597,19 @@ static void airoha_remove(struct platfor
|
||||
@@ -3534,15 +3598,19 @@ static void airoha_remove(struct platfor
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(eth->ports); i++) {
|
||||
struct airoha_gdm_port *port = eth->ports[i];
|
||||
|
||||
+29
-29
@@ -60,7 +60,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
u32 vip_port;
|
||||
|
||||
vip_port = eth->soc->ops.get_vip_port(port, port->nbq);
|
||||
@@ -1003,10 +1004,13 @@ static void airoha_qdma_wake_netdev_txqs
|
||||
@@ -1004,10 +1005,13 @@ static void airoha_qdma_wake_netdev_txqs
|
||||
if (!port)
|
||||
continue;
|
||||
|
||||
@@ -76,7 +76,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
for (j = 0; j < dev->dev->num_tx_queues; j++) {
|
||||
if (airoha_qdma_get_txq(qdma, j) != qid)
|
||||
continue;
|
||||
@@ -1711,9 +1715,10 @@ static void airoha_qdma_stop_napi(struct
|
||||
@@ -1712,9 +1716,10 @@ static void airoha_qdma_stop_napi(struct
|
||||
}
|
||||
}
|
||||
|
||||
@@ -89,7 +89,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
u32 val, i = 0;
|
||||
|
||||
spin_lock(&port->stats.lock);
|
||||
@@ -1860,7 +1865,7 @@ static int airoha_dev_open(struct net_de
|
||||
@@ -1861,7 +1866,7 @@ static int airoha_dev_open(struct net_de
|
||||
int err, len = ETH_HLEN + netdev->mtu + ETH_FCS_LEN;
|
||||
struct airoha_gdm_dev *dev = netdev_priv(netdev);
|
||||
struct airoha_gdm_port *port = dev->port;
|
||||
@@ -98,7 +98,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
u32 pse_port = FE_PSE_PORT_PPE1;
|
||||
|
||||
#if defined(CONFIG_PCS_AIROHA)
|
||||
@@ -1877,7 +1882,7 @@ static int airoha_dev_open(struct net_de
|
||||
@@ -1878,7 +1883,7 @@ static int airoha_dev_open(struct net_de
|
||||
#endif
|
||||
|
||||
netif_tx_start_all_queues(netdev);
|
||||
@@ -107,7 +107,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
@@ -1914,11 +1919,11 @@ static int airoha_dev_stop(struct net_de
|
||||
@@ -1915,11 +1920,11 @@ static int airoha_dev_stop(struct net_de
|
||||
{
|
||||
struct airoha_gdm_dev *dev = netdev_priv(netdev);
|
||||
struct airoha_gdm_port *port = dev->port;
|
||||
@@ -121,7 +121,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
for (i = 0; i < netdev->num_tx_queues; i++)
|
||||
netdev_tx_reset_subqueue(netdev, i);
|
||||
|
||||
@@ -1951,21 +1956,21 @@ static int airoha_dev_stop(struct net_de
|
||||
@@ -1952,21 +1957,21 @@ static int airoha_dev_stop(struct net_de
|
||||
static int airoha_dev_set_macaddr(struct net_device *netdev, void *p)
|
||||
{
|
||||
struct airoha_gdm_dev *dev = netdev_priv(netdev);
|
||||
@@ -147,7 +147,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
u32 val, pse_port, chan;
|
||||
int i, src_port;
|
||||
|
||||
@@ -2012,7 +2017,7 @@ static int airoha_set_gdm2_loopback(stru
|
||||
@@ -2013,7 +2018,7 @@ static int airoha_set_gdm2_loopback(stru
|
||||
__field_prep(SP_CPORT_MASK(val), FE_PSE_PORT_CDM2));
|
||||
|
||||
for (i = 0; i < eth->soc->num_ppe; i++)
|
||||
@@ -156,7 +156,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
|
||||
if (port->id == AIROHA_GDM4_IDX && airoha_is_7581(eth)) {
|
||||
u32 mask = FC_ID_OF_SRC_PORT_MASK(port->nbq);
|
||||
@@ -2032,9 +2037,9 @@ static int airoha_dev_init(struct net_de
|
||||
@@ -2033,9 +2038,9 @@ static int airoha_dev_init(struct net_de
|
||||
int i;
|
||||
|
||||
/* QDMA0 is used for lan ports while QDMA1 is used for WAN ports */
|
||||
@@ -169,7 +169,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
|
||||
switch (port->id) {
|
||||
case AIROHA_GDM3_IDX:
|
||||
@@ -2043,7 +2048,7 @@ static int airoha_dev_init(struct net_de
|
||||
@@ -2044,7 +2049,7 @@ static int airoha_dev_init(struct net_de
|
||||
if (!eth->ports[1]) {
|
||||
int err;
|
||||
|
||||
@@ -178,7 +178,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
@@ -2053,8 +2058,7 @@ static int airoha_dev_init(struct net_de
|
||||
@@ -2054,8 +2059,7 @@ static int airoha_dev_init(struct net_de
|
||||
}
|
||||
|
||||
for (i = 0; i < eth->soc->num_ppe; i++)
|
||||
@@ -188,7 +188,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -2066,7 +2070,7 @@ static void airoha_dev_get_stats64(struc
|
||||
@@ -2067,7 +2071,7 @@ static void airoha_dev_get_stats64(struc
|
||||
struct airoha_gdm_port *port = dev->port;
|
||||
unsigned int start;
|
||||
|
||||
@@ -197,7 +197,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
do {
|
||||
start = u64_stats_fetch_begin(&port->stats.syncp);
|
||||
storage->rx_packets = port->stats.rx_ok_pkts;
|
||||
@@ -2086,8 +2090,8 @@ static int airoha_dev_change_mtu(struct
|
||||
@@ -2087,8 +2091,8 @@ static int airoha_dev_change_mtu(struct
|
||||
{
|
||||
struct airoha_gdm_dev *dev = netdev_priv(netdev);
|
||||
struct airoha_gdm_port *port = dev->port;
|
||||
@@ -207,7 +207,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
|
||||
airoha_fe_rmw(eth, REG_GDM_LEN_CFG(port->id),
|
||||
GDM_LONG_LEN_MASK,
|
||||
@@ -2161,10 +2165,10 @@ static u32 airoha_get_dsa_tag(struct sk_
|
||||
@@ -2162,10 +2166,10 @@ static u32 airoha_get_dsa_tag(struct sk_
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -221,7 +221,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
|
||||
switch (eth->soc->version) {
|
||||
case 0x7583:
|
||||
@@ -2182,8 +2186,7 @@ static int airoha_dev_set_features(struc
|
||||
@@ -2183,8 +2187,7 @@ static int airoha_dev_set_features(struc
|
||||
{
|
||||
netdev_features_t diff = netdev->features ^ features;
|
||||
struct airoha_gdm_dev *dev = netdev_priv(netdev);
|
||||
@@ -231,7 +231,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
struct airoha_eth *eth = qdma->eth;
|
||||
int qdma_id = qdma - ð->qdma[0];
|
||||
int i;
|
||||
@@ -2225,10 +2228,10 @@ static int airoha_dev_set_features(struc
|
||||
@@ -2226,10 +2229,10 @@ static int airoha_dev_set_features(struc
|
||||
if (!p)
|
||||
continue;
|
||||
|
||||
@@ -244,7 +244,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
if (d->dev == netdev)
|
||||
continue;
|
||||
|
||||
@@ -2245,8 +2248,7 @@ static netdev_tx_t airoha_dev_xmit(struc
|
||||
@@ -2246,8 +2249,7 @@ static netdev_tx_t airoha_dev_xmit(struc
|
||||
struct net_device *netdev)
|
||||
{
|
||||
struct airoha_gdm_dev *dev = netdev_priv(netdev);
|
||||
@@ -254,7 +254,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
u32 nr_frags, tag, msg0, msg1, len;
|
||||
struct airoha_queue_entry *e;
|
||||
struct netdev_queue *txq;
|
||||
@@ -2284,7 +2286,7 @@ static netdev_tx_t airoha_dev_xmit(struc
|
||||
@@ -2285,7 +2287,7 @@ static netdev_tx_t airoha_dev_xmit(struc
|
||||
}
|
||||
}
|
||||
|
||||
@@ -263,7 +263,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
msg1 = FIELD_PREP(QDMA_ETH_TXMSG_FPORT_MASK, fport) |
|
||||
FIELD_PREP(QDMA_ETH_TXMSG_METER_MASK, 0x7f);
|
||||
|
||||
@@ -2387,8 +2389,7 @@ static void airoha_ethtool_get_drvinfo(s
|
||||
@@ -2388,8 +2390,7 @@ static void airoha_ethtool_get_drvinfo(s
|
||||
struct ethtool_drvinfo *info)
|
||||
{
|
||||
struct airoha_gdm_dev *dev = netdev_priv(netdev);
|
||||
@@ -273,7 +273,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
|
||||
strscpy(info->driver, eth->dev->driver->name, sizeof(info->driver));
|
||||
strscpy(info->bus_info, dev_name(eth->dev), sizeof(info->bus_info));
|
||||
@@ -2401,7 +2402,7 @@ static void airoha_ethtool_get_mac_stats
|
||||
@@ -2402,7 +2403,7 @@ static void airoha_ethtool_get_mac_stats
|
||||
struct airoha_gdm_port *port = dev->port;
|
||||
unsigned int start;
|
||||
|
||||
@@ -282,7 +282,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
do {
|
||||
start = u64_stats_fetch_begin(&port->stats.syncp);
|
||||
stats->FramesTransmittedOK = port->stats.tx_ok_pkts;
|
||||
@@ -2441,7 +2442,7 @@ airoha_ethtool_get_rmon_stats(struct net
|
||||
@@ -2442,7 +2443,7 @@ airoha_ethtool_get_rmon_stats(struct net
|
||||
ARRAY_SIZE(hw_stats->rx_len) + 1);
|
||||
|
||||
*ranges = airoha_ethtool_rmon_ranges;
|
||||
@@ -291,7 +291,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
do {
|
||||
int i;
|
||||
|
||||
@@ -2461,18 +2462,17 @@ static int airoha_qdma_set_chan_tx_sched
|
||||
@@ -2462,18 +2463,17 @@ static int airoha_qdma_set_chan_tx_sched
|
||||
const u16 *weights, u8 n_weights)
|
||||
{
|
||||
struct airoha_gdm_dev *dev = netdev_priv(netdev);
|
||||
@@ -312,7 +312,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
TWRR_RW_CMD_MASK |
|
||||
FIELD_PREP(TWRR_CHAN_IDX_MASK, channel) |
|
||||
FIELD_PREP(TWRR_QUEUE_IDX_MASK, i) |
|
||||
@@ -2480,13 +2480,12 @@ static int airoha_qdma_set_chan_tx_sched
|
||||
@@ -2481,13 +2481,12 @@ static int airoha_qdma_set_chan_tx_sched
|
||||
err = read_poll_timeout(airoha_qdma_rr, status,
|
||||
status & TWRR_RW_CMD_DONE,
|
||||
USEC_PER_MSEC, 10 * USEC_PER_MSEC,
|
||||
@@ -328,7 +328,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
CHAN_QOS_MODE_MASK(channel),
|
||||
__field_prep(CHAN_QOS_MODE_MASK(channel), mode));
|
||||
|
||||
@@ -2552,9 +2551,9 @@ static int airoha_qdma_get_tx_ets_stats(
|
||||
@@ -2553,9 +2552,9 @@ static int airoha_qdma_get_tx_ets_stats(
|
||||
struct airoha_gdm_dev *dev = netdev_priv(netdev);
|
||||
struct airoha_gdm_port *port = dev->port;
|
||||
|
||||
@@ -340,7 +340,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
REG_CNTR_VAL((channel << 1) + 1));
|
||||
u64 tx_packets = (cpu_tx_packets - port->cpu_tx_packets) +
|
||||
(fwd_tx_packets - port->fwd_tx_packets);
|
||||
@@ -2818,17 +2817,16 @@ static int airoha_qdma_set_tx_rate_limit
|
||||
@@ -2819,17 +2818,16 @@ static int airoha_qdma_set_tx_rate_limit
|
||||
u32 bucket_size)
|
||||
{
|
||||
struct airoha_gdm_dev *dev = netdev_priv(netdev);
|
||||
@@ -360,7 +360,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
REG_EGRESS_TRTCM_CFG,
|
||||
i, rate, bucket_size);
|
||||
if (err)
|
||||
@@ -2878,11 +2876,11 @@ static int airoha_tc_htb_alloc_leaf_queu
|
||||
@@ -2879,11 +2877,11 @@ static int airoha_tc_htb_alloc_leaf_queu
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -374,7 +374,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(qdma->q_rx); i++) {
|
||||
@@ -2961,7 +2959,6 @@ static int airoha_dev_tc_matchall(struct
|
||||
@@ -2962,7 +2960,6 @@ static int airoha_dev_tc_matchall(struct
|
||||
{
|
||||
enum trtcm_unit_type unit_type = TRTCM_BYTE_UNIT;
|
||||
struct airoha_gdm_dev *dev = netdev_priv(netdev);
|
||||
@@ -382,7 +382,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
u32 rate = 0, bucket_size = 0;
|
||||
|
||||
switch (f->command) {
|
||||
@@ -2986,7 +2983,7 @@ static int airoha_dev_tc_matchall(struct
|
||||
@@ -2987,7 +2984,7 @@ static int airoha_dev_tc_matchall(struct
|
||||
fallthrough;
|
||||
}
|
||||
case TC_CLSMATCHALL_DESTROY:
|
||||
@@ -391,7 +391,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
unit_type);
|
||||
default:
|
||||
return -EOPNOTSUPP;
|
||||
@@ -2998,8 +2995,7 @@ static int airoha_dev_setup_tc_block_cb(
|
||||
@@ -2999,8 +2996,7 @@ static int airoha_dev_setup_tc_block_cb(
|
||||
{
|
||||
struct net_device *netdev = cb_priv;
|
||||
struct airoha_gdm_dev *dev = netdev_priv(netdev);
|
||||
@@ -401,7 +401,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
|
||||
if (!tc_can_offload(netdev))
|
||||
return -EOPNOTSUPP;
|
||||
@@ -3234,7 +3230,7 @@ static void airoha_mac_link_up(struct ph
|
||||
@@ -3235,7 +3231,7 @@ static void airoha_mac_link_up(struct ph
|
||||
struct airoha_gdm_dev *dev = container_of(config, struct airoha_gdm_dev,
|
||||
phylink_config);
|
||||
struct airoha_gdm_port *port = dev->port;
|
||||
|
||||
+1
-1
@@ -37,7 +37,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
val = (addr[0] << 16) | (addr[1] << 8) | addr[2];
|
||||
airoha_fe_wr(eth, reg, val);
|
||||
|
||||
@@ -2037,7 +2035,7 @@ static int airoha_dev_init(struct net_de
|
||||
@@ -2038,7 +2036,7 @@ static int airoha_dev_init(struct net_de
|
||||
int i;
|
||||
|
||||
/* QDMA0 is used for lan ports while QDMA1 is used for WAN ports */
|
||||
|
||||
+7
-7
@@ -22,7 +22,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
|
||||
--- a/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
@@ -2834,30 +2834,40 @@ static int airoha_qdma_set_tx_rate_limit
|
||||
@@ -2835,30 +2835,40 @@ static int airoha_qdma_set_tx_rate_limit
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -75,7 +75,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
|
||||
err = netif_set_real_num_tx_queues(netdev, num_tx_queues + 1);
|
||||
if (err) {
|
||||
@@ -2865,13 +2875,17 @@ static int airoha_tc_htb_alloc_leaf_queu
|
||||
@@ -2866,13 +2876,17 @@ static int airoha_tc_htb_alloc_leaf_queu
|
||||
opt->quantum);
|
||||
NL_SET_ERR_MSG_MOD(opt->extack,
|
||||
"failed setting real_num_tx_queues");
|
||||
@@ -95,7 +95,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
}
|
||||
|
||||
static int airoha_qdma_set_rx_meter(struct airoha_gdm_dev *dev,
|
||||
@@ -3052,11 +3066,13 @@ static int airoha_dev_setup_tc_block(str
|
||||
@@ -3053,11 +3067,13 @@ static int airoha_dev_setup_tc_block(str
|
||||
static void airoha_tc_remove_htb_queue(struct net_device *netdev, int queue)
|
||||
{
|
||||
struct airoha_gdm_dev *dev = netdev_priv(netdev);
|
||||
@@ -111,7 +111,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
}
|
||||
|
||||
static int airoha_tc_htb_delete_leaf_queue(struct net_device *netdev,
|
||||
@@ -3064,9 +3080,8 @@ static int airoha_tc_htb_delete_leaf_que
|
||||
@@ -3065,9 +3081,8 @@ static int airoha_tc_htb_delete_leaf_que
|
||||
{
|
||||
u32 channel = TC_H_MIN(opt->classid) % AIROHA_NUM_QOS_CHANNELS;
|
||||
struct airoha_gdm_dev *dev = netdev_priv(netdev);
|
||||
@@ -122,7 +122,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
NL_SET_ERR_MSG_MOD(opt->extack, "invalid queue id");
|
||||
return -EINVAL;
|
||||
}
|
||||
@@ -3079,10 +3094,9 @@ static int airoha_tc_htb_delete_leaf_que
|
||||
@@ -3080,10 +3095,9 @@ static int airoha_tc_htb_delete_leaf_que
|
||||
static int airoha_tc_htb_destroy(struct net_device *netdev)
|
||||
{
|
||||
struct airoha_gdm_dev *dev = netdev_priv(netdev);
|
||||
@@ -134,7 +134,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
airoha_tc_remove_htb_queue(netdev, q);
|
||||
|
||||
return 0;
|
||||
@@ -3093,9 +3107,8 @@ static int airoha_tc_get_htb_get_leaf_qu
|
||||
@@ -3094,9 +3108,8 @@ static int airoha_tc_get_htb_get_leaf_qu
|
||||
{
|
||||
u32 channel = TC_H_MIN(opt->classid) % AIROHA_NUM_QOS_CHANNELS;
|
||||
struct airoha_gdm_dev *dev = netdev_priv(netdev);
|
||||
@@ -145,7 +145,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
NL_SET_ERR_MSG_MOD(opt->extack, "invalid queue id");
|
||||
return -EINVAL;
|
||||
}
|
||||
@@ -3114,6 +3127,7 @@ static int airoha_tc_setup_qdisc_htb(str
|
||||
@@ -3115,6 +3128,7 @@ static int airoha_tc_setup_qdisc_htb(str
|
||||
case TC_HTB_DESTROY:
|
||||
return airoha_tc_htb_destroy(dev);
|
||||
case TC_HTB_NODE_MODIFY:
|
||||
|
||||
+1
-1
@@ -21,7 +21,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
|
||||
--- a/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
@@ -2547,19 +2547,17 @@ static int airoha_qdma_get_tx_ets_stats(
|
||||
@@ -2548,19 +2548,17 @@ static int airoha_qdma_get_tx_ets_stats(
|
||||
struct tc_ets_qopt_offload *opt)
|
||||
{
|
||||
struct airoha_gdm_dev *dev = netdev_priv(netdev);
|
||||
|
||||
+26
-23
@@ -171,7 +171,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
/* 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
|
||||
@@ -996,24 +988,27 @@ static void airoha_qdma_wake_netdev_txqs
|
||||
@@ -997,24 +989,27 @@ static void airoha_qdma_wake_netdev_txqs
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(eth->ports); i++) {
|
||||
struct airoha_gdm_port *port = eth->ports[i];
|
||||
@@ -209,7 +209,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
}
|
||||
}
|
||||
q->txq_stopped = false;
|
||||
@@ -1902,11 +1897,9 @@ static int airoha_dev_open(struct net_de
|
||||
@@ -1903,11 +1898,9 @@ static int airoha_dev_open(struct net_de
|
||||
GLOBAL_CFG_RX_DMA_EN_MASK);
|
||||
atomic_inc(&qdma->users);
|
||||
|
||||
@@ -223,7 +223,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
airoha_set_gdm_port_fwd_cfg(qdma->eth, REG_GDM_FWD_CFG(port->id),
|
||||
pse_port);
|
||||
|
||||
@@ -2001,7 +1994,7 @@ static int airoha_set_gdm2_loopback(stru
|
||||
@@ -2002,7 +1995,7 @@ static int airoha_set_gdm2_loopback(stru
|
||||
airoha_fe_clear(eth, REG_FE_VIP_PORT_EN, BIT(AIROHA_GDM2_IDX));
|
||||
airoha_fe_clear(eth, REG_FE_IFC_PORT_EN, BIT(AIROHA_GDM2_IDX));
|
||||
|
||||
@@ -232,7 +232,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
if (src_port < 0)
|
||||
return src_port;
|
||||
|
||||
@@ -2018,7 +2011,7 @@ static int airoha_set_gdm2_loopback(stru
|
||||
@@ -2019,7 +2012,7 @@ static int airoha_set_gdm2_loopback(stru
|
||||
airoha_ppe_set_cpu_port(dev, i, AIROHA_GDM2_IDX);
|
||||
|
||||
if (port->id == AIROHA_GDM4_IDX && airoha_is_7581(eth)) {
|
||||
@@ -241,7 +241,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
|
||||
airoha_fe_rmw(eth, REG_SRC_PORT_FC_MAP6, mask,
|
||||
__field_prep(mask, AIROHA_GDM2_IDX));
|
||||
@@ -2032,7 +2025,7 @@ static int airoha_dev_init(struct net_de
|
||||
@@ -2033,7 +2026,7 @@ static int airoha_dev_init(struct net_de
|
||||
struct airoha_gdm_dev *dev = netdev_priv(netdev);
|
||||
struct airoha_gdm_port *port = dev->port;
|
||||
struct airoha_eth *eth = dev->eth;
|
||||
@@ -250,7 +250,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
|
||||
/* QDMA0 is used for lan ports while QDMA1 is used for WAN ports */
|
||||
dev->qdma = ð->qdma[!airoha_is_lan_gdm_dev(dev)];
|
||||
@@ -2055,8 +2048,8 @@ static int airoha_dev_init(struct net_de
|
||||
@@ -2056,8 +2049,8 @@ static int airoha_dev_init(struct net_de
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -261,7 +261,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -2221,20 +2214,26 @@ static int airoha_dev_set_features(struc
|
||||
@@ -2222,20 +2215,26 @@ static int airoha_dev_set_features(struc
|
||||
} else {
|
||||
for (i = 0; i < ARRAY_SIZE(eth->ports); i++) {
|
||||
struct airoha_gdm_port *p = eth->ports[i];
|
||||
@@ -296,7 +296,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
}
|
||||
airoha_fe_lro_disable(eth, qdma_id);
|
||||
}
|
||||
@@ -2285,7 +2284,8 @@ static netdev_tx_t airoha_dev_xmit(struc
|
||||
@@ -2286,7 +2285,8 @@ static netdev_tx_t airoha_dev_xmit(struc
|
||||
}
|
||||
|
||||
fport = airoha_get_fe_port(dev);
|
||||
@@ -306,7 +306,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
FIELD_PREP(QDMA_ETH_TXMSG_METER_MASK, 0x7f);
|
||||
|
||||
q = &qdma->q_tx[qid];
|
||||
@@ -3221,12 +3221,15 @@ bool airoha_is_valid_gdm_dev(struct airo
|
||||
@@ -3222,12 +3222,15 @@ bool airoha_is_valid_gdm_dev(struct airo
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(eth->ports); i++) {
|
||||
struct airoha_gdm_port *port = eth->ports[i];
|
||||
@@ -324,7 +324,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
}
|
||||
|
||||
return false;
|
||||
@@ -3350,10 +3353,11 @@ static int airoha_setup_phylink(struct n
|
||||
@@ -3351,10 +3354,11 @@ static int airoha_setup_phylink(struct n
|
||||
|
||||
static int airoha_alloc_gdm_device(struct airoha_eth *eth,
|
||||
struct airoha_gdm_port *port,
|
||||
@@ -338,7 +338,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
int err;
|
||||
|
||||
netdev = devm_alloc_etherdev_mqs(eth->dev, sizeof(*dev),
|
||||
@@ -3371,7 +3375,6 @@ static int airoha_alloc_gdm_device(struc
|
||||
@@ -3372,7 +3376,6 @@ static int airoha_alloc_gdm_device(struc
|
||||
netdev->hw_features = AIROHA_HW_FEATURES | NETIF_F_LRO;
|
||||
netdev->features |= AIROHA_HW_FEATURES;
|
||||
netdev->vlan_features = AIROHA_HW_FEATURES;
|
||||
@@ -346,7 +346,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
SET_NETDEV_DEV(netdev, eth->dev);
|
||||
|
||||
/* reserve hw queues for HTB offloading */
|
||||
@@ -3389,11 +3392,25 @@ static int airoha_alloc_gdm_device(struc
|
||||
@@ -3390,11 +3393,25 @@ static int airoha_alloc_gdm_device(struc
|
||||
netdev->dev_addr);
|
||||
}
|
||||
|
||||
@@ -373,7 +373,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
|
||||
#if defined(CONFIG_PCS_AIROHA)
|
||||
if (airhoa_is_phy_external(port)) {
|
||||
@@ -3411,7 +3428,8 @@ static int airoha_alloc_gdm_port(struct
|
||||
@@ -3412,7 +3429,8 @@ static int airoha_alloc_gdm_port(struct
|
||||
{
|
||||
const __be32 *id_ptr = of_get_property(np, "reg", NULL);
|
||||
struct airoha_gdm_port *port;
|
||||
@@ -383,7 +383,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
u32 id;
|
||||
|
||||
if (!id_ptr) {
|
||||
@@ -3439,15 +3457,51 @@ static int airoha_alloc_gdm_port(struct
|
||||
@@ -3440,15 +3458,51 @@ static int airoha_alloc_gdm_port(struct
|
||||
u64_stats_init(&port->stats.syncp);
|
||||
spin_lock_init(&port->stats.lock);
|
||||
port->id = id;
|
||||
@@ -438,7 +438,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
}
|
||||
|
||||
static int airoha_register_gdm_devices(struct airoha_eth *eth)
|
||||
@@ -3456,14 +3510,22 @@ static int airoha_register_gdm_devices(s
|
||||
@@ -3457,14 +3511,22 @@ static int airoha_register_gdm_devices(s
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(eth->ports); i++) {
|
||||
struct airoha_gdm_port *port = eth->ports[i];
|
||||
@@ -465,7 +465,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
}
|
||||
|
||||
set_bit(DEV_STATE_REGISTERED, ð->state);
|
||||
@@ -3570,18 +3632,27 @@ error_napi_stop:
|
||||
@@ -3571,18 +3633,27 @@ error_napi_stop:
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(eth->ports); i++) {
|
||||
struct airoha_gdm_port *port = eth->ports[i];
|
||||
@@ -499,7 +499,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
}
|
||||
airoha_metadata_dst_free(port);
|
||||
}
|
||||
@@ -3603,19 +3674,26 @@ static void airoha_remove(struct platfor
|
||||
@@ -3604,19 +3675,26 @@ static void airoha_remove(struct platfor
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(eth->ports); i++) {
|
||||
struct airoha_gdm_port *port = eth->ports[i];
|
||||
@@ -531,7 +531,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
airoha_metadata_dst_free(port);
|
||||
}
|
||||
airoha_hw_cleanup(eth);
|
||||
@@ -3677,6 +3755,39 @@ static u32 airoha_en7581_get_vip_port(st
|
||||
@@ -3678,6 +3756,39 @@ static u32 airoha_en7581_get_vip_port(st
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -571,7 +571,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
static const char * const an7583_xsi_rsts_names[] = {
|
||||
"hsi0-mac",
|
||||
"hsi1-mac",
|
||||
@@ -3725,6 +3836,36 @@ static u32 airoha_an7583_get_vip_port(st
|
||||
@@ -3726,6 +3837,36 @@ static u32 airoha_an7583_get_vip_port(st
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -608,7 +608,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
static const struct airoha_eth_soc_data en7581_soc_data = {
|
||||
.version = 0x7581,
|
||||
.xsi_rsts_names = en7581_xsi_rsts_names,
|
||||
@@ -3733,6 +3874,7 @@ static const struct airoha_eth_soc_data
|
||||
@@ -3734,6 +3875,7 @@ static const struct airoha_eth_soc_data
|
||||
.ops = {
|
||||
.get_sport = airoha_en7581_get_sport,
|
||||
.get_vip_port = airoha_en7581_get_vip_port,
|
||||
@@ -616,7 +616,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
},
|
||||
};
|
||||
|
||||
@@ -3744,6 +3886,7 @@ static const struct airoha_eth_soc_data
|
||||
@@ -3745,6 +3887,7 @@ static const struct airoha_eth_soc_data
|
||||
.ops = {
|
||||
.get_sport = airoha_an7583_get_sport,
|
||||
.get_vip_port = airoha_an7583_get_vip_port,
|
||||
@@ -682,7 +682,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
airoha_fe_rmw(eth, REG_PPE_MTU(i, p),
|
||||
FP0_EGRESS_MTU_MASK |
|
||||
FP1_EGRESS_MTU_MASK,
|
||||
@@ -178,11 +176,24 @@ static void airoha_ppe_hw_init(struct ai
|
||||
@@ -178,11 +176,27 @@ static void airoha_ppe_hw_init(struct ai
|
||||
AIROHA_MAX_MTU) |
|
||||
FIELD_PREP(FP1_EGRESS_MTU_MASK,
|
||||
AIROHA_MAX_MTU));
|
||||
@@ -698,6 +698,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
+
|
||||
+ for (j = 0; j < ARRAY_SIZE(port->devs); j++) {
|
||||
+ struct airoha_gdm_dev *dev = port->devs[j];
|
||||
+ int ppe_id;
|
||||
+ u8 fport;
|
||||
+
|
||||
+ if (!dev)
|
||||
@@ -705,8 +706,10 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
|
||||
- airoha_ppe_set_cpu_port(port->dev, i,
|
||||
- airoha_get_fe_port(port->dev));
|
||||
+ ppe_id = !airoha_is_lan_gdm_dev(dev) &&
|
||||
+ airoha_ppe_is_enabled(eth, 1);
|
||||
+ fport = airoha_get_fe_port(dev);
|
||||
+ airoha_ppe_set_cpu_port(dev, i, fport);
|
||||
+ airoha_ppe_set_cpu_port(dev, ppe_id, fport);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+5
-5
@@ -23,7 +23,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
|
||||
--- a/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
@@ -1858,8 +1858,8 @@ static int airoha_dev_open(struct net_de
|
||||
@@ -1859,8 +1859,8 @@ static int airoha_dev_open(struct net_de
|
||||
int err, len = ETH_HLEN + netdev->mtu + ETH_FCS_LEN;
|
||||
struct airoha_gdm_dev *dev = netdev_priv(netdev);
|
||||
struct airoha_gdm_port *port = dev->port;
|
||||
@@ -33,7 +33,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
|
||||
#if defined(CONFIG_PCS_AIROHA)
|
||||
if (airhoa_is_phy_external(port)) {
|
||||
@@ -1887,10 +1887,20 @@ static int airoha_dev_open(struct net_de
|
||||
@@ -1888,10 +1888,20 @@ static int airoha_dev_open(struct net_de
|
||||
airoha_fe_clear(qdma->eth, REG_GDM_INGRESS_CFG(port->id),
|
||||
GDM_STAG_EN_MASK);
|
||||
|
||||
@@ -58,7 +58,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
|
||||
airoha_qdma_set(qdma, REG_QDMA_GLOBAL_CFG,
|
||||
GLOBAL_CFG_TX_DMA_EN_MASK |
|
||||
@@ -1906,6 +1916,30 @@ static int airoha_dev_open(struct net_de
|
||||
@@ -1907,6 +1917,30 @@ static int airoha_dev_open(struct net_de
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -89,7 +89,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
static int airoha_dev_stop(struct net_device *netdev)
|
||||
{
|
||||
struct airoha_gdm_dev *dev = netdev_priv(netdev);
|
||||
@@ -1918,8 +1952,12 @@ static int airoha_dev_stop(struct net_de
|
||||
@@ -1919,8 +1953,12 @@ static int airoha_dev_stop(struct net_de
|
||||
for (i = 0; i < netdev->num_tx_queues; i++)
|
||||
netdev_tx_reset_subqueue(netdev, i);
|
||||
|
||||
@@ -104,7 +104,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
|
||||
if (atomic_dec_and_test(&qdma->users)) {
|
||||
airoha_qdma_clear(qdma, REG_QDMA_GLOBAL_CFG,
|
||||
@@ -2081,13 +2119,10 @@ static int airoha_dev_change_mtu(struct
|
||||
@@ -2082,13 +2120,10 @@ static int airoha_dev_change_mtu(struct
|
||||
{
|
||||
struct airoha_gdm_dev *dev = netdev_priv(netdev);
|
||||
struct airoha_gdm_port *port = dev->port;
|
||||
|
||||
@@ -29,7 +29,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
|
||||
--- a/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
@@ -2058,36 +2058,80 @@ static int airoha_set_gdm2_loopback(stru
|
||||
@@ -2059,36 +2059,80 @@ static int airoha_set_gdm2_loopback(stru
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -163,7 +163,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
static inline bool airoha_is_7581(struct airoha_eth *eth)
|
||||
--- a/drivers/net/ethernet/airoha/airoha_ppe.c
|
||||
+++ b/drivers/net/ethernet/airoha/airoha_ppe.c
|
||||
@@ -351,7 +351,7 @@ static int airoha_ppe_foe_entry_prepare(
|
||||
@@ -354,7 +354,7 @@ static int airoha_ppe_foe_entry_prepare(
|
||||
return -EINVAL;
|
||||
|
||||
port = dev->port;
|
||||
|
||||
+2
-2
@@ -111,7 +111,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
}
|
||||
|
||||
static void airoha_set_gdm_port_fwd_cfg(struct airoha_eth *eth, u32 addr,
|
||||
@@ -1985,13 +2039,18 @@ static int airoha_dev_stop(struct net_de
|
||||
@@ -1986,13 +2040,18 @@ static int airoha_dev_stop(struct net_de
|
||||
static int airoha_dev_set_macaddr(struct net_device *netdev, void *p)
|
||||
{
|
||||
struct airoha_gdm_dev *dev = netdev_priv(netdev);
|
||||
@@ -145,7 +145,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
u32 hash);
|
||||
--- a/drivers/net/ethernet/airoha/airoha_ppe.c
|
||||
+++ b/drivers/net/ethernet/airoha/airoha_ppe.c
|
||||
@@ -1494,12 +1494,10 @@ void airoha_ppe_check_skb(struct airoha_
|
||||
@@ -1497,12 +1497,10 @@ void airoha_ppe_check_skb(struct airoha_
|
||||
airoha_ppe_foe_insert_entry(ppe, skb, hash, rx_wlan);
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -17,7 +17,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
|
||||
--- a/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
@@ -2055,7 +2055,7 @@ static int airoha_dev_set_macaddr(struct
|
||||
@@ -2056,7 +2056,7 @@ static int airoha_dev_set_macaddr(struct
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
{
|
||||
struct airoha_gdm_port *port = dev->port;
|
||||
struct airoha_eth *eth = dev->eth;
|
||||
@@ -2187,7 +2187,7 @@ static int airoha_dev_init(struct net_de
|
||||
@@ -2188,7 +2188,7 @@ static int airoha_dev_init(struct net_de
|
||||
(port->id == AIROHA_GDM3_IDX || port->id == AIROHA_GDM4_IDX)) {
|
||||
int err;
|
||||
|
||||
|
||||
+6
-6
@@ -19,7 +19,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
|
||||
--- a/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
@@ -1915,6 +1915,11 @@ static int airoha_dev_open(struct net_de
|
||||
@@ -1916,6 +1916,11 @@ static int airoha_dev_open(struct net_de
|
||||
u32 cur_len, pse_port = FE_PSE_PORT_PPE1;
|
||||
struct airoha_qdma *qdma = dev->qdma;
|
||||
|
||||
@@ -31,7 +31,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
#if defined(CONFIG_PCS_AIROHA)
|
||||
if (airhoa_is_phy_external(port)) {
|
||||
err = phylink_of_phy_connect(dev->phylink, netdev->dev.of_node, 0);
|
||||
@@ -2117,6 +2122,45 @@ static int airoha_enable_gdm2_loopback(s
|
||||
@@ -2118,6 +2123,45 @@ static int airoha_enable_gdm2_loopback(s
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -77,7 +77,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
static struct airoha_gdm_dev *
|
||||
airoha_get_wan_gdm_dev(struct airoha_eth *eth)
|
||||
{
|
||||
@@ -2521,6 +2565,80 @@ error:
|
||||
@@ -2522,6 +2566,80 @@ error:
|
||||
return NETDEV_TX_OK;
|
||||
}
|
||||
|
||||
@@ -158,7 +158,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
static void airoha_ethtool_get_drvinfo(struct net_device *netdev,
|
||||
struct ethtool_drvinfo *info)
|
||||
{
|
||||
@@ -2529,6 +2647,7 @@ static void airoha_ethtool_get_drvinfo(s
|
||||
@@ -2530,6 +2648,7 @@ static void airoha_ethtool_get_drvinfo(s
|
||||
|
||||
strscpy(info->driver, eth->dev->driver->name, sizeof(info->driver));
|
||||
strscpy(info->bus_info, dev_name(eth->dev), sizeof(info->bus_info));
|
||||
@@ -166,7 +166,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
}
|
||||
|
||||
static void airoha_ethtool_get_mac_stats(struct net_device *netdev,
|
||||
@@ -2593,6 +2712,56 @@ airoha_ethtool_get_rmon_stats(struct net
|
||||
@@ -2594,6 +2713,56 @@ airoha_ethtool_get_rmon_stats(struct net
|
||||
} while (u64_stats_fetch_retry(&port->stats.syncp, start));
|
||||
}
|
||||
|
||||
@@ -223,7 +223,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
static int airoha_qdma_set_chan_tx_sched(struct net_device *netdev,
|
||||
int channel, enum tx_sched_mode mode,
|
||||
const u16 *weights, u8 n_weights)
|
||||
@@ -3314,6 +3483,10 @@ static const struct ethtool_ops airoha_e
|
||||
@@ -3315,6 +3484,10 @@ static const struct ethtool_ops airoha_e
|
||||
.get_rmon_stats = airoha_ethtool_get_rmon_stats,
|
||||
.get_link_ksettings = phy_ethtool_get_link_ksettings,
|
||||
.get_link = ethtool_op_get_link,
|
||||
|
||||
@@ -28,37 +28,24 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
+ 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, AIROHA_MAX_MTU));
|
||||
+ FIELD_PREP(GDM_LONG_LEN_MASK, AIROHA_MAX_RX_SIZE));
|
||||
+ }
|
||||
|
||||
airoha_fe_rmw(eth, REG_CDM_VLAN_CTRL(1), CDM_VLAN_MASK,
|
||||
FIELD_PREP(CDM_VLAN_MASK, 0x8100));
|
||||
@@ -1907,13 +1912,37 @@ static void airoha_update_hw_stats(struc
|
||||
@@ -1908,13 +1913,24 @@ static void airoha_update_hw_stats(struc
|
||||
spin_unlock(&port->stats.lock);
|
||||
}
|
||||
|
||||
+void airoha_set_port_mtu(struct airoha_eth *eth, struct airoha_gdm_port *port)
|
||||
+static void airoha_dev_set_mtu(struct net_device *netdev)
|
||||
+{
|
||||
+ u32 mtu = 0, index;
|
||||
+ int i;
|
||||
+ struct airoha_gdm_dev *dev = netdev_priv(netdev);
|
||||
+
|
||||
+ for (i = 0; i < ARRAY_SIZE(port->devs); i++) {
|
||||
+ struct airoha_gdm_dev *dev = port->devs[i];
|
||||
+ struct net_device *netdev;
|
||||
+
|
||||
+ if (!dev)
|
||||
+ continue;
|
||||
+
|
||||
+ netdev = dev->dev;
|
||||
+ if (netif_running(netdev))
|
||||
+ mtu = max_t(u32, mtu, netdev->mtu);
|
||||
+ }
|
||||
+
|
||||
+ index = port->id == AIROHA_GDM4_IDX ? 7 : port->id;
|
||||
+ for (i = 0; i < eth->soc->num_ppe; i++)
|
||||
+ airoha_fe_rmw(eth, REG_PPE_MTU(i, index),
|
||||
+ FP_EGRESS_MTU_MASK(index),
|
||||
+ __field_prep(FP_EGRESS_MTU_MASK(index), mtu));
|
||||
+ airoha_ppe_set_mtu(dev);
|
||||
+ if (!airoha_is_lan_gdm_dev(dev))
|
||||
+ airoha_fe_rmw(dev->eth, REG_WAN_MTU0,
|
||||
+ WAN_MTU0_MASK,
|
||||
+ FIELD_PREP(WAN_MTU0_MASK, netdev->mtu));
|
||||
+}
|
||||
+
|
||||
static int airoha_dev_open(struct net_device *netdev)
|
||||
@@ -73,7 +60,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
|
||||
if (port->id == AIROHA_GDM2_IDX && airoha_is_lan_gdm_dev(dev)) {
|
||||
/* GDM2 can be used just as wan */
|
||||
@@ -1946,19 +1975,12 @@ static int airoha_dev_open(struct net_de
|
||||
@@ -1947,19 +1963,7 @@ static int airoha_dev_open(struct net_de
|
||||
airoha_fe_clear(qdma->eth, REG_GDM_INGRESS_CFG(port->id),
|
||||
GDM_STAG_EN_MASK);
|
||||
|
||||
@@ -90,16 +77,11 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
- FIELD_PREP(GDM_SHORT_LEN_MASK, 60) |
|
||||
- FIELD_PREP(GDM_LONG_LEN_MASK, len));
|
||||
- }
|
||||
+ airoha_set_port_mtu(qdma->eth, port);
|
||||
+ if (!airoha_is_lan_gdm_dev(dev))
|
||||
+ airoha_fe_rmw(qdma->eth, REG_WAN_MTU0,
|
||||
+ WAN_MTU0_MASK,
|
||||
+ FIELD_PREP(WAN_MTU0_MASK, netdev->mtu));
|
||||
+
|
||||
+ airoha_dev_set_mtu(netdev);
|
||||
port->users++;
|
||||
|
||||
airoha_qdma_set(qdma, REG_QDMA_GLOBAL_CFG,
|
||||
@@ -1975,30 +1997,6 @@ static int airoha_dev_open(struct net_de
|
||||
@@ -1976,30 +1980,6 @@ static int airoha_dev_open(struct net_de
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -130,7 +112,16 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
static int airoha_dev_stop(struct net_device *netdev)
|
||||
{
|
||||
struct airoha_gdm_dev *dev = netdev_priv(netdev);
|
||||
@@ -2082,10 +2080,6 @@ static int airoha_enable_gdm2_loopback(s
|
||||
@@ -2013,7 +1993,7 @@ static int airoha_dev_stop(struct net_de
|
||||
netdev_tx_reset_subqueue(netdev, i);
|
||||
|
||||
if (--port->users)
|
||||
- airoha_set_port_mtu(dev->eth, port);
|
||||
+ airoha_ppe_set_mtu(dev);
|
||||
else
|
||||
airoha_set_gdm_port_fwd_cfg(qdma->eth,
|
||||
REG_GDM_FWD_CFG(port->id),
|
||||
@@ -2083,10 +2063,6 @@ static int airoha_enable_gdm2_loopback(s
|
||||
FIELD_PREP(LPBK_CHAN_MASK, chan) |
|
||||
LBK_GAP_MODE_MASK | LBK_LEN_MODE_MASK |
|
||||
LBK_CHAN_MODE_MASK | LPBK_EN_MASK);
|
||||
@@ -141,29 +132,80 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
/* Forward the traffic to the proper GDM port */
|
||||
pse_port = port->id == AIROHA_GDM3_IDX ? FE_PSE_PORT_GDM3
|
||||
: FE_PSE_PORT_GDM4;
|
||||
@@ -2612,6 +2606,9 @@ static int airoha_dev_set_wan_flag(struc
|
||||
@@ -2270,7 +2246,7 @@ static int airoha_dev_change_mtu(struct
|
||||
|
||||
WRITE_ONCE(netdev->mtu, mtu);
|
||||
if (port->users)
|
||||
- airoha_set_port_mtu(dev->eth, port);
|
||||
+ airoha_dev_set_mtu(netdev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -2613,6 +2589,7 @@ static int airoha_dev_set_wan_flag(struc
|
||||
default:
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
+ airoha_fe_rmw(eth, REG_WAN_MTU0,
|
||||
+ WAN_MTU0_MASK,
|
||||
+ FIELD_PREP(WAN_MTU0_MASK, netdev->mtu));
|
||||
+ airoha_dev_set_mtu(netdev);
|
||||
} else {
|
||||
switch (port->id) {
|
||||
case AIROHA_GDM3_IDX:
|
||||
--- a/drivers/net/ethernet/airoha/airoha_eth.h
|
||||
+++ b/drivers/net/ethernet/airoha/airoha_eth.h
|
||||
@@ -706,6 +706,7 @@ int airoha_get_fe_port(struct airoha_gdm
|
||||
@@ -23,6 +23,7 @@
|
||||
#define AIROHA_MAX_DSA_PORTS 7
|
||||
#define AIROHA_MAX_NUM_RSTS 3
|
||||
#define AIROHA_MAX_MTU 9220
|
||||
+#define AIROHA_MAX_RX_SIZE 16128
|
||||
#define AIROHA_MAX_PACKET_SIZE 2048
|
||||
#define AIROHA_NUM_QOS_CHANNELS 4
|
||||
#define AIROHA_NUM_QOS_QUEUES 8
|
||||
@@ -706,6 +707,7 @@ int airoha_get_fe_port(struct airoha_gdm
|
||||
bool airoha_is_valid_gdm_dev(struct airoha_eth *eth,
|
||||
struct airoha_gdm_dev *dev);
|
||||
|
||||
+void airoha_set_port_mtu(struct airoha_eth *eth, struct airoha_gdm_port *port);
|
||||
+void airoha_ppe_set_mtu(struct airoha_gdm_dev *dev);
|
||||
void airoha_ppe_set_cpu_port(struct airoha_gdm_dev *dev, u8 ppe_id, u8 fport);
|
||||
bool airoha_ppe_is_enabled(struct airoha_eth *eth, int index);
|
||||
void airoha_ppe_check_skb(struct airoha_ppe_dev *dev, struct sk_buff *skb,
|
||||
--- a/drivers/net/ethernet/airoha/airoha_ppe.c
|
||||
+++ b/drivers/net/ethernet/airoha/airoha_ppe.c
|
||||
@@ -116,8 +116,6 @@ static void airoha_ppe_hw_init(struct ai
|
||||
@@ -98,6 +98,35 @@ void airoha_ppe_set_cpu_port(struct airo
|
||||
__field_prep(DFT_CPORT_MASK(fport), fe_cpu_port));
|
||||
}
|
||||
|
||||
+void airoha_ppe_set_mtu(struct airoha_gdm_dev *dev)
|
||||
+{
|
||||
+ struct airoha_gdm_port *port = dev->port;
|
||||
+ struct airoha_eth *eth = dev->eth;
|
||||
+ int i, ppe_id, index;
|
||||
+ u32 mtu = 0;
|
||||
+
|
||||
+ for (i = 0; i < ARRAY_SIZE(port->devs); i++) {
|
||||
+ struct airoha_gdm_dev *d = port->devs[i];
|
||||
+ struct net_device *netdev;
|
||||
+
|
||||
+ if (!d)
|
||||
+ continue;
|
||||
+
|
||||
+ if (d->qdma != dev->qdma)
|
||||
+ continue;
|
||||
+
|
||||
+ netdev = d->dev;
|
||||
+ if (netif_running(netdev))
|
||||
+ mtu = max_t(u32, mtu, netdev->mtu);
|
||||
+ }
|
||||
+
|
||||
+ ppe_id = !airoha_is_lan_gdm_dev(dev) && airoha_ppe_is_enabled(eth, 1);
|
||||
+ index = port->id == AIROHA_GDM4_IDX ? 7 : port->id;
|
||||
+ airoha_fe_rmw(eth, REG_PPE_MTU(ppe_id, index),
|
||||
+ FP_EGRESS_MTU_MASK(index),
|
||||
+ __field_prep(FP_EGRESS_MTU_MASK(index), mtu));
|
||||
+}
|
||||
+
|
||||
static void airoha_ppe_hw_init(struct airoha_ppe *ppe)
|
||||
{
|
||||
u32 sram_ppe_num_data_entries = PPE_SRAM_NUM_ENTRIES, sram_num_entries;
|
||||
@@ -116,8 +145,6 @@ static void airoha_ppe_hw_init(struct ai
|
||||
PPE_RAM_NUM_ENTRIES_SHIFT(sram_ppe_num_data_entries);
|
||||
|
||||
for (i = 0; i < eth->soc->num_ppe; i++) {
|
||||
@@ -172,7 +214,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
airoha_fe_wr(eth, REG_PPE_TB_BASE(i),
|
||||
ppe->foe_dma + sram_tb_size);
|
||||
|
||||
@@ -167,15 +165,6 @@ static void airoha_ppe_hw_init(struct ai
|
||||
@@ -167,15 +194,6 @@ static void airoha_ppe_hw_init(struct ai
|
||||
airoha_fe_wr(eth, REG_PPE_HASH_SEED(i), PPE_HASH_SEED);
|
||||
airoha_fe_clear(eth, REG_PPE_PPE_FLOW_CFG(i),
|
||||
PPE_FLOW_CFG_IP6_6RD_MASK);
|
||||
@@ -188,14 +230,14 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
}
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(eth->ports); i++) {
|
||||
@@ -185,6 +174,7 @@ static void airoha_ppe_hw_init(struct ai
|
||||
if (!port)
|
||||
continue;
|
||||
|
||||
+ airoha_set_port_mtu(eth, port);
|
||||
for (j = 0; j < ARRAY_SIZE(port->devs); j++) {
|
||||
struct airoha_gdm_dev *dev = port->devs[j];
|
||||
u8 fport;
|
||||
@@ -197,6 +215,7 @@ static void airoha_ppe_hw_init(struct ai
|
||||
airoha_ppe_is_enabled(eth, 1);
|
||||
fport = airoha_get_fe_port(dev);
|
||||
airoha_ppe_set_cpu_port(dev, ppe_id, fport);
|
||||
+ airoha_ppe_set_mtu(dev);
|
||||
}
|
||||
}
|
||||
}
|
||||
--- a/drivers/net/ethernet/airoha/airoha_regs.h
|
||||
+++ b/drivers/net/ethernet/airoha/airoha_regs.h
|
||||
@@ -341,9 +341,8 @@
|
||||
|
||||
+16
-16
@@ -46,7 +46,7 @@ Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
|
||||
airoha_fe_crsn_qsel_init(eth);
|
||||
|
||||
airoha_fe_clear(eth, REG_FE_CPORT_CFG, FE_CPORT_QUEUE_XFC_MASK);
|
||||
@@ -1767,149 +1775,169 @@ static void airoha_qdma_stop_napi(struct
|
||||
@@ -1768,149 +1776,169 @@ static void airoha_qdma_stop_napi(struct
|
||||
}
|
||||
}
|
||||
|
||||
@@ -245,9 +245,7 @@ Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
|
||||
+
|
||||
+ u64_stats_update_end(&dev->stats.syncp);
|
||||
+}
|
||||
|
||||
- /* reset mib counters */
|
||||
- airoha_fe_set(eth, REG_FE_GDM_MIB_CLEAR(port->id),
|
||||
+
|
||||
+static void airoha_update_hw_stats(struct airoha_gdm_dev *dev)
|
||||
+{
|
||||
+ struct airoha_gdm_port *port = dev->port;
|
||||
@@ -259,7 +257,9 @@ Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
|
||||
+ if (port->devs[i])
|
||||
+ airoha_dev_get_hw_stats(port->devs[i]);
|
||||
+ }
|
||||
+
|
||||
|
||||
- /* reset mib counters */
|
||||
- airoha_fe_set(eth, REG_FE_GDM_MIB_CLEAR(port->id),
|
||||
+ /* Reset MIB counters */
|
||||
+ airoha_fe_set(dev->eth, REG_FE_GDM_MIB_CLEAR(port->id),
|
||||
FE_GDM_MIB_RX_CLEAR_MASK | FE_GDM_MIB_TX_CLEAR_MASK);
|
||||
@@ -269,8 +269,8 @@ Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
|
||||
+ spin_unlock(&port->stats_lock);
|
||||
}
|
||||
|
||||
void airoha_set_port_mtu(struct airoha_eth *eth, struct airoha_gdm_port *port)
|
||||
@@ -2237,23 +2265,22 @@ static void airoha_dev_get_stats64(struc
|
||||
static void airoha_dev_set_mtu(struct net_device *netdev)
|
||||
@@ -2220,23 +2248,22 @@ static void airoha_dev_get_stats64(struc
|
||||
struct rtnl_link_stats64 *storage)
|
||||
{
|
||||
struct airoha_gdm_dev *dev = netdev_priv(netdev);
|
||||
@@ -306,7 +306,7 @@ Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
|
||||
}
|
||||
|
||||
static int airoha_dev_change_mtu(struct net_device *netdev, int mtu)
|
||||
@@ -2651,20 +2678,19 @@ static void airoha_ethtool_get_mac_stats
|
||||
@@ -2632,20 +2659,19 @@ static void airoha_ethtool_get_mac_stats
|
||||
struct ethtool_eth_mac_stats *stats)
|
||||
{
|
||||
struct airoha_gdm_dev *dev = netdev_priv(netdev);
|
||||
@@ -336,7 +336,7 @@ Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
|
||||
}
|
||||
|
||||
static const struct ethtool_rmon_hist_range airoha_ethtool_rmon_ranges[] = {
|
||||
@@ -2684,8 +2710,7 @@ airoha_ethtool_get_rmon_stats(struct net
|
||||
@@ -2665,8 +2691,7 @@ airoha_ethtool_get_rmon_stats(struct net
|
||||
const struct ethtool_rmon_hist_range **ranges)
|
||||
{
|
||||
struct airoha_gdm_dev *dev = netdev_priv(netdev);
|
||||
@@ -346,7 +346,7 @@ Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
|
||||
unsigned int start;
|
||||
|
||||
BUILD_BUG_ON(ARRAY_SIZE(airoha_ethtool_rmon_ranges) !=
|
||||
@@ -2698,7 +2723,7 @@ airoha_ethtool_get_rmon_stats(struct net
|
||||
@@ -2679,7 +2704,7 @@ airoha_ethtool_get_rmon_stats(struct net
|
||||
do {
|
||||
int i;
|
||||
|
||||
@@ -355,7 +355,7 @@ Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
|
||||
stats->fragments = hw_stats->rx_fragment;
|
||||
stats->jabbers = hw_stats->rx_jabber;
|
||||
for (i = 0; i < ARRAY_SIZE(airoha_ethtool_rmon_ranges) - 1;
|
||||
@@ -2706,7 +2731,7 @@ airoha_ethtool_get_rmon_stats(struct net
|
||||
@@ -2687,7 +2712,7 @@ airoha_ethtool_get_rmon_stats(struct net
|
||||
stats->hist[i] = hw_stats->rx_len[i];
|
||||
stats->hist_tx[i] = hw_stats->tx_len[i];
|
||||
}
|
||||
@@ -364,7 +364,7 @@ Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
|
||||
}
|
||||
|
||||
static int airoha_ethtool_set_priv_flags(struct net_device *netdev, u32 flags)
|
||||
@@ -3714,6 +3739,7 @@ static int airoha_alloc_gdm_device(struc
|
||||
@@ -3695,6 +3720,7 @@ static int airoha_alloc_gdm_device(struc
|
||||
|
||||
netdev->dev.of_node = of_node_get(np);
|
||||
dev = netdev_priv(netdev);
|
||||
@@ -372,7 +372,7 @@ Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
|
||||
dev->dev = netdev;
|
||||
dev->port = port;
|
||||
dev->eth = eth;
|
||||
@@ -3762,9 +3788,8 @@ static int airoha_alloc_gdm_port(struct
|
||||
@@ -3743,9 +3769,8 @@ static int airoha_alloc_gdm_port(struct
|
||||
if (!port)
|
||||
return -ENOMEM;
|
||||
|
||||
@@ -385,7 +385,7 @@ Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
|
||||
err = airoha_metadata_dst_alloc(port);
|
||||
--- a/drivers/net/ethernet/airoha/airoha_eth.h
|
||||
+++ b/drivers/net/ethernet/airoha/airoha_eth.h
|
||||
@@ -227,8 +227,6 @@ struct airoha_tx_irq_queue {
|
||||
@@ -228,8 +228,6 @@ struct airoha_tx_irq_queue {
|
||||
};
|
||||
|
||||
struct airoha_hw_stats {
|
||||
@@ -394,7 +394,7 @@ Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
|
||||
struct u64_stats_sync syncp;
|
||||
|
||||
/* get_stats64 */
|
||||
@@ -572,6 +570,8 @@ struct airoha_gdm_dev {
|
||||
@@ -573,6 +571,8 @@ struct airoha_gdm_dev {
|
||||
|
||||
u32 flags;
|
||||
int nbq;
|
||||
@@ -403,7 +403,7 @@ Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
|
||||
};
|
||||
|
||||
struct airoha_gdm_port {
|
||||
@@ -579,7 +579,8 @@ struct airoha_gdm_port {
|
||||
@@ -580,7 +580,8 @@ struct airoha_gdm_port {
|
||||
int id;
|
||||
int users;
|
||||
|
||||
|
||||
+1
-1
@@ -18,7 +18,7 @@ Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
|
||||
|
||||
--- a/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
@@ -2362,17 +2362,9 @@ static u32 airoha_get_dsa_tag(struct sk_
|
||||
@@ -2345,17 +2345,9 @@ static u32 airoha_get_dsa_tag(struct sk_
|
||||
int airoha_get_fe_port(struct airoha_gdm_dev *dev)
|
||||
{
|
||||
struct airoha_gdm_port *port = dev->port;
|
||||
|
||||
@@ -0,0 +1,198 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
|
||||
#include "ar9344.dtsi"
|
||||
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
#include <dt-bindings/input/input.h>
|
||||
#include <dt-bindings/leds/common.h>
|
||||
|
||||
/ {
|
||||
compatible = "meraki,z1", "qca,ar9344";
|
||||
model = "Cisco Meraki Z1";
|
||||
|
||||
aliases {
|
||||
led-boot = &led_power_orange;
|
||||
led-failsafe = &led_power_orange;
|
||||
led-upgrade = &led_power_orange;
|
||||
label-mac-device = ð0;
|
||||
};
|
||||
|
||||
chosen {
|
||||
bootargs = "console=ttyS0,115200n8";
|
||||
};
|
||||
|
||||
keys {
|
||||
compatible = "gpio-keys";
|
||||
|
||||
reset {
|
||||
label = "Reset button";
|
||||
linux,code = <KEY_RESTART>;
|
||||
gpios = <&gpio 12 GPIO_ACTIVE_LOW>;
|
||||
debounce-interval = <60>;
|
||||
};
|
||||
};
|
||||
|
||||
leds {
|
||||
compatible = "gpio-leds";
|
||||
|
||||
led_power_orange: led-0 {
|
||||
function = LED_FUNCTION_POWER;
|
||||
color = <LED_COLOR_ID_ORANGE>;
|
||||
gpios = <&gpio 17 GPIO_ACTIVE_LOW>;
|
||||
default-state = "on";
|
||||
panic-indicator;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&ref {
|
||||
clock-frequency = <40000000>;
|
||||
};
|
||||
|
||||
&gpio {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&jtag_disable_pins>;
|
||||
|
||||
gpio_ext_lna0 {
|
||||
gpio-hog;
|
||||
gpios = <18 GPIO_ACTIVE_HIGH>;
|
||||
output-low;
|
||||
line-name = "z1:ext:lna0";
|
||||
};
|
||||
|
||||
gpio_ext_lna1 {
|
||||
gpio-hog;
|
||||
gpios = <19 GPIO_ACTIVE_HIGH>;
|
||||
output-low;
|
||||
line-name = "z1:ext:lna1";
|
||||
};
|
||||
};
|
||||
|
||||
&usb {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&usb_phy {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&pcie {
|
||||
status = "okay";
|
||||
|
||||
ath9k: wifi@0,0 {
|
||||
compatible = "pci168c,002a";
|
||||
reg = <0x0000 0 0 0 0>;
|
||||
qca,no-eeprom;
|
||||
nvmem-cells = <&macaddr_board_66 3>;
|
||||
nvmem-cell-names = "mac-address";
|
||||
};
|
||||
};
|
||||
|
||||
&wmac {
|
||||
status = "okay";
|
||||
qca,no-eeprom;
|
||||
|
||||
nvmem-cells = <&macaddr_board_66 2>;
|
||||
nvmem-cell-names = "mac-address";
|
||||
};
|
||||
|
||||
&nand {
|
||||
status = "okay";
|
||||
|
||||
nand-ecc-mode = "soft";
|
||||
nand-ecc-algo = "bch";
|
||||
nand-ecc-strength = <4>;
|
||||
nand-ecc-step-size = <512>;
|
||||
nand-is-boot-medium;
|
||||
|
||||
partitions {
|
||||
compatible = "fixed-partitions";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
||||
partition@0 {
|
||||
label = "loader1";
|
||||
reg = <0x0 0x20000>;
|
||||
read-only;
|
||||
};
|
||||
|
||||
partition@20000 {
|
||||
label = "kernel";
|
||||
reg = <0x20000 0x7e0000>;
|
||||
};
|
||||
|
||||
partition@800000 {
|
||||
label = "loader2";
|
||||
reg = <0x800000 0x20000>;
|
||||
read-only;
|
||||
};
|
||||
|
||||
partition@820000 {
|
||||
label = "recovery";
|
||||
reg = <0x820000 0x7e0000>;
|
||||
};
|
||||
|
||||
partition@1000000 {
|
||||
label = "ubi";
|
||||
reg = <0x1000000 0x6fe0000>;
|
||||
|
||||
volumes {
|
||||
ubi-volume-board-config {
|
||||
volname = "board-config";
|
||||
|
||||
nvmem-layout {
|
||||
compatible = "fixed-layout";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
||||
macaddr_board_66: macaddr@66 {
|
||||
compatible = "mac-base";
|
||||
reg = <0x66 0x6>;
|
||||
#nvmem-cell-cells = <1>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
partition@7fe0000 {
|
||||
label = "origcaldata";
|
||||
reg = <0x7fe0000 0x20000>;
|
||||
read-only;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&mdio0 {
|
||||
status = "okay";
|
||||
|
||||
phy0: ethernet-phy@0 {
|
||||
reg = <0>;
|
||||
phy-mode = "rgmii";
|
||||
|
||||
qca,ar8327-initvals = <
|
||||
0x04 0x07600000 /* PORT0 PAD MODE CTRL */
|
||||
0x7c 0x0000007e /* PORT0_STATUS */
|
||||
>;
|
||||
};
|
||||
};
|
||||
|
||||
ð0 {
|
||||
status = "okay";
|
||||
|
||||
pll-data = <0x06000000 0x00000101 0x00001313>;
|
||||
phy-mode = "rgmii-id";
|
||||
nvmem-cells = <&macaddr_board_66 0>;
|
||||
nvmem-cell-names = "mac-address";
|
||||
|
||||
fixed-link {
|
||||
speed = <1000>;
|
||||
full-duplex;
|
||||
};
|
||||
|
||||
gmac-config {
|
||||
device = <&gmac>;
|
||||
rgmii-gmac0 = <1>;
|
||||
switch-only-mode = <1>;
|
||||
};
|
||||
};
|
||||
@@ -19,6 +19,14 @@ define Build/meraki-header
|
||||
@mv $@.new $@
|
||||
endef
|
||||
|
||||
define Build/meraki-old-nand
|
||||
-$(STAGING_DIR_HOST)/bin/mkmerakifw-old \
|
||||
-B $(1) -s \
|
||||
-i $@ \
|
||||
-o $@.new
|
||||
@mv $@.new $@
|
||||
endef
|
||||
|
||||
# attention: only zlib compression is allowed for the boot fs
|
||||
define Build/zyxel-buildkerneljffs
|
||||
mkdir -p $@.tmp/boot
|
||||
@@ -322,6 +330,25 @@ define Device/meraki_mr18
|
||||
endef
|
||||
TARGET_DEVICES += meraki_mr18
|
||||
|
||||
define Device/meraki_z1
|
||||
SOC = ar9344
|
||||
DEVICE_VENDOR := Meraki
|
||||
DEVICE_MODEL := Z1
|
||||
DEVICE_PACKAGES := kmod-usb2 kmod-usb-ledtrig-usbport kmod-owl-loader \
|
||||
kmod-leds-uleds kmod-spi-gpio nu801 -uboot-envtools
|
||||
KERNEL_SIZE := 8064k
|
||||
BLOCKSIZE := 128k
|
||||
PAGESIZE := 2048
|
||||
LOADER_TYPE := bin
|
||||
LZMA_TEXT_START := 0x82800000
|
||||
KERNEL := kernel-bin | append-dtb | lzma | loader-kernel | \
|
||||
pad-to $$(BLOCKSIZE) | meraki-old-nand z1
|
||||
KERNEL_INITRAMFS := $$(KERNEL)
|
||||
IMAGE/sysupgrade.bin := sysupgrade-tar | append-metadata
|
||||
SUPPORTED_DEVICES += z1
|
||||
endef
|
||||
TARGET_DEVICES += meraki_z1
|
||||
|
||||
# fake rootfs is mandatory, pad-offset 129 equals (2 * uimage_header + '\0')
|
||||
define Device/netgear_ath79_nand
|
||||
DEVICE_VENDOR := NETGEAR
|
||||
|
||||
@@ -30,6 +30,9 @@ netgear,pgzng1)
|
||||
netgear,r6100)
|
||||
ucidef_set_led_netdev "wan-green" "WAN (green)" "green:wan" "eth1"
|
||||
;;
|
||||
meraki,z1)
|
||||
ucidef_set_led_default "diag" "DIAG" "green:tricolor" "1"
|
||||
;;
|
||||
netgear,wndr3700-v4|\
|
||||
netgear,wndr4300|\
|
||||
netgear,wndr4300sw|\
|
||||
|
||||
@@ -44,6 +44,10 @@ ath79_setup_interfaces()
|
||||
ucidef_add_switch "switch0" \
|
||||
"6u@eth1" "1:lan" "2:lan" "3:lan" "4:lan" "5:wan" "0u@eth0"
|
||||
;;
|
||||
meraki,z1)
|
||||
ucidef_add_switch "switch0" \
|
||||
"0@eth0" "1:lan" "2:lan" "3:lan" "4:lan" "5:wan"
|
||||
;;
|
||||
netgear,pgzng1)
|
||||
ucidef_set_interfaces_lan_wan "eth1" "eth0"
|
||||
;;
|
||||
@@ -104,6 +108,10 @@ ath79_setup_macs()
|
||||
wan_mac=$(mtd_get_mac_binary art 0x0)
|
||||
lan_mac=$(macaddr_add "$wan_mac" 1)
|
||||
;;
|
||||
meraki,z1)
|
||||
base_mac=$(mtd_get_mac_binary_ubi board-config 102)
|
||||
wan_mac=$(macaddr_add "$base_mac" 1)
|
||||
;;
|
||||
netgear,wndr3700-v4|\
|
||||
netgear,wndr4300|\
|
||||
netgear,wndr4300sw|\
|
||||
|
||||
@@ -18,6 +18,16 @@ case "$FIRMWARE" in
|
||||
caldata_extract "odm-caldata" 0x1000 0x440
|
||||
fi
|
||||
;;
|
||||
meraki,z1)
|
||||
. /lib/upgrade/nand.sh
|
||||
|
||||
if [ -n "$(nand_find_volume ubi0 caldata)" ]; then
|
||||
caldata_extract_ubi "caldata" 0x1000 0x800
|
||||
else
|
||||
caldata_extract "origcaldata" 0x1000 0x800
|
||||
ath9k_patch_mac $(macaddr_add $(mtd_get_mac_binary_ubi board-config 102) 2)
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
caldata_die "board $board is not supported yet"
|
||||
;;
|
||||
@@ -34,6 +44,16 @@ case "$FIRMWARE" in
|
||||
caldata_extract "odm-caldata" 0x5000 0x440
|
||||
fi
|
||||
;;
|
||||
meraki,z1)
|
||||
. /lib/upgrade/nand.sh
|
||||
|
||||
if [ -n "$(nand_find_volume ubi0 caldata)" ]; then
|
||||
caldata_extract_ubi "caldata" 0x15000 0x1000
|
||||
else
|
||||
caldata_extract "origcaldata" 0x15000 0x1000
|
||||
ath9k_patch_mac $(macaddr_add $(mtd_get_mac_binary_ubi board-config 102) 3)
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
caldata_die "board $board is not supported yet"
|
||||
;;
|
||||
|
||||
@@ -4,6 +4,9 @@
|
||||
board=$(board_name)
|
||||
|
||||
case "$board" in
|
||||
meraki,z1)
|
||||
migrate_leds ":tricolor0=:tricolor"
|
||||
;;
|
||||
esac
|
||||
|
||||
remove_devicename_leds
|
||||
|
||||
+19
-32
@@ -1,4 +1,4 @@
|
||||
From 60a23e663e0c607ae4ed871aaa24d257051ad557 Mon Sep 17 00:00:00 2001
|
||||
From 1ad83956d550a252fffc473a191dbe155c4a383e Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Golle <daniel@makrotopia.org>
|
||||
Date: Tue, 24 Mar 2026 17:56:35 +0000
|
||||
Subject: [PATCH 01/19] net: dsa: mxl862xx: store firmware version for feature
|
||||
@@ -8,15 +8,15 @@ Query the firmware version at init (already done in wait_ready),
|
||||
cache it in priv->fw_version, and provide MXL862XX_FW_VER_MIN()
|
||||
for version-gated code paths throughout the driver.
|
||||
|
||||
The union mxl862xx_fw_version lays out major/minor/revision so
|
||||
that the u32 raw field compares with natural version ordering on
|
||||
both big- and little-endian machines.
|
||||
MXL862XX_FW_VER() packs major/minor/revision into a u32 with
|
||||
bitwise shifts so that versions compare with natural ordering,
|
||||
independent of host endianness.
|
||||
|
||||
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
---
|
||||
drivers/net/dsa/mxl862xx/mxl862xx.c | 3 +++
|
||||
drivers/net/dsa/mxl862xx/mxl862xx.h | 36 +++++++++++++++++++++++++++++
|
||||
2 files changed, 39 insertions(+)
|
||||
drivers/net/dsa/mxl862xx/mxl862xx.h | 23 +++++++++++++++++++++++
|
||||
2 files changed, 26 insertions(+)
|
||||
|
||||
--- a/drivers/net/dsa/mxl862xx/mxl862xx.c
|
||||
+++ b/drivers/net/dsa/mxl862xx/mxl862xx.c
|
||||
@@ -40,46 +40,33 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
#include <linux/mdio.h>
|
||||
#include <linux/workqueue.h>
|
||||
#include <net/dsa.h>
|
||||
@@ -241,6 +242,38 @@ struct mxl862xx_port {
|
||||
@@ -241,6 +242,25 @@ struct mxl862xx_port {
|
||||
spinlock_t stats_lock; /* protects stats accumulators */
|
||||
};
|
||||
|
||||
+/**
|
||||
+ * union mxl862xx_fw_version - firmware version for comparison and display
|
||||
+ * struct mxl862xx_fw_version - firmware version for comparison and display
|
||||
+ * @major: firmware major version
|
||||
+ * @minor: firmware minor version
|
||||
+ * @revision: firmware revision number
|
||||
+ * @raw: combined u32 for direct >= comparison (major most significant)
|
||||
+ *
|
||||
+ * The struct layout places major in the most-significant byte of the
|
||||
+ * u32 on both big- and little-endian machines, so raw values compare
|
||||
+ * with the natural major > minor > revision ordering.
|
||||
+ */
|
||||
+union mxl862xx_fw_version {
|
||||
+ struct {
|
||||
+#if defined(__BIG_ENDIAN)
|
||||
+ u8 major;
|
||||
+ u8 minor;
|
||||
+ u16 revision;
|
||||
+#elif defined(__LITTLE_ENDIAN)
|
||||
+ u16 revision;
|
||||
+ u8 minor;
|
||||
+ u8 major;
|
||||
+#endif
|
||||
+ };
|
||||
+ u32 raw;
|
||||
+struct mxl862xx_fw_version {
|
||||
+ u8 major;
|
||||
+ u8 minor;
|
||||
+ u16 revision;
|
||||
+};
|
||||
+
|
||||
+#define MXL862XX_FW_VER(maj, min, rev) \
|
||||
+ ((union mxl862xx_fw_version){ .major = (maj), .minor = (min), \
|
||||
+ .revision = (rev) }).raw
|
||||
+ (((u32)(maj) << 24) | ((u32)(min) << 16) | (rev))
|
||||
+#define MXL862XX_FW_VER_MIN(priv, maj, min, rev) \
|
||||
+ ((priv)->fw_version.raw >= MXL862XX_FW_VER(maj, min, rev))
|
||||
+ (MXL862XX_FW_VER((priv)->fw_version.major, (priv)->fw_version.minor, \
|
||||
+ (priv)->fw_version.revision) >= \
|
||||
+ MXL862XX_FW_VER(maj, min, rev))
|
||||
+
|
||||
/* Bit indices for struct mxl862xx_priv::flags */
|
||||
#define MXL862XX_FLAG_CRC_ERR 0
|
||||
#define MXL862XX_FLAG_WORK_STOPPED 1
|
||||
@@ -258,6 +291,8 @@ struct mxl862xx_port {
|
||||
@@ -258,6 +278,8 @@ struct mxl862xx_port {
|
||||
* @drop_meter: index of the single shared zero-rate firmware meter
|
||||
* used to unconditionally drop traffic (used to block
|
||||
* flooding)
|
||||
@@ -88,11 +75,11 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
* @ports: per-port state, indexed by switch port number
|
||||
* @bridges: maps DSA bridge number to firmware bridge ID;
|
||||
* zero means no firmware bridge allocated for that
|
||||
@@ -275,6 +310,7 @@ struct mxl862xx_priv {
|
||||
@@ -275,6 +297,7 @@ struct mxl862xx_priv {
|
||||
struct work_struct crc_err_work;
|
||||
unsigned long flags;
|
||||
u16 drop_meter;
|
||||
+ union mxl862xx_fw_version fw_version;
|
||||
+ struct mxl862xx_fw_version fw_version;
|
||||
struct mxl862xx_port ports[MXL862XX_MAX_PORTS];
|
||||
u16 bridges[MXL862XX_MAX_BRIDGES + 1];
|
||||
u16 evlan_ingress_size;
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
From cefa0447dc95a4ddd5093f7b8cf35e654870283f Mon Sep 17 00:00:00 2001
|
||||
From eaf472bfc89692cd3cc5e0298c90791f4c1c3244 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Golle <daniel@makrotopia.org>
|
||||
Date: Wed, 25 Mar 2026 21:39:30 +0000
|
||||
Subject: [PATCH 02/19] net: dsa: mxl862xx: move phylink stubs to
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
From 3c1d77006daca1df20d612850535bc6050e266ee Mon Sep 17 00:00:00 2001
|
||||
From 483be884b2fdee28ac70458067c45a1369939144 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Golle <daniel@makrotopia.org>
|
||||
Date: Thu, 26 Mar 2026 01:50:00 +0000
|
||||
Subject: [PATCH 03/19] net: dsa: mxl862xx: move API macros to mxl862xx-host.h
|
||||
|
||||
+399
-597
File diff suppressed because it is too large
Load Diff
+82
-77
@@ -1,32 +1,54 @@
|
||||
From 3659914c43a587a1ca6418867834831aa518ac35 Mon Sep 17 00:00:00 2001
|
||||
From 74044a2d2e62fcc3ee2b6cf22742fa94609c529e Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Golle <daniel@makrotopia.org>
|
||||
Date: Tue, 24 Mar 2026 18:14:33 +0000
|
||||
Subject: [PATCH 05/19] net: dsa: mxl862xx: add SerDes ethtool statistics
|
||||
|
||||
Expose SerDes equalization and signal detect parameters as ethtool
|
||||
statistics on ports 9-16 (XPCS-backed ports). Uses the XPCS EQ_GET
|
||||
and SIGNAL_DETECT firmware commands to read TX/RX equalization
|
||||
coefficients, DFE taps, and link-level signal status.
|
||||
Expose SerDes equalization parameters as ethtool statistics on
|
||||
ports 9-16 (XPCS-backed ports). Uses the XPCS EQ_GET firmware
|
||||
command to read TX/RX equalization coefficients and DFE taps.
|
||||
|
||||
The 19 additional stats (serdes_tx_*, serdes_rx_*, serdes_pma_link,
|
||||
serdes_link_fault, serdes_in_reset) are appended after the standard
|
||||
RMON counters and gated on firmware >= 1.0.80.
|
||||
The 15 additional stats (serdes_tx_*, serdes_rx_*) are appended
|
||||
after the standard RMON counters and gated on firmware >= 1.0.84.
|
||||
|
||||
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
---
|
||||
drivers/net/dsa/mxl862xx/mxl862xx-api.h | 88 +++++++++++++++++++
|
||||
drivers/net/dsa/mxl862xx/mxl862xx-cmd.h | 2 +
|
||||
drivers/net/dsa/mxl862xx/mxl862xx-phylink.c | 93 +++++++++++++++++++++
|
||||
drivers/net/dsa/mxl862xx/mxl862xx-api.h | 92 +++++++++++++++++++
|
||||
drivers/net/dsa/mxl862xx/mxl862xx-cmd.h | 1 +
|
||||
drivers/net/dsa/mxl862xx/mxl862xx-phylink.c | 97 +++++++++++++++++++++
|
||||
drivers/net/dsa/mxl862xx/mxl862xx-phylink.h | 3 +
|
||||
drivers/net/dsa/mxl862xx/mxl862xx.c | 6 +-
|
||||
5 files changed, 191 insertions(+), 1 deletion(-)
|
||||
5 files changed, 198 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/net/dsa/mxl862xx/mxl862xx-api.h
|
||||
+++ b/drivers/net/dsa/mxl862xx/mxl862xx-api.h
|
||||
@@ -1812,4 +1812,92 @@ struct mxl862xx_xpcs_reset_cfg {
|
||||
@@ -1668,4 +1668,96 @@ struct mxl862xx_xpcs_pcs_link_up {
|
||||
__le16 result;
|
||||
} __packed;
|
||||
|
||||
+/**
|
||||
+ * struct mxl862xx_xpcs_loopback_cfg - loopback control
|
||||
+ * @port_id: XPCS port index
|
||||
+ * @mode: loopback mode. See &enum mxl862xx_xpcs_loopback_mode
|
||||
+ * @result: firmware result
|
||||
+ */
|
||||
+struct mxl862xx_xpcs_loopback_cfg {
|
||||
+ u8 port_id;
|
||||
+ u8 mode; /* enum mxl862xx_xpcs_loopback_mode */
|
||||
+ __le16 result;
|
||||
+} __packed;
|
||||
+
|
||||
+/**
|
||||
+ * struct mxl862xx_xpcs_reset_cfg - XPCS reset
|
||||
+ * @port_id: XPCS port index
|
||||
+ * @reset_type: reset type. See &enum mxl862xx_xpcs_reset_type
|
||||
+ * @result: firmware result
|
||||
+ */
|
||||
+struct mxl862xx_xpcs_reset_cfg {
|
||||
+ u8 port_id;
|
||||
+ u8 reset_type; /* enum mxl862xx_xpcs_reset_type */
|
||||
+ __le16 result;
|
||||
+} __packed;
|
||||
+
|
||||
+/**
|
||||
+ * struct mxl862xx_xpcs_eq_item - single equalization parameter
|
||||
+ * @value: current initial value
|
||||
@@ -94,42 +116,21 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
+ struct mxl862xx_xpcs_tx_eq_info tx;
|
||||
+ struct mxl862xx_xpcs_rx_eq_info rx;
|
||||
+} __packed;
|
||||
+
|
||||
+/**
|
||||
+ * struct mxl862xx_xpcs_signal_detect - signal detect status
|
||||
+ * @port_id: XPCS port index (0 or 1)
|
||||
+ * @rx_signal: RX signal detected
|
||||
+ * @pma_link: PMA link up
|
||||
+ * @link_fault: PCS link fault
|
||||
+ * @in_reset: XPCS in reset
|
||||
+ * @result: firmware result
|
||||
+ */
|
||||
+struct mxl862xx_xpcs_signal_detect {
|
||||
+ u8 port_id:2;
|
||||
+ u8 rx_signal:1;
|
||||
+ u8 pma_link:1;
|
||||
+ u8 link_fault:1;
|
||||
+ u8 in_reset:1;
|
||||
+ u8 __rsv:2;
|
||||
+ u8 __pad;
|
||||
+ __le16 result;
|
||||
+} __packed;
|
||||
+
|
||||
#endif /* __MXL862XX_API_H */
|
||||
--- a/drivers/net/dsa/mxl862xx/mxl862xx-cmd.h
|
||||
+++ b/drivers/net/dsa/mxl862xx/mxl862xx-cmd.h
|
||||
@@ -83,6 +83,8 @@
|
||||
#define MXL862XX_XPCS_FORCE_SPEED (MXL862XX_XPCS_MAGIC + 0x7)
|
||||
@@ -79,6 +79,7 @@
|
||||
#define MXL862XX_XPCS_PCS_LINK_UP (MXL862XX_XPCS_MAGIC + 0x7)
|
||||
#define MXL862XX_XPCS_LOOPBACK (MXL862XX_XPCS_MAGIC + 0x8)
|
||||
#define MXL862XX_XPCS_RESET (MXL862XX_XPCS_MAGIC + 0x9)
|
||||
+#define MXL862XX_XPCS_EQ_GET (MXL862XX_XPCS_MAGIC + 0xc)
|
||||
+#define MXL862XX_XPCS_SIGNAL_DETECT (MXL862XX_XPCS_MAGIC + 0xd)
|
||||
|
||||
#define MMD_API_MAXIMUM_ID 0x7fff
|
||||
|
||||
--- a/drivers/net/dsa/mxl862xx/mxl862xx-phylink.c
|
||||
+++ b/drivers/net/dsa/mxl862xx/mxl862xx-phylink.c
|
||||
@@ -439,3 +439,96 @@ const struct phylink_mac_ops mxl862xx_ph
|
||||
@@ -401,3 +401,100 @@ const struct phylink_mac_ops mxl862xx_ph
|
||||
.mac_link_up = mxl862xx_phylink_mac_link_up,
|
||||
.mac_select_pcs = mxl862xx_phylink_mac_select_pcs,
|
||||
};
|
||||
@@ -152,18 +153,19 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
+ "serdes_rx_dfe_bypass",
|
||||
+ "serdes_rx_adapt_mode",
|
||||
+ "serdes_rx_adapt_sel",
|
||||
+ "serdes_rx_signal",
|
||||
+ "serdes_pma_link",
|
||||
+ "serdes_link_fault",
|
||||
+ "serdes_in_reset",
|
||||
+};
|
||||
+
|
||||
+static bool mxl862xx_port_has_serdes_stats(struct dsa_switch *ds, int port)
|
||||
+{
|
||||
+ struct mxl862xx_priv *priv = ds->priv;
|
||||
+
|
||||
+ return port >= 9 && port <= 16 &&
|
||||
+ MXL862XX_FW_VER_MIN(priv, 1, 0, 80);
|
||||
+ /* Firmware reads EQ/signal status per XPCS, not per lane. Expose
|
||||
+ * the stats only on the slot-0 port of each XPCS (9 and 13) so
|
||||
+ * users don't see four duplicate copies labelled as if they were
|
||||
+ * independent per-port readings.
|
||||
+ */
|
||||
+ return (port == 9 || port == 13) &&
|
||||
+ MXL862XX_FW_VER_MIN(priv, 1, 0, 84);
|
||||
+}
|
||||
+
|
||||
+int mxl862xx_serdes_stats_count(struct dsa_switch *ds, int port)
|
||||
@@ -185,50 +187,53 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
+ ethtool_puts(&data, mxl862xx_serdes_stats[i]);
|
||||
+}
|
||||
+
|
||||
+static u64 mxl862xx_eq_effective(const struct mxl862xx_xpcs_eq_item *it)
|
||||
+{
|
||||
+ return it->ovrd_en ? it->ovrd : it->value;
|
||||
+}
|
||||
+
|
||||
+void mxl862xx_serdes_get_stats(struct dsa_switch *ds, int port, u64 *data)
|
||||
+{
|
||||
+ struct mxl862xx_xpcs_eq_get eq = {
|
||||
+ .port_id = mxl862xx_xpcs_port_id(port),
|
||||
+ .port_id = MXL862XX_SERDES_PORT_ID(port),
|
||||
+ };
|
||||
+ struct mxl862xx_xpcs_signal_detect sig = {};
|
||||
+ int ret;
|
||||
+
|
||||
+ if (!mxl862xx_port_has_serdes_stats(ds, port))
|
||||
+ return;
|
||||
+
|
||||
+ sig.port_id = mxl862xx_xpcs_port_id(port);
|
||||
+
|
||||
+ if (!MXL862XX_API_READ(ds->priv, MXL862XX_XPCS_EQ_GET, eq)) {
|
||||
+ *data++ = eq.tx.main.value;
|
||||
+ *data++ = eq.tx.pre.value;
|
||||
+ *data++ = eq.tx.post.value;
|
||||
+ *data++ = eq.tx.iboost_lvl.value;
|
||||
+ *data++ = eq.tx.vboost_lvl.value;
|
||||
+ *data++ = eq.tx.vboost_en.value;
|
||||
+ *data++ = eq.rx.att_lvl.value;
|
||||
+ *data++ = eq.rx.vga1_gain.value;
|
||||
+ *data++ = eq.rx.vga2_gain.value;
|
||||
+ *data++ = eq.rx.ctle_boost.value;
|
||||
+ *data++ = eq.rx.ctle_pole.value;
|
||||
+ *data++ = eq.rx.dfe_tap1.value;
|
||||
+ *data++ = eq.rx.dfe_bypass.value;
|
||||
+ *data++ = eq.rx.adapt_mode.value;
|
||||
+ *data++ = eq.rx.adapt_sel.value;
|
||||
+ } else {
|
||||
+ data += 15;
|
||||
+ ret = MXL862XX_API_READ(ds->priv, MXL862XX_XPCS_EQ_GET, eq);
|
||||
+ if (ret) {
|
||||
+ dev_err(ds->dev,
|
||||
+ "port %d: XPCS EQ_GET failed: %d\n", port, ret);
|
||||
+ return;
|
||||
+ }
|
||||
+ if ((s16)le16_to_cpu(eq.result) < 0) {
|
||||
+ dev_err(ds->dev,
|
||||
+ "port %d: XPCS EQ_GET firmware result: %d\n",
|
||||
+ port, (s16)le16_to_cpu(eq.result));
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ if (!MXL862XX_API_READ(ds->priv, MXL862XX_XPCS_SIGNAL_DETECT, sig)) {
|
||||
+ *data++ = sig.rx_signal;
|
||||
+ *data++ = sig.pma_link;
|
||||
+ *data++ = sig.link_fault;
|
||||
+ *data++ = sig.in_reset;
|
||||
+ } else {
|
||||
+ data += 4;
|
||||
+ }
|
||||
+ *data++ = mxl862xx_eq_effective(&eq.tx.main);
|
||||
+ *data++ = mxl862xx_eq_effective(&eq.tx.pre);
|
||||
+ *data++ = mxl862xx_eq_effective(&eq.tx.post);
|
||||
+ *data++ = mxl862xx_eq_effective(&eq.tx.iboost_lvl);
|
||||
+ *data++ = mxl862xx_eq_effective(&eq.tx.vboost_lvl);
|
||||
+ *data++ = mxl862xx_eq_effective(&eq.tx.vboost_en);
|
||||
+ *data++ = mxl862xx_eq_effective(&eq.rx.att_lvl);
|
||||
+ *data++ = mxl862xx_eq_effective(&eq.rx.vga1_gain);
|
||||
+ *data++ = mxl862xx_eq_effective(&eq.rx.vga2_gain);
|
||||
+ *data++ = mxl862xx_eq_effective(&eq.rx.ctle_boost);
|
||||
+ *data++ = mxl862xx_eq_effective(&eq.rx.ctle_pole);
|
||||
+ *data++ = mxl862xx_eq_effective(&eq.rx.dfe_tap1);
|
||||
+ *data++ = mxl862xx_eq_effective(&eq.rx.dfe_bypass);
|
||||
+ *data++ = mxl862xx_eq_effective(&eq.rx.adapt_mode);
|
||||
+ *data++ = mxl862xx_eq_effective(&eq.rx.adapt_sel);
|
||||
+}
|
||||
--- a/drivers/net/dsa/mxl862xx/mxl862xx-phylink.h
|
||||
+++ b/drivers/net/dsa/mxl862xx/mxl862xx-phylink.h
|
||||
@@ -12,5 +12,8 @@ void mxl862xx_phylink_get_caps(struct ds
|
||||
@@ -17,5 +17,8 @@ void mxl862xx_phylink_get_caps(struct ds
|
||||
struct phylink_config *config);
|
||||
void mxl862xx_setup_pcs(struct mxl862xx_priv *priv, struct mxl862xx_pcs *pcs,
|
||||
int port);
|
||||
@@ -239,7 +244,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
#endif /* __MXL862XX_PHYLINK_H */
|
||||
--- a/drivers/net/dsa/mxl862xx/mxl862xx.c
|
||||
+++ b/drivers/net/dsa/mxl862xx/mxl862xx.c
|
||||
@@ -1775,6 +1775,8 @@ static void mxl862xx_get_strings(struct
|
||||
@@ -1776,6 +1776,8 @@ static void mxl862xx_get_strings(struct
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(mxl862xx_mib); i++)
|
||||
ethtool_puts(&data, mxl862xx_mib[i].name);
|
||||
@@ -248,7 +253,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
}
|
||||
|
||||
static int mxl862xx_get_sset_count(struct dsa_switch *ds, int port, int sset)
|
||||
@@ -1782,7 +1784,7 @@ static int mxl862xx_get_sset_count(struc
|
||||
@@ -1783,7 +1785,7 @@ static int mxl862xx_get_sset_count(struc
|
||||
if (sset != ETH_SS_STATS)
|
||||
return 0;
|
||||
|
||||
@@ -257,7 +262,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
}
|
||||
|
||||
static int mxl862xx_read_rmon(struct dsa_switch *ds, int port,
|
||||
@@ -1818,6 +1820,8 @@ static void mxl862xx_get_ethtool_stats(s
|
||||
@@ -1819,6 +1821,8 @@ static void mxl862xx_get_ethtool_stats(s
|
||||
else
|
||||
*data++ = le64_to_cpu(*(__le64 *)field);
|
||||
}
|
||||
|
||||
-208
@@ -1,208 +0,0 @@
|
||||
From ce66c0be462c8500dfc483395e68be4326ebf296 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Golle <daniel@makrotopia.org>
|
||||
Date: Tue, 24 Mar 2026 18:15:32 +0000
|
||||
Subject: [PATCH 06/19] net: dsa: mxl862xx: add SerDes self-test via PRBS and
|
||||
BERT
|
||||
|
||||
Implement the dsa_switch_ops.self_test callback for SerDes ports
|
||||
(9-16). Two loopback tests are run:
|
||||
|
||||
1. PCS-level PRBS31: enables TX/RX PRBS31 pattern at the PCS layer,
|
||||
waits 100ms, then reads the error counter.
|
||||
2. SerDes-level BERT PRBS31: enables TX/RX BERT with PRBS31 pattern
|
||||
at the SerDes layer, waits 100ms, then reads the error counter.
|
||||
|
||||
Both tests clean up (disable pattern generators) regardless of outcome.
|
||||
Gated on firmware >= 1.0.80 via mxl862xx_port_has_serdes_stats().
|
||||
|
||||
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
---
|
||||
drivers/net/dsa/mxl862xx/mxl862xx-api.h | 45 +++++++++++
|
||||
drivers/net/dsa/mxl862xx/mxl862xx-cmd.h | 2 +
|
||||
drivers/net/dsa/mxl862xx/mxl862xx-phylink.c | 85 +++++++++++++++++++++
|
||||
drivers/net/dsa/mxl862xx/mxl862xx-phylink.h | 3 +
|
||||
drivers/net/dsa/mxl862xx/mxl862xx.c | 1 +
|
||||
5 files changed, 136 insertions(+)
|
||||
|
||||
--- a/drivers/net/dsa/mxl862xx/mxl862xx-api.h
|
||||
+++ b/drivers/net/dsa/mxl862xx/mxl862xx-api.h
|
||||
@@ -1900,4 +1900,49 @@ struct mxl862xx_xpcs_signal_detect {
|
||||
__le16 result;
|
||||
} __packed;
|
||||
|
||||
+/**
|
||||
+ * struct mxl862xx_xpcs_prbs_cfg - PCS-level PRBS31 test pattern
|
||||
+ * @port_id: XPCS port index (0 or 1)
|
||||
+ * @tx_en: TX PRBS31 enable
|
||||
+ * @rx_en: RX PRBS31 enable
|
||||
+ * @read_err: read error count
|
||||
+ * @rx_err_cnt: RX PRBS31 error count (valid when read_err=1)
|
||||
+ * @result: firmware result
|
||||
+ */
|
||||
+struct mxl862xx_xpcs_prbs_cfg {
|
||||
+ u8 port_id:2;
|
||||
+ u8 tx_en:1;
|
||||
+ u8 rx_en:1;
|
||||
+ u8 read_err:1;
|
||||
+ u8 __rsv:3;
|
||||
+ u8 __pad;
|
||||
+ __le16 rx_err_cnt;
|
||||
+ __le16 result;
|
||||
+} __packed;
|
||||
+
|
||||
+/**
|
||||
+ * struct mxl862xx_xpcs_bert_cfg - SerDes-level BERT test pattern
|
||||
+ * @port_id: XPCS port index (0 or 1)
|
||||
+ * @tx_en: TX BERT enable
|
||||
+ * @rx_en: RX BERT enable
|
||||
+ * @read_err: read RX error count
|
||||
+ * @clear_err: clear RX error counter
|
||||
+ * @insert_err: insert one TX error
|
||||
+ * @pattern: PRBS pattern type (1-7; 0 = disable)
|
||||
+ * @rx_err_cnt: RX BERT error count (valid when read_err=1)
|
||||
+ * @result: firmware result
|
||||
+ */
|
||||
+struct mxl862xx_xpcs_bert_cfg {
|
||||
+ u8 port_id:2;
|
||||
+ u8 tx_en:1;
|
||||
+ u8 rx_en:1;
|
||||
+ u8 read_err:1;
|
||||
+ u8 clear_err:1;
|
||||
+ u8 insert_err:1;
|
||||
+ u8 __rsv:1;
|
||||
+ u8 pattern;
|
||||
+ __le16 rx_err_cnt;
|
||||
+ __le16 result;
|
||||
+} __packed;
|
||||
+
|
||||
#endif /* __MXL862XX_API_H */
|
||||
--- a/drivers/net/dsa/mxl862xx/mxl862xx-cmd.h
|
||||
+++ b/drivers/net/dsa/mxl862xx/mxl862xx-cmd.h
|
||||
@@ -83,6 +83,8 @@
|
||||
#define MXL862XX_XPCS_FORCE_SPEED (MXL862XX_XPCS_MAGIC + 0x7)
|
||||
#define MXL862XX_XPCS_LOOPBACK (MXL862XX_XPCS_MAGIC + 0x8)
|
||||
#define MXL862XX_XPCS_RESET (MXL862XX_XPCS_MAGIC + 0x9)
|
||||
+#define MXL862XX_XPCS_PRBS_CFG (MXL862XX_XPCS_MAGIC + 0xa)
|
||||
+#define MXL862XX_XPCS_BERT_CFG (MXL862XX_XPCS_MAGIC + 0xb)
|
||||
#define MXL862XX_XPCS_EQ_GET (MXL862XX_XPCS_MAGIC + 0xc)
|
||||
#define MXL862XX_XPCS_SIGNAL_DETECT (MXL862XX_XPCS_MAGIC + 0xd)
|
||||
|
||||
--- a/drivers/net/dsa/mxl862xx/mxl862xx-phylink.c
|
||||
+++ b/drivers/net/dsa/mxl862xx/mxl862xx-phylink.c
|
||||
@@ -532,3 +532,88 @@ void mxl862xx_serdes_get_stats(struct ds
|
||||
data += 4;
|
||||
}
|
||||
}
|
||||
+
|
||||
+void mxl862xx_serdes_self_test(struct dsa_switch *ds, int port,
|
||||
+ struct ethtool_test *etest, u64 *data)
|
||||
+{
|
||||
+ struct mxl862xx_xpcs_prbs_cfg prbs = {};
|
||||
+ struct mxl862xx_xpcs_bert_cfg bert = {};
|
||||
+ struct mxl862xx_priv *priv = ds->priv;
|
||||
+ int xpcs_id = mxl862xx_xpcs_port_id(port);
|
||||
+ int i = 0;
|
||||
+ int ret;
|
||||
+
|
||||
+ if (!mxl862xx_port_has_serdes_stats(ds, port))
|
||||
+ return;
|
||||
+
|
||||
+ /* Test 1: PCS PRBS31 */
|
||||
+ prbs.port_id = xpcs_id;
|
||||
+ prbs.tx_en = 1;
|
||||
+ prbs.rx_en = 1;
|
||||
+ ret = MXL862XX_API_WRITE(priv, MXL862XX_XPCS_PRBS_CFG, prbs);
|
||||
+ if (ret) {
|
||||
+ data[i++] = 1;
|
||||
+ goto skip_prbs;
|
||||
+ }
|
||||
+
|
||||
+ msleep(100);
|
||||
+
|
||||
+ memset(&prbs, 0, sizeof(prbs));
|
||||
+ prbs.port_id = xpcs_id;
|
||||
+ prbs.read_err = 1;
|
||||
+ ret = MXL862XX_API_READ(priv, MXL862XX_XPCS_PRBS_CFG, prbs);
|
||||
+
|
||||
+ /* Disable PRBS */
|
||||
+ memset(&prbs, 0, sizeof(prbs));
|
||||
+ prbs.port_id = xpcs_id;
|
||||
+ MXL862XX_API_WRITE(priv, MXL862XX_XPCS_PRBS_CFG, prbs);
|
||||
+
|
||||
+ if (ret) {
|
||||
+ data[i++] = 1;
|
||||
+ } else {
|
||||
+ data[i] = le16_to_cpu(prbs.rx_err_cnt) ? 1 : 0;
|
||||
+ if (data[i])
|
||||
+ etest->flags |= ETH_TEST_FL_FAILED;
|
||||
+ i++;
|
||||
+ }
|
||||
+
|
||||
+skip_prbs:
|
||||
+ /* Test 2: SerDes BERT PRBS31 -- clear error counter first */
|
||||
+ bert.port_id = xpcs_id;
|
||||
+ bert.clear_err = 1;
|
||||
+ MXL862XX_API_WRITE(priv, MXL862XX_XPCS_BERT_CFG, bert);
|
||||
+
|
||||
+ /* Enable BERT with PRBS31 pattern */
|
||||
+ memset(&bert, 0, sizeof(bert));
|
||||
+ bert.port_id = xpcs_id;
|
||||
+ bert.tx_en = 1;
|
||||
+ bert.rx_en = 1;
|
||||
+ bert.pattern = 6; /* PRBS31 */
|
||||
+ ret = MXL862XX_API_WRITE(priv, MXL862XX_XPCS_BERT_CFG, bert);
|
||||
+ if (ret) {
|
||||
+ data[i++] = 1;
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ msleep(100);
|
||||
+
|
||||
+ /* Read error count */
|
||||
+ memset(&bert, 0, sizeof(bert));
|
||||
+ bert.port_id = xpcs_id;
|
||||
+ bert.read_err = 1;
|
||||
+ ret = MXL862XX_API_READ(priv, MXL862XX_XPCS_BERT_CFG, bert);
|
||||
+
|
||||
+ /* Disable BERT */
|
||||
+ memset(&bert, 0, sizeof(bert));
|
||||
+ bert.port_id = xpcs_id;
|
||||
+ MXL862XX_API_WRITE(priv, MXL862XX_XPCS_BERT_CFG, bert);
|
||||
+
|
||||
+ if (ret) {
|
||||
+ data[i++] = 1;
|
||||
+ } else {
|
||||
+ data[i] = le16_to_cpu(bert.rx_err_cnt) ? 1 : 0;
|
||||
+ if (data[i])
|
||||
+ etest->flags |= ETH_TEST_FL_FAILED;
|
||||
+ i++;
|
||||
+ }
|
||||
+}
|
||||
--- a/drivers/net/dsa/mxl862xx/mxl862xx-phylink.h
|
||||
+++ b/drivers/net/dsa/mxl862xx/mxl862xx-phylink.h
|
||||
@@ -3,6 +3,7 @@
|
||||
#ifndef __MXL862XX_PHYLINK_H
|
||||
#define __MXL862XX_PHYLINK_H
|
||||
|
||||
+#include <linux/ethtool.h>
|
||||
#include <linux/phylink.h>
|
||||
|
||||
#include "mxl862xx.h"
|
||||
@@ -15,5 +16,7 @@ void mxl862xx_setup_pcs(struct mxl862xx_
|
||||
int mxl862xx_serdes_stats_count(struct dsa_switch *ds, int port);
|
||||
void mxl862xx_serdes_get_strings(struct dsa_switch *ds, int port, u8 *data);
|
||||
void mxl862xx_serdes_get_stats(struct dsa_switch *ds, int port, u64 *data);
|
||||
+void mxl862xx_serdes_self_test(struct dsa_switch *ds, int port,
|
||||
+ struct ethtool_test *etest, u64 *data);
|
||||
|
||||
#endif /* __MXL862XX_PHYLINK_H */
|
||||
--- a/drivers/net/dsa/mxl862xx/mxl862xx.c
|
||||
+++ b/drivers/net/dsa/mxl862xx/mxl862xx.c
|
||||
@@ -2088,6 +2088,7 @@ static const struct dsa_switch_ops mxl86
|
||||
.get_pause_stats = mxl862xx_get_pause_stats,
|
||||
.get_rmon_stats = mxl862xx_get_rmon_stats,
|
||||
.get_stats64 = mxl862xx_get_stats64,
|
||||
+ .self_test = mxl862xx_serdes_self_test,
|
||||
};
|
||||
|
||||
static int mxl862xx_probe(struct mdio_device *mdiodev)
|
||||
+70
-46
@@ -1,7 +1,7 @@
|
||||
From e6defbd42db6e64c2bb203f82b7d7f8c0691a052 Mon Sep 17 00:00:00 2001
|
||||
From 50a84327282120a51af12da91214ed9e06f585cb Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Golle <daniel@makrotopia.org>
|
||||
Date: Tue, 24 Mar 2026 18:51:13 +0000
|
||||
Subject: [PATCH 07/19] net: dsa: mxl862xx: trap link-local and multicast
|
||||
Subject: [PATCH 06/19] net: dsa: mxl862xx: trap link-local and multicast
|
||||
snooping frames to CPU
|
||||
|
||||
Install per-CTP PCE rules on each user port that trap IEEE 802.1D
|
||||
@@ -19,10 +19,21 @@ all flood modes enabled. Each trap rule points the bridge engine at
|
||||
this FID via bFidEnable so that IGMP and MLD frames are never
|
||||
silently dropped by the ingress port's private flood policy.
|
||||
|
||||
Three multicast snooping rules are installed per port:
|
||||
offset 2 -- IPv4 IGMP (IP protocol 2, all versions)
|
||||
offset 3 -- ICMPv6 types 130-132 (MLDv1 query, report, done)
|
||||
offset 4 -- ICMPv6 type 143 (MLDv2 Listener Report)
|
||||
Rules are written through the firmware's logical-index API,
|
||||
GSW_TFLOW_PCERULELOGICWRITE. The firmware translates the logical
|
||||
index in @rule->pattern.index into a physical position within the
|
||||
per-CTP block selected by @rule->region and @rule->logicalportid,
|
||||
and grows the hardware block size on demand as rules are inserted.
|
||||
A single dispatch helper, mxl862xx_pce_rule_write(), centralises the
|
||||
firmware command so the trap callers do not need to know which API
|
||||
variant is used. Four logical indices are consumed in each port's
|
||||
per-CTP block (index 0 is reserved by the firmware for its
|
||||
flow-control marking rule):
|
||||
|
||||
index 1 -- IEEE 802.1D link-local (dst 01:80:c2:00:00:0x)
|
||||
index 2 -- IPv4 IGMP (IP protocol 2, all versions)
|
||||
index 3 -- ICMPv6 types 130-132 (MLDv1 query, report, done)
|
||||
index 4 -- ICMPv6 type 143 (MLDv2 Listener Report)
|
||||
|
||||
Add the PCE rule firmware API structures, command definitions, and
|
||||
the rule block allocation interface.
|
||||
@@ -30,15 +41,15 @@ the rule block allocation interface.
|
||||
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
---
|
||||
drivers/net/dsa/mxl862xx/mxl862xx-api.h | 684 ++++++++++++++++++++++++
|
||||
drivers/net/dsa/mxl862xx/mxl862xx-cmd.h | 5 +
|
||||
drivers/net/dsa/mxl862xx/mxl862xx.c | 186 +++++++
|
||||
drivers/net/dsa/mxl862xx/mxl862xx-cmd.h | 6 +
|
||||
drivers/net/dsa/mxl862xx/mxl862xx.c | 198 +++++++
|
||||
drivers/net/dsa/mxl862xx/mxl862xx.h | 8 +
|
||||
4 files changed, 883 insertions(+)
|
||||
4 files changed, 896 insertions(+)
|
||||
|
||||
--- a/drivers/net/dsa/mxl862xx/mxl862xx-api.h
|
||||
+++ b/drivers/net/dsa/mxl862xx/mxl862xx-api.h
|
||||
@@ -1420,6 +1420,690 @@ struct mxl862xx_port_link_cfg {
|
||||
u8 lpi;
|
||||
@@ -1184,6 +1184,690 @@ struct mxl862xx_ctp_port_assignment {
|
||||
__le16 bridge_port_id;
|
||||
} __packed;
|
||||
|
||||
+/* PCE (Packet Classification Engine) rule structures.
|
||||
@@ -694,7 +705,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
+ * @action: Forwarding action (portmap, cross-state, etc.)
|
||||
+ *
|
||||
+ * This structure is passed to the firmware via the MDIO data
|
||||
+ * buffer using the %MXL862XX_TFLOW_PCERULEWRITE command.
|
||||
+ * buffer using the %MXL862XX_TFLOW_PCERULELOGICWRITE command.
|
||||
+ * The binary layout must exactly match the firmware's
|
||||
+ * GSW_PCE_rule_t (466 bytes, packed, little-endian scalars).
|
||||
+ */
|
||||
@@ -738,13 +749,14 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
#define MXL862XX_BRDG_MAGIC 0x300
|
||||
#define MXL862XX_BRDGPORT_MAGIC 0x400
|
||||
#define MXL862XX_CTP_MAGIC 0x500
|
||||
@@ -31,6 +32,10 @@
|
||||
@@ -30,6 +31,11 @@
|
||||
#define MXL862XX_COMMON_CFGSET (MXL862XX_COMMON_MAGIC + 0xa)
|
||||
#define MXL862XX_COMMON_REGISTERMOD (MXL862XX_COMMON_MAGIC + 0x11)
|
||||
|
||||
+#define MXL862XX_TFLOW_PCERULEWRITE (MXL862XX_TFLOW_MAGIC + 0x2)
|
||||
+#define MXL862XX_TFLOW_PCERULEALLOC (MXL862XX_TFLOW_MAGIC + 0x4)
|
||||
+#define MXL862XX_TFLOW_PCERULEFREE (MXL862XX_TFLOW_MAGIC + 0x5)
|
||||
+#define MXL862XX_TFLOW_PCERULELOGICWRITE \
|
||||
+ (MXL862XX_TFLOW_MAGIC + 0xa)
|
||||
+
|
||||
#define MXL862XX_BRIDGE_ALLOC (MXL862XX_BRDG_MAGIC + 0x1)
|
||||
#define MXL862XX_BRIDGE_CONFIGSET (MXL862XX_BRDG_MAGIC + 0x2)
|
||||
@@ -771,21 +783,35 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
return 0;
|
||||
|
||||
not_ready_yet:
|
||||
@@ -381,6 +384,158 @@ static int mxl862xx_setup_drop_meter(str
|
||||
@@ -381,6 +384,170 @@ static int mxl862xx_setup_drop_meter(str
|
||||
return MXL862XX_API_WRITE(priv, MXL862XX_COMMON_REGISTERMOD, reg);
|
||||
}
|
||||
|
||||
+
|
||||
+/* Per-CTP offsets for protocol trap rules. Each port's CTP flow-table
|
||||
+ * block is pre-allocated by the firmware during init (44 entries per
|
||||
+ * port on a 10-port SKU, of which offset 0 is reserved for flow-control
|
||||
+ * marking). Offsets 1-4 are used for link-local and multicast snooping
|
||||
+ * traps; all others remain free.
|
||||
+/* Per-CTP logical indices for protocol trap rules.
|
||||
+ *
|
||||
+ * The firmware pre-allocates a per-CTP PCE block for every port during
|
||||
+ * init and reserves logical index 0 for its flow-control marking rule.
|
||||
+ * Logical indices 1-4 are used here for link-local and multicast
|
||||
+ * snooping traps; the firmware grows the underlying hardware block on
|
||||
+ * demand as PCERULELOGICWRITE inserts new entries.
|
||||
+ */
|
||||
+#define MXL862XX_LINK_LOCAL_CTP_OFFSET 1
|
||||
+#define MXL862XX_IGMP_CTP_OFFSET 2
|
||||
+#define MXL862XX_MLDV1_CTP_OFFSET 3
|
||||
+#define MXL862XX_MLDV2_CTP_OFFSET 4
|
||||
+#define MXL862XX_LINK_LOCAL_CTP_INDEX 1
|
||||
+#define MXL862XX_IGMP_CTP_INDEX 2
|
||||
+#define MXL862XX_MLDV1_CTP_INDEX 3
|
||||
+#define MXL862XX_MLDV2_CTP_INDEX 4
|
||||
+
|
||||
+/* Install (or overwrite) a PCE rule via the firmware's logical-index
|
||||
+ * API. The firmware translates the logical index in @rule->pattern.index
|
||||
+ * to a physical position within the block selected by @rule->region and
|
||||
+ * @rule->logicalportid, and expands the hardware block size as needed.
|
||||
+ */
|
||||
+static int mxl862xx_pce_rule_write(struct mxl862xx_priv *priv,
|
||||
+ struct mxl862xx_pce_rule *rule)
|
||||
+{
|
||||
+ return MXL862XX_API_WRITE(priv, MXL862XX_TFLOW_PCERULELOGICWRITE,
|
||||
+ *rule);
|
||||
+}
|
||||
+
|
||||
+/* Fill the action fields of a PCE rule that traps ingress frames to
|
||||
+ * the CPU port. Used by both the link-local trap and the multicast
|
||||
@@ -826,12 +852,9 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
+ * The firmware does not install this rule by default because its own
|
||||
+ * STP module is not used when DSA manages STP.
|
||||
+ *
|
||||
+ * The rule is written into the port's per-CTP flow table at offset 1.
|
||||
+ * The firmware already allocates a 44-entry block for every CTP during
|
||||
+ * init (8 entries exposed initially, expandable), so no dynamic
|
||||
+ * allocation via PCERULEALLOC is needed. Using region=CTP causes the
|
||||
+ * firmware to translate the CTP-relative offset into an absolute
|
||||
+ * hardware index.
|
||||
+ * The rule is written into the port's per-CTP flow table at logical
|
||||
+ * index 1 using PCERULELOGICWRITE, which selects the per-CTP block via
|
||||
+ * @region and @logicalportid and grows the block on demand.
|
||||
+ *
|
||||
+ * Cross-state is enabled so that link-local frames reach the CPU even
|
||||
+ * when the bridge port is in BLOCKING or LEARNING state.
|
||||
@@ -844,7 +867,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
+ rule.logicalportid = port;
|
||||
+ rule.region = cpu_to_le32(MXL862XX_PCE_RULE_CTP);
|
||||
+
|
||||
+ rule.pattern.index = cpu_to_le16(MXL862XX_LINK_LOCAL_CTP_OFFSET);
|
||||
+ rule.pattern.index = cpu_to_le16(MXL862XX_LINK_LOCAL_CTP_INDEX);
|
||||
+ rule.pattern.enable = 1;
|
||||
+ rule.pattern.mac_dst_enable = 1;
|
||||
+ memcpy(rule.pattern.mac_dst, eth_reserved_addr_base, ETH_ALEN);
|
||||
@@ -852,7 +875,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
+
|
||||
+ mxl862xx_fill_cpu_trap_action(ds, port, &rule);
|
||||
+
|
||||
+ return MXL862XX_API_WRITE(priv, MXL862XX_TFLOW_PCERULEWRITE, rule);
|
||||
+ return mxl862xx_pce_rule_write(priv, &rule);
|
||||
+}
|
||||
+
|
||||
+/* Install PCE rules that trap IGMP and MLD frames to the CPU port for
|
||||
@@ -862,10 +885,11 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
+ * never classified as blocked unknown MC regardless of the ingress
|
||||
+ * port's standalone flood policy.
|
||||
+ *
|
||||
+ * Three rules are installed per port:
|
||||
+ * offset 2 -- IPv4 IGMP (IP protocol 2, all versions)
|
||||
+ * offset 3 -- ICMPv6 types 130-132 (MLDv1 query, report, done)
|
||||
+ * offset 4 -- ICMPv6 type 143 (MLDv2 Listener Report)
|
||||
+ * Three rules are installed per port at logical indices in the per-CTP
|
||||
+ * block:
|
||||
+ * index 2 -- IPv4 IGMP (IP protocol 2, all versions)
|
||||
+ * index 3 -- ICMPv6 types 130-132 (MLDv1 query, report, done)
|
||||
+ * index 4 -- ICMPv6 type 143 (MLDv2 Listener Report)
|
||||
+ *
|
||||
+ * The MLDv1 rule uses range mode on the first two bytes after the IP
|
||||
+ * header (ICMPv6 type + code): lower bound 0x8200 (type 130, code 0)
|
||||
@@ -883,12 +907,12 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
+ mxl862xx_fill_cpu_trap_action(ds, port, &rule);
|
||||
+
|
||||
+ /* IGMP: IPv4 protocol 2, all versions */
|
||||
+ rule.pattern.index = cpu_to_le16(MXL862XX_IGMP_CTP_OFFSET);
|
||||
+ rule.pattern.index = cpu_to_le16(MXL862XX_IGMP_CTP_INDEX);
|
||||
+ rule.pattern.enable = 1;
|
||||
+ rule.pattern.protocol = IPPROTO_IGMP;
|
||||
+ rule.pattern.protocol_enable = 1;
|
||||
+
|
||||
+ ret = MXL862XX_API_WRITE(priv, MXL862XX_TFLOW_PCERULEWRITE, rule);
|
||||
+ ret = mxl862xx_pce_rule_write(priv, &rule);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
@@ -896,7 +920,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
+ * Range mode covers all three types with any code value.
|
||||
+ */
|
||||
+ memset(&rule.pattern, 0, sizeof(rule.pattern));
|
||||
+ rule.pattern.index = cpu_to_le16(MXL862XX_MLDV1_CTP_OFFSET);
|
||||
+ rule.pattern.index = cpu_to_le16(MXL862XX_MLDV1_CTP_INDEX);
|
||||
+ rule.pattern.enable = 1;
|
||||
+ rule.pattern.protocol = IPPROTO_ICMPV6;
|
||||
+ rule.pattern.protocol_enable = 1;
|
||||
@@ -907,7 +931,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
+ rule.pattern.app_data_msb_enable = 1;
|
||||
+ rule.pattern.app_mask_range_msb_select = 1; /* range mode */
|
||||
+
|
||||
+ ret = MXL862XX_API_WRITE(priv, MXL862XX_TFLOW_PCERULEWRITE, rule);
|
||||
+ ret = mxl862xx_pce_rule_write(priv, &rule);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
@@ -915,7 +939,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
+ * Nibble mask 0x3 masks nibbles 0-1 (lower byte = code field).
|
||||
+ */
|
||||
+ memset(&rule.pattern, 0, sizeof(rule.pattern));
|
||||
+ rule.pattern.index = cpu_to_le16(MXL862XX_MLDV2_CTP_OFFSET);
|
||||
+ rule.pattern.index = cpu_to_le16(MXL862XX_MLDV2_CTP_INDEX);
|
||||
+ rule.pattern.enable = 1;
|
||||
+ rule.pattern.protocol = IPPROTO_ICMPV6;
|
||||
+ rule.pattern.protocol_enable = 1;
|
||||
@@ -924,13 +948,13 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
+ rule.pattern.app_data_msb_enable = 1;
|
||||
+ /* app_mask_range_msb_select = 0: nibble mask mode (default) */
|
||||
+
|
||||
+ return MXL862XX_API_WRITE(priv, MXL862XX_TFLOW_PCERULEWRITE, rule);
|
||||
+ return mxl862xx_pce_rule_write(priv, &rule);
|
||||
+}
|
||||
+
|
||||
static int mxl862xx_set_bridge_port(struct dsa_switch *ds, int port)
|
||||
{
|
||||
struct mxl862xx_bridge_port_config br_port_cfg = {};
|
||||
@@ -683,6 +838,28 @@ static int mxl862xx_setup(struct dsa_swi
|
||||
@@ -684,6 +851,28 @@ static int mxl862xx_setup(struct dsa_swi
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
@@ -959,7 +983,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
schedule_delayed_work(&priv->stats_work,
|
||||
MXL862XX_STATS_POLL_INTERVAL);
|
||||
|
||||
@@ -1382,6 +1559,15 @@ static int mxl862xx_port_setup(struct ds
|
||||
@@ -1383,6 +1572,15 @@ static int mxl862xx_port_setup(struct ds
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
@@ -977,7 +1001,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
if (ret)
|
||||
--- a/drivers/net/dsa/mxl862xx/mxl862xx.h
|
||||
+++ b/drivers/net/dsa/mxl862xx/mxl862xx.h
|
||||
@@ -319,6 +319,13 @@ union mxl862xx_fw_version {
|
||||
@@ -317,6 +317,13 @@ struct mxl862xx_fw_version {
|
||||
* @evlan_ingress_size: per-port ingress Extended VLAN block size
|
||||
* @evlan_egress_size: per-port egress Extended VLAN block size
|
||||
* @vf_block_size: per-port VLAN Filter block size
|
||||
@@ -991,7 +1015,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
* @stats_work: periodic work item that polls RMON hardware counters
|
||||
* and accumulates them into 64-bit per-port stats
|
||||
*/
|
||||
@@ -335,6 +342,7 @@ struct mxl862xx_priv {
|
||||
@@ -334,6 +341,7 @@ struct mxl862xx_priv {
|
||||
u16 evlan_ingress_size;
|
||||
u16 evlan_egress_size;
|
||||
u16 vf_block_size;
|
||||
+3
-3
@@ -1,7 +1,7 @@
|
||||
From 264838ee8ee3ad611a84df96d889429f1ded2148 Mon Sep 17 00:00:00 2001
|
||||
From 6126dff8c28e71091c23fd0cc2f55b1a50e117a6 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Golle <daniel@makrotopia.org>
|
||||
Date: Tue, 24 Mar 2026 18:51:21 +0000
|
||||
Subject: [PATCH 08/19] net: dsa: mxl862xx: warn about old firmware default PCE
|
||||
Subject: [PATCH 07/19] net: dsa: mxl862xx: warn about old firmware default PCE
|
||||
rules
|
||||
|
||||
Firmware versions older than 1.0.80 install global PCE rules at
|
||||
@@ -19,7 +19,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
|
||||
--- a/drivers/net/dsa/mxl862xx/mxl862xx.c
|
||||
+++ b/drivers/net/dsa/mxl862xx/mxl862xx.c
|
||||
@@ -860,6 +860,10 @@ static int mxl862xx_setup(struct dsa_swi
|
||||
@@ -873,6 +873,10 @@ static int mxl862xx_setup(struct dsa_swi
|
||||
true, true, true);
|
||||
if (ret)
|
||||
return ret;
|
||||
+63
-73
@@ -1,7 +1,7 @@
|
||||
From d7ed9b681298d206d81e9cf3c93558d6e912ae88 Mon Sep 17 00:00:00 2001
|
||||
From 69a0946ef48325b85f4a331152d6340f39083053 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Golle <daniel@makrotopia.org>
|
||||
Date: Sun, 22 Mar 2026 00:58:04 +0000
|
||||
Subject: [PATCH 09/20] net: dsa: add 802.1Q VLAN-based tag driver for MxL862xx
|
||||
Subject: [PATCH 08/19] net: dsa: add 802.1Q VLAN-based tag driver for MxL862xx
|
||||
|
||||
The MxL862xx native 8-byte special tag (SpTag) requires firmware
|
||||
support on the switch CPU and is not compatible with all SoC Ethernet
|
||||
@@ -22,13 +22,13 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
drivers/net/dsa/mxl862xx/Kconfig | 1 +
|
||||
drivers/net/dsa/mxl862xx/mxl862xx-api.h | 221 +++
|
||||
drivers/net/dsa/mxl862xx/mxl862xx-cmd.h | 2 +
|
||||
drivers/net/dsa/mxl862xx/mxl862xx.c | 1678 ++++++++++++++++++++---
|
||||
drivers/net/dsa/mxl862xx/mxl862xx.c | 1677 ++++++++++++++++++++---
|
||||
drivers/net/dsa/mxl862xx/mxl862xx.h | 12 +
|
||||
include/net/dsa.h | 2 +
|
||||
net/dsa/Kconfig | 7 +
|
||||
net/dsa/Makefile | 1 +
|
||||
net/dsa/tag_mxl862xx_8021q.c | 65 +
|
||||
9 files changed, 1803 insertions(+), 186 deletions(-)
|
||||
9 files changed, 1804 insertions(+), 184 deletions(-)
|
||||
create mode 100644 net/dsa/tag_mxl862xx_8021q.c
|
||||
|
||||
--- a/drivers/net/dsa/mxl862xx/Kconfig
|
||||
@@ -43,10 +43,11 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
These switches have two 10GE SerDes interfaces, one typically
|
||||
--- a/drivers/net/dsa/mxl862xx/mxl862xx-api.h
|
||||
+++ b/drivers/net/dsa/mxl862xx/mxl862xx-api.h
|
||||
@@ -1185,6 +1185,227 @@ struct mxl862xx_ctp_port_assignment {
|
||||
@@ -1184,6 +1184,227 @@ struct mxl862xx_ctp_port_assignment {
|
||||
__le16 bridge_port_id;
|
||||
} __packed;
|
||||
|
||||
/**
|
||||
+/**
|
||||
+ * enum mxl862xx_ctp_port_config_mask - CTP Port Configuration Mask
|
||||
+ * @MXL862XX_CTP_PORT_CONFIG_MASK_BRIDGE_PORT_ID:
|
||||
+ * Mask for bridge_port_id.
|
||||
@@ -267,10 +268,9 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
+ u8 egress_mirror_enable;
|
||||
+} __packed;
|
||||
+
|
||||
+/**
|
||||
* enum mxl862xx_port_duplex - Ethernet port duplex status
|
||||
* @MXL862XX_DUPLEX_FULL: Port operates in full-duplex mode
|
||||
* @MXL862XX_DUPLEX_HALF: Port operates in half-duplex mode
|
||||
/* PCE (Packet Classification Engine) rule structures.
|
||||
*
|
||||
* Binary layout must exactly match the firmware's GSW_PCE_rule_t
|
||||
--- a/drivers/net/dsa/mxl862xx/mxl862xx-cmd.h
|
||||
+++ b/drivers/net/dsa/mxl862xx/mxl862xx-cmd.h
|
||||
@@ -47,12 +47,14 @@
|
||||
@@ -387,9 +387,9 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
}
|
||||
|
||||
/* PHY access via firmware relay */
|
||||
@@ -396,6 +459,78 @@ static int mxl862xx_setup_drop_meter(str
|
||||
#define MXL862XX_MLDV1_CTP_OFFSET 3
|
||||
#define MXL862XX_MLDV2_CTP_OFFSET 4
|
||||
@@ -410,6 +473,78 @@ static int mxl862xx_pce_rule_write(struc
|
||||
*rule);
|
||||
}
|
||||
|
||||
+/**
|
||||
+ * mxl862xx_cpu_bridge_port_id - Get the bridge port ID for CPU-side forwarding
|
||||
@@ -466,7 +466,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
/* Fill the action fields of a PCE rule that traps ingress frames to
|
||||
* the CPU port. Used by both the link-local trap and the multicast
|
||||
* snooping traps. The caller must already have set the rule header
|
||||
@@ -404,24 +539,36 @@ static int mxl862xx_setup_drop_meter(str
|
||||
@@ -418,24 +553,36 @@ static int mxl862xx_pce_rule_write(struc
|
||||
* PORTMAP_ALTERNATIVE redirects the frame to the CPU port but does
|
||||
* not by itself bypass downstream flood gates. In SpTag mode the
|
||||
* ingress port's private FID may have forward_unknown_multicast=false,
|
||||
@@ -505,17 +505,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
rule->action.cross_state_action =
|
||||
cpu_to_le32(MXL862XX_PCE_ACTION_CROSS_STATE_CROSS);
|
||||
|
||||
@@ -441,9 +588,6 @@ static void mxl862xx_fill_cpu_trap_actio
|
||||
* allocation via PCERULEALLOC is needed. Using region=CTP causes the
|
||||
* firmware to translate the CTP-relative offset into an absolute
|
||||
* hardware index.
|
||||
- *
|
||||
- * Cross-state is enabled so that link-local frames reach the CPU even
|
||||
- * when the bridge port is in BLOCKING or LEARNING state.
|
||||
*/
|
||||
static int mxl862xx_setup_link_local_trap(struct dsa_switch *ds, int port)
|
||||
{
|
||||
@@ -552,11 +696,17 @@ static int mxl862xx_set_bridge_port(stru
|
||||
@@ -564,11 +711,17 @@ static int mxl862xx_set_bridge_port(stru
|
||||
return 0;
|
||||
|
||||
if (dsa_port_is_cpu(dp)) {
|
||||
@@ -538,7 +528,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
}
|
||||
} else if (dp->bridge) {
|
||||
dsa_switch_for_each_bridge_member(member_dp, ds,
|
||||
@@ -567,10 +717,10 @@ static int mxl862xx_set_bridge_port(stru
|
||||
@@ -579,10 +732,10 @@ static int mxl862xx_set_bridge_port(stru
|
||||
member_dp->index);
|
||||
}
|
||||
mxl862xx_fw_portmap_set_bit(br_port_cfg.bridge_port_map,
|
||||
@@ -551,7 +541,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
p->flood_block = 0;
|
||||
p->learning = false;
|
||||
}
|
||||
@@ -774,10 +924,12 @@ static void mxl862xx_free_bridge(struct
|
||||
@@ -786,10 +939,12 @@ static void mxl862xx_free_bridge(struct
|
||||
static int mxl862xx_setup(struct dsa_switch *ds)
|
||||
{
|
||||
struct mxl862xx_priv *priv = ds->priv;
|
||||
@@ -566,16 +556,16 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
|
||||
ret = mxl862xx_reset(priv);
|
||||
if (ret)
|
||||
@@ -790,7 +942,7 @@ static int mxl862xx_setup(struct dsa_swi
|
||||
for (i = 0; i < 8; i++)
|
||||
mxl862xx_setup_pcs(priv, &priv->serdes_ports[i], i + 9);
|
||||
@@ -803,7 +958,7 @@ static int mxl862xx_setup(struct dsa_swi
|
||||
mxl862xx_setup_pcs(priv, &priv->serdes_ports[i],
|
||||
i + MXL862XX_FIRST_SERDES_PORT);
|
||||
|
||||
- /* Calculate Extended VLAN block sizes.
|
||||
+ /* Calculate Extended VLAN and VLAN Filter block sizes.
|
||||
* With VLAN Filter handling VID membership checks:
|
||||
* Ingress: only final catchall rules (PVID insertion, 802.1Q
|
||||
* accept, non-8021Q TPID handling, discard).
|
||||
@@ -798,46 +950,151 @@ static int mxl862xx_setup(struct dsa_swi
|
||||
@@ -811,46 +966,151 @@ static int mxl862xx_setup(struct dsa_swi
|
||||
* ingress EVLAN rules are needed. (7 entries.)
|
||||
* Egress: 2 rules per VID that needs tag stripping (untagged VIDs).
|
||||
* No egress final catchalls -- VLAN Filter does the discard.
|
||||
@@ -739,7 +729,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
|
||||
/* Allocate a dedicated PCE snooping FID with all flood modes enabled.
|
||||
* Per-port PCE trap rules (link-local, IGMP, MLD) set bFidEnable to
|
||||
@@ -860,10 +1117,6 @@ static int mxl862xx_setup(struct dsa_swi
|
||||
@@ -873,10 +1133,6 @@ static int mxl862xx_setup(struct dsa_swi
|
||||
true, true, true);
|
||||
if (ret)
|
||||
return ret;
|
||||
@@ -750,7 +740,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
schedule_delayed_work(&priv->stats_work,
|
||||
MXL862XX_STATS_POLL_INTERVAL);
|
||||
|
||||
@@ -944,10 +1197,71 @@ static int mxl862xx_configure_sp_tag_pro
|
||||
@@ -957,10 +1213,71 @@ static int mxl862xx_configure_sp_tag_pro
|
||||
return MXL862XX_API_WRITE(ds->priv, MXL862XX_SS_SPTAG_SET, tag);
|
||||
}
|
||||
|
||||
@@ -823,7 +813,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
{
|
||||
struct mxl862xx_extendedvlan_config cfg = {};
|
||||
struct mxl862xx_extendedvlan_filter_vlan *fv;
|
||||
@@ -1016,6 +1330,31 @@ static int mxl862xx_evlan_write_rule(str
|
||||
@@ -1029,6 +1346,31 @@ static int mxl862xx_evlan_write_rule(str
|
||||
cpu_to_le32(MXL862XX_EXTENDEDVLAN_TREATMENT_DISCARD_UPSTREAM);
|
||||
}
|
||||
break;
|
||||
@@ -855,7 +845,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
}
|
||||
|
||||
return MXL862XX_API_WRITE(priv, MXL862XX_EXTENDEDVLAN_SET, cfg);
|
||||
@@ -1054,7 +1393,7 @@ static int mxl862xx_evlan_write_final_ru
|
||||
@@ -1067,7 +1409,7 @@ static int mxl862xx_evlan_write_final_ru
|
||||
for (i = 0; i < n_rules; i++) {
|
||||
ret = mxl862xx_evlan_write_rule(priv, blk->block_id,
|
||||
start_idx + i, &rules[i],
|
||||
@@ -864,7 +854,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
@@ -1175,6 +1514,41 @@ static int mxl862xx_vf_del_vid(struct mx
|
||||
@@ -1188,6 +1530,41 @@ static int mxl862xx_vf_del_vid(struct mx
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -906,7 +896,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
static int mxl862xx_evlan_program_ingress(struct mxl862xx_priv *priv, int port)
|
||||
{
|
||||
struct mxl862xx_port *p = &priv->ports[port];
|
||||
@@ -1199,8 +1573,8 @@ static int mxl862xx_evlan_program_egress
|
||||
@@ -1212,8 +1589,8 @@ static int mxl862xx_evlan_program_egress
|
||||
const struct mxl862xx_evlan_rule_desc *vid_rules;
|
||||
struct mxl862xx_vf_vid *vfv;
|
||||
u16 old_active = blk->n_active;
|
||||
@@ -916,7 +906,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
|
||||
if (p->vlan_filtering) {
|
||||
vid_rules = vid_accept_standard;
|
||||
@@ -1214,13 +1588,23 @@ static int mxl862xx_evlan_program_egress
|
||||
@@ -1227,13 +1604,23 @@ static int mxl862xx_evlan_program_egress
|
||||
if (!vfv->untagged)
|
||||
continue;
|
||||
|
||||
@@ -941,7 +931,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
@@ -1229,7 +1613,29 @@ static int mxl862xx_evlan_program_egress
|
||||
@@ -1242,7 +1629,29 @@ static int mxl862xx_evlan_program_egress
|
||||
idx++, &vid_rules[1],
|
||||
vfv->vid,
|
||||
vfv->untagged,
|
||||
@@ -972,7 +962,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
@@ -1241,8 +1647,7 @@ static int mxl862xx_evlan_program_egress
|
||||
@@ -1254,8 +1663,7 @@ static int mxl862xx_evlan_program_egress
|
||||
*/
|
||||
for (i = idx; i < old_active; i++) {
|
||||
ret = mxl862xx_evlan_deactivate_entry(priv,
|
||||
@@ -982,7 +972,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
@@ -1267,13 +1672,16 @@ static int mxl862xx_port_vlan_filtering(
|
||||
@@ -1280,13 +1688,16 @@ static int mxl862xx_port_vlan_filtering(
|
||||
p->vlan_filtering = vlan_filtering;
|
||||
|
||||
if (changed) {
|
||||
@@ -1004,7 +994,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
|
||||
ret = mxl862xx_evlan_program_ingress(priv, port);
|
||||
if (ret)
|
||||
@@ -1493,22 +1901,575 @@ static void mxl862xx_port_bridge_leave(s
|
||||
@@ -1506,22 +1917,575 @@ static void mxl862xx_port_bridge_leave(s
|
||||
port, ERR_PTR(err));
|
||||
|
||||
/* Revert leaving port, omitted by the sync above, to its
|
||||
@@ -1582,7 +1572,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
static int mxl862xx_port_setup(struct dsa_switch *ds, int port)
|
||||
{
|
||||
struct mxl862xx_priv *priv = ds->priv;
|
||||
@@ -1530,33 +2491,52 @@ static int mxl862xx_port_setup(struct ds
|
||||
@@ -1543,33 +2507,52 @@ static int mxl862xx_port_setup(struct ds
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
@@ -1651,7 +1641,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
if (ret)
|
||||
return ret;
|
||||
ret = mxl862xx_set_bridge_port(ds, port);
|
||||
@@ -1572,24 +2552,7 @@ static int mxl862xx_port_setup(struct ds
|
||||
@@ -1585,24 +2568,7 @@ static int mxl862xx_port_setup(struct ds
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
@@ -1676,7 +1666,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1611,7 +2574,7 @@ static void mxl862xx_port_teardown(struc
|
||||
@@ -1624,7 +2590,7 @@ static void mxl862xx_port_teardown(struc
|
||||
priv->ports[port].setup_done = false;
|
||||
}
|
||||
|
||||
@@ -1685,7 +1675,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
{
|
||||
struct mxl862xx_priv *priv = ds->priv;
|
||||
|
||||
@@ -1629,23 +2592,247 @@ static int mxl862xx_get_fid(struct dsa_s
|
||||
@@ -1642,23 +2608,247 @@ static int mxl862xx_get_fid(struct dsa_s
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1718,12 +1708,12 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
+ if (dsa_is_cpu_port(ds, port) && priv->tag_proto == DSA_TAG_PROTO_MXL862_8021Q &&
|
||||
+ db.type == DSA_DB_PORT) {
|
||||
+ bp_cpu = priv->ports[db.dp->index].bridge_port_cpu;
|
||||
+
|
||||
|
||||
- param.port_id = cpu_to_le32(port);
|
||||
+ if (bp_cpu)
|
||||
+ return bp_cpu;
|
||||
+ }
|
||||
|
||||
- param.port_id = cpu_to_le32(port);
|
||||
+
|
||||
+ return port;
|
||||
+}
|
||||
+
|
||||
@@ -1941,7 +1931,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
if (ret)
|
||||
dev_err(ds->dev, "failed to add FDB entry on port %d\n", port);
|
||||
|
||||
@@ -1655,18 +2842,25 @@ static int mxl862xx_port_fdb_add(struct
|
||||
@@ -1668,18 +2858,25 @@ static int mxl862xx_port_fdb_add(struct
|
||||
static int mxl862xx_port_fdb_del(struct dsa_switch *ds, int port,
|
||||
const unsigned char *addr, u16 vid, const struct dsa_db db)
|
||||
{
|
||||
@@ -1950,7 +1940,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
struct mxl862xx_priv *priv = ds->priv;
|
||||
+ struct dsa_port *target_dp;
|
||||
+ int fid, ret;
|
||||
+
|
||||
|
||||
+ /* Mirror of the standalone->bridge FID path in fdb_add */
|
||||
+ if (priv->tag_proto == DSA_TAG_PROTO_MXL862_8021Q && dsa_is_cpu_port(ds, port) &&
|
||||
+ db.type == DSA_DB_PORT && vid > 0) {
|
||||
@@ -1960,7 +1950,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
+ mxl862xx_fdb_del_per_fid(ds, addr, vid,
|
||||
+ priv->bridges[target_dp->bridge->num]);
|
||||
+ }
|
||||
|
||||
+
|
||||
+ fid = mxl862xx_get_fid(ds, db);
|
||||
if (fid < 0)
|
||||
return fid;
|
||||
@@ -1974,7 +1964,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
if (ret)
|
||||
dev_err(ds->dev, "failed to remove FDB entry on port %d\n", port);
|
||||
|
||||
@@ -1705,84 +2899,153 @@ static int mxl862xx_port_fdb_dump(struct
|
||||
@@ -1718,84 +2915,153 @@ static int mxl862xx_port_fdb_dump(struct
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -2075,7 +2065,8 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
- sizeof(aparam.port_map));
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
|
||||
- mxl862xx_fw_portmap_set_bit(aparam.port_map, port);
|
||||
+/**
|
||||
+ * mxl862xx_mac_del_host_bridge - Remove every user-port VBP bit from a host
|
||||
+ * FDB/MDB entry, dropping the entry when its
|
||||
@@ -2099,14 +2090,13 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
+ struct dsa_port *dp;
|
||||
+ u16 vbp;
|
||||
|
||||
- mxl862xx_fw_portmap_set_bit(aparam.port_map, port);
|
||||
- return MXL862XX_API_WRITE(priv, MXL862XX_MAC_TABLEENTRYADD, aparam);
|
||||
+ dsa_switch_for_each_user_port(dp, ds) {
|
||||
+ vbp = priv->ports[dp->index].bridge_port_cpu;
|
||||
+ if (vbp)
|
||||
+ mxl862xx_fw_portmap_set_bit(del_map, vbp);
|
||||
+ }
|
||||
|
||||
- return MXL862XX_API_WRITE(priv, MXL862XX_MAC_TABLEENTRYADD, aparam);
|
||||
+
|
||||
+ return mxl862xx_mac_portmap_del(priv, addr, fid, vid, del_map);
|
||||
}
|
||||
|
||||
@@ -2120,7 +2110,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
- int fid = mxl862xx_get_fid(ds, db), ret;
|
||||
struct mxl862xx_priv *priv = ds->priv;
|
||||
+ int fid, ret;
|
||||
|
||||
+
|
||||
+ /* tag_8021q host MDB for bridged ports: clear all VBP bits */
|
||||
+ if (priv->tag_proto == DSA_TAG_PROTO_MXL862_8021Q && dsa_is_cpu_port(ds, port) &&
|
||||
+ db.type == DSA_DB_BRIDGE) {
|
||||
@@ -2130,7 +2120,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
+ return mxl862xx_mac_del_host_bridge(ds, mdb->addr,
|
||||
+ mdb->vid, &db.bridge);
|
||||
+ }
|
||||
+
|
||||
|
||||
+ fid = mxl862xx_get_fid(ds, db);
|
||||
if (fid < 0)
|
||||
return fid;
|
||||
@@ -2175,7 +2165,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -1867,6 +3130,9 @@ static void mxl862xx_host_flood_work_fn(
|
||||
@@ -1880,6 +3146,9 @@ static void mxl862xx_host_flood_work_fn(
|
||||
host_flood_work);
|
||||
struct mxl862xx_priv *priv = p->priv;
|
||||
struct dsa_switch *ds = priv->ds;
|
||||
@@ -2185,7 +2175,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
|
||||
rtnl_lock();
|
||||
|
||||
@@ -1876,13 +3142,34 @@ static void mxl862xx_host_flood_work_fn(
|
||||
@@ -1889,13 +3158,34 @@ static void mxl862xx_host_flood_work_fn(
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -2227,7 +2217,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
|
||||
rtnl_unlock();
|
||||
}
|
||||
@@ -2248,7 +3535,9 @@ static void mxl862xx_get_stats64(struct
|
||||
@@ -2261,7 +3551,9 @@ static void mxl862xx_get_stats64(struct
|
||||
|
||||
static const struct dsa_switch_ops mxl862xx_switch_ops = {
|
||||
.get_tag_protocol = mxl862xx_get_tag_protocol,
|
||||
@@ -2237,7 +2227,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
.port_setup = mxl862xx_port_setup,
|
||||
.port_teardown = mxl862xx_port_teardown,
|
||||
.phylink_get_caps = mxl862xx_phylink_get_caps,
|
||||
@@ -2270,6 +3559,8 @@ static const struct dsa_switch_ops mxl86
|
||||
@@ -2283,6 +3575,8 @@ static const struct dsa_switch_ops mxl86
|
||||
.port_vlan_filtering = mxl862xx_port_vlan_filtering,
|
||||
.port_vlan_add = mxl862xx_port_vlan_add,
|
||||
.port_vlan_del = mxl862xx_port_vlan_del,
|
||||
@@ -2246,7 +2236,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
.get_strings = mxl862xx_get_strings,
|
||||
.get_sset_count = mxl862xx_get_sset_count,
|
||||
.get_ethtool_stats = mxl862xx_get_ethtool_stats,
|
||||
@@ -2318,6 +3609,8 @@ static int mxl862xx_probe(struct mdio_de
|
||||
@@ -2330,6 +3624,8 @@ static int mxl862xx_probe(struct mdio_de
|
||||
|
||||
INIT_DELAYED_WORK(&priv->stats_work, mxl862xx_stats_work_fn);
|
||||
|
||||
@@ -2255,7 +2245,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
dev_set_drvdata(dev, ds);
|
||||
|
||||
err = dsa_register_switch(ds);
|
||||
@@ -2346,6 +3639,19 @@ static void mxl862xx_remove(struct mdio_
|
||||
@@ -2358,6 +3654,19 @@ static void mxl862xx_remove(struct mdio_
|
||||
set_bit(MXL862XX_FLAG_WORK_STOPPED, &priv->flags);
|
||||
cancel_delayed_work_sync(&priv->stats_work);
|
||||
|
||||
@@ -2277,7 +2267,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
mxl862xx_host_shutdown(priv);
|
||||
--- a/drivers/net/dsa/mxl862xx/mxl862xx.h
|
||||
+++ b/drivers/net/dsa/mxl862xx/mxl862xx.h
|
||||
@@ -209,6 +209,9 @@ struct mxl862xx_port_stats {
|
||||
@@ -212,6 +212,9 @@ struct mxl862xx_port_stats {
|
||||
* @vf: per-port VLAN Filter block state
|
||||
* @ingress_evlan: ingress extended VLAN block state
|
||||
* @egress_evlan: egress extended VLAN block state
|
||||
@@ -2287,7 +2277,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
* @host_flood_uc: desired host unicast flood state (true = flood);
|
||||
* updated atomically by port_set_host_flood, consumed
|
||||
* by the deferred host_flood_work
|
||||
@@ -223,6 +226,7 @@ struct mxl862xx_port_stats {
|
||||
@@ -226,6 +229,7 @@ struct mxl862xx_port_stats {
|
||||
* periodically by the stats polling work
|
||||
* @stats_lock: protects accumulator reads in .get_stats64 against
|
||||
* concurrent updates from the polling work
|
||||
@@ -2295,7 +2285,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
*/
|
||||
struct mxl862xx_port {
|
||||
struct mxl862xx_priv *priv;
|
||||
@@ -235,9 +239,13 @@ struct mxl862xx_port {
|
||||
@@ -238,9 +242,13 @@ struct mxl862xx_port {
|
||||
struct mxl862xx_vf_block vf;
|
||||
struct mxl862xx_evlan_block ingress_evlan;
|
||||
struct mxl862xx_evlan_block egress_evlan;
|
||||
@@ -2309,7 +2299,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
struct mxl862xx_port_stats stats;
|
||||
spinlock_t stats_lock; /* protects stats accumulators */
|
||||
};
|
||||
@@ -304,6 +312,7 @@ union mxl862xx_fw_version {
|
||||
@@ -298,6 +306,7 @@ struct mxl862xx_fw_version {
|
||||
* before CRC-triggered shutdown and cleared after;
|
||||
* %MXL862XX_FLAG_WORK_STOPPED is set before cancelling
|
||||
* stats_work to prevent rescheduling during teardown
|
||||
@@ -2317,7 +2307,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
* @drop_meter: index of the single shared zero-rate firmware meter
|
||||
* used to unconditionally drop traffic (used to block
|
||||
* flooding)
|
||||
@@ -318,6 +327,7 @@ union mxl862xx_fw_version {
|
||||
@@ -316,6 +325,7 @@ struct mxl862xx_fw_version {
|
||||
* (0 .. ds->max_num_bridges).
|
||||
* @evlan_ingress_size: per-port ingress Extended VLAN block size
|
||||
* @evlan_egress_size: per-port egress Extended VLAN block size
|
||||
@@ -2325,15 +2315,15 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
* @vf_block_size: per-port VLAN Filter block size
|
||||
* @cpu_trap_fid: firmware bridge FID allocated for PCE-trapped frames;
|
||||
* configured with uc/mc/bc flood all enabled so that
|
||||
@@ -334,6 +344,7 @@ struct mxl862xx_priv {
|
||||
@@ -332,6 +342,7 @@ struct mxl862xx_priv {
|
||||
struct mdio_device *mdiodev;
|
||||
struct work_struct crc_err_work;
|
||||
unsigned long flags;
|
||||
+ enum dsa_tag_protocol tag_proto;
|
||||
u16 drop_meter;
|
||||
union mxl862xx_fw_version fw_version;
|
||||
struct mxl862xx_fw_version fw_version;
|
||||
struct mxl862xx_pcs serdes_ports[8];
|
||||
@@ -341,6 +352,7 @@ struct mxl862xx_priv {
|
||||
@@ -340,6 +351,7 @@ struct mxl862xx_priv {
|
||||
u16 bridges[MXL862XX_MAX_BRIDGES + 1];
|
||||
u16 evlan_ingress_size;
|
||||
u16 evlan_egress_size;
|
||||
+22
-22
@@ -1,7 +1,7 @@
|
||||
From a32f6a9c09b90e767a03ddac34d061545a0cf15e Mon Sep 17 00:00:00 2001
|
||||
From 4220567bd18b2174c74e90d22f3bf47422c1fdf6 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Golle <daniel@makrotopia.org>
|
||||
Date: Tue, 24 Mar 2026 03:44:41 +0000
|
||||
Subject: [PATCH 10/20] net: dsa: mxl862xx: add link aggregation support
|
||||
Subject: [PATCH 09/19] net: dsa: mxl862xx: add link aggregation support
|
||||
|
||||
Implement LAG offloading via the firmware's trunking engine. A
|
||||
dedicated firmware bridge port is allocated per LAG and remains
|
||||
@@ -90,8 +90,8 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
#define INT_GPHY_READ (GPY_GPY2XX_MAGIC + 0x1)
|
||||
--- a/drivers/net/dsa/mxl862xx/mxl862xx.c
|
||||
+++ b/drivers/net/dsa/mxl862xx/mxl862xx.c
|
||||
@@ -680,7 +680,42 @@ static int mxl862xx_setup_snooping_traps
|
||||
return MXL862XX_API_WRITE(priv, MXL862XX_TFLOW_PCERULEWRITE, rule);
|
||||
@@ -695,7 +695,42 @@ static int mxl862xx_setup_snooping_traps
|
||||
return mxl862xx_pce_rule_write(priv, &rule);
|
||||
}
|
||||
|
||||
-static int mxl862xx_set_bridge_port(struct dsa_switch *ds, int port)
|
||||
@@ -134,7 +134,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
{
|
||||
struct mxl862xx_bridge_port_config br_port_cfg = {};
|
||||
struct dsa_port *dp = dsa_to_port(ds, port);
|
||||
@@ -713,8 +748,12 @@ static int mxl862xx_set_bridge_port(stru
|
||||
@@ -728,8 +763,12 @@ static int mxl862xx_set_bridge_port(stru
|
||||
dp->bridge->dev) {
|
||||
if (member_dp->index == port)
|
||||
continue;
|
||||
@@ -149,7 +149,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
}
|
||||
mxl862xx_fw_portmap_set_bit(br_port_cfg.bridge_port_map,
|
||||
mxl862xx_cpu_bridge_port_id(ds, port));
|
||||
@@ -727,7 +766,7 @@ static int mxl862xx_set_bridge_port(stru
|
||||
@@ -742,7 +781,7 @@ static int mxl862xx_set_bridge_port(stru
|
||||
|
||||
bridge_id = dp->bridge ? priv->bridges[dp->bridge->num] : p->fid;
|
||||
|
||||
@@ -158,7 +158,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
br_port_cfg.bridge_id = cpu_to_le16(bridge_id);
|
||||
br_port_cfg.mask = cpu_to_le32(MXL862XX_BRIDGE_PORT_CONFIG_MASK_BRIDGE_ID |
|
||||
MXL862XX_BRIDGE_PORT_CONFIG_MASK_BRIDGE_PORT_MAP |
|
||||
@@ -808,11 +847,38 @@ static int mxl862xx_set_bridge_port(stru
|
||||
@@ -823,11 +862,38 @@ static int mxl862xx_set_bridge_port(stru
|
||||
br_port_cfg);
|
||||
}
|
||||
|
||||
@@ -198,7 +198,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
|
||||
dsa_switch_for_each_bridge_member(dp, ds, bridge->dev) {
|
||||
err = mxl862xx_set_bridge_port(ds, dp->index);
|
||||
@@ -820,6 +886,25 @@ static int mxl862xx_sync_bridge_members(
|
||||
@@ -835,6 +901,25 @@ static int mxl862xx_sync_bridge_members(
|
||||
ret = err;
|
||||
}
|
||||
|
||||
@@ -224,7 +224,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -1859,6 +1944,408 @@ static int mxl862xx_setup_cpu_bridge(str
|
||||
@@ -1875,6 +1960,408 @@ static int mxl862xx_setup_cpu_bridge(str
|
||||
return mxl862xx_set_bridge_port(ds, port);
|
||||
}
|
||||
|
||||
@@ -633,7 +633,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
static int mxl862xx_port_bridge_join(struct dsa_switch *ds, int port,
|
||||
const struct dsa_bridge bridge,
|
||||
bool *tx_fwd_offload,
|
||||
@@ -1884,7 +2371,18 @@ static int mxl862xx_port_bridge_join(str
|
||||
@@ -1900,7 +2387,18 @@ static int mxl862xx_port_bridge_join(str
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -653,7 +653,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
}
|
||||
|
||||
static void mxl862xx_port_bridge_leave(struct dsa_switch *ds, int port,
|
||||
@@ -1935,6 +2433,17 @@ static void mxl862xx_port_bridge_leave(s
|
||||
@@ -1951,6 +2449,17 @@ static void mxl862xx_port_bridge_leave(s
|
||||
"failed to update CPU VBP for port %d: %pe\n", port,
|
||||
ERR_PTR(err));
|
||||
|
||||
@@ -671,7 +671,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
if (!dsa_bridge_ports(ds, bridge.dev))
|
||||
mxl862xx_free_bridge(ds, &bridge);
|
||||
}
|
||||
@@ -2593,18 +3102,17 @@ static int mxl862xx_get_fid(struct dsa_s
|
||||
@@ -2609,18 +3118,17 @@ static int mxl862xx_get_fid(struct dsa_s
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -697,7 +697,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
*/
|
||||
static int mxl862xx_fdb_bridge_port(struct dsa_switch *ds, int port,
|
||||
const struct dsa_db db)
|
||||
@@ -2620,7 +3128,7 @@ static int mxl862xx_fdb_bridge_port(stru
|
||||
@@ -2636,7 +3144,7 @@ static int mxl862xx_fdb_bridge_port(stru
|
||||
return bp_cpu;
|
||||
}
|
||||
|
||||
@@ -706,7 +706,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2867,11 +3375,43 @@ static int mxl862xx_port_fdb_del(struct
|
||||
@@ -2883,11 +3391,43 @@ static int mxl862xx_port_fdb_del(struct
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -750,7 +750,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
u32 entry_port_id;
|
||||
int ret;
|
||||
|
||||
@@ -2885,7 +3425,7 @@ static int mxl862xx_port_fdb_dump(struct
|
||||
@@ -2901,7 +3441,7 @@ static int mxl862xx_port_fdb_dump(struct
|
||||
|
||||
entry_port_id = le32_to_cpu(param.port_id);
|
||||
|
||||
@@ -759,7 +759,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
ret = cb(param.mac, FIELD_GET(MXL862XX_TCI_VLAN_ID,
|
||||
le16_to_cpu(param.tci)),
|
||||
param.static_entry, data);
|
||||
@@ -3556,6 +4096,11 @@ static const struct dsa_switch_ops mxl86
|
||||
@@ -3572,6 +4112,11 @@ static const struct dsa_switch_ops mxl86
|
||||
.port_fdb_dump = mxl862xx_port_fdb_dump,
|
||||
.port_mdb_add = mxl862xx_port_mdb_add,
|
||||
.port_mdb_del = mxl862xx_port_mdb_del,
|
||||
@@ -771,7 +771,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
.port_vlan_filtering = mxl862xx_port_vlan_filtering,
|
||||
.port_vlan_add = mxl862xx_port_vlan_add,
|
||||
.port_vlan_del = mxl862xx_port_vlan_del,
|
||||
@@ -3597,6 +4142,7 @@ static int mxl862xx_probe(struct mdio_de
|
||||
@@ -3612,6 +4157,7 @@ static int mxl862xx_probe(struct mdio_de
|
||||
ds->num_ports = MXL862XX_MAX_PORTS;
|
||||
ds->fdb_isolation = true;
|
||||
ds->max_num_bridges = MXL862XX_MAX_BRIDGES;
|
||||
@@ -781,7 +781,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
|
||||
--- a/drivers/net/dsa/mxl862xx/mxl862xx.h
|
||||
+++ b/drivers/net/dsa/mxl862xx/mxl862xx.h
|
||||
@@ -16,6 +16,19 @@ struct mxl862xx_priv;
|
||||
@@ -19,6 +19,19 @@ struct mxl862xx_priv;
|
||||
#define MXL862XX_MAX_BRIDGE_PORTS 128
|
||||
#define MXL862XX_TOTAL_EVLAN_ENTRIES 1024
|
||||
#define MXL862XX_TOTAL_VF_ENTRIES 1024
|
||||
@@ -801,7 +801,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
|
||||
/* Number of __le16 words in a firmware portmap (128-bit bitmap). */
|
||||
#define MXL862XX_FW_PORTMAP_WORDS (MXL862XX_MAX_BRIDGE_PORTS / 16)
|
||||
@@ -227,6 +240,12 @@ struct mxl862xx_port_stats {
|
||||
@@ -230,6 +243,12 @@ struct mxl862xx_port_stats {
|
||||
* @stats_lock: protects accumulator reads in .get_stats64 against
|
||||
* concurrent updates from the polling work
|
||||
* @tag_8021q_vid: currently assigned tag_8021q management VID
|
||||
@@ -814,7 +814,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
*/
|
||||
struct mxl862xx_port {
|
||||
struct mxl862xx_priv *priv;
|
||||
@@ -246,6 +265,9 @@ struct mxl862xx_port {
|
||||
@@ -249,6 +268,9 @@ struct mxl862xx_port {
|
||||
struct work_struct host_flood_work;
|
||||
u16 tag_8021q_vid;
|
||||
struct mxl862xx_evlan_block cpu_egress_evlan;
|
||||
@@ -824,7 +824,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
struct mxl862xx_port_stats stats;
|
||||
spinlock_t stats_lock; /* protects stats accumulators */
|
||||
};
|
||||
@@ -336,6 +358,15 @@ union mxl862xx_fw_version {
|
||||
@@ -334,6 +356,15 @@ struct mxl862xx_fw_version {
|
||||
* policy. Set once in setup() and referenced by
|
||||
* fill_cpu_trap_action() via bFidEnable. The PCE FID
|
||||
* action field is 6 bits, so this value must be <= 63.
|
||||
@@ -840,7 +840,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
* @stats_work: periodic work item that polls RMON hardware counters
|
||||
* and accumulates them into 64-bit per-port stats
|
||||
*/
|
||||
@@ -355,6 +386,8 @@ struct mxl862xx_priv {
|
||||
@@ -354,6 +385,8 @@ struct mxl862xx_priv {
|
||||
u16 cpu_evlan_ingress_size;
|
||||
u16 vf_block_size;
|
||||
u16 cpu_trap_fid;
|
||||
+15
-15
@@ -1,7 +1,7 @@
|
||||
From d919c2f8da9dbd4dda57ceebb5c8b103805b58d1 Mon Sep 17 00:00:00 2001
|
||||
From 8f7296099da5eaedfe5108a6fe93296bcc0c4b45 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Golle <daniel@makrotopia.org>
|
||||
Date: Tue, 24 Mar 2026 12:05:29 +0000
|
||||
Subject: [PATCH 11/19] net: dsa: mxl862xx: add support for mirror port
|
||||
Subject: [PATCH 10/19] net: dsa: mxl862xx: add support for mirror port
|
||||
|
||||
The MxL862xx hardware supports a single monitor port which can be
|
||||
configured to mirror any other port's ingress and/or egress traffic.
|
||||
@@ -40,17 +40,17 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
* @age_timer: Custom MAC table aging timer in seconds
|
||||
--- a/drivers/net/dsa/mxl862xx/mxl862xx-cmd.h
|
||||
+++ b/drivers/net/dsa/mxl862xx/mxl862xx-cmd.h
|
||||
@@ -30,6 +30,7 @@
|
||||
#define MXL862XX_COMMON_PORTCFGGET (MXL862XX_COMMON_MAGIC + 0x7)
|
||||
@@ -29,6 +29,7 @@
|
||||
|
||||
#define MXL862XX_COMMON_CFGGET (MXL862XX_COMMON_MAGIC + 0x9)
|
||||
#define MXL862XX_COMMON_CFGSET (MXL862XX_COMMON_MAGIC + 0xa)
|
||||
+#define MXL862XX_COMMON_MONITORPORTCFGSET (MXL862XX_COMMON_MAGIC + 0xe)
|
||||
#define MXL862XX_COMMON_REGISTERMOD (MXL862XX_COMMON_MAGIC + 0x11)
|
||||
|
||||
#define MXL862XX_TFLOW_PCERULEWRITE (MXL862XX_TFLOW_MAGIC + 0x2)
|
||||
#define MXL862XX_TFLOW_PCERULEALLOC (MXL862XX_TFLOW_MAGIC + 0x4)
|
||||
--- a/drivers/net/dsa/mxl862xx/mxl862xx.c
|
||||
+++ b/drivers/net/dsa/mxl862xx/mxl862xx.c
|
||||
@@ -1100,6 +1100,8 @@ static int mxl862xx_setup(struct dsa_swi
|
||||
@@ -1116,6 +1116,8 @@ static int mxl862xx_setup(struct dsa_swi
|
||||
(n_user_ports + n_cpu_ports);
|
||||
}
|
||||
|
||||
@@ -59,8 +59,8 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
ret = mxl862xx_setup_drop_meter(ds);
|
||||
if (ret)
|
||||
return ret;
|
||||
@@ -3167,6 +3169,120 @@ static int mxl862xx_fdb_del_per_fid(stru
|
||||
return MXL862XX_API_WRITE(priv, MXL862XX_MAC_TABLEENTRYREMOVE, param);
|
||||
@@ -1960,6 +1962,120 @@ static int mxl862xx_setup_cpu_bridge(str
|
||||
return mxl862xx_set_bridge_port(ds, port);
|
||||
}
|
||||
|
||||
+static int mxl862xx_port_mirror_add(struct dsa_switch *ds, int port,
|
||||
@@ -178,9 +178,9 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
+}
|
||||
+
|
||||
/**
|
||||
* mxl862xx_mac_portmap_add - Set port bits in a MAC table entry's portmap
|
||||
* @priv: driver private data
|
||||
@@ -4096,6 +4212,8 @@ static const struct dsa_switch_ops mxl86
|
||||
* mxl862xx_lag_master_port - Find the LAG master (lowest-numbered member)
|
||||
* @ds: DSA switch
|
||||
@@ -4112,6 +4228,8 @@ static const struct dsa_switch_ops mxl86
|
||||
.port_fdb_dump = mxl862xx_port_fdb_dump,
|
||||
.port_mdb_add = mxl862xx_port_mdb_add,
|
||||
.port_mdb_del = mxl862xx_port_mdb_del,
|
||||
@@ -191,7 +191,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
.port_lag_change = mxl862xx_port_lag_change,
|
||||
--- a/drivers/net/dsa/mxl862xx/mxl862xx.h
|
||||
+++ b/drivers/net/dsa/mxl862xx/mxl862xx.h
|
||||
@@ -240,6 +240,8 @@ struct mxl862xx_port_stats {
|
||||
@@ -243,6 +243,8 @@ struct mxl862xx_port_stats {
|
||||
* @stats_lock: protects accumulator reads in .get_stats64 against
|
||||
* concurrent updates from the polling work
|
||||
* @tag_8021q_vid: currently assigned tag_8021q management VID
|
||||
@@ -200,7 +200,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
* @lag: non-NULL when port is member of a LAG group;
|
||||
* points to the DSA LAG structure
|
||||
* @lag_tx_enabled: true when this port is active for TX in its LAG
|
||||
@@ -265,6 +267,8 @@ struct mxl862xx_port {
|
||||
@@ -268,6 +270,8 @@ struct mxl862xx_port {
|
||||
struct work_struct host_flood_work;
|
||||
u16 tag_8021q_vid;
|
||||
struct mxl862xx_evlan_block cpu_egress_evlan;
|
||||
@@ -209,7 +209,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
struct dsa_lag *lag;
|
||||
bool lag_tx_enabled;
|
||||
u8 lag_hash_bits;
|
||||
@@ -367,6 +371,8 @@ union mxl862xx_fw_version {
|
||||
@@ -365,6 +369,8 @@ struct mxl862xx_fw_version {
|
||||
* @trunk_hash: current global hash field bitmask (6 bits,
|
||||
* MXL862XX_TRUNK_HASH_*); union of all active LAGs'
|
||||
* hash requirements
|
||||
@@ -218,7 +218,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
* @stats_work: periodic work item that polls RMON hardware counters
|
||||
* and accumulates them into 64-bit per-port stats
|
||||
*/
|
||||
@@ -388,6 +394,7 @@ struct mxl862xx_priv {
|
||||
@@ -387,6 +393,7 @@ struct mxl862xx_priv {
|
||||
u16 cpu_trap_fid;
|
||||
u16 lag_bridge_ports[MXL862XX_MAX_LAG_IDS + 1];
|
||||
u8 trunk_hash;
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
From 64269d9d809962a0f7e68e9b618d81e561e3eb6f Mon Sep 17 00:00:00 2001
|
||||
From d11e0b07317e04f347de1b5053bb6720d72fd111 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Golle <daniel@makrotopia.org>
|
||||
Date: Tue, 24 Mar 2026 16:30:08 +0000
|
||||
Subject: [PATCH 12/19] net: dsa: wire flash_update devlink callback to drivers
|
||||
Subject: [PATCH 11/19] net: dsa: wire flash_update devlink callback to drivers
|
||||
|
||||
Add a devlink_flash_update callback to dsa_switch_ops so that DSA
|
||||
drivers can support devlink dev flash without open-coding the devlink
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
From fed4225f75b6fe6898e48f472cbbee0aaa046760 Mon Sep 17 00:00:00 2001
|
||||
From 4dd558c7422fcd2b5c76994928fe3a65e0059fb4 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Golle <daniel@makrotopia.org>
|
||||
Date: Tue, 24 Mar 2026 16:30:17 +0000
|
||||
Subject: [PATCH 13/19] net: dsa: mxl862xx: add SMDIO clause-22 register access
|
||||
Subject: [PATCH 12/19] net: dsa: mxl862xx: add SMDIO clause-22 register access
|
||||
|
||||
Add mxl862xx_smdio_read() and mxl862xx_smdio_write() for clause-22
|
||||
SMDIO register access. MCUboot rescue mode only exposes clause-22
|
||||
+8
-9
@@ -1,7 +1,7 @@
|
||||
From fa186b09e346e0b7f2504232731bc9e4dee0c600 Mon Sep 17 00:00:00 2001
|
||||
From 099e70920b16f5da14d34bc00ac58a5ca95c1e33 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Golle <daniel@makrotopia.org>
|
||||
Date: Tue, 24 Mar 2026 16:30:31 +0000
|
||||
Subject: [PATCH 14/19] net: dsa: mxl862xx: add devlink flash_update and
|
||||
Subject: [PATCH 13/19] net: dsa: mxl862xx: add devlink flash_update and
|
||||
info_get
|
||||
|
||||
Implement runtime firmware upgrade via "devlink dev flash" and version
|
||||
@@ -35,9 +35,9 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
drivers/net/dsa/mxl862xx/mxl862xx-fw.c | 434 +++++++++++++++++++++++
|
||||
drivers/net/dsa/mxl862xx/mxl862xx-fw.h | 15 +
|
||||
drivers/net/dsa/mxl862xx/mxl862xx-host.c | 7 +
|
||||
drivers/net/dsa/mxl862xx/mxl862xx.c | 4 +
|
||||
drivers/net/dsa/mxl862xx/mxl862xx.c | 3 +
|
||||
drivers/net/dsa/mxl862xx/mxl862xx.h | 2 +
|
||||
7 files changed, 464 insertions(+), 1 deletion(-)
|
||||
7 files changed, 463 insertions(+), 1 deletion(-)
|
||||
create mode 100644 drivers/net/dsa/mxl862xx/mxl862xx-fw.c
|
||||
create mode 100644 drivers/net/dsa/mxl862xx/mxl862xx-fw.h
|
||||
|
||||
@@ -57,7 +57,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
+#define SYS_MISC_FW_UPDATE (SYS_MISC_MAGIC + 0x1)
|
||||
#define SYS_MISC_FW_VERSION (SYS_MISC_MAGIC + 0x2)
|
||||
|
||||
#define MXL862XX_XPCS_MAGIC 0x1a00
|
||||
#define MXL862XX_XPCS_PCS_CONFIG (MXL862XX_XPCS_MAGIC + 0x1)
|
||||
--- /dev/null
|
||||
+++ b/drivers/net/dsa/mxl862xx/mxl862xx-fw.c
|
||||
@@ -0,0 +1,434 @@
|
||||
@@ -546,19 +546,18 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
#include "mxl862xx-host.h"
|
||||
#include "mxl862xx-phylink.h"
|
||||
|
||||
@@ -4233,6 +4234,9 @@ static const struct dsa_switch_ops mxl86
|
||||
@@ -4248,6 +4249,8 @@ static const struct dsa_switch_ops mxl86
|
||||
.get_pause_stats = mxl862xx_get_pause_stats,
|
||||
.get_rmon_stats = mxl862xx_get_rmon_stats,
|
||||
.get_stats64 = mxl862xx_get_stats64,
|
||||
.self_test = mxl862xx_serdes_self_test,
|
||||
+ .devlink_info_get = mxl862xx_devlink_info_get,
|
||||
+ .devlink_flash_update = mxl862xx_devlink_flash_update,
|
||||
+
|
||||
};
|
||||
|
||||
static int mxl862xx_probe(struct mdio_device *mdiodev)
|
||||
--- a/drivers/net/dsa/mxl862xx/mxl862xx.h
|
||||
+++ b/drivers/net/dsa/mxl862xx/mxl862xx.h
|
||||
@@ -395,6 +395,8 @@ struct mxl862xx_priv {
|
||||
@@ -394,6 +394,8 @@ struct mxl862xx_priv {
|
||||
u16 lag_bridge_ports[MXL862XX_MAX_LAG_IDS + 1];
|
||||
u8 trunk_hash;
|
||||
int mirror_dest;
|
||||
+6
-6
@@ -1,7 +1,7 @@
|
||||
From 05bc981690d6ef03143a094f28714aa0171ab571 Mon Sep 17 00:00:00 2001
|
||||
From d27d60f42f5188d6cfcb771d2188633f1031646f Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Golle <daniel@makrotopia.org>
|
||||
Date: Wed, 1 Apr 2026 13:43:08 +0100
|
||||
Subject: [PATCH 15/19] net: dsa: mxl862xx: implement port MTU configuration
|
||||
Subject: [PATCH 14/19] net: dsa: mxl862xx: implement port MTU configuration
|
||||
|
||||
The firmware exposes a global max_packet_len register via
|
||||
MXL862XX_COMMON_CFGSET. Since this is switch-wide rather than
|
||||
@@ -25,7 +25,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/of_mdio.h>
|
||||
@@ -3727,6 +3728,53 @@ static int mxl862xx_set_ageing_time(stru
|
||||
@@ -3743,6 +3744,53 @@ static int mxl862xx_set_ageing_time(stru
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -79,7 +79,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
static void mxl862xx_port_stp_state_set(struct dsa_switch *ds, int port,
|
||||
u8 state)
|
||||
{
|
||||
@@ -4202,6 +4250,8 @@ static const struct dsa_switch_ops mxl86
|
||||
@@ -4218,6 +4266,8 @@ static const struct dsa_switch_ops mxl86
|
||||
.port_disable = mxl862xx_port_disable,
|
||||
.port_fast_age = mxl862xx_port_fast_age,
|
||||
.set_ageing_time = mxl862xx_set_ageing_time,
|
||||
@@ -90,7 +90,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
.port_pre_bridge_flags = mxl862xx_port_pre_bridge_flags,
|
||||
--- a/drivers/net/dsa/mxl862xx/mxl862xx.h
|
||||
+++ b/drivers/net/dsa/mxl862xx/mxl862xx.h
|
||||
@@ -248,6 +248,8 @@ struct mxl862xx_port_stats {
|
||||
@@ -251,6 +251,8 @@ struct mxl862xx_port_stats {
|
||||
* @lag_hash_bits: hash field bitmask (MXL862XX_TRUNK_HASH_*) requested
|
||||
* when this port joined its LAG; used to recompute the
|
||||
* global trunk_hash when a LAG is destroyed
|
||||
@@ -99,7 +99,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
*/
|
||||
struct mxl862xx_port {
|
||||
struct mxl862xx_priv *priv;
|
||||
@@ -272,6 +274,7 @@ struct mxl862xx_port {
|
||||
@@ -275,6 +277,7 @@ struct mxl862xx_port {
|
||||
struct dsa_lag *lag;
|
||||
bool lag_tx_enabled;
|
||||
u8 lag_hash_bits;
|
||||
+7
-7
@@ -1,7 +1,7 @@
|
||||
From b723f7484006aadbaa51e16b870f3c98390605b1 Mon Sep 17 00:00:00 2001
|
||||
From ba48edffc80f3dd676a9e8cf63aa4778a4ed0f0d Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Golle <daniel@makrotopia.org>
|
||||
Date: Wed, 1 Apr 2026 13:43:12 +0100
|
||||
Subject: [PATCH 16/19] net: dsa: mxl862xx: support BR_HAIRPIN_MODE bridge flag
|
||||
Subject: [PATCH 15/19] net: dsa: mxl862xx: support BR_HAIRPIN_MODE bridge flag
|
||||
|
||||
Implement hairpin mode by including the port's own bridge port ID in
|
||||
its forwarding portmap. When hairpin is enabled, bridged frames whose
|
||||
@@ -24,7 +24,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
|
||||
--- a/drivers/net/dsa/mxl862xx/mxl862xx.c
|
||||
+++ b/drivers/net/dsa/mxl862xx/mxl862xx.c
|
||||
@@ -759,6 +759,10 @@ static int __mxl862xx_set_bridge_port(st
|
||||
@@ -774,6 +774,10 @@ static int __mxl862xx_set_bridge_port(st
|
||||
}
|
||||
mxl862xx_fw_portmap_set_bit(br_port_cfg.bridge_port_map,
|
||||
mxl862xx_cpu_bridge_port_id(ds, port));
|
||||
@@ -35,7 +35,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
} else {
|
||||
mxl862xx_fw_portmap_set_bit(br_port_cfg.bridge_port_map,
|
||||
mxl862xx_cpu_bridge_port_id(ds, port));
|
||||
@@ -3895,7 +3899,7 @@ static int mxl862xx_port_pre_bridge_flag
|
||||
@@ -3911,7 +3915,7 @@ static int mxl862xx_port_pre_bridge_flag
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
if (flags.mask & ~(BR_FLOOD | BR_MCAST_FLOOD | BR_BCAST_FLOOD |
|
||||
@@ -44,7 +44,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
@@ -3937,7 +3941,11 @@ static int mxl862xx_port_bridge_flags(st
|
||||
@@ -3953,7 +3957,11 @@ static int mxl862xx_port_bridge_flags(st
|
||||
if (flags.mask & BR_LEARNING)
|
||||
priv->ports[port].learning = !!(flags.val & BR_LEARNING);
|
||||
|
||||
@@ -59,7 +59,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
if (ret)
|
||||
--- a/drivers/net/dsa/mxl862xx/mxl862xx.h
|
||||
+++ b/drivers/net/dsa/mxl862xx/mxl862xx.h
|
||||
@@ -240,6 +240,10 @@ struct mxl862xx_port_stats {
|
||||
@@ -243,6 +243,10 @@ struct mxl862xx_port_stats {
|
||||
* @stats_lock: protects accumulator reads in .get_stats64 against
|
||||
* concurrent updates from the polling work
|
||||
* @tag_8021q_vid: currently assigned tag_8021q management VID
|
||||
@@ -70,7 +70,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
* @ingress_mirror: true when ingress mirroring is active on this port
|
||||
* @egress_mirror: true when egress mirroring is active on this port
|
||||
* @lag: non-NULL when port is member of a LAG group;
|
||||
@@ -269,6 +273,7 @@ struct mxl862xx_port {
|
||||
@@ -272,6 +276,7 @@ struct mxl862xx_port {
|
||||
struct work_struct host_flood_work;
|
||||
u16 tag_8021q_vid;
|
||||
struct mxl862xx_evlan_block cpu_egress_evlan;
|
||||
+8
-8
@@ -1,7 +1,7 @@
|
||||
From d8f20ba50ce0f93f34a41a9b833be76a5d1d2714 Mon Sep 17 00:00:00 2001
|
||||
From 45fcd9669da62b27823004480c07854c54574a1a Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Golle <daniel@makrotopia.org>
|
||||
Date: Wed, 25 Mar 2026 01:51:33 +0000
|
||||
Subject: [PATCH 17/19] net: dsa: mxl862xx: support BR_ISOLATED bridge flag
|
||||
Subject: [PATCH 16/19] net: dsa: mxl862xx: support BR_ISOLATED bridge flag
|
||||
|
||||
Implement port isolation by excluding isolated ports from each other's
|
||||
forwarding portmaps in sync_bridge_members. Non-isolated ports can
|
||||
@@ -19,7 +19,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
|
||||
--- a/drivers/net/dsa/mxl862xx/mxl862xx.c
|
||||
+++ b/drivers/net/dsa/mxl862xx/mxl862xx.c
|
||||
@@ -752,6 +752,8 @@ static int __mxl862xx_set_bridge_port(st
|
||||
@@ -767,6 +767,8 @@ static int __mxl862xx_set_bridge_port(st
|
||||
continue;
|
||||
if (!mxl862xx_is_lag_master(priv, member_dp->index))
|
||||
continue;
|
||||
@@ -28,7 +28,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
mxl862xx_fw_portmap_set_bit(
|
||||
br_port_cfg.bridge_port_map,
|
||||
mxl862xx_lag_bridge_port(priv,
|
||||
@@ -3899,7 +3901,7 @@ static int mxl862xx_port_pre_bridge_flag
|
||||
@@ -3915,7 +3917,7 @@ static int mxl862xx_port_pre_bridge_flag
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
if (flags.mask & ~(BR_FLOOD | BR_MCAST_FLOOD | BR_BCAST_FLOOD |
|
||||
@@ -37,7 +37,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
@@ -3912,6 +3914,7 @@ static int mxl862xx_port_bridge_flags(st
|
||||
@@ -3928,6 +3930,7 @@ static int mxl862xx_port_bridge_flags(st
|
||||
struct mxl862xx_priv *priv = ds->priv;
|
||||
unsigned long old_block = priv->ports[port].flood_block;
|
||||
unsigned long block = old_block;
|
||||
@@ -45,7 +45,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
int ret;
|
||||
|
||||
if (flags.mask & BR_FLOOD) {
|
||||
@@ -3952,6 +3955,21 @@ static int mxl862xx_port_bridge_flags(st
|
||||
@@ -3968,6 +3971,21 @@ static int mxl862xx_port_bridge_flags(st
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -69,7 +69,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
|
||||
--- a/drivers/net/dsa/mxl862xx/mxl862xx.h
|
||||
+++ b/drivers/net/dsa/mxl862xx/mxl862xx.h
|
||||
@@ -213,6 +213,9 @@ struct mxl862xx_port_stats {
|
||||
@@ -216,6 +216,9 @@ struct mxl862xx_port_stats {
|
||||
* @flood_block: bitmask of firmware meter indices that are currently
|
||||
* rate-limiting flood traffic on this port (zero-rate
|
||||
* meters used to block flooding)
|
||||
@@ -79,7 +79,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
* @learning: true when address learning is enabled on this port
|
||||
* @setup_done: set at end of port_setup, cleared at start of
|
||||
* port_teardown; guards deferred work against
|
||||
@@ -259,6 +262,7 @@ struct mxl862xx_port {
|
||||
@@ -262,6 +265,7 @@ struct mxl862xx_port {
|
||||
struct mxl862xx_priv *priv;
|
||||
u16 fid;
|
||||
unsigned long flood_block;
|
||||
+134
@@ -0,0 +1,134 @@
|
||||
From 8120b9b88ec47ee41b8350e3e4341839f5fdc28e Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Golle <daniel@makrotopia.org>
|
||||
Date: Tue, 24 Mar 2026 18:17:49 +0000
|
||||
Subject: [PATCH 17/19] DO NOT SUBMIT: net: dsa: mxl862xx: re-introduce PCE
|
||||
workaround for old firmware
|
||||
|
||||
Re-introduce the legacy PCE rule paths needed for firmware versions
|
||||
older than 1.0.83.
|
||||
|
||||
Firmware >= 1.0.83 exposes the new GSW_TFLOW_PCERULELOGICWRITE API
|
||||
which selects the per-CTP block via @region/@logicalportid and grows
|
||||
the hardware block on demand. Older firmware lacks that command and
|
||||
exposes only the legacy GSW_TFLOW_PCERULEWRITE call, where the rule
|
||||
index is a direct offset into a fixed-size pre-allocated CTP block.
|
||||
Add MXL862XX_TFLOW_PCERULEWRITE back to mxl862xx-cmd.h and make
|
||||
mxl862xx_pce_rule_write() pick the right command at runtime based on
|
||||
the cached firmware version.
|
||||
|
||||
In addition, firmware older than 1.0.80 still installs global PCE
|
||||
rules at boot that redirect link-local frames (BPDUs, LLDP, LACP) to
|
||||
port 0 (the on-chip microcontroller) instead of the DSA CPU port.
|
||||
With port 0 disabled under DSA these rules silently drop matching
|
||||
traffic. Re-introduce mxl862xx_disable_fw_global_rules() to clear
|
||||
them out during setup. The upstream submission replaced that call
|
||||
with a dev_warn() since firmware >= 1.0.80 no longer installs the
|
||||
problematic rules.
|
||||
|
||||
This commit is for downstream use only and must not be submitted
|
||||
upstream.
|
||||
|
||||
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
---
|
||||
drivers/net/dsa/mxl862xx/mxl862xx-cmd.h | 1 +
|
||||
drivers/net/dsa/mxl862xx/mxl862xx.c | 61 +++++++++++++++++++++----
|
||||
2 files changed, 53 insertions(+), 9 deletions(-)
|
||||
|
||||
--- a/drivers/net/dsa/mxl862xx/mxl862xx-cmd.h
|
||||
+++ b/drivers/net/dsa/mxl862xx/mxl862xx-cmd.h
|
||||
@@ -32,6 +32,7 @@
|
||||
#define MXL862XX_COMMON_MONITORPORTCFGSET (MXL862XX_COMMON_MAGIC + 0xe)
|
||||
#define MXL862XX_COMMON_REGISTERMOD (MXL862XX_COMMON_MAGIC + 0x11)
|
||||
|
||||
+#define MXL862XX_TFLOW_PCERULEWRITE (MXL862XX_TFLOW_MAGIC + 0x2)
|
||||
#define MXL862XX_TFLOW_PCERULEALLOC (MXL862XX_TFLOW_MAGIC + 0x4)
|
||||
#define MXL862XX_TFLOW_PCERULEFREE (MXL862XX_TFLOW_MAGIC + 0x5)
|
||||
#define MXL862XX_TFLOW_PCERULELOGICWRITE \
|
||||
--- a/drivers/net/dsa/mxl862xx/mxl862xx.c
|
||||
+++ b/drivers/net/dsa/mxl862xx/mxl862xx.c
|
||||
@@ -449,6 +449,43 @@ static int mxl862xx_setup_drop_meter(str
|
||||
return MXL862XX_API_WRITE(priv, MXL862XX_COMMON_REGISTERMOD, reg);
|
||||
}
|
||||
|
||||
+/* Disable firmware global PCE rules that trap various protocols to the
|
||||
+ * on-die microcontroller (port 0) via PORTMAP_CPU. Under DSA, these
|
||||
+ * frames must either reach the host CPU via per-port rules (link-local)
|
||||
+ * or through the normal bridge forwarding path (ARP broadcast), so the
|
||||
+ * global firmware rules are not needed. With the microcontroller port
|
||||
+ * disabled they would silently drop matching traffic.
|
||||
+ *
|
||||
+ * Global rules have lower indices than CTP rules, hence higher priority
|
||||
+ * in the PCE pipeline -- they must be explicitly disabled or they will
|
||||
+ * shadow the per-CTP traps.
|
||||
+ *
|
||||
+ * Indices from gsw_flow_index.h:
|
||||
+ * 1 -- BPDU (STP/RSTP, dst 01:80:c2:00:00:00)
|
||||
+ * 3 -- LLDP (EtherType 0x88cc)
|
||||
+ * 4 -- OAM/LACP (EtherType 0x8809)
|
||||
+ * 6 -- System MAC (dst 02:e0:92:00:00:01, vendor management MAC)
|
||||
+ * 7 -- ARP Request (broadcast + EtherType 0x0806 + TPA 192.0.2.1)
|
||||
+ */
|
||||
+static int mxl862xx_disable_fw_global_rules(struct dsa_switch *ds)
|
||||
+{
|
||||
+ static const u16 indices[] = { 1, 3, 4, 6, 7 };
|
||||
+ struct mxl862xx_pce_rule rule;
|
||||
+ int i, ret;
|
||||
+
|
||||
+ for (i = 0; i < ARRAY_SIZE(indices); i++) {
|
||||
+ memset(&rule, 0, sizeof(rule));
|
||||
+ rule.pattern.index = cpu_to_le16(indices[i]);
|
||||
+ /* pattern.enable == 0 -> rule is disabled */
|
||||
+
|
||||
+ ret = MXL862XX_API_WRITE(ds->priv,
|
||||
+ MXL862XX_TFLOW_PCERULEWRITE, rule);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
|
||||
/* Per-CTP logical indices for protocol trap rules.
|
||||
*
|
||||
@@ -463,16 +500,20 @@ static int mxl862xx_setup_drop_meter(str
|
||||
#define MXL862XX_MLDV1_CTP_INDEX 3
|
||||
#define MXL862XX_MLDV2_CTP_INDEX 4
|
||||
|
||||
-/* Install (or overwrite) a PCE rule via the firmware's logical-index
|
||||
- * API. The firmware translates the logical index in @rule->pattern.index
|
||||
- * to a physical position within the block selected by @rule->region and
|
||||
- * @rule->logicalportid, and expands the hardware block size as needed.
|
||||
+/* Install (or overwrite) a PCE rule. On firmware >= 1.0.83 use the
|
||||
+ * logical-index API (PCERULELOGICWRITE), which grows the per-CTP block
|
||||
+ * on demand. On older firmware that API does not exist, so fall back
|
||||
+ * to the legacy PCERULEWRITE call which uses the rule index as a
|
||||
+ * direct offset into a fixed-size pre-allocated CTP block.
|
||||
*/
|
||||
static int mxl862xx_pce_rule_write(struct mxl862xx_priv *priv,
|
||||
struct mxl862xx_pce_rule *rule)
|
||||
{
|
||||
- return MXL862XX_API_WRITE(priv, MXL862XX_TFLOW_PCERULELOGICWRITE,
|
||||
- *rule);
|
||||
+ u16 cmd = MXL862XX_FW_VER_MIN(priv, 1, 0, 83) ?
|
||||
+ MXL862XX_TFLOW_PCERULELOGICWRITE :
|
||||
+ MXL862XX_TFLOW_PCERULEWRITE;
|
||||
+
|
||||
+ return MXL862XX_API_WRITE(priv, cmd, *rule);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1130,9 +1171,11 @@ static int mxl862xx_setup(struct dsa_swi
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
- if (!MXL862XX_FW_VER_MIN(priv, 1, 0, 80))
|
||||
- dev_warn(ds->dev, "firmware < 1.0.80 installs global PCE rules "
|
||||
- "that interfere with DSA operation, please update\n");
|
||||
+ if (!MXL862XX_FW_VER_MIN(priv, 1, 0, 80)) {
|
||||
+ ret = mxl862xx_disable_fw_global_rules(ds);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+ }
|
||||
|
||||
/* Pre-allocate firmware resources for all ports. The DSA core
|
||||
* calls change_tag_protocol() between setup() and port_setup(),
|
||||
+490
@@ -0,0 +1,490 @@
|
||||
From 494a1eb62219d9ccb97a60e15ea59e7de2f5d9bc Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Golle <daniel@makrotopia.org>
|
||||
Date: Tue, 24 Mar 2026 18:19:56 +0000
|
||||
Subject: [PATCH 18/19] DO NOT SUBMIT: net: dsa: mxl862xx: legacy SFP API
|
||||
fallback for old firmware
|
||||
|
||||
Re-introduce the SYS_MISC_SFP_SET-based PCS implementation as a
|
||||
fallback for firmware versions older than 1.0.84 which lack the
|
||||
XPCS API. mxl862xx_setup_pcs() selects between the XPCS ops and
|
||||
legacy SFP ops based on firmware version.
|
||||
|
||||
This commit is for downstream use only and must not be submitted
|
||||
upstream.
|
||||
|
||||
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
---
|
||||
drivers/net/dsa/mxl862xx/mxl862xx-api.h | 244 ++++++++++++++++++++
|
||||
drivers/net/dsa/mxl862xx/mxl862xx-cmd.h | 3 +
|
||||
drivers/net/dsa/mxl862xx/mxl862xx-phylink.c | 155 ++++++++++++-
|
||||
drivers/net/dsa/mxl862xx/mxl862xx-phylink.h | 3 +
|
||||
4 files changed, 401 insertions(+), 4 deletions(-)
|
||||
|
||||
--- a/drivers/net/dsa/mxl862xx/mxl862xx-api.h
|
||||
+++ b/drivers/net/dsa/mxl862xx/mxl862xx-api.h
|
||||
@@ -2164,6 +2164,18 @@ struct mxl862xx_sys_fw_image_version {
|
||||
} __packed;
|
||||
|
||||
/**
|
||||
+ * enum mxl862xx_port_duplex - Ethernet port duplex status
|
||||
+ * @MXL862XX_DUPLEX_FULL: Port operates in full-duplex mode
|
||||
+ * @MXL862XX_DUPLEX_HALF: Port operates in half-duplex mode
|
||||
+ * @MXL862XX_DUPLEX_AUTO: Port operates in Auto mode
|
||||
+ */
|
||||
+enum mxl862xx_port_duplex {
|
||||
+ MXL862XX_DUPLEX_FULL = 0,
|
||||
+ MXL862XX_DUPLEX_HALF,
|
||||
+ MXL862XX_DUPLEX_AUTO,
|
||||
+};
|
||||
+
|
||||
+/**
|
||||
* enum mxl862xx_port_type - Port Type
|
||||
* @MXL862XX_LOGICAL_PORT: Logical Port
|
||||
* @MXL862XX_PHYSICAL_PORT: Physical Port
|
||||
@@ -2178,6 +2190,238 @@ enum mxl862xx_port_type {
|
||||
};
|
||||
|
||||
/**
|
||||
+ * enum mxl862xx_port_enable - port enable type selection.
|
||||
+ * @MXL862XX_PORT_DISABLE: the port is disabled in both directions
|
||||
+ * @MXL862XX_PORT_ENABLE_RXTX: the port is enabled in both directions
|
||||
+ * @MXL862XX_PORT_ENABLE_RX: the port is enabled in the receive direction
|
||||
+ * @MXL862XX_PORT_ENABLE_TX: the port is enabled in the transmit direction
|
||||
+ */
|
||||
+enum mxl862xx_port_enable {
|
||||
+ MXL862XX_PORT_DISABLE = 0,
|
||||
+ MXL862XX_PORT_ENABLE_RXTX,
|
||||
+ MXL862XX_PORT_ENABLE_RX,
|
||||
+ MXL862XX_PORT_ENABLE_TX,
|
||||
+};
|
||||
+
|
||||
+/**
|
||||
+ * enum mxl862xx_port_flow - ethernet flow control status
|
||||
+ * @MXL862XX_FLOW_AUTO: automatic flow control
|
||||
+ * @MXL862XX_FLOW_RX: receive flow control only
|
||||
+ * @MXL862XX_FLOW_TX: transmit flow control only
|
||||
+ * @MXL862XX_FLOW_RXTX: receive and transmit flow control
|
||||
+ * @MXL862XX_FLOW_OFF: no flow control
|
||||
+ */
|
||||
+enum mxl862xx_port_flow {
|
||||
+ MXL862XX_FLOW_AUTO = 0,
|
||||
+ MXL862XX_FLOW_RX,
|
||||
+ MXL862XX_FLOW_TX,
|
||||
+ MXL862XX_FLOW_RXTX,
|
||||
+ MXL862XX_FLOW_OFF,
|
||||
+};
|
||||
+
|
||||
+/**
|
||||
+ * enum mxl862xx_port_monitor - port mirror options
|
||||
+ * @MXL862XX_PORT_MONITOR_NONE: mirroring is disabled
|
||||
+ * @MXL862XX_PORT_MONITOR_RX: ingress packets are mirrored
|
||||
+ * @MXL862XX_PORT_MONITOR_TX: egress packets are mirrored
|
||||
+ * @MXL862XX_PORT_MONITOR_RXTX: ingress and egress packets are mirrored
|
||||
+ * @MXL862XX_PORT_MONITOR_VLAN_UNKNOWN: mirroring of 'unknown VLAN violation' frames
|
||||
+ * @MXL862XX_PORT_MONITOR_VLAN_MEMBERSHIP: mirroring of 'VLAN ingress or egress membership
|
||||
+ * violation' frames
|
||||
+ * @MXL862XX_PORT_MONITOR_PORT_STATE: mirroring of 'port state violation' frames
|
||||
+ * @MXL862XX_PORT_MONITOR_LEARNING_LIMIT: mirroring of 'MAC learning limit violation' frames
|
||||
+ * @MXL862XX_PORT_MONITOR_PORT_LOCK: mirroring of 'port lock violation' frames
|
||||
+ */
|
||||
+enum mxl862xx_port_monitor {
|
||||
+ MXL862XX_PORT_MONITOR_NONE = 0,
|
||||
+ MXL862XX_PORT_MONITOR_RX,
|
||||
+ MXL862XX_PORT_MONITOR_TX,
|
||||
+ MXL862XX_PORT_MONITOR_RXTX,
|
||||
+ MXL862XX_PORT_MONITOR_VLAN_UNKNOWN,
|
||||
+ MXL862XX_PORT_MONITOR_VLAN_MEMBERSHIP = 16,
|
||||
+ MXL862XX_PORT_MONITOR_PORT_STATE = 32,
|
||||
+ MXL862XX_PORT_MONITOR_LEARNING_LIMIT = 64,
|
||||
+ MXL862XX_PORT_MONITOR_PORT_LOCK = 128,
|
||||
+};
|
||||
+
|
||||
+/**
|
||||
+ * enum mxl862xx_if_rmon_mode - interface RMON counter mode
|
||||
+ * @MXL862XX_IF_RMON_FID: FID based RMON counters
|
||||
+ * @MXL862XX_IF_RMON_SUBID: sub-interface ID based
|
||||
+ * @MXL862XX_IF_RMON_FLOWID_LSB: flow ID based (bits 3:0)
|
||||
+ * @MXL862XX_IF_RMON_FLOWID_MSB: flow ID based (bits 7:4)
|
||||
+ */
|
||||
+enum mxl862xx_if_rmon_mode {
|
||||
+ MXL862XX_IF_RMON_FID = 0,
|
||||
+ MXL862XX_IF_RMON_SUBID,
|
||||
+ MXL862XX_IF_RMON_FLOWID_LSB,
|
||||
+ MXL862XX_IF_RMON_FLOWID_MSB,
|
||||
+};
|
||||
+
|
||||
+/**
|
||||
+ * struct mxl862xx_port_cfg - Port Configuration Parameters
|
||||
+ * @port_type: See &enum mxl862xx_port_type
|
||||
+ * @port_id: Ethernet Port number (zero-based counting)
|
||||
+ * @enable: See &enum mxl862xx_port_enable
|
||||
+ * @unicast_unknown_drop: Drop unknown unicast packets
|
||||
+ * @multicast_unknown_drop: Drop unknown multicast packets
|
||||
+ * @reserved_packet_drop: Drop reserved packet types
|
||||
+ * @broadcast_drop: Drop broadcast packets
|
||||
+ * @aging: Enables MAC address table aging.
|
||||
+ * @learning: MAC address table learning
|
||||
+ * @learning_mac_port_lock: Automatic MAC address table learning locking on the port
|
||||
+ * @learning_limit: Automatic MAC address table learning limitation on this port
|
||||
+ * @mac_spoofing_detection: MAC spoofing detection. Identifies ingress packets that carry
|
||||
+ * a MAC source address which was previously learned on a different ingress port
|
||||
+ * @flow_ctrl: See &enum mxl862xx_port_flow
|
||||
+ * @port_monitor: See &enum mxl862xx_port_monitor
|
||||
+ * @if_counters: Assign Interface RMON Counters for this Port
|
||||
+ * @if_count_start_idx: Interface RMON Counters Start Index
|
||||
+ * @if_rmonmode: See &enum mxl862xx_if_rmon_mode
|
||||
+ */
|
||||
+struct mxl862xx_port_cfg {
|
||||
+ __le32 port_type; /* enum mxl862xx_port_type */
|
||||
+ __le16 port_id;
|
||||
+ __le32 enable; /* enum mxl862xx_port_enable */
|
||||
+ u8 unicast_unknown_drop;
|
||||
+ u8 multicast_unknown_drop;
|
||||
+ u8 reserved_packet_drop;
|
||||
+ u8 broadcast_drop;
|
||||
+ u8 aging;
|
||||
+ u8 learning;
|
||||
+ u8 learning_mac_port_lock;
|
||||
+ __le16 learning_limit;
|
||||
+ u8 mac_spoofing_detection;
|
||||
+ __le32 flow_ctrl; /* enum mxl862xx_port_flow */
|
||||
+ __le32 port_monitor; /* enum mxl862xx_port_monitor */
|
||||
+ u8 if_counters;
|
||||
+ __le32 if_count_start_idx;
|
||||
+ __le32 if_rmonmode; /* enum mxl862xx_if_rmon_mode */
|
||||
+} __packed;
|
||||
+
|
||||
+/**
|
||||
+ * enum mxl862xx_port_speed - Ethernet port speed mode
|
||||
+ * @MXL862XX_PORT_SPEED_10: 10 Mbit/s
|
||||
+ * @MXL862XX_PORT_SPEED_100: 100 Mbit/s
|
||||
+ * @MXL862XX_PORT_SPEED_200: 200 Mbit/s
|
||||
+ * @MXL862XX_PORT_SPEED_1000: 1000 Mbit/s
|
||||
+ * @MXL862XX_PORT_SPEED_2500: 2.5 Gbit/s
|
||||
+ * @MXL862XX_PORT_SPEED_5000: 5 Gbit/s
|
||||
+ * @MXL862XX_PORT_SPEED_10000: 10 Gbit/s
|
||||
+ * @MXL862XX_PORT_SPEED_AUTO: Auto speed for XGMAC
|
||||
+ */
|
||||
+enum mxl862xx_port_speed {
|
||||
+ MXL862XX_PORT_SPEED_10 = 0,
|
||||
+ MXL862XX_PORT_SPEED_100,
|
||||
+ MXL862XX_PORT_SPEED_200,
|
||||
+ MXL862XX_PORT_SPEED_1000,
|
||||
+ MXL862XX_PORT_SPEED_2500,
|
||||
+ MXL862XX_PORT_SPEED_5000,
|
||||
+ MXL862XX_PORT_SPEED_10000,
|
||||
+ MXL862XX_PORT_SPEED_AUTO,
|
||||
+};
|
||||
+
|
||||
+/**
|
||||
+ * enum mxl862xx_port_link - Force the MAC and PHY link modus
|
||||
+ * @MXL862XX_PORT_LINK_UP: Link up
|
||||
+ * @MXL862XX_PORT_LINK_DOWN: Link down
|
||||
+ * @MXL862XX_PORT_LINK_AUTO: Link Auto
|
||||
+ */
|
||||
+enum mxl862xx_port_link {
|
||||
+ MXL862XX_PORT_LINK_UP = 0,
|
||||
+ MXL862XX_PORT_LINK_DOWN,
|
||||
+ MXL862XX_PORT_LINK_AUTO,
|
||||
+};
|
||||
+
|
||||
+/**
|
||||
+ * enum mxl862xx_mii_mode - Ethernet port interface mode
|
||||
+ * @MXL862XX_PORT_HW_MII: Normal PHY interface
|
||||
+ * @MXL862XX_PORT_HW_RMII: Reduced MII interface in normal mode
|
||||
+ * @MXL862XX_PORT_HW_GMII: GMII or MII, depending upon the speed
|
||||
+ * @MXL862XX_PORT_HW_RGMII: RGMII mode
|
||||
+ * @MXL862XX_PORT_HW_XGMII: XGMII mode
|
||||
+ */
|
||||
+enum mxl862xx_mii_mode {
|
||||
+ MXL862XX_PORT_HW_MII = 0,
|
||||
+ MXL862XX_PORT_HW_RMII,
|
||||
+ MXL862XX_PORT_HW_GMII,
|
||||
+ MXL862XX_PORT_HW_RGMII,
|
||||
+ MXL862XX_PORT_HW_XGMII,
|
||||
+};
|
||||
+
|
||||
+/**
|
||||
+ * enum mxl862xx_mii_type - Ethernet port configuration for PHY or MAC mode
|
||||
+ * @MXL862XX_PORT_MAC: The Ethernet port is configured to work in MAC mode
|
||||
+ * @MXL862XX_PORT_PHY: The Ethernet port is configured to work in PHY mode
|
||||
+ */
|
||||
+enum mxl862xx_mii_type {
|
||||
+ MXL862XX_PORT_MAC = 0,
|
||||
+ MXL862XX_PORT_PHY,
|
||||
+};
|
||||
+
|
||||
+/**
|
||||
+ * enum mxl862xx_clk_mode - Ethernet port clock source configuration
|
||||
+ * @MXL862XX_PORT_CLK_NA: Clock Mode not applicable
|
||||
+ * @MXL862XX_PORT_CLK_MASTER: Clock Master Mode.
|
||||
+ * @MXL862XX_PORT_CLK_SLAVE: Clock Slave Mode.
|
||||
+ */
|
||||
+enum mxl862xx_clk_mode {
|
||||
+ MXL862XX_PORT_CLK_NA = 0,
|
||||
+ MXL862XX_PORT_CLK_MASTER,
|
||||
+ MXL862XX_PORT_CLK_SLAVE,
|
||||
+};
|
||||
+
|
||||
+/**
|
||||
+ * struct mxl862xx_port_link_cfg - Ethernet port link, speed status and flow control status
|
||||
+ * @port_id: Ethernet Port number
|
||||
+ * @duplex_force: Force Port Duplex Mode
|
||||
+ * @duplex: See &enum mxl862xx_port_duplex
|
||||
+ * @speed_force: Force Link Speed
|
||||
+ * @speed: See &enum mxl862xx_port_speed
|
||||
+ * @link_force: Force Link
|
||||
+ * @link: See &enum mxl862xx_port_link
|
||||
+ * @mii_mode: See &enum mxl862xx_mii_mode
|
||||
+ * @mii_type: See &enum mxl862xx_mii_type
|
||||
+ * @clk_mode: See &enum mxl862xx_clk_mode
|
||||
+ * @lpi: 'Low Power Idle' Support for 'Energy Efficient Ethernet'
|
||||
+ */
|
||||
+struct mxl862xx_port_link_cfg {
|
||||
+ __le16 port_id;
|
||||
+ u8 duplex_force;
|
||||
+ __le32 duplex; /* enum mxl862xx_port_duplex */
|
||||
+ u8 speed_force;
|
||||
+ __le32 speed; /* enum mxl862xx_port_speed */
|
||||
+ u8 link_force;
|
||||
+ __le32 link; /* enum mxl862xx_port_link */
|
||||
+ __le32 mii_mode; /* enum mxl862xx_mii_mode */
|
||||
+ __le32 mii_type; /* enum mxl862xx_mii_type */
|
||||
+ __le32 clk_mode; /* enum mxl862xx_clk_mode */
|
||||
+ u8 lpi;
|
||||
+} __packed;
|
||||
+
|
||||
+/**
|
||||
+ * struct mxl862xx_sys_sfp_cfg - legacy SFP/SerDes port configuration
|
||||
+ * @port_id: port id (0 or 1)
|
||||
+ * @option: config options (0 - SFP mode/speed/link-status, 1 - flow control)
|
||||
+ * @mode: SFP mode (0 - auto, 1 - fix, 2 - disable)
|
||||
+ * @speed: select speed when mode is 1
|
||||
+ * @link: get link state
|
||||
+ * @fc_en: flow control (0 - disable, 1 - enable)
|
||||
+ */
|
||||
+struct mxl862xx_sys_sfp_cfg {
|
||||
+ u8 port_id:4;
|
||||
+ u8 option:4;
|
||||
+ union {
|
||||
+ struct {
|
||||
+ u8 mode;
|
||||
+ u8 speed;
|
||||
+ u8 link;
|
||||
+ };
|
||||
+ u8 fc_en;
|
||||
+ };
|
||||
+} __packed;
|
||||
+
|
||||
+/**
|
||||
* enum mxl862xx_rmon_port_type - RMON counter table type
|
||||
* @MXL862XX_RMON_CTP_PORT_RX: CTP RX counters
|
||||
* @MXL862XX_RMON_CTP_PORT_TX: CTP TX counters
|
||||
--- a/drivers/net/dsa/mxl862xx/mxl862xx-cmd.h
|
||||
+++ b/drivers/net/dsa/mxl862xx/mxl862xx-cmd.h
|
||||
@@ -27,6 +27,8 @@
|
||||
#define SYS_MISC_MAGIC 0x1900
|
||||
#define MXL862XX_XPCS_MAGIC 0x1a00
|
||||
|
||||
+#define MXL862XX_COMMON_PORTLINKCFGGET (MXL862XX_COMMON_MAGIC + 0x5)
|
||||
+#define MXL862XX_COMMON_PORTCFGGET (MXL862XX_COMMON_MAGIC + 0x7)
|
||||
#define MXL862XX_COMMON_CFGGET (MXL862XX_COMMON_MAGIC + 0x9)
|
||||
#define MXL862XX_COMMON_CFGSET (MXL862XX_COMMON_MAGIC + 0xa)
|
||||
#define MXL862XX_COMMON_MONITORPORTCFGSET (MXL862XX_COMMON_MAGIC + 0xe)
|
||||
@@ -86,6 +88,7 @@
|
||||
|
||||
#define SYS_MISC_FW_UPDATE (SYS_MISC_MAGIC + 0x1)
|
||||
#define SYS_MISC_FW_VERSION (SYS_MISC_MAGIC + 0x2)
|
||||
+#define SYS_MISC_SFP_SET (SYS_MISC_MAGIC + 0xe)
|
||||
|
||||
#define MXL862XX_XPCS_PCS_CONFIG (MXL862XX_XPCS_MAGIC + 0x1)
|
||||
#define MXL862XX_XPCS_PCS_GET_STATE (MXL862XX_XPCS_MAGIC + 0x2)
|
||||
--- a/drivers/net/dsa/mxl862xx/mxl862xx-phylink.c
|
||||
+++ b/drivers/net/dsa/mxl862xx/mxl862xx-phylink.c
|
||||
@@ -62,6 +62,152 @@ static struct mxl862xx_pcs *pcs_to_mxl86
|
||||
return container_of(pcs, struct mxl862xx_pcs, pcs);
|
||||
}
|
||||
|
||||
+/* Legacy SFP-based PCS implementation for firmware < 1.0.84 */
|
||||
+static int mxl862xx_legacy_pcs_config(struct phylink_pcs *pcs,
|
||||
+ unsigned int neg_mode,
|
||||
+ phy_interface_t interface,
|
||||
+ const unsigned long *advertising,
|
||||
+ bool permit_pause_to_mac)
|
||||
+{
|
||||
+ struct mxl862xx_pcs *mpcs = pcs_to_mxl862xx_pcs(pcs);
|
||||
+ struct mxl862xx_priv *priv = mpcs->priv;
|
||||
+ struct mxl862xx_sys_sfp_cfg ser_intf = {
|
||||
+ .option = 0,
|
||||
+ .mode = 1,
|
||||
+ };
|
||||
+
|
||||
+ if (mpcs->slot != 0)
|
||||
+ return 0;
|
||||
+
|
||||
+ ser_intf.port_id = mpcs->serdes_id;
|
||||
+
|
||||
+ switch (interface) {
|
||||
+ case PHY_INTERFACE_MODE_SGMII:
|
||||
+ ser_intf.speed = 8;
|
||||
+ break;
|
||||
+ case PHY_INTERFACE_MODE_1000BASEX:
|
||||
+ ser_intf.speed = (neg_mode & PHYLINK_PCS_NEG_INBAND) ? 1 : 7;
|
||||
+ break;
|
||||
+ case PHY_INTERFACE_MODE_2500BASEX:
|
||||
+ ser_intf.speed = 4;
|
||||
+ break;
|
||||
+ case PHY_INTERFACE_MODE_10GBASER:
|
||||
+ ser_intf.speed = 2;
|
||||
+ break;
|
||||
+ case PHY_INTERFACE_MODE_USXGMII:
|
||||
+ ser_intf.speed = 3;
|
||||
+ break;
|
||||
+ default:
|
||||
+ dev_err(priv->ds->dev, "unsupported interface: %s\n",
|
||||
+ phy_modes(interface));
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ return MXL862XX_API_WRITE(priv, SYS_MISC_SFP_SET, ser_intf);
|
||||
+}
|
||||
+
|
||||
+static void mxl862xx_legacy_pcs_get_state(struct phylink_pcs *pcs,
|
||||
+ struct phylink_link_state *state)
|
||||
+{
|
||||
+ struct mxl862xx_pcs *mpcs = pcs_to_mxl862xx_pcs(pcs);
|
||||
+ struct mxl862xx_priv *priv = mpcs->priv;
|
||||
+ struct mxl862xx_port_link_cfg port_link_cfg = {
|
||||
+ .port_id = cpu_to_le16(MXL862XX_PCS_PORT(mpcs)),
|
||||
+ };
|
||||
+ struct mxl862xx_port_cfg port_cfg = {
|
||||
+ .port_id = cpu_to_le16(MXL862XX_PCS_PORT(mpcs)),
|
||||
+ };
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = MXL862XX_API_READ(priv, MXL862XX_COMMON_PORTLINKCFGGET,
|
||||
+ port_link_cfg);
|
||||
+ if (ret)
|
||||
+ return;
|
||||
+
|
||||
+ ret = MXL862XX_API_READ(priv, MXL862XX_COMMON_PORTCFGGET, port_cfg);
|
||||
+ if (ret)
|
||||
+ return;
|
||||
+
|
||||
+ state->link = (le32_to_cpu(port_link_cfg.link) == MXL862XX_PORT_LINK_UP);
|
||||
+ state->an_complete = state->link;
|
||||
+
|
||||
+ switch (le32_to_cpu(port_link_cfg.speed)) {
|
||||
+ case MXL862XX_PORT_SPEED_10:
|
||||
+ state->speed = SPEED_10;
|
||||
+ break;
|
||||
+ case MXL862XX_PORT_SPEED_100:
|
||||
+ state->speed = SPEED_100;
|
||||
+ break;
|
||||
+ case MXL862XX_PORT_SPEED_1000:
|
||||
+ state->speed = SPEED_1000;
|
||||
+ break;
|
||||
+ case MXL862XX_PORT_SPEED_2500:
|
||||
+ state->speed = SPEED_2500;
|
||||
+ break;
|
||||
+ case MXL862XX_PORT_SPEED_5000:
|
||||
+ state->speed = SPEED_5000;
|
||||
+ break;
|
||||
+ case MXL862XX_PORT_SPEED_10000:
|
||||
+ state->speed = SPEED_10000;
|
||||
+ break;
|
||||
+ default:
|
||||
+ state->speed = SPEED_UNKNOWN;
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ switch (le32_to_cpu(port_link_cfg.duplex)) {
|
||||
+ case MXL862XX_DUPLEX_HALF:
|
||||
+ state->duplex = DUPLEX_HALF;
|
||||
+ break;
|
||||
+ case MXL862XX_DUPLEX_FULL:
|
||||
+ state->duplex = DUPLEX_FULL;
|
||||
+ break;
|
||||
+ default:
|
||||
+ state->duplex = DUPLEX_UNKNOWN;
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ state->pause &= ~(MLO_PAUSE_RX | MLO_PAUSE_TX);
|
||||
+ switch (le32_to_cpu(port_cfg.flow_ctrl)) {
|
||||
+ case MXL862XX_FLOW_RXTX:
|
||||
+ state->pause |= MLO_PAUSE_TXRX_MASK;
|
||||
+ break;
|
||||
+ case MXL862XX_FLOW_TX:
|
||||
+ state->pause |= MLO_PAUSE_TX;
|
||||
+ break;
|
||||
+ case MXL862XX_FLOW_RX:
|
||||
+ state->pause |= MLO_PAUSE_RX;
|
||||
+ break;
|
||||
+ case MXL862XX_FLOW_OFF:
|
||||
+ default:
|
||||
+ break;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static unsigned int
|
||||
+mxl862xx_legacy_pcs_inband_caps(struct phylink_pcs *pcs,
|
||||
+ phy_interface_t interface)
|
||||
+{
|
||||
+ switch (interface) {
|
||||
+ case PHY_INTERFACE_MODE_SGMII:
|
||||
+ case PHY_INTERFACE_MODE_USXGMII:
|
||||
+ return LINK_INBAND_ENABLE;
|
||||
+ case PHY_INTERFACE_MODE_1000BASEX:
|
||||
+ return LINK_INBAND_DISABLE | LINK_INBAND_ENABLE;
|
||||
+ case PHY_INTERFACE_MODE_10GBASER:
|
||||
+ case PHY_INTERFACE_MODE_2500BASEX:
|
||||
+ return LINK_INBAND_DISABLE;
|
||||
+ default:
|
||||
+ return 0;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static const struct phylink_pcs_ops mxl862xx_legacy_pcs_ops = {
|
||||
+ .pcs_get_state = mxl862xx_legacy_pcs_get_state,
|
||||
+ .pcs_config = mxl862xx_legacy_pcs_config,
|
||||
+ .pcs_inband_caps = mxl862xx_legacy_pcs_inband_caps,
|
||||
+};
|
||||
+
|
||||
static int mxl862xx_xpcs_if_mode(phy_interface_t interface)
|
||||
{
|
||||
switch (interface) {
|
||||
@@ -351,7 +497,10 @@ void mxl862xx_setup_pcs(struct mxl862xx_
|
||||
pcs->slot = MXL862XX_SERDES_SLOT(port);
|
||||
pcs->interface = PHY_INTERFACE_MODE_NA;
|
||||
|
||||
- pcs->pcs.ops = &mxl862xx_pcs_ops;
|
||||
+ if (MXL862XX_FW_VER_MIN(priv, 1, 0, 84))
|
||||
+ pcs->pcs.ops = &mxl862xx_pcs_ops;
|
||||
+ else
|
||||
+ pcs->pcs.ops = &mxl862xx_legacy_pcs_ops;
|
||||
pcs->pcs.poll = true;
|
||||
}
|
||||
|
||||
@@ -363,9 +512,6 @@ mxl862xx_phylink_mac_select_pcs(struct p
|
||||
struct mxl862xx_priv *priv = dp->ds->priv;
|
||||
int port = dp->index;
|
||||
|
||||
- if (!MXL862XX_FW_VER_MIN(priv, 1, 0, 84))
|
||||
- return NULL;
|
||||
-
|
||||
switch (port) {
|
||||
case 9 ... 16:
|
||||
return &priv->serdes_ports[port - 9].pcs;
|
||||
--- a/drivers/net/dsa/mxl862xx/mxl862xx-phylink.h
|
||||
+++ b/drivers/net/dsa/mxl862xx/mxl862xx-phylink.h
|
||||
@@ -11,6 +11,9 @@
|
||||
(((port) - MXL862XX_FIRST_SERDES_PORT) % MXL862XX_SERDES_SLOTS)
|
||||
#define MXL862XX_SERDES_PORT_ID(port) \
|
||||
(((port) - MXL862XX_FIRST_SERDES_PORT) / MXL862XX_SERDES_SLOTS)
|
||||
+#define MXL862XX_PCS_PORT(mpcs) \
|
||||
+ (MXL862XX_FIRST_SERDES_PORT + \
|
||||
+ (mpcs)->serdes_id * MXL862XX_SERDES_SLOTS + (mpcs)->slot)
|
||||
|
||||
extern const struct phylink_mac_ops mxl862xx_phylink_mac_ops;
|
||||
void mxl862xx_phylink_get_caps(struct dsa_switch *ds, int port,
|
||||
-81
@@ -1,81 +0,0 @@
|
||||
From 8856f7610167a3005ecef401c8528111d153b554 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Golle <daniel@makrotopia.org>
|
||||
Date: Tue, 24 Mar 2026 18:17:49 +0000
|
||||
Subject: [PATCH 18/19] DO NOT SUBMIT: net: dsa: mxl862xx: re-introduce PCE
|
||||
workaround for old firmware
|
||||
|
||||
Re-introduce the mxl862xx_disable_fw_global_rules() function that
|
||||
disables firmware default global PCE rules for firmware versions
|
||||
older than 1.0.80. The upstream submission replaced this with a
|
||||
dev_warn() since firmware >= 1.0.80 no longer installs these rules,
|
||||
but downstream deployments may still run older firmware.
|
||||
|
||||
This commit is for downstream use only and must not be submitted
|
||||
upstream.
|
||||
|
||||
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
---
|
||||
drivers/net/dsa/mxl862xx/mxl862xx.c | 45 +++++++++++++++++++++++++++--
|
||||
1 file changed, 42 insertions(+), 3 deletions(-)
|
||||
|
||||
--- a/drivers/net/dsa/mxl862xx/mxl862xx.c
|
||||
+++ b/drivers/net/dsa/mxl862xx/mxl862xx.c
|
||||
@@ -449,6 +449,43 @@ static int mxl862xx_setup_drop_meter(str
|
||||
return MXL862XX_API_WRITE(priv, MXL862XX_COMMON_REGISTERMOD, reg);
|
||||
}
|
||||
|
||||
+/* Disable firmware global PCE rules that trap various protocols to the
|
||||
+ * on-die microcontroller (port 0) via PORTMAP_CPU. Under DSA, these
|
||||
+ * frames must either reach the host CPU via per-port rules (link-local)
|
||||
+ * or through the normal bridge forwarding path (ARP broadcast), so the
|
||||
+ * global firmware rules are not needed. With the microcontroller port
|
||||
+ * disabled they would silently drop matching traffic.
|
||||
+ *
|
||||
+ * Global rules have lower indices than CTP rules, hence higher priority
|
||||
+ * in the PCE pipeline -- they must be explicitly disabled or they will
|
||||
+ * shadow the per-CTP traps.
|
||||
+ *
|
||||
+ * Indices from gsw_flow_index.h:
|
||||
+ * 1 -- BPDU (STP/RSTP, dst 01:80:c2:00:00:00)
|
||||
+ * 3 -- LLDP (EtherType 0x88cc)
|
||||
+ * 4 -- OAM/LACP (EtherType 0x8809)
|
||||
+ * 6 -- System MAC (dst 02:e0:92:00:00:01, vendor management MAC)
|
||||
+ * 7 -- ARP Request (broadcast + EtherType 0x0806 + TPA 192.0.2.1)
|
||||
+ */
|
||||
+static int mxl862xx_disable_fw_global_rules(struct dsa_switch *ds)
|
||||
+{
|
||||
+ static const u16 indices[] = { 1, 3, 4, 6, 7 };
|
||||
+ struct mxl862xx_pce_rule rule;
|
||||
+ int i, ret;
|
||||
+
|
||||
+ for (i = 0; i < ARRAY_SIZE(indices); i++) {
|
||||
+ memset(&rule, 0, sizeof(rule));
|
||||
+ rule.pattern.index = cpu_to_le16(indices[i]);
|
||||
+ /* pattern.enable == 0 -> rule is disabled */
|
||||
+
|
||||
+ ret = MXL862XX_API_WRITE(ds->priv,
|
||||
+ MXL862XX_TFLOW_PCERULEWRITE, rule);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
|
||||
/* Per-CTP offsets for protocol trap rules. Each port's CTP flow-table
|
||||
* block is pre-allocated by the firmware during init (44 entries per
|
||||
@@ -1114,9 +1151,11 @@ static int mxl862xx_setup(struct dsa_swi
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
- if (!MXL862XX_FW_VER_MIN(priv, 1, 0, 80))
|
||||
- dev_warn(ds->dev, "firmware < 1.0.80 installs global PCE rules "
|
||||
- "that interfere with DSA operation, please update\n");
|
||||
+ if (!MXL862XX_FW_VER_MIN(priv, 1, 0, 80)) {
|
||||
+ ret = mxl862xx_disable_fw_global_rules(ds);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+ }
|
||||
|
||||
/* Pre-allocate firmware resources for all ports. The DSA core
|
||||
* calls change_tag_protocol() between setup() and port_setup(),
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
From df0c747216063041ba0d786b01f9b1e2aba5316a Mon Sep 17 00:00:00 2001
|
||||
From 332dd61f50b096256f889ecb4d730d385e58aec2 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Golle <daniel@makrotopia.org>
|
||||
Date: Wed, 22 Apr 2026 15:15:52 +0100
|
||||
Subject: [PATCH] DO NOT SUBMIT: net: dsa: mxl862xx: increase CMD timeout
|
||||
Subject: [PATCH 19/19] DO NOT SUBMIT: net: dsa: mxl862xx: increase CMD timeout
|
||||
|
||||
Lift the command timeout by 10x from 500ms to 5s.
|
||||
This is done because older firmware can be extremely slow to respond
|
||||
-251
@@ -1,251 +0,0 @@
|
||||
From f0548f842b9ff31f19452a2fc72a16f937d86008 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Golle <daniel@makrotopia.org>
|
||||
Date: Tue, 24 Mar 2026 18:19:56 +0000
|
||||
Subject: [PATCH 26/26] DO NOT SUBMIT: net: dsa: mxl862xx: legacy SFP API
|
||||
fallback for old firmware
|
||||
|
||||
Re-introduce the SYS_MISC_SFP_SET-based PCS implementation as a
|
||||
fallback for firmware versions older than 1.0.80 which lack the
|
||||
XPCS API. mxl862xx_setup_pcs() selects between the XPCS ops and
|
||||
legacy SFP ops based on firmware version.
|
||||
|
||||
This commit is for downstream use only and must not be submitted
|
||||
upstream.
|
||||
|
||||
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
---
|
||||
drivers/net/dsa/mxl862xx/mxl862xx-api.h | 22 +++
|
||||
drivers/net/dsa/mxl862xx/mxl862xx-cmd.h | 1 +
|
||||
drivers/net/dsa/mxl862xx/mxl862xx-phylink.c | 160 +++++++++++++++++++-
|
||||
3 files changed, 178 insertions(+), 5 deletions(-)
|
||||
|
||||
--- a/drivers/net/dsa/mxl862xx/mxl862xx-api.h
|
||||
+++ b/drivers/net/dsa/mxl862xx/mxl862xx-api.h
|
||||
@@ -2400,6 +2400,28 @@ struct mxl862xx_sys_fw_image_version {
|
||||
} __packed;
|
||||
|
||||
/**
|
||||
+ * struct mxl862xx_sys_sfp_cfg - legacy SFP/SerDes port configuration
|
||||
+ * @port_id: port id (0 or 1)
|
||||
+ * @option: config options (0 - SFP mode/speed/link-status, 1 - flow control)
|
||||
+ * @mode: SFP mode (0 - auto, 1 - fix, 2 - disable)
|
||||
+ * @speed: select speed when mode is 1
|
||||
+ * @link: get link state
|
||||
+ * @fc_en: flow control (0 - disable, 1 - enable)
|
||||
+ */
|
||||
+struct mxl862xx_sys_sfp_cfg {
|
||||
+ u8 port_id:4;
|
||||
+ u8 option:4;
|
||||
+ union {
|
||||
+ struct {
|
||||
+ u8 mode;
|
||||
+ u8 speed;
|
||||
+ u8 link;
|
||||
+ };
|
||||
+ u8 fc_en;
|
||||
+ };
|
||||
+} __packed;
|
||||
+
|
||||
+/**
|
||||
* enum mxl862xx_rmon_port_type - RMON counter table type
|
||||
* @MXL862XX_RMON_CTP_PORT_RX: CTP RX counters
|
||||
* @MXL862XX_RMON_CTP_PORT_TX: CTP TX counters
|
||||
--- a/drivers/net/dsa/mxl862xx/mxl862xx-cmd.h
|
||||
+++ b/drivers/net/dsa/mxl862xx/mxl862xx-cmd.h
|
||||
@@ -85,6 +85,7 @@
|
||||
|
||||
#define SYS_MISC_FW_UPDATE (SYS_MISC_MAGIC + 0x1)
|
||||
#define SYS_MISC_FW_VERSION (SYS_MISC_MAGIC + 0x2)
|
||||
+#define SYS_MISC_SFP_SET (SYS_MISC_MAGIC + 0xe)
|
||||
|
||||
#define MXL862XX_XPCS_MAGIC 0x1a00
|
||||
#define MXL862XX_XPCS_PCS_CONFIG (MXL862XX_XPCS_MAGIC + 0x1)
|
||||
--- a/drivers/net/dsa/mxl862xx/mxl862xx-phylink.c
|
||||
+++ b/drivers/net/dsa/mxl862xx/mxl862xx-phylink.c
|
||||
@@ -52,6 +52,155 @@ static struct mxl862xx_pcs *pcs_to_mxl86
|
||||
return container_of(pcs, struct mxl862xx_pcs, pcs);
|
||||
}
|
||||
|
||||
+/* Legacy SFP-based PCS implementation for firmware < 1.0.80 */
|
||||
+static int mxl862xx_legacy_pcs_config(struct phylink_pcs *pcs,
|
||||
+ unsigned int neg_mode,
|
||||
+ phy_interface_t interface,
|
||||
+ const unsigned long *advertising,
|
||||
+ bool permit_pause_to_mac)
|
||||
+{
|
||||
+ struct mxl862xx_priv *priv = pcs_to_mxl862xx_pcs(pcs)->priv;
|
||||
+ int port = pcs_to_mxl862xx_pcs(pcs)->port;
|
||||
+ struct mxl862xx_sys_sfp_cfg ser_intf = {
|
||||
+ .option = 0,
|
||||
+ .mode = 1,
|
||||
+ };
|
||||
+
|
||||
+ if (port != 9 && port != 13)
|
||||
+ return 0;
|
||||
+
|
||||
+ if (port == 9)
|
||||
+ ser_intf.port_id = 0;
|
||||
+ else
|
||||
+ ser_intf.port_id = 1;
|
||||
+
|
||||
+ switch (interface) {
|
||||
+ case PHY_INTERFACE_MODE_SGMII:
|
||||
+ ser_intf.speed = 8;
|
||||
+ break;
|
||||
+ case PHY_INTERFACE_MODE_1000BASEX:
|
||||
+ ser_intf.speed = (neg_mode & PHYLINK_PCS_NEG_INBAND) ? 1 : 7;
|
||||
+ break;
|
||||
+ case PHY_INTERFACE_MODE_2500BASEX:
|
||||
+ ser_intf.speed = 4;
|
||||
+ break;
|
||||
+ case PHY_INTERFACE_MODE_10GBASER:
|
||||
+ ser_intf.speed = 2;
|
||||
+ break;
|
||||
+ case PHY_INTERFACE_MODE_USXGMII:
|
||||
+ ser_intf.speed = 3;
|
||||
+ break;
|
||||
+ default:
|
||||
+ dev_err(priv->ds->dev, "unsupported interface: %s\n",
|
||||
+ phy_modes(interface));
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ return MXL862XX_API_WRITE(priv, SYS_MISC_SFP_SET, ser_intf);
|
||||
+}
|
||||
+
|
||||
+static void mxl862xx_legacy_pcs_get_state(struct phylink_pcs *pcs,
|
||||
+ struct phylink_link_state *state)
|
||||
+{
|
||||
+ struct mxl862xx_priv *priv = pcs_to_mxl862xx_pcs(pcs)->priv;
|
||||
+ int port = pcs_to_mxl862xx_pcs(pcs)->port;
|
||||
+ struct mxl862xx_port_link_cfg port_link_cfg = {
|
||||
+ .port_id = port,
|
||||
+ };
|
||||
+ struct mxl862xx_port_cfg port_cfg = {
|
||||
+ .port_id = port,
|
||||
+ };
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = MXL862XX_API_READ(priv, MXL862XX_COMMON_PORTLINKCFGGET,
|
||||
+ port_link_cfg);
|
||||
+ if (ret)
|
||||
+ return;
|
||||
+
|
||||
+ ret = MXL862XX_API_READ(priv, MXL862XX_COMMON_PORTCFGGET, port_cfg);
|
||||
+ if (ret)
|
||||
+ return;
|
||||
+
|
||||
+ state->link = (port_link_cfg.link == MXL862XX_PORT_LINK_UP);
|
||||
+ state->an_complete = state->link;
|
||||
+
|
||||
+ switch (port_link_cfg.speed) {
|
||||
+ case MXL862XX_PORT_SPEED_10:
|
||||
+ state->speed = SPEED_10;
|
||||
+ break;
|
||||
+ case MXL862XX_PORT_SPEED_100:
|
||||
+ state->speed = SPEED_100;
|
||||
+ break;
|
||||
+ case MXL862XX_PORT_SPEED_1000:
|
||||
+ state->speed = SPEED_1000;
|
||||
+ break;
|
||||
+ case MXL862XX_PORT_SPEED_2500:
|
||||
+ state->speed = SPEED_2500;
|
||||
+ break;
|
||||
+ case MXL862XX_PORT_SPEED_5000:
|
||||
+ state->speed = SPEED_5000;
|
||||
+ break;
|
||||
+ case MXL862XX_PORT_SPEED_10000:
|
||||
+ state->speed = SPEED_10000;
|
||||
+ break;
|
||||
+ default:
|
||||
+ state->speed = SPEED_UNKNOWN;
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ switch (port_link_cfg.duplex) {
|
||||
+ case MXL862XX_DUPLEX_HALF:
|
||||
+ state->duplex = DUPLEX_HALF;
|
||||
+ break;
|
||||
+ case MXL862XX_DUPLEX_FULL:
|
||||
+ state->duplex = DUPLEX_FULL;
|
||||
+ break;
|
||||
+ default:
|
||||
+ state->duplex = DUPLEX_UNKNOWN;
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ state->pause &= ~(MLO_PAUSE_RX | MLO_PAUSE_TX);
|
||||
+ switch (port_cfg.flow_ctrl) {
|
||||
+ case MXL862XX_FLOW_RXTX:
|
||||
+ state->pause |= MLO_PAUSE_TXRX_MASK;
|
||||
+ break;
|
||||
+ case MXL862XX_FLOW_TX:
|
||||
+ state->pause |= MLO_PAUSE_TX;
|
||||
+ break;
|
||||
+ case MXL862XX_FLOW_RX:
|
||||
+ state->pause |= MLO_PAUSE_RX;
|
||||
+ break;
|
||||
+ case MXL862XX_FLOW_OFF:
|
||||
+ default:
|
||||
+ break;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static unsigned int
|
||||
+mxl862xx_legacy_pcs_inband_caps(struct phylink_pcs *pcs,
|
||||
+ phy_interface_t interface)
|
||||
+{
|
||||
+ switch (interface) {
|
||||
+ case PHY_INTERFACE_MODE_SGMII:
|
||||
+ case PHY_INTERFACE_MODE_USXGMII:
|
||||
+ return LINK_INBAND_ENABLE;
|
||||
+ case PHY_INTERFACE_MODE_1000BASEX:
|
||||
+ return LINK_INBAND_DISABLE | LINK_INBAND_ENABLE;
|
||||
+ case PHY_INTERFACE_MODE_10GBASER:
|
||||
+ case PHY_INTERFACE_MODE_2500BASEX:
|
||||
+ return LINK_INBAND_DISABLE;
|
||||
+ default:
|
||||
+ return 0;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static const struct phylink_pcs_ops mxl862xx_legacy_pcs_ops = {
|
||||
+ .pcs_get_state = mxl862xx_legacy_pcs_get_state,
|
||||
+ .pcs_config = mxl862xx_legacy_pcs_config,
|
||||
+ .pcs_inband_caps = mxl862xx_legacy_pcs_inband_caps,
|
||||
+};
|
||||
+
|
||||
static int mxl862xx_xpcs_port_id(int port)
|
||||
{
|
||||
return port >= 13;
|
||||
@@ -389,7 +538,10 @@ void mxl862xx_setup_pcs(struct mxl862xx_
|
||||
pcs->priv = priv;
|
||||
pcs->port = port;
|
||||
|
||||
- pcs->pcs.ops = &mxl862xx_pcs_ops;
|
||||
+ if (MXL862XX_FW_VER_MIN(priv, 1, 0, 80))
|
||||
+ pcs->pcs.ops = &mxl862xx_pcs_ops;
|
||||
+ else
|
||||
+ pcs->pcs.ops = &mxl862xx_legacy_pcs_ops;
|
||||
pcs->pcs.poll = true;
|
||||
}
|
||||
|
||||
@@ -401,9 +553,6 @@ mxl862xx_phylink_mac_select_pcs(struct p
|
||||
struct mxl862xx_priv *priv = dp->ds->priv;
|
||||
int port = dp->index;
|
||||
|
||||
- if (!MXL862XX_FW_VER_MIN(priv, 1, 0, 80))
|
||||
- return NULL;
|
||||
-
|
||||
switch (port) {
|
||||
case 9 ... 16:
|
||||
return &priv->serdes_ports[port - 9].pcs;
|
||||
@@ -534,7 +683,7 @@ void mxl862xx_serdes_get_stats(struct ds
|
||||
}
|
||||
|
||||
void mxl862xx_serdes_self_test(struct dsa_switch *ds, int port,
|
||||
- struct ethtool_test *etest, u64 *data)
|
||||
+ struct ethtool_test *etest, u64 *data)
|
||||
{
|
||||
struct mxl862xx_xpcs_prbs_cfg prbs = {};
|
||||
struct mxl862xx_xpcs_bert_cfg bert = {};
|
||||
+19
-32
@@ -1,4 +1,4 @@
|
||||
From 60a23e663e0c607ae4ed871aaa24d257051ad557 Mon Sep 17 00:00:00 2001
|
||||
From 1ad83956d550a252fffc473a191dbe155c4a383e Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Golle <daniel@makrotopia.org>
|
||||
Date: Tue, 24 Mar 2026 17:56:35 +0000
|
||||
Subject: [PATCH 01/19] net: dsa: mxl862xx: store firmware version for feature
|
||||
@@ -8,15 +8,15 @@ Query the firmware version at init (already done in wait_ready),
|
||||
cache it in priv->fw_version, and provide MXL862XX_FW_VER_MIN()
|
||||
for version-gated code paths throughout the driver.
|
||||
|
||||
The union mxl862xx_fw_version lays out major/minor/revision so
|
||||
that the u32 raw field compares with natural version ordering on
|
||||
both big- and little-endian machines.
|
||||
MXL862XX_FW_VER() packs major/minor/revision into a u32 with
|
||||
bitwise shifts so that versions compare with natural ordering,
|
||||
independent of host endianness.
|
||||
|
||||
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
---
|
||||
drivers/net/dsa/mxl862xx/mxl862xx.c | 3 +++
|
||||
drivers/net/dsa/mxl862xx/mxl862xx.h | 36 +++++++++++++++++++++++++++++
|
||||
2 files changed, 39 insertions(+)
|
||||
drivers/net/dsa/mxl862xx/mxl862xx.h | 23 +++++++++++++++++++++++
|
||||
2 files changed, 26 insertions(+)
|
||||
|
||||
--- a/drivers/net/dsa/mxl862xx/mxl862xx.c
|
||||
+++ b/drivers/net/dsa/mxl862xx/mxl862xx.c
|
||||
@@ -40,46 +40,33 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
#include <linux/mdio.h>
|
||||
#include <linux/workqueue.h>
|
||||
#include <net/dsa.h>
|
||||
@@ -241,6 +242,38 @@ struct mxl862xx_port {
|
||||
@@ -241,6 +242,25 @@ struct mxl862xx_port {
|
||||
spinlock_t stats_lock; /* protects stats accumulators */
|
||||
};
|
||||
|
||||
+/**
|
||||
+ * union mxl862xx_fw_version - firmware version for comparison and display
|
||||
+ * struct mxl862xx_fw_version - firmware version for comparison and display
|
||||
+ * @major: firmware major version
|
||||
+ * @minor: firmware minor version
|
||||
+ * @revision: firmware revision number
|
||||
+ * @raw: combined u32 for direct >= comparison (major most significant)
|
||||
+ *
|
||||
+ * The struct layout places major in the most-significant byte of the
|
||||
+ * u32 on both big- and little-endian machines, so raw values compare
|
||||
+ * with the natural major > minor > revision ordering.
|
||||
+ */
|
||||
+union mxl862xx_fw_version {
|
||||
+ struct {
|
||||
+#if defined(__BIG_ENDIAN)
|
||||
+ u8 major;
|
||||
+ u8 minor;
|
||||
+ u16 revision;
|
||||
+#elif defined(__LITTLE_ENDIAN)
|
||||
+ u16 revision;
|
||||
+ u8 minor;
|
||||
+ u8 major;
|
||||
+#endif
|
||||
+ };
|
||||
+ u32 raw;
|
||||
+struct mxl862xx_fw_version {
|
||||
+ u8 major;
|
||||
+ u8 minor;
|
||||
+ u16 revision;
|
||||
+};
|
||||
+
|
||||
+#define MXL862XX_FW_VER(maj, min, rev) \
|
||||
+ ((union mxl862xx_fw_version){ .major = (maj), .minor = (min), \
|
||||
+ .revision = (rev) }).raw
|
||||
+ (((u32)(maj) << 24) | ((u32)(min) << 16) | (rev))
|
||||
+#define MXL862XX_FW_VER_MIN(priv, maj, min, rev) \
|
||||
+ ((priv)->fw_version.raw >= MXL862XX_FW_VER(maj, min, rev))
|
||||
+ (MXL862XX_FW_VER((priv)->fw_version.major, (priv)->fw_version.minor, \
|
||||
+ (priv)->fw_version.revision) >= \
|
||||
+ MXL862XX_FW_VER(maj, min, rev))
|
||||
+
|
||||
/* Bit indices for struct mxl862xx_priv::flags */
|
||||
#define MXL862XX_FLAG_CRC_ERR 0
|
||||
#define MXL862XX_FLAG_WORK_STOPPED 1
|
||||
@@ -258,6 +291,8 @@ struct mxl862xx_port {
|
||||
@@ -258,6 +278,8 @@ struct mxl862xx_port {
|
||||
* @drop_meter: index of the single shared zero-rate firmware meter
|
||||
* used to unconditionally drop traffic (used to block
|
||||
* flooding)
|
||||
@@ -88,11 +75,11 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
* @ports: per-port state, indexed by switch port number
|
||||
* @bridges: maps DSA bridge number to firmware bridge ID;
|
||||
* zero means no firmware bridge allocated for that
|
||||
@@ -275,6 +310,7 @@ struct mxl862xx_priv {
|
||||
@@ -275,6 +297,7 @@ struct mxl862xx_priv {
|
||||
struct work_struct crc_err_work;
|
||||
unsigned long flags;
|
||||
u16 drop_meter;
|
||||
+ union mxl862xx_fw_version fw_version;
|
||||
+ struct mxl862xx_fw_version fw_version;
|
||||
struct mxl862xx_port ports[MXL862XX_MAX_PORTS];
|
||||
u16 bridges[MXL862XX_MAX_BRIDGES + 1];
|
||||
u16 evlan_ingress_size;
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
From cefa0447dc95a4ddd5093f7b8cf35e654870283f Mon Sep 17 00:00:00 2001
|
||||
From eaf472bfc89692cd3cc5e0298c90791f4c1c3244 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Golle <daniel@makrotopia.org>
|
||||
Date: Wed, 25 Mar 2026 21:39:30 +0000
|
||||
Subject: [PATCH 02/19] net: dsa: mxl862xx: move phylink stubs to
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
From 3c1d77006daca1df20d612850535bc6050e266ee Mon Sep 17 00:00:00 2001
|
||||
From 483be884b2fdee28ac70458067c45a1369939144 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Golle <daniel@makrotopia.org>
|
||||
Date: Thu, 26 Mar 2026 01:50:00 +0000
|
||||
Subject: [PATCH 03/19] net: dsa: mxl862xx: move API macros to mxl862xx-host.h
|
||||
|
||||
+400
-602
File diff suppressed because it is too large
Load Diff
+82
-77
@@ -1,32 +1,54 @@
|
||||
From 3659914c43a587a1ca6418867834831aa518ac35 Mon Sep 17 00:00:00 2001
|
||||
From 74044a2d2e62fcc3ee2b6cf22742fa94609c529e Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Golle <daniel@makrotopia.org>
|
||||
Date: Tue, 24 Mar 2026 18:14:33 +0000
|
||||
Subject: [PATCH 05/19] net: dsa: mxl862xx: add SerDes ethtool statistics
|
||||
|
||||
Expose SerDes equalization and signal detect parameters as ethtool
|
||||
statistics on ports 9-16 (XPCS-backed ports). Uses the XPCS EQ_GET
|
||||
and SIGNAL_DETECT firmware commands to read TX/RX equalization
|
||||
coefficients, DFE taps, and link-level signal status.
|
||||
Expose SerDes equalization parameters as ethtool statistics on
|
||||
ports 9-16 (XPCS-backed ports). Uses the XPCS EQ_GET firmware
|
||||
command to read TX/RX equalization coefficients and DFE taps.
|
||||
|
||||
The 19 additional stats (serdes_tx_*, serdes_rx_*, serdes_pma_link,
|
||||
serdes_link_fault, serdes_in_reset) are appended after the standard
|
||||
RMON counters and gated on firmware >= 1.0.80.
|
||||
The 15 additional stats (serdes_tx_*, serdes_rx_*) are appended
|
||||
after the standard RMON counters and gated on firmware >= 1.0.84.
|
||||
|
||||
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
---
|
||||
drivers/net/dsa/mxl862xx/mxl862xx-api.h | 88 +++++++++++++++++++
|
||||
drivers/net/dsa/mxl862xx/mxl862xx-cmd.h | 2 +
|
||||
drivers/net/dsa/mxl862xx/mxl862xx-phylink.c | 93 +++++++++++++++++++++
|
||||
drivers/net/dsa/mxl862xx/mxl862xx-api.h | 92 +++++++++++++++++++
|
||||
drivers/net/dsa/mxl862xx/mxl862xx-cmd.h | 1 +
|
||||
drivers/net/dsa/mxl862xx/mxl862xx-phylink.c | 97 +++++++++++++++++++++
|
||||
drivers/net/dsa/mxl862xx/mxl862xx-phylink.h | 3 +
|
||||
drivers/net/dsa/mxl862xx/mxl862xx.c | 6 +-
|
||||
5 files changed, 191 insertions(+), 1 deletion(-)
|
||||
5 files changed, 198 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/net/dsa/mxl862xx/mxl862xx-api.h
|
||||
+++ b/drivers/net/dsa/mxl862xx/mxl862xx-api.h
|
||||
@@ -1812,4 +1812,92 @@ struct mxl862xx_xpcs_reset_cfg {
|
||||
@@ -1668,4 +1668,96 @@ struct mxl862xx_xpcs_pcs_link_up {
|
||||
__le16 result;
|
||||
} __packed;
|
||||
|
||||
+/**
|
||||
+ * struct mxl862xx_xpcs_loopback_cfg - loopback control
|
||||
+ * @port_id: XPCS port index
|
||||
+ * @mode: loopback mode. See &enum mxl862xx_xpcs_loopback_mode
|
||||
+ * @result: firmware result
|
||||
+ */
|
||||
+struct mxl862xx_xpcs_loopback_cfg {
|
||||
+ u8 port_id;
|
||||
+ u8 mode; /* enum mxl862xx_xpcs_loopback_mode */
|
||||
+ __le16 result;
|
||||
+} __packed;
|
||||
+
|
||||
+/**
|
||||
+ * struct mxl862xx_xpcs_reset_cfg - XPCS reset
|
||||
+ * @port_id: XPCS port index
|
||||
+ * @reset_type: reset type. See &enum mxl862xx_xpcs_reset_type
|
||||
+ * @result: firmware result
|
||||
+ */
|
||||
+struct mxl862xx_xpcs_reset_cfg {
|
||||
+ u8 port_id;
|
||||
+ u8 reset_type; /* enum mxl862xx_xpcs_reset_type */
|
||||
+ __le16 result;
|
||||
+} __packed;
|
||||
+
|
||||
+/**
|
||||
+ * struct mxl862xx_xpcs_eq_item - single equalization parameter
|
||||
+ * @value: current initial value
|
||||
@@ -94,42 +116,21 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
+ struct mxl862xx_xpcs_tx_eq_info tx;
|
||||
+ struct mxl862xx_xpcs_rx_eq_info rx;
|
||||
+} __packed;
|
||||
+
|
||||
+/**
|
||||
+ * struct mxl862xx_xpcs_signal_detect - signal detect status
|
||||
+ * @port_id: XPCS port index (0 or 1)
|
||||
+ * @rx_signal: RX signal detected
|
||||
+ * @pma_link: PMA link up
|
||||
+ * @link_fault: PCS link fault
|
||||
+ * @in_reset: XPCS in reset
|
||||
+ * @result: firmware result
|
||||
+ */
|
||||
+struct mxl862xx_xpcs_signal_detect {
|
||||
+ u8 port_id:2;
|
||||
+ u8 rx_signal:1;
|
||||
+ u8 pma_link:1;
|
||||
+ u8 link_fault:1;
|
||||
+ u8 in_reset:1;
|
||||
+ u8 __rsv:2;
|
||||
+ u8 __pad;
|
||||
+ __le16 result;
|
||||
+} __packed;
|
||||
+
|
||||
#endif /* __MXL862XX_API_H */
|
||||
--- a/drivers/net/dsa/mxl862xx/mxl862xx-cmd.h
|
||||
+++ b/drivers/net/dsa/mxl862xx/mxl862xx-cmd.h
|
||||
@@ -83,6 +83,8 @@
|
||||
#define MXL862XX_XPCS_FORCE_SPEED (MXL862XX_XPCS_MAGIC + 0x7)
|
||||
@@ -79,6 +79,7 @@
|
||||
#define MXL862XX_XPCS_PCS_LINK_UP (MXL862XX_XPCS_MAGIC + 0x7)
|
||||
#define MXL862XX_XPCS_LOOPBACK (MXL862XX_XPCS_MAGIC + 0x8)
|
||||
#define MXL862XX_XPCS_RESET (MXL862XX_XPCS_MAGIC + 0x9)
|
||||
+#define MXL862XX_XPCS_EQ_GET (MXL862XX_XPCS_MAGIC + 0xc)
|
||||
+#define MXL862XX_XPCS_SIGNAL_DETECT (MXL862XX_XPCS_MAGIC + 0xd)
|
||||
|
||||
#define MMD_API_MAXIMUM_ID 0x7fff
|
||||
|
||||
--- a/drivers/net/dsa/mxl862xx/mxl862xx-phylink.c
|
||||
+++ b/drivers/net/dsa/mxl862xx/mxl862xx-phylink.c
|
||||
@@ -456,3 +456,96 @@ const struct phylink_mac_ops mxl862xx_ph
|
||||
@@ -414,3 +414,100 @@ const struct phylink_mac_ops mxl862xx_ph
|
||||
.mac_link_up = mxl862xx_phylink_mac_link_up,
|
||||
.mac_select_pcs = mxl862xx_phylink_mac_select_pcs,
|
||||
};
|
||||
@@ -152,18 +153,19 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
+ "serdes_rx_dfe_bypass",
|
||||
+ "serdes_rx_adapt_mode",
|
||||
+ "serdes_rx_adapt_sel",
|
||||
+ "serdes_rx_signal",
|
||||
+ "serdes_pma_link",
|
||||
+ "serdes_link_fault",
|
||||
+ "serdes_in_reset",
|
||||
+};
|
||||
+
|
||||
+static bool mxl862xx_port_has_serdes_stats(struct dsa_switch *ds, int port)
|
||||
+{
|
||||
+ struct mxl862xx_priv *priv = ds->priv;
|
||||
+
|
||||
+ return port >= 9 && port <= 16 &&
|
||||
+ MXL862XX_FW_VER_MIN(priv, 1, 0, 80);
|
||||
+ /* Firmware reads EQ/signal status per XPCS, not per lane. Expose
|
||||
+ * the stats only on the slot-0 port of each XPCS (9 and 13) so
|
||||
+ * users don't see four duplicate copies labelled as if they were
|
||||
+ * independent per-port readings.
|
||||
+ */
|
||||
+ return (port == 9 || port == 13) &&
|
||||
+ MXL862XX_FW_VER_MIN(priv, 1, 0, 84);
|
||||
+}
|
||||
+
|
||||
+int mxl862xx_serdes_stats_count(struct dsa_switch *ds, int port)
|
||||
@@ -185,50 +187,53 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
+ ethtool_puts(&data, mxl862xx_serdes_stats[i]);
|
||||
+}
|
||||
+
|
||||
+static u64 mxl862xx_eq_effective(const struct mxl862xx_xpcs_eq_item *it)
|
||||
+{
|
||||
+ return it->ovrd_en ? it->ovrd : it->value;
|
||||
+}
|
||||
+
|
||||
+void mxl862xx_serdes_get_stats(struct dsa_switch *ds, int port, u64 *data)
|
||||
+{
|
||||
+ struct mxl862xx_xpcs_eq_get eq = {
|
||||
+ .port_id = mxl862xx_xpcs_port_id(port),
|
||||
+ .port_id = MXL862XX_SERDES_PORT_ID(port),
|
||||
+ };
|
||||
+ struct mxl862xx_xpcs_signal_detect sig = {};
|
||||
+ int ret;
|
||||
+
|
||||
+ if (!mxl862xx_port_has_serdes_stats(ds, port))
|
||||
+ return;
|
||||
+
|
||||
+ sig.port_id = mxl862xx_xpcs_port_id(port);
|
||||
+
|
||||
+ if (!MXL862XX_API_READ(ds->priv, MXL862XX_XPCS_EQ_GET, eq)) {
|
||||
+ *data++ = eq.tx.main.value;
|
||||
+ *data++ = eq.tx.pre.value;
|
||||
+ *data++ = eq.tx.post.value;
|
||||
+ *data++ = eq.tx.iboost_lvl.value;
|
||||
+ *data++ = eq.tx.vboost_lvl.value;
|
||||
+ *data++ = eq.tx.vboost_en.value;
|
||||
+ *data++ = eq.rx.att_lvl.value;
|
||||
+ *data++ = eq.rx.vga1_gain.value;
|
||||
+ *data++ = eq.rx.vga2_gain.value;
|
||||
+ *data++ = eq.rx.ctle_boost.value;
|
||||
+ *data++ = eq.rx.ctle_pole.value;
|
||||
+ *data++ = eq.rx.dfe_tap1.value;
|
||||
+ *data++ = eq.rx.dfe_bypass.value;
|
||||
+ *data++ = eq.rx.adapt_mode.value;
|
||||
+ *data++ = eq.rx.adapt_sel.value;
|
||||
+ } else {
|
||||
+ data += 15;
|
||||
+ ret = MXL862XX_API_READ(ds->priv, MXL862XX_XPCS_EQ_GET, eq);
|
||||
+ if (ret) {
|
||||
+ dev_err(ds->dev,
|
||||
+ "port %d: XPCS EQ_GET failed: %d\n", port, ret);
|
||||
+ return;
|
||||
+ }
|
||||
+ if ((s16)le16_to_cpu(eq.result) < 0) {
|
||||
+ dev_err(ds->dev,
|
||||
+ "port %d: XPCS EQ_GET firmware result: %d\n",
|
||||
+ port, (s16)le16_to_cpu(eq.result));
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ if (!MXL862XX_API_READ(ds->priv, MXL862XX_XPCS_SIGNAL_DETECT, sig)) {
|
||||
+ *data++ = sig.rx_signal;
|
||||
+ *data++ = sig.pma_link;
|
||||
+ *data++ = sig.link_fault;
|
||||
+ *data++ = sig.in_reset;
|
||||
+ } else {
|
||||
+ data += 4;
|
||||
+ }
|
||||
+ *data++ = mxl862xx_eq_effective(&eq.tx.main);
|
||||
+ *data++ = mxl862xx_eq_effective(&eq.tx.pre);
|
||||
+ *data++ = mxl862xx_eq_effective(&eq.tx.post);
|
||||
+ *data++ = mxl862xx_eq_effective(&eq.tx.iboost_lvl);
|
||||
+ *data++ = mxl862xx_eq_effective(&eq.tx.vboost_lvl);
|
||||
+ *data++ = mxl862xx_eq_effective(&eq.tx.vboost_en);
|
||||
+ *data++ = mxl862xx_eq_effective(&eq.rx.att_lvl);
|
||||
+ *data++ = mxl862xx_eq_effective(&eq.rx.vga1_gain);
|
||||
+ *data++ = mxl862xx_eq_effective(&eq.rx.vga2_gain);
|
||||
+ *data++ = mxl862xx_eq_effective(&eq.rx.ctle_boost);
|
||||
+ *data++ = mxl862xx_eq_effective(&eq.rx.ctle_pole);
|
||||
+ *data++ = mxl862xx_eq_effective(&eq.rx.dfe_tap1);
|
||||
+ *data++ = mxl862xx_eq_effective(&eq.rx.dfe_bypass);
|
||||
+ *data++ = mxl862xx_eq_effective(&eq.rx.adapt_mode);
|
||||
+ *data++ = mxl862xx_eq_effective(&eq.rx.adapt_sel);
|
||||
+}
|
||||
--- a/drivers/net/dsa/mxl862xx/mxl862xx-phylink.h
|
||||
+++ b/drivers/net/dsa/mxl862xx/mxl862xx-phylink.h
|
||||
@@ -12,5 +12,8 @@ void mxl862xx_phylink_get_caps(struct ds
|
||||
@@ -17,5 +17,8 @@ void mxl862xx_phylink_get_caps(struct ds
|
||||
struct phylink_config *config);
|
||||
void mxl862xx_setup_pcs(struct mxl862xx_priv *priv, struct mxl862xx_pcs *pcs,
|
||||
int port);
|
||||
@@ -239,7 +244,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
#endif /* __MXL862XX_PHYLINK_H */
|
||||
--- a/drivers/net/dsa/mxl862xx/mxl862xx.c
|
||||
+++ b/drivers/net/dsa/mxl862xx/mxl862xx.c
|
||||
@@ -1775,6 +1775,8 @@ static void mxl862xx_get_strings(struct
|
||||
@@ -1776,6 +1776,8 @@ static void mxl862xx_get_strings(struct
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(mxl862xx_mib); i++)
|
||||
ethtool_puts(&data, mxl862xx_mib[i].name);
|
||||
@@ -248,7 +253,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
}
|
||||
|
||||
static int mxl862xx_get_sset_count(struct dsa_switch *ds, int port, int sset)
|
||||
@@ -1782,7 +1784,7 @@ static int mxl862xx_get_sset_count(struc
|
||||
@@ -1783,7 +1785,7 @@ static int mxl862xx_get_sset_count(struc
|
||||
if (sset != ETH_SS_STATS)
|
||||
return 0;
|
||||
|
||||
@@ -257,7 +262,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
}
|
||||
|
||||
static int mxl862xx_read_rmon(struct dsa_switch *ds, int port,
|
||||
@@ -1818,6 +1820,8 @@ static void mxl862xx_get_ethtool_stats(s
|
||||
@@ -1819,6 +1821,8 @@ static void mxl862xx_get_ethtool_stats(s
|
||||
else
|
||||
*data++ = le64_to_cpu(*(__le64 *)field);
|
||||
}
|
||||
|
||||
-208
@@ -1,208 +0,0 @@
|
||||
From ce66c0be462c8500dfc483395e68be4326ebf296 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Golle <daniel@makrotopia.org>
|
||||
Date: Tue, 24 Mar 2026 18:15:32 +0000
|
||||
Subject: [PATCH 06/19] net: dsa: mxl862xx: add SerDes self-test via PRBS and
|
||||
BERT
|
||||
|
||||
Implement the dsa_switch_ops.self_test callback for SerDes ports
|
||||
(9-16). Two loopback tests are run:
|
||||
|
||||
1. PCS-level PRBS31: enables TX/RX PRBS31 pattern at the PCS layer,
|
||||
waits 100ms, then reads the error counter.
|
||||
2. SerDes-level BERT PRBS31: enables TX/RX BERT with PRBS31 pattern
|
||||
at the SerDes layer, waits 100ms, then reads the error counter.
|
||||
|
||||
Both tests clean up (disable pattern generators) regardless of outcome.
|
||||
Gated on firmware >= 1.0.80 via mxl862xx_port_has_serdes_stats().
|
||||
|
||||
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
---
|
||||
drivers/net/dsa/mxl862xx/mxl862xx-api.h | 45 +++++++++++
|
||||
drivers/net/dsa/mxl862xx/mxl862xx-cmd.h | 2 +
|
||||
drivers/net/dsa/mxl862xx/mxl862xx-phylink.c | 85 +++++++++++++++++++++
|
||||
drivers/net/dsa/mxl862xx/mxl862xx-phylink.h | 3 +
|
||||
drivers/net/dsa/mxl862xx/mxl862xx.c | 1 +
|
||||
5 files changed, 136 insertions(+)
|
||||
|
||||
--- a/drivers/net/dsa/mxl862xx/mxl862xx-api.h
|
||||
+++ b/drivers/net/dsa/mxl862xx/mxl862xx-api.h
|
||||
@@ -1900,4 +1900,49 @@ struct mxl862xx_xpcs_signal_detect {
|
||||
__le16 result;
|
||||
} __packed;
|
||||
|
||||
+/**
|
||||
+ * struct mxl862xx_xpcs_prbs_cfg - PCS-level PRBS31 test pattern
|
||||
+ * @port_id: XPCS port index (0 or 1)
|
||||
+ * @tx_en: TX PRBS31 enable
|
||||
+ * @rx_en: RX PRBS31 enable
|
||||
+ * @read_err: read error count
|
||||
+ * @rx_err_cnt: RX PRBS31 error count (valid when read_err=1)
|
||||
+ * @result: firmware result
|
||||
+ */
|
||||
+struct mxl862xx_xpcs_prbs_cfg {
|
||||
+ u8 port_id:2;
|
||||
+ u8 tx_en:1;
|
||||
+ u8 rx_en:1;
|
||||
+ u8 read_err:1;
|
||||
+ u8 __rsv:3;
|
||||
+ u8 __pad;
|
||||
+ __le16 rx_err_cnt;
|
||||
+ __le16 result;
|
||||
+} __packed;
|
||||
+
|
||||
+/**
|
||||
+ * struct mxl862xx_xpcs_bert_cfg - SerDes-level BERT test pattern
|
||||
+ * @port_id: XPCS port index (0 or 1)
|
||||
+ * @tx_en: TX BERT enable
|
||||
+ * @rx_en: RX BERT enable
|
||||
+ * @read_err: read RX error count
|
||||
+ * @clear_err: clear RX error counter
|
||||
+ * @insert_err: insert one TX error
|
||||
+ * @pattern: PRBS pattern type (1-7; 0 = disable)
|
||||
+ * @rx_err_cnt: RX BERT error count (valid when read_err=1)
|
||||
+ * @result: firmware result
|
||||
+ */
|
||||
+struct mxl862xx_xpcs_bert_cfg {
|
||||
+ u8 port_id:2;
|
||||
+ u8 tx_en:1;
|
||||
+ u8 rx_en:1;
|
||||
+ u8 read_err:1;
|
||||
+ u8 clear_err:1;
|
||||
+ u8 insert_err:1;
|
||||
+ u8 __rsv:1;
|
||||
+ u8 pattern;
|
||||
+ __le16 rx_err_cnt;
|
||||
+ __le16 result;
|
||||
+} __packed;
|
||||
+
|
||||
#endif /* __MXL862XX_API_H */
|
||||
--- a/drivers/net/dsa/mxl862xx/mxl862xx-cmd.h
|
||||
+++ b/drivers/net/dsa/mxl862xx/mxl862xx-cmd.h
|
||||
@@ -83,6 +83,8 @@
|
||||
#define MXL862XX_XPCS_FORCE_SPEED (MXL862XX_XPCS_MAGIC + 0x7)
|
||||
#define MXL862XX_XPCS_LOOPBACK (MXL862XX_XPCS_MAGIC + 0x8)
|
||||
#define MXL862XX_XPCS_RESET (MXL862XX_XPCS_MAGIC + 0x9)
|
||||
+#define MXL862XX_XPCS_PRBS_CFG (MXL862XX_XPCS_MAGIC + 0xa)
|
||||
+#define MXL862XX_XPCS_BERT_CFG (MXL862XX_XPCS_MAGIC + 0xb)
|
||||
#define MXL862XX_XPCS_EQ_GET (MXL862XX_XPCS_MAGIC + 0xc)
|
||||
#define MXL862XX_XPCS_SIGNAL_DETECT (MXL862XX_XPCS_MAGIC + 0xd)
|
||||
|
||||
--- a/drivers/net/dsa/mxl862xx/mxl862xx-phylink.c
|
||||
+++ b/drivers/net/dsa/mxl862xx/mxl862xx-phylink.c
|
||||
@@ -549,3 +549,88 @@ void mxl862xx_serdes_get_stats(struct ds
|
||||
data += 4;
|
||||
}
|
||||
}
|
||||
+
|
||||
+void mxl862xx_serdes_self_test(struct dsa_switch *ds, int port,
|
||||
+ struct ethtool_test *etest, u64 *data)
|
||||
+{
|
||||
+ struct mxl862xx_xpcs_prbs_cfg prbs = {};
|
||||
+ struct mxl862xx_xpcs_bert_cfg bert = {};
|
||||
+ struct mxl862xx_priv *priv = ds->priv;
|
||||
+ int xpcs_id = mxl862xx_xpcs_port_id(port);
|
||||
+ int i = 0;
|
||||
+ int ret;
|
||||
+
|
||||
+ if (!mxl862xx_port_has_serdes_stats(ds, port))
|
||||
+ return;
|
||||
+
|
||||
+ /* Test 1: PCS PRBS31 */
|
||||
+ prbs.port_id = xpcs_id;
|
||||
+ prbs.tx_en = 1;
|
||||
+ prbs.rx_en = 1;
|
||||
+ ret = MXL862XX_API_WRITE(priv, MXL862XX_XPCS_PRBS_CFG, prbs);
|
||||
+ if (ret) {
|
||||
+ data[i++] = 1;
|
||||
+ goto skip_prbs;
|
||||
+ }
|
||||
+
|
||||
+ msleep(100);
|
||||
+
|
||||
+ memset(&prbs, 0, sizeof(prbs));
|
||||
+ prbs.port_id = xpcs_id;
|
||||
+ prbs.read_err = 1;
|
||||
+ ret = MXL862XX_API_READ(priv, MXL862XX_XPCS_PRBS_CFG, prbs);
|
||||
+
|
||||
+ /* Disable PRBS */
|
||||
+ memset(&prbs, 0, sizeof(prbs));
|
||||
+ prbs.port_id = xpcs_id;
|
||||
+ MXL862XX_API_WRITE(priv, MXL862XX_XPCS_PRBS_CFG, prbs);
|
||||
+
|
||||
+ if (ret) {
|
||||
+ data[i++] = 1;
|
||||
+ } else {
|
||||
+ data[i] = le16_to_cpu(prbs.rx_err_cnt) ? 1 : 0;
|
||||
+ if (data[i])
|
||||
+ etest->flags |= ETH_TEST_FL_FAILED;
|
||||
+ i++;
|
||||
+ }
|
||||
+
|
||||
+skip_prbs:
|
||||
+ /* Test 2: SerDes BERT PRBS31 -- clear error counter first */
|
||||
+ bert.port_id = xpcs_id;
|
||||
+ bert.clear_err = 1;
|
||||
+ MXL862XX_API_WRITE(priv, MXL862XX_XPCS_BERT_CFG, bert);
|
||||
+
|
||||
+ /* Enable BERT with PRBS31 pattern */
|
||||
+ memset(&bert, 0, sizeof(bert));
|
||||
+ bert.port_id = xpcs_id;
|
||||
+ bert.tx_en = 1;
|
||||
+ bert.rx_en = 1;
|
||||
+ bert.pattern = 6; /* PRBS31 */
|
||||
+ ret = MXL862XX_API_WRITE(priv, MXL862XX_XPCS_BERT_CFG, bert);
|
||||
+ if (ret) {
|
||||
+ data[i++] = 1;
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ msleep(100);
|
||||
+
|
||||
+ /* Read error count */
|
||||
+ memset(&bert, 0, sizeof(bert));
|
||||
+ bert.port_id = xpcs_id;
|
||||
+ bert.read_err = 1;
|
||||
+ ret = MXL862XX_API_READ(priv, MXL862XX_XPCS_BERT_CFG, bert);
|
||||
+
|
||||
+ /* Disable BERT */
|
||||
+ memset(&bert, 0, sizeof(bert));
|
||||
+ bert.port_id = xpcs_id;
|
||||
+ MXL862XX_API_WRITE(priv, MXL862XX_XPCS_BERT_CFG, bert);
|
||||
+
|
||||
+ if (ret) {
|
||||
+ data[i++] = 1;
|
||||
+ } else {
|
||||
+ data[i] = le16_to_cpu(bert.rx_err_cnt) ? 1 : 0;
|
||||
+ if (data[i])
|
||||
+ etest->flags |= ETH_TEST_FL_FAILED;
|
||||
+ i++;
|
||||
+ }
|
||||
+}
|
||||
--- a/drivers/net/dsa/mxl862xx/mxl862xx-phylink.h
|
||||
+++ b/drivers/net/dsa/mxl862xx/mxl862xx-phylink.h
|
||||
@@ -3,6 +3,7 @@
|
||||
#ifndef __MXL862XX_PHYLINK_H
|
||||
#define __MXL862XX_PHYLINK_H
|
||||
|
||||
+#include <linux/ethtool.h>
|
||||
#include <linux/phylink.h>
|
||||
|
||||
#include "mxl862xx.h"
|
||||
@@ -15,5 +16,7 @@ void mxl862xx_setup_pcs(struct mxl862xx_
|
||||
int mxl862xx_serdes_stats_count(struct dsa_switch *ds, int port);
|
||||
void mxl862xx_serdes_get_strings(struct dsa_switch *ds, int port, u8 *data);
|
||||
void mxl862xx_serdes_get_stats(struct dsa_switch *ds, int port, u64 *data);
|
||||
+void mxl862xx_serdes_self_test(struct dsa_switch *ds, int port,
|
||||
+ struct ethtool_test *etest, u64 *data);
|
||||
|
||||
#endif /* __MXL862XX_PHYLINK_H */
|
||||
--- a/drivers/net/dsa/mxl862xx/mxl862xx.c
|
||||
+++ b/drivers/net/dsa/mxl862xx/mxl862xx.c
|
||||
@@ -2088,6 +2088,7 @@ static const struct dsa_switch_ops mxl86
|
||||
.get_pause_stats = mxl862xx_get_pause_stats,
|
||||
.get_rmon_stats = mxl862xx_get_rmon_stats,
|
||||
.get_stats64 = mxl862xx_get_stats64,
|
||||
+ .self_test = mxl862xx_serdes_self_test,
|
||||
};
|
||||
|
||||
static int mxl862xx_probe(struct mdio_device *mdiodev)
|
||||
+70
-46
@@ -1,7 +1,7 @@
|
||||
From e6defbd42db6e64c2bb203f82b7d7f8c0691a052 Mon Sep 17 00:00:00 2001
|
||||
From 50a84327282120a51af12da91214ed9e06f585cb Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Golle <daniel@makrotopia.org>
|
||||
Date: Tue, 24 Mar 2026 18:51:13 +0000
|
||||
Subject: [PATCH 07/19] net: dsa: mxl862xx: trap link-local and multicast
|
||||
Subject: [PATCH 06/19] net: dsa: mxl862xx: trap link-local and multicast
|
||||
snooping frames to CPU
|
||||
|
||||
Install per-CTP PCE rules on each user port that trap IEEE 802.1D
|
||||
@@ -19,10 +19,21 @@ all flood modes enabled. Each trap rule points the bridge engine at
|
||||
this FID via bFidEnable so that IGMP and MLD frames are never
|
||||
silently dropped by the ingress port's private flood policy.
|
||||
|
||||
Three multicast snooping rules are installed per port:
|
||||
offset 2 -- IPv4 IGMP (IP protocol 2, all versions)
|
||||
offset 3 -- ICMPv6 types 130-132 (MLDv1 query, report, done)
|
||||
offset 4 -- ICMPv6 type 143 (MLDv2 Listener Report)
|
||||
Rules are written through the firmware's logical-index API,
|
||||
GSW_TFLOW_PCERULELOGICWRITE. The firmware translates the logical
|
||||
index in @rule->pattern.index into a physical position within the
|
||||
per-CTP block selected by @rule->region and @rule->logicalportid,
|
||||
and grows the hardware block size on demand as rules are inserted.
|
||||
A single dispatch helper, mxl862xx_pce_rule_write(), centralises the
|
||||
firmware command so the trap callers do not need to know which API
|
||||
variant is used. Four logical indices are consumed in each port's
|
||||
per-CTP block (index 0 is reserved by the firmware for its
|
||||
flow-control marking rule):
|
||||
|
||||
index 1 -- IEEE 802.1D link-local (dst 01:80:c2:00:00:0x)
|
||||
index 2 -- IPv4 IGMP (IP protocol 2, all versions)
|
||||
index 3 -- ICMPv6 types 130-132 (MLDv1 query, report, done)
|
||||
index 4 -- ICMPv6 type 143 (MLDv2 Listener Report)
|
||||
|
||||
Add the PCE rule firmware API structures, command definitions, and
|
||||
the rule block allocation interface.
|
||||
@@ -30,15 +41,15 @@ the rule block allocation interface.
|
||||
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
---
|
||||
drivers/net/dsa/mxl862xx/mxl862xx-api.h | 684 ++++++++++++++++++++++++
|
||||
drivers/net/dsa/mxl862xx/mxl862xx-cmd.h | 5 +
|
||||
drivers/net/dsa/mxl862xx/mxl862xx.c | 186 +++++++
|
||||
drivers/net/dsa/mxl862xx/mxl862xx-cmd.h | 6 +
|
||||
drivers/net/dsa/mxl862xx/mxl862xx.c | 198 +++++++
|
||||
drivers/net/dsa/mxl862xx/mxl862xx.h | 8 +
|
||||
4 files changed, 883 insertions(+)
|
||||
4 files changed, 896 insertions(+)
|
||||
|
||||
--- a/drivers/net/dsa/mxl862xx/mxl862xx-api.h
|
||||
+++ b/drivers/net/dsa/mxl862xx/mxl862xx-api.h
|
||||
@@ -1420,6 +1420,690 @@ struct mxl862xx_port_link_cfg {
|
||||
u8 lpi;
|
||||
@@ -1184,6 +1184,690 @@ struct mxl862xx_ctp_port_assignment {
|
||||
__le16 bridge_port_id;
|
||||
} __packed;
|
||||
|
||||
+/* PCE (Packet Classification Engine) rule structures.
|
||||
@@ -694,7 +705,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
+ * @action: Forwarding action (portmap, cross-state, etc.)
|
||||
+ *
|
||||
+ * This structure is passed to the firmware via the MDIO data
|
||||
+ * buffer using the %MXL862XX_TFLOW_PCERULEWRITE command.
|
||||
+ * buffer using the %MXL862XX_TFLOW_PCERULELOGICWRITE command.
|
||||
+ * The binary layout must exactly match the firmware's
|
||||
+ * GSW_PCE_rule_t (466 bytes, packed, little-endian scalars).
|
||||
+ */
|
||||
@@ -738,13 +749,14 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
#define MXL862XX_BRDG_MAGIC 0x300
|
||||
#define MXL862XX_BRDGPORT_MAGIC 0x400
|
||||
#define MXL862XX_CTP_MAGIC 0x500
|
||||
@@ -31,6 +32,10 @@
|
||||
@@ -30,6 +31,11 @@
|
||||
#define MXL862XX_COMMON_CFGSET (MXL862XX_COMMON_MAGIC + 0xa)
|
||||
#define MXL862XX_COMMON_REGISTERMOD (MXL862XX_COMMON_MAGIC + 0x11)
|
||||
|
||||
+#define MXL862XX_TFLOW_PCERULEWRITE (MXL862XX_TFLOW_MAGIC + 0x2)
|
||||
+#define MXL862XX_TFLOW_PCERULEALLOC (MXL862XX_TFLOW_MAGIC + 0x4)
|
||||
+#define MXL862XX_TFLOW_PCERULEFREE (MXL862XX_TFLOW_MAGIC + 0x5)
|
||||
+#define MXL862XX_TFLOW_PCERULELOGICWRITE \
|
||||
+ (MXL862XX_TFLOW_MAGIC + 0xa)
|
||||
+
|
||||
#define MXL862XX_BRIDGE_ALLOC (MXL862XX_BRDG_MAGIC + 0x1)
|
||||
#define MXL862XX_BRIDGE_CONFIGSET (MXL862XX_BRDG_MAGIC + 0x2)
|
||||
@@ -771,21 +783,35 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
return 0;
|
||||
|
||||
not_ready_yet:
|
||||
@@ -381,6 +384,158 @@ static int mxl862xx_setup_drop_meter(str
|
||||
@@ -381,6 +384,170 @@ static int mxl862xx_setup_drop_meter(str
|
||||
return MXL862XX_API_WRITE(priv, MXL862XX_COMMON_REGISTERMOD, reg);
|
||||
}
|
||||
|
||||
+
|
||||
+/* Per-CTP offsets for protocol trap rules. Each port's CTP flow-table
|
||||
+ * block is pre-allocated by the firmware during init (44 entries per
|
||||
+ * port on a 10-port SKU, of which offset 0 is reserved for flow-control
|
||||
+ * marking). Offsets 1-4 are used for link-local and multicast snooping
|
||||
+ * traps; all others remain free.
|
||||
+/* Per-CTP logical indices for protocol trap rules.
|
||||
+ *
|
||||
+ * The firmware pre-allocates a per-CTP PCE block for every port during
|
||||
+ * init and reserves logical index 0 for its flow-control marking rule.
|
||||
+ * Logical indices 1-4 are used here for link-local and multicast
|
||||
+ * snooping traps; the firmware grows the underlying hardware block on
|
||||
+ * demand as PCERULELOGICWRITE inserts new entries.
|
||||
+ */
|
||||
+#define MXL862XX_LINK_LOCAL_CTP_OFFSET 1
|
||||
+#define MXL862XX_IGMP_CTP_OFFSET 2
|
||||
+#define MXL862XX_MLDV1_CTP_OFFSET 3
|
||||
+#define MXL862XX_MLDV2_CTP_OFFSET 4
|
||||
+#define MXL862XX_LINK_LOCAL_CTP_INDEX 1
|
||||
+#define MXL862XX_IGMP_CTP_INDEX 2
|
||||
+#define MXL862XX_MLDV1_CTP_INDEX 3
|
||||
+#define MXL862XX_MLDV2_CTP_INDEX 4
|
||||
+
|
||||
+/* Install (or overwrite) a PCE rule via the firmware's logical-index
|
||||
+ * API. The firmware translates the logical index in @rule->pattern.index
|
||||
+ * to a physical position within the block selected by @rule->region and
|
||||
+ * @rule->logicalportid, and expands the hardware block size as needed.
|
||||
+ */
|
||||
+static int mxl862xx_pce_rule_write(struct mxl862xx_priv *priv,
|
||||
+ struct mxl862xx_pce_rule *rule)
|
||||
+{
|
||||
+ return MXL862XX_API_WRITE(priv, MXL862XX_TFLOW_PCERULELOGICWRITE,
|
||||
+ *rule);
|
||||
+}
|
||||
+
|
||||
+/* Fill the action fields of a PCE rule that traps ingress frames to
|
||||
+ * the CPU port. Used by both the link-local trap and the multicast
|
||||
@@ -826,12 +852,9 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
+ * The firmware does not install this rule by default because its own
|
||||
+ * STP module is not used when DSA manages STP.
|
||||
+ *
|
||||
+ * The rule is written into the port's per-CTP flow table at offset 1.
|
||||
+ * The firmware already allocates a 44-entry block for every CTP during
|
||||
+ * init (8 entries exposed initially, expandable), so no dynamic
|
||||
+ * allocation via PCERULEALLOC is needed. Using region=CTP causes the
|
||||
+ * firmware to translate the CTP-relative offset into an absolute
|
||||
+ * hardware index.
|
||||
+ * The rule is written into the port's per-CTP flow table at logical
|
||||
+ * index 1 using PCERULELOGICWRITE, which selects the per-CTP block via
|
||||
+ * @region and @logicalportid and grows the block on demand.
|
||||
+ *
|
||||
+ * Cross-state is enabled so that link-local frames reach the CPU even
|
||||
+ * when the bridge port is in BLOCKING or LEARNING state.
|
||||
@@ -844,7 +867,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
+ rule.logicalportid = port;
|
||||
+ rule.region = cpu_to_le32(MXL862XX_PCE_RULE_CTP);
|
||||
+
|
||||
+ rule.pattern.index = cpu_to_le16(MXL862XX_LINK_LOCAL_CTP_OFFSET);
|
||||
+ rule.pattern.index = cpu_to_le16(MXL862XX_LINK_LOCAL_CTP_INDEX);
|
||||
+ rule.pattern.enable = 1;
|
||||
+ rule.pattern.mac_dst_enable = 1;
|
||||
+ memcpy(rule.pattern.mac_dst, eth_reserved_addr_base, ETH_ALEN);
|
||||
@@ -852,7 +875,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
+
|
||||
+ mxl862xx_fill_cpu_trap_action(ds, port, &rule);
|
||||
+
|
||||
+ return MXL862XX_API_WRITE(priv, MXL862XX_TFLOW_PCERULEWRITE, rule);
|
||||
+ return mxl862xx_pce_rule_write(priv, &rule);
|
||||
+}
|
||||
+
|
||||
+/* Install PCE rules that trap IGMP and MLD frames to the CPU port for
|
||||
@@ -862,10 +885,11 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
+ * never classified as blocked unknown MC regardless of the ingress
|
||||
+ * port's standalone flood policy.
|
||||
+ *
|
||||
+ * Three rules are installed per port:
|
||||
+ * offset 2 -- IPv4 IGMP (IP protocol 2, all versions)
|
||||
+ * offset 3 -- ICMPv6 types 130-132 (MLDv1 query, report, done)
|
||||
+ * offset 4 -- ICMPv6 type 143 (MLDv2 Listener Report)
|
||||
+ * Three rules are installed per port at logical indices in the per-CTP
|
||||
+ * block:
|
||||
+ * index 2 -- IPv4 IGMP (IP protocol 2, all versions)
|
||||
+ * index 3 -- ICMPv6 types 130-132 (MLDv1 query, report, done)
|
||||
+ * index 4 -- ICMPv6 type 143 (MLDv2 Listener Report)
|
||||
+ *
|
||||
+ * The MLDv1 rule uses range mode on the first two bytes after the IP
|
||||
+ * header (ICMPv6 type + code): lower bound 0x8200 (type 130, code 0)
|
||||
@@ -883,12 +907,12 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
+ mxl862xx_fill_cpu_trap_action(ds, port, &rule);
|
||||
+
|
||||
+ /* IGMP: IPv4 protocol 2, all versions */
|
||||
+ rule.pattern.index = cpu_to_le16(MXL862XX_IGMP_CTP_OFFSET);
|
||||
+ rule.pattern.index = cpu_to_le16(MXL862XX_IGMP_CTP_INDEX);
|
||||
+ rule.pattern.enable = 1;
|
||||
+ rule.pattern.protocol = IPPROTO_IGMP;
|
||||
+ rule.pattern.protocol_enable = 1;
|
||||
+
|
||||
+ ret = MXL862XX_API_WRITE(priv, MXL862XX_TFLOW_PCERULEWRITE, rule);
|
||||
+ ret = mxl862xx_pce_rule_write(priv, &rule);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
@@ -896,7 +920,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
+ * Range mode covers all three types with any code value.
|
||||
+ */
|
||||
+ memset(&rule.pattern, 0, sizeof(rule.pattern));
|
||||
+ rule.pattern.index = cpu_to_le16(MXL862XX_MLDV1_CTP_OFFSET);
|
||||
+ rule.pattern.index = cpu_to_le16(MXL862XX_MLDV1_CTP_INDEX);
|
||||
+ rule.pattern.enable = 1;
|
||||
+ rule.pattern.protocol = IPPROTO_ICMPV6;
|
||||
+ rule.pattern.protocol_enable = 1;
|
||||
@@ -907,7 +931,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
+ rule.pattern.app_data_msb_enable = 1;
|
||||
+ rule.pattern.app_mask_range_msb_select = 1; /* range mode */
|
||||
+
|
||||
+ ret = MXL862XX_API_WRITE(priv, MXL862XX_TFLOW_PCERULEWRITE, rule);
|
||||
+ ret = mxl862xx_pce_rule_write(priv, &rule);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
@@ -915,7 +939,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
+ * Nibble mask 0x3 masks nibbles 0-1 (lower byte = code field).
|
||||
+ */
|
||||
+ memset(&rule.pattern, 0, sizeof(rule.pattern));
|
||||
+ rule.pattern.index = cpu_to_le16(MXL862XX_MLDV2_CTP_OFFSET);
|
||||
+ rule.pattern.index = cpu_to_le16(MXL862XX_MLDV2_CTP_INDEX);
|
||||
+ rule.pattern.enable = 1;
|
||||
+ rule.pattern.protocol = IPPROTO_ICMPV6;
|
||||
+ rule.pattern.protocol_enable = 1;
|
||||
@@ -924,13 +948,13 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
+ rule.pattern.app_data_msb_enable = 1;
|
||||
+ /* app_mask_range_msb_select = 0: nibble mask mode (default) */
|
||||
+
|
||||
+ return MXL862XX_API_WRITE(priv, MXL862XX_TFLOW_PCERULEWRITE, rule);
|
||||
+ return mxl862xx_pce_rule_write(priv, &rule);
|
||||
+}
|
||||
+
|
||||
static int mxl862xx_set_bridge_port(struct dsa_switch *ds, int port)
|
||||
{
|
||||
struct mxl862xx_bridge_port_config br_port_cfg = {};
|
||||
@@ -683,6 +838,28 @@ static int mxl862xx_setup(struct dsa_swi
|
||||
@@ -684,6 +851,28 @@ static int mxl862xx_setup(struct dsa_swi
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
@@ -959,7 +983,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
schedule_delayed_work(&priv->stats_work,
|
||||
MXL862XX_STATS_POLL_INTERVAL);
|
||||
|
||||
@@ -1382,6 +1559,15 @@ static int mxl862xx_port_setup(struct ds
|
||||
@@ -1383,6 +1572,15 @@ static int mxl862xx_port_setup(struct ds
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
@@ -977,7 +1001,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
if (ret)
|
||||
--- a/drivers/net/dsa/mxl862xx/mxl862xx.h
|
||||
+++ b/drivers/net/dsa/mxl862xx/mxl862xx.h
|
||||
@@ -319,6 +319,13 @@ union mxl862xx_fw_version {
|
||||
@@ -317,6 +317,13 @@ struct mxl862xx_fw_version {
|
||||
* @evlan_ingress_size: per-port ingress Extended VLAN block size
|
||||
* @evlan_egress_size: per-port egress Extended VLAN block size
|
||||
* @vf_block_size: per-port VLAN Filter block size
|
||||
@@ -991,7 +1015,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
* @stats_work: periodic work item that polls RMON hardware counters
|
||||
* and accumulates them into 64-bit per-port stats
|
||||
*/
|
||||
@@ -335,6 +342,7 @@ struct mxl862xx_priv {
|
||||
@@ -334,6 +341,7 @@ struct mxl862xx_priv {
|
||||
u16 evlan_ingress_size;
|
||||
u16 evlan_egress_size;
|
||||
u16 vf_block_size;
|
||||
+3
-3
@@ -1,7 +1,7 @@
|
||||
From 264838ee8ee3ad611a84df96d889429f1ded2148 Mon Sep 17 00:00:00 2001
|
||||
From 6126dff8c28e71091c23fd0cc2f55b1a50e117a6 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Golle <daniel@makrotopia.org>
|
||||
Date: Tue, 24 Mar 2026 18:51:21 +0000
|
||||
Subject: [PATCH 08/19] net: dsa: mxl862xx: warn about old firmware default PCE
|
||||
Subject: [PATCH 07/19] net: dsa: mxl862xx: warn about old firmware default PCE
|
||||
rules
|
||||
|
||||
Firmware versions older than 1.0.80 install global PCE rules at
|
||||
@@ -19,7 +19,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
|
||||
--- a/drivers/net/dsa/mxl862xx/mxl862xx.c
|
||||
+++ b/drivers/net/dsa/mxl862xx/mxl862xx.c
|
||||
@@ -860,6 +860,10 @@ static int mxl862xx_setup(struct dsa_swi
|
||||
@@ -873,6 +873,10 @@ static int mxl862xx_setup(struct dsa_swi
|
||||
true, true, true);
|
||||
if (ret)
|
||||
return ret;
|
||||
+63
-73
@@ -1,7 +1,7 @@
|
||||
From d7ed9b681298d206d81e9cf3c93558d6e912ae88 Mon Sep 17 00:00:00 2001
|
||||
From 69a0946ef48325b85f4a331152d6340f39083053 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Golle <daniel@makrotopia.org>
|
||||
Date: Sun, 22 Mar 2026 00:58:04 +0000
|
||||
Subject: [PATCH 09/20] net: dsa: add 802.1Q VLAN-based tag driver for MxL862xx
|
||||
Subject: [PATCH 08/19] net: dsa: add 802.1Q VLAN-based tag driver for MxL862xx
|
||||
|
||||
The MxL862xx native 8-byte special tag (SpTag) requires firmware
|
||||
support on the switch CPU and is not compatible with all SoC Ethernet
|
||||
@@ -22,13 +22,13 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
drivers/net/dsa/mxl862xx/Kconfig | 1 +
|
||||
drivers/net/dsa/mxl862xx/mxl862xx-api.h | 221 +++
|
||||
drivers/net/dsa/mxl862xx/mxl862xx-cmd.h | 2 +
|
||||
drivers/net/dsa/mxl862xx/mxl862xx.c | 1678 ++++++++++++++++++++---
|
||||
drivers/net/dsa/mxl862xx/mxl862xx.c | 1677 ++++++++++++++++++++---
|
||||
drivers/net/dsa/mxl862xx/mxl862xx.h | 12 +
|
||||
include/net/dsa.h | 2 +
|
||||
net/dsa/Kconfig | 7 +
|
||||
net/dsa/Makefile | 1 +
|
||||
net/dsa/tag_mxl862xx_8021q.c | 65 +
|
||||
9 files changed, 1803 insertions(+), 186 deletions(-)
|
||||
9 files changed, 1804 insertions(+), 184 deletions(-)
|
||||
create mode 100644 net/dsa/tag_mxl862xx_8021q.c
|
||||
|
||||
--- a/drivers/net/dsa/mxl862xx/Kconfig
|
||||
@@ -43,10 +43,11 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
These switches have two 10GE SerDes interfaces, one typically
|
||||
--- a/drivers/net/dsa/mxl862xx/mxl862xx-api.h
|
||||
+++ b/drivers/net/dsa/mxl862xx/mxl862xx-api.h
|
||||
@@ -1185,6 +1185,227 @@ struct mxl862xx_ctp_port_assignment {
|
||||
@@ -1184,6 +1184,227 @@ struct mxl862xx_ctp_port_assignment {
|
||||
__le16 bridge_port_id;
|
||||
} __packed;
|
||||
|
||||
/**
|
||||
+/**
|
||||
+ * enum mxl862xx_ctp_port_config_mask - CTP Port Configuration Mask
|
||||
+ * @MXL862XX_CTP_PORT_CONFIG_MASK_BRIDGE_PORT_ID:
|
||||
+ * Mask for bridge_port_id.
|
||||
@@ -267,10 +268,9 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
+ u8 egress_mirror_enable;
|
||||
+} __packed;
|
||||
+
|
||||
+/**
|
||||
* enum mxl862xx_port_duplex - Ethernet port duplex status
|
||||
* @MXL862XX_DUPLEX_FULL: Port operates in full-duplex mode
|
||||
* @MXL862XX_DUPLEX_HALF: Port operates in half-duplex mode
|
||||
/* PCE (Packet Classification Engine) rule structures.
|
||||
*
|
||||
* Binary layout must exactly match the firmware's GSW_PCE_rule_t
|
||||
--- a/drivers/net/dsa/mxl862xx/mxl862xx-cmd.h
|
||||
+++ b/drivers/net/dsa/mxl862xx/mxl862xx-cmd.h
|
||||
@@ -47,12 +47,14 @@
|
||||
@@ -387,9 +387,9 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
}
|
||||
|
||||
/* PHY access via firmware relay */
|
||||
@@ -396,6 +459,78 @@ static int mxl862xx_setup_drop_meter(str
|
||||
#define MXL862XX_MLDV1_CTP_OFFSET 3
|
||||
#define MXL862XX_MLDV2_CTP_OFFSET 4
|
||||
@@ -410,6 +473,78 @@ static int mxl862xx_pce_rule_write(struc
|
||||
*rule);
|
||||
}
|
||||
|
||||
+/**
|
||||
+ * mxl862xx_cpu_bridge_port_id - Get the bridge port ID for CPU-side forwarding
|
||||
@@ -466,7 +466,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
/* Fill the action fields of a PCE rule that traps ingress frames to
|
||||
* the CPU port. Used by both the link-local trap and the multicast
|
||||
* snooping traps. The caller must already have set the rule header
|
||||
@@ -404,24 +539,36 @@ static int mxl862xx_setup_drop_meter(str
|
||||
@@ -418,24 +553,36 @@ static int mxl862xx_pce_rule_write(struc
|
||||
* PORTMAP_ALTERNATIVE redirects the frame to the CPU port but does
|
||||
* not by itself bypass downstream flood gates. In SpTag mode the
|
||||
* ingress port's private FID may have forward_unknown_multicast=false,
|
||||
@@ -505,17 +505,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
rule->action.cross_state_action =
|
||||
cpu_to_le32(MXL862XX_PCE_ACTION_CROSS_STATE_CROSS);
|
||||
|
||||
@@ -441,9 +588,6 @@ static void mxl862xx_fill_cpu_trap_actio
|
||||
* allocation via PCERULEALLOC is needed. Using region=CTP causes the
|
||||
* firmware to translate the CTP-relative offset into an absolute
|
||||
* hardware index.
|
||||
- *
|
||||
- * Cross-state is enabled so that link-local frames reach the CPU even
|
||||
- * when the bridge port is in BLOCKING or LEARNING state.
|
||||
*/
|
||||
static int mxl862xx_setup_link_local_trap(struct dsa_switch *ds, int port)
|
||||
{
|
||||
@@ -552,11 +696,17 @@ static int mxl862xx_set_bridge_port(stru
|
||||
@@ -564,11 +711,17 @@ static int mxl862xx_set_bridge_port(stru
|
||||
return 0;
|
||||
|
||||
if (dsa_port_is_cpu(dp)) {
|
||||
@@ -538,7 +528,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
}
|
||||
} else if (dp->bridge) {
|
||||
dsa_switch_for_each_bridge_member(member_dp, ds,
|
||||
@@ -567,10 +717,10 @@ static int mxl862xx_set_bridge_port(stru
|
||||
@@ -579,10 +732,10 @@ static int mxl862xx_set_bridge_port(stru
|
||||
member_dp->index);
|
||||
}
|
||||
mxl862xx_fw_portmap_set_bit(br_port_cfg.bridge_port_map,
|
||||
@@ -551,7 +541,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
p->flood_block = 0;
|
||||
p->learning = false;
|
||||
}
|
||||
@@ -774,10 +924,12 @@ static void mxl862xx_free_bridge(struct
|
||||
@@ -786,10 +939,12 @@ static void mxl862xx_free_bridge(struct
|
||||
static int mxl862xx_setup(struct dsa_switch *ds)
|
||||
{
|
||||
struct mxl862xx_priv *priv = ds->priv;
|
||||
@@ -566,16 +556,16 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
|
||||
ret = mxl862xx_reset(priv);
|
||||
if (ret)
|
||||
@@ -790,7 +942,7 @@ static int mxl862xx_setup(struct dsa_swi
|
||||
for (i = 0; i < 8; i++)
|
||||
mxl862xx_setup_pcs(priv, &priv->serdes_ports[i], i + 9);
|
||||
@@ -803,7 +958,7 @@ static int mxl862xx_setup(struct dsa_swi
|
||||
mxl862xx_setup_pcs(priv, &priv->serdes_ports[i],
|
||||
i + MXL862XX_FIRST_SERDES_PORT);
|
||||
|
||||
- /* Calculate Extended VLAN block sizes.
|
||||
+ /* Calculate Extended VLAN and VLAN Filter block sizes.
|
||||
* With VLAN Filter handling VID membership checks:
|
||||
* Ingress: only final catchall rules (PVID insertion, 802.1Q
|
||||
* accept, non-8021Q TPID handling, discard).
|
||||
@@ -798,46 +950,151 @@ static int mxl862xx_setup(struct dsa_swi
|
||||
@@ -811,46 +966,151 @@ static int mxl862xx_setup(struct dsa_swi
|
||||
* ingress EVLAN rules are needed. (7 entries.)
|
||||
* Egress: 2 rules per VID that needs tag stripping (untagged VIDs).
|
||||
* No egress final catchalls -- VLAN Filter does the discard.
|
||||
@@ -739,7 +729,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
|
||||
/* Allocate a dedicated PCE snooping FID with all flood modes enabled.
|
||||
* Per-port PCE trap rules (link-local, IGMP, MLD) set bFidEnable to
|
||||
@@ -860,10 +1117,6 @@ static int mxl862xx_setup(struct dsa_swi
|
||||
@@ -873,10 +1133,6 @@ static int mxl862xx_setup(struct dsa_swi
|
||||
true, true, true);
|
||||
if (ret)
|
||||
return ret;
|
||||
@@ -750,7 +740,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
schedule_delayed_work(&priv->stats_work,
|
||||
MXL862XX_STATS_POLL_INTERVAL);
|
||||
|
||||
@@ -944,10 +1197,71 @@ static int mxl862xx_configure_sp_tag_pro
|
||||
@@ -957,10 +1213,71 @@ static int mxl862xx_configure_sp_tag_pro
|
||||
return MXL862XX_API_WRITE(ds->priv, MXL862XX_SS_SPTAG_SET, tag);
|
||||
}
|
||||
|
||||
@@ -823,7 +813,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
{
|
||||
struct mxl862xx_extendedvlan_config cfg = {};
|
||||
struct mxl862xx_extendedvlan_filter_vlan *fv;
|
||||
@@ -1016,6 +1330,31 @@ static int mxl862xx_evlan_write_rule(str
|
||||
@@ -1029,6 +1346,31 @@ static int mxl862xx_evlan_write_rule(str
|
||||
cpu_to_le32(MXL862XX_EXTENDEDVLAN_TREATMENT_DISCARD_UPSTREAM);
|
||||
}
|
||||
break;
|
||||
@@ -855,7 +845,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
}
|
||||
|
||||
return MXL862XX_API_WRITE(priv, MXL862XX_EXTENDEDVLAN_SET, cfg);
|
||||
@@ -1054,7 +1393,7 @@ static int mxl862xx_evlan_write_final_ru
|
||||
@@ -1067,7 +1409,7 @@ static int mxl862xx_evlan_write_final_ru
|
||||
for (i = 0; i < n_rules; i++) {
|
||||
ret = mxl862xx_evlan_write_rule(priv, blk->block_id,
|
||||
start_idx + i, &rules[i],
|
||||
@@ -864,7 +854,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
@@ -1175,6 +1514,41 @@ static int mxl862xx_vf_del_vid(struct mx
|
||||
@@ -1188,6 +1530,41 @@ static int mxl862xx_vf_del_vid(struct mx
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -906,7 +896,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
static int mxl862xx_evlan_program_ingress(struct mxl862xx_priv *priv, int port)
|
||||
{
|
||||
struct mxl862xx_port *p = &priv->ports[port];
|
||||
@@ -1199,8 +1573,8 @@ static int mxl862xx_evlan_program_egress
|
||||
@@ -1212,8 +1589,8 @@ static int mxl862xx_evlan_program_egress
|
||||
const struct mxl862xx_evlan_rule_desc *vid_rules;
|
||||
struct mxl862xx_vf_vid *vfv;
|
||||
u16 old_active = blk->n_active;
|
||||
@@ -916,7 +906,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
|
||||
if (p->vlan_filtering) {
|
||||
vid_rules = vid_accept_standard;
|
||||
@@ -1214,13 +1588,23 @@ static int mxl862xx_evlan_program_egress
|
||||
@@ -1227,13 +1604,23 @@ static int mxl862xx_evlan_program_egress
|
||||
if (!vfv->untagged)
|
||||
continue;
|
||||
|
||||
@@ -941,7 +931,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
@@ -1229,7 +1613,29 @@ static int mxl862xx_evlan_program_egress
|
||||
@@ -1242,7 +1629,29 @@ static int mxl862xx_evlan_program_egress
|
||||
idx++, &vid_rules[1],
|
||||
vfv->vid,
|
||||
vfv->untagged,
|
||||
@@ -972,7 +962,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
@@ -1241,8 +1647,7 @@ static int mxl862xx_evlan_program_egress
|
||||
@@ -1254,8 +1663,7 @@ static int mxl862xx_evlan_program_egress
|
||||
*/
|
||||
for (i = idx; i < old_active; i++) {
|
||||
ret = mxl862xx_evlan_deactivate_entry(priv,
|
||||
@@ -982,7 +972,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
@@ -1267,13 +1672,16 @@ static int mxl862xx_port_vlan_filtering(
|
||||
@@ -1280,13 +1688,16 @@ static int mxl862xx_port_vlan_filtering(
|
||||
p->vlan_filtering = vlan_filtering;
|
||||
|
||||
if (changed) {
|
||||
@@ -1004,7 +994,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
|
||||
ret = mxl862xx_evlan_program_ingress(priv, port);
|
||||
if (ret)
|
||||
@@ -1493,22 +1901,575 @@ static void mxl862xx_port_bridge_leave(s
|
||||
@@ -1506,22 +1917,575 @@ static void mxl862xx_port_bridge_leave(s
|
||||
port, ERR_PTR(err));
|
||||
|
||||
/* Revert leaving port, omitted by the sync above, to its
|
||||
@@ -1582,7 +1572,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
static int mxl862xx_port_setup(struct dsa_switch *ds, int port)
|
||||
{
|
||||
struct mxl862xx_priv *priv = ds->priv;
|
||||
@@ -1530,33 +2491,52 @@ static int mxl862xx_port_setup(struct ds
|
||||
@@ -1543,33 +2507,52 @@ static int mxl862xx_port_setup(struct ds
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
@@ -1651,7 +1641,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
if (ret)
|
||||
return ret;
|
||||
ret = mxl862xx_set_bridge_port(ds, port);
|
||||
@@ -1572,24 +2552,7 @@ static int mxl862xx_port_setup(struct ds
|
||||
@@ -1585,24 +2568,7 @@ static int mxl862xx_port_setup(struct ds
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
@@ -1676,7 +1666,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1611,7 +2574,7 @@ static void mxl862xx_port_teardown(struc
|
||||
@@ -1624,7 +2590,7 @@ static void mxl862xx_port_teardown(struc
|
||||
priv->ports[port].setup_done = false;
|
||||
}
|
||||
|
||||
@@ -1685,7 +1675,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
{
|
||||
struct mxl862xx_priv *priv = ds->priv;
|
||||
|
||||
@@ -1629,23 +2592,247 @@ static int mxl862xx_get_fid(struct dsa_s
|
||||
@@ -1642,23 +2608,247 @@ static int mxl862xx_get_fid(struct dsa_s
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1718,12 +1708,12 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
+ if (dsa_is_cpu_port(ds, port) && priv->tag_proto == DSA_TAG_PROTO_MXL862_8021Q &&
|
||||
+ db.type == DSA_DB_PORT) {
|
||||
+ bp_cpu = priv->ports[db.dp->index].bridge_port_cpu;
|
||||
+
|
||||
|
||||
- param.port_id = cpu_to_le32(port);
|
||||
+ if (bp_cpu)
|
||||
+ return bp_cpu;
|
||||
+ }
|
||||
|
||||
- param.port_id = cpu_to_le32(port);
|
||||
+
|
||||
+ return port;
|
||||
+}
|
||||
+
|
||||
@@ -1941,7 +1931,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
if (ret)
|
||||
dev_err(ds->dev, "failed to add FDB entry on port %d\n", port);
|
||||
|
||||
@@ -1655,18 +2842,25 @@ static int mxl862xx_port_fdb_add(struct
|
||||
@@ -1668,18 +2858,25 @@ static int mxl862xx_port_fdb_add(struct
|
||||
static int mxl862xx_port_fdb_del(struct dsa_switch *ds, int port,
|
||||
const unsigned char *addr, u16 vid, const struct dsa_db db)
|
||||
{
|
||||
@@ -1950,7 +1940,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
struct mxl862xx_priv *priv = ds->priv;
|
||||
+ struct dsa_port *target_dp;
|
||||
+ int fid, ret;
|
||||
+
|
||||
|
||||
+ /* Mirror of the standalone->bridge FID path in fdb_add */
|
||||
+ if (priv->tag_proto == DSA_TAG_PROTO_MXL862_8021Q && dsa_is_cpu_port(ds, port) &&
|
||||
+ db.type == DSA_DB_PORT && vid > 0) {
|
||||
@@ -1960,7 +1950,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
+ mxl862xx_fdb_del_per_fid(ds, addr, vid,
|
||||
+ priv->bridges[target_dp->bridge->num]);
|
||||
+ }
|
||||
|
||||
+
|
||||
+ fid = mxl862xx_get_fid(ds, db);
|
||||
if (fid < 0)
|
||||
return fid;
|
||||
@@ -1974,7 +1964,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
if (ret)
|
||||
dev_err(ds->dev, "failed to remove FDB entry on port %d\n", port);
|
||||
|
||||
@@ -1705,84 +2899,153 @@ static int mxl862xx_port_fdb_dump(struct
|
||||
@@ -1718,84 +2915,153 @@ static int mxl862xx_port_fdb_dump(struct
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -2075,7 +2065,8 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
- sizeof(aparam.port_map));
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
|
||||
- mxl862xx_fw_portmap_set_bit(aparam.port_map, port);
|
||||
+/**
|
||||
+ * mxl862xx_mac_del_host_bridge - Remove every user-port VBP bit from a host
|
||||
+ * FDB/MDB entry, dropping the entry when its
|
||||
@@ -2099,14 +2090,13 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
+ struct dsa_port *dp;
|
||||
+ u16 vbp;
|
||||
|
||||
- mxl862xx_fw_portmap_set_bit(aparam.port_map, port);
|
||||
- return MXL862XX_API_WRITE(priv, MXL862XX_MAC_TABLEENTRYADD, aparam);
|
||||
+ dsa_switch_for_each_user_port(dp, ds) {
|
||||
+ vbp = priv->ports[dp->index].bridge_port_cpu;
|
||||
+ if (vbp)
|
||||
+ mxl862xx_fw_portmap_set_bit(del_map, vbp);
|
||||
+ }
|
||||
|
||||
- return MXL862XX_API_WRITE(priv, MXL862XX_MAC_TABLEENTRYADD, aparam);
|
||||
+
|
||||
+ return mxl862xx_mac_portmap_del(priv, addr, fid, vid, del_map);
|
||||
}
|
||||
|
||||
@@ -2120,7 +2110,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
- int fid = mxl862xx_get_fid(ds, db), ret;
|
||||
struct mxl862xx_priv *priv = ds->priv;
|
||||
+ int fid, ret;
|
||||
|
||||
+
|
||||
+ /* tag_8021q host MDB for bridged ports: clear all VBP bits */
|
||||
+ if (priv->tag_proto == DSA_TAG_PROTO_MXL862_8021Q && dsa_is_cpu_port(ds, port) &&
|
||||
+ db.type == DSA_DB_BRIDGE) {
|
||||
@@ -2130,7 +2120,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
+ return mxl862xx_mac_del_host_bridge(ds, mdb->addr,
|
||||
+ mdb->vid, &db.bridge);
|
||||
+ }
|
||||
+
|
||||
|
||||
+ fid = mxl862xx_get_fid(ds, db);
|
||||
if (fid < 0)
|
||||
return fid;
|
||||
@@ -2175,7 +2165,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -1867,6 +3130,9 @@ static void mxl862xx_host_flood_work_fn(
|
||||
@@ -1880,6 +3146,9 @@ static void mxl862xx_host_flood_work_fn(
|
||||
host_flood_work);
|
||||
struct mxl862xx_priv *priv = p->priv;
|
||||
struct dsa_switch *ds = priv->ds;
|
||||
@@ -2185,7 +2175,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
|
||||
rtnl_lock();
|
||||
|
||||
@@ -1876,13 +3142,34 @@ static void mxl862xx_host_flood_work_fn(
|
||||
@@ -1889,13 +3158,34 @@ static void mxl862xx_host_flood_work_fn(
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -2227,7 +2217,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
|
||||
rtnl_unlock();
|
||||
}
|
||||
@@ -2248,7 +3535,9 @@ static void mxl862xx_get_stats64(struct
|
||||
@@ -2261,7 +3551,9 @@ static void mxl862xx_get_stats64(struct
|
||||
|
||||
static const struct dsa_switch_ops mxl862xx_switch_ops = {
|
||||
.get_tag_protocol = mxl862xx_get_tag_protocol,
|
||||
@@ -2237,7 +2227,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
.port_setup = mxl862xx_port_setup,
|
||||
.port_teardown = mxl862xx_port_teardown,
|
||||
.phylink_get_caps = mxl862xx_phylink_get_caps,
|
||||
@@ -2270,6 +3559,8 @@ static const struct dsa_switch_ops mxl86
|
||||
@@ -2283,6 +3575,8 @@ static const struct dsa_switch_ops mxl86
|
||||
.port_vlan_filtering = mxl862xx_port_vlan_filtering,
|
||||
.port_vlan_add = mxl862xx_port_vlan_add,
|
||||
.port_vlan_del = mxl862xx_port_vlan_del,
|
||||
@@ -2246,7 +2236,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
.get_strings = mxl862xx_get_strings,
|
||||
.get_sset_count = mxl862xx_get_sset_count,
|
||||
.get_ethtool_stats = mxl862xx_get_ethtool_stats,
|
||||
@@ -2318,6 +3609,8 @@ static int mxl862xx_probe(struct mdio_de
|
||||
@@ -2330,6 +3624,8 @@ static int mxl862xx_probe(struct mdio_de
|
||||
|
||||
INIT_DELAYED_WORK(&priv->stats_work, mxl862xx_stats_work_fn);
|
||||
|
||||
@@ -2255,7 +2245,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
dev_set_drvdata(dev, ds);
|
||||
|
||||
err = dsa_register_switch(ds);
|
||||
@@ -2346,6 +3639,19 @@ static void mxl862xx_remove(struct mdio_
|
||||
@@ -2358,6 +3654,19 @@ static void mxl862xx_remove(struct mdio_
|
||||
set_bit(MXL862XX_FLAG_WORK_STOPPED, &priv->flags);
|
||||
cancel_delayed_work_sync(&priv->stats_work);
|
||||
|
||||
@@ -2277,7 +2267,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
mxl862xx_host_shutdown(priv);
|
||||
--- a/drivers/net/dsa/mxl862xx/mxl862xx.h
|
||||
+++ b/drivers/net/dsa/mxl862xx/mxl862xx.h
|
||||
@@ -209,6 +209,9 @@ struct mxl862xx_port_stats {
|
||||
@@ -212,6 +212,9 @@ struct mxl862xx_port_stats {
|
||||
* @vf: per-port VLAN Filter block state
|
||||
* @ingress_evlan: ingress extended VLAN block state
|
||||
* @egress_evlan: egress extended VLAN block state
|
||||
@@ -2287,7 +2277,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
* @host_flood_uc: desired host unicast flood state (true = flood);
|
||||
* updated atomically by port_set_host_flood, consumed
|
||||
* by the deferred host_flood_work
|
||||
@@ -223,6 +226,7 @@ struct mxl862xx_port_stats {
|
||||
@@ -226,6 +229,7 @@ struct mxl862xx_port_stats {
|
||||
* periodically by the stats polling work
|
||||
* @stats_lock: protects accumulator reads in .get_stats64 against
|
||||
* concurrent updates from the polling work
|
||||
@@ -2295,7 +2285,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
*/
|
||||
struct mxl862xx_port {
|
||||
struct mxl862xx_priv *priv;
|
||||
@@ -235,9 +239,13 @@ struct mxl862xx_port {
|
||||
@@ -238,9 +242,13 @@ struct mxl862xx_port {
|
||||
struct mxl862xx_vf_block vf;
|
||||
struct mxl862xx_evlan_block ingress_evlan;
|
||||
struct mxl862xx_evlan_block egress_evlan;
|
||||
@@ -2309,7 +2299,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
struct mxl862xx_port_stats stats;
|
||||
spinlock_t stats_lock; /* protects stats accumulators */
|
||||
};
|
||||
@@ -304,6 +312,7 @@ union mxl862xx_fw_version {
|
||||
@@ -298,6 +306,7 @@ struct mxl862xx_fw_version {
|
||||
* before CRC-triggered shutdown and cleared after;
|
||||
* %MXL862XX_FLAG_WORK_STOPPED is set before cancelling
|
||||
* stats_work to prevent rescheduling during teardown
|
||||
@@ -2317,7 +2307,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
* @drop_meter: index of the single shared zero-rate firmware meter
|
||||
* used to unconditionally drop traffic (used to block
|
||||
* flooding)
|
||||
@@ -318,6 +327,7 @@ union mxl862xx_fw_version {
|
||||
@@ -316,6 +325,7 @@ struct mxl862xx_fw_version {
|
||||
* (0 .. ds->max_num_bridges).
|
||||
* @evlan_ingress_size: per-port ingress Extended VLAN block size
|
||||
* @evlan_egress_size: per-port egress Extended VLAN block size
|
||||
@@ -2325,15 +2315,15 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
* @vf_block_size: per-port VLAN Filter block size
|
||||
* @cpu_trap_fid: firmware bridge FID allocated for PCE-trapped frames;
|
||||
* configured with uc/mc/bc flood all enabled so that
|
||||
@@ -334,6 +344,7 @@ struct mxl862xx_priv {
|
||||
@@ -332,6 +342,7 @@ struct mxl862xx_priv {
|
||||
struct mdio_device *mdiodev;
|
||||
struct work_struct crc_err_work;
|
||||
unsigned long flags;
|
||||
+ enum dsa_tag_protocol tag_proto;
|
||||
u16 drop_meter;
|
||||
union mxl862xx_fw_version fw_version;
|
||||
struct mxl862xx_fw_version fw_version;
|
||||
struct mxl862xx_pcs serdes_ports[8];
|
||||
@@ -341,6 +352,7 @@ struct mxl862xx_priv {
|
||||
@@ -340,6 +351,7 @@ struct mxl862xx_priv {
|
||||
u16 bridges[MXL862XX_MAX_BRIDGES + 1];
|
||||
u16 evlan_ingress_size;
|
||||
u16 evlan_egress_size;
|
||||
+22
-22
@@ -1,7 +1,7 @@
|
||||
From a32f6a9c09b90e767a03ddac34d061545a0cf15e Mon Sep 17 00:00:00 2001
|
||||
From 4220567bd18b2174c74e90d22f3bf47422c1fdf6 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Golle <daniel@makrotopia.org>
|
||||
Date: Tue, 24 Mar 2026 03:44:41 +0000
|
||||
Subject: [PATCH 10/20] net: dsa: mxl862xx: add link aggregation support
|
||||
Subject: [PATCH 09/19] net: dsa: mxl862xx: add link aggregation support
|
||||
|
||||
Implement LAG offloading via the firmware's trunking engine. A
|
||||
dedicated firmware bridge port is allocated per LAG and remains
|
||||
@@ -90,8 +90,8 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
#define INT_GPHY_READ (GPY_GPY2XX_MAGIC + 0x1)
|
||||
--- a/drivers/net/dsa/mxl862xx/mxl862xx.c
|
||||
+++ b/drivers/net/dsa/mxl862xx/mxl862xx.c
|
||||
@@ -680,7 +680,42 @@ static int mxl862xx_setup_snooping_traps
|
||||
return MXL862XX_API_WRITE(priv, MXL862XX_TFLOW_PCERULEWRITE, rule);
|
||||
@@ -695,7 +695,42 @@ static int mxl862xx_setup_snooping_traps
|
||||
return mxl862xx_pce_rule_write(priv, &rule);
|
||||
}
|
||||
|
||||
-static int mxl862xx_set_bridge_port(struct dsa_switch *ds, int port)
|
||||
@@ -134,7 +134,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
{
|
||||
struct mxl862xx_bridge_port_config br_port_cfg = {};
|
||||
struct dsa_port *dp = dsa_to_port(ds, port);
|
||||
@@ -713,8 +748,12 @@ static int mxl862xx_set_bridge_port(stru
|
||||
@@ -728,8 +763,12 @@ static int mxl862xx_set_bridge_port(stru
|
||||
dp->bridge->dev) {
|
||||
if (member_dp->index == port)
|
||||
continue;
|
||||
@@ -149,7 +149,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
}
|
||||
mxl862xx_fw_portmap_set_bit(br_port_cfg.bridge_port_map,
|
||||
mxl862xx_cpu_bridge_port_id(ds, port));
|
||||
@@ -727,7 +766,7 @@ static int mxl862xx_set_bridge_port(stru
|
||||
@@ -742,7 +781,7 @@ static int mxl862xx_set_bridge_port(stru
|
||||
|
||||
bridge_id = dp->bridge ? priv->bridges[dp->bridge->num] : p->fid;
|
||||
|
||||
@@ -158,7 +158,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
br_port_cfg.bridge_id = cpu_to_le16(bridge_id);
|
||||
br_port_cfg.mask = cpu_to_le32(MXL862XX_BRIDGE_PORT_CONFIG_MASK_BRIDGE_ID |
|
||||
MXL862XX_BRIDGE_PORT_CONFIG_MASK_BRIDGE_PORT_MAP |
|
||||
@@ -808,11 +847,38 @@ static int mxl862xx_set_bridge_port(stru
|
||||
@@ -823,11 +862,38 @@ static int mxl862xx_set_bridge_port(stru
|
||||
br_port_cfg);
|
||||
}
|
||||
|
||||
@@ -198,7 +198,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
|
||||
dsa_switch_for_each_bridge_member(dp, ds, bridge->dev) {
|
||||
err = mxl862xx_set_bridge_port(ds, dp->index);
|
||||
@@ -820,6 +886,25 @@ static int mxl862xx_sync_bridge_members(
|
||||
@@ -835,6 +901,25 @@ static int mxl862xx_sync_bridge_members(
|
||||
ret = err;
|
||||
}
|
||||
|
||||
@@ -224,7 +224,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -1859,6 +1944,408 @@ static int mxl862xx_setup_cpu_bridge(str
|
||||
@@ -1875,6 +1960,408 @@ static int mxl862xx_setup_cpu_bridge(str
|
||||
return mxl862xx_set_bridge_port(ds, port);
|
||||
}
|
||||
|
||||
@@ -633,7 +633,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
static int mxl862xx_port_bridge_join(struct dsa_switch *ds, int port,
|
||||
const struct dsa_bridge bridge,
|
||||
bool *tx_fwd_offload,
|
||||
@@ -1884,7 +2371,18 @@ static int mxl862xx_port_bridge_join(str
|
||||
@@ -1900,7 +2387,18 @@ static int mxl862xx_port_bridge_join(str
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -653,7 +653,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
}
|
||||
|
||||
static void mxl862xx_port_bridge_leave(struct dsa_switch *ds, int port,
|
||||
@@ -1935,6 +2433,17 @@ static void mxl862xx_port_bridge_leave(s
|
||||
@@ -1951,6 +2449,17 @@ static void mxl862xx_port_bridge_leave(s
|
||||
"failed to update CPU VBP for port %d: %pe\n", port,
|
||||
ERR_PTR(err));
|
||||
|
||||
@@ -671,7 +671,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
if (!dsa_bridge_ports(ds, bridge.dev))
|
||||
mxl862xx_free_bridge(ds, &bridge);
|
||||
}
|
||||
@@ -2593,18 +3102,17 @@ static int mxl862xx_get_fid(struct dsa_s
|
||||
@@ -2609,18 +3118,17 @@ static int mxl862xx_get_fid(struct dsa_s
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -697,7 +697,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
*/
|
||||
static int mxl862xx_fdb_bridge_port(struct dsa_switch *ds, int port,
|
||||
const struct dsa_db db)
|
||||
@@ -2620,7 +3128,7 @@ static int mxl862xx_fdb_bridge_port(stru
|
||||
@@ -2636,7 +3144,7 @@ static int mxl862xx_fdb_bridge_port(stru
|
||||
return bp_cpu;
|
||||
}
|
||||
|
||||
@@ -706,7 +706,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2867,11 +3375,43 @@ static int mxl862xx_port_fdb_del(struct
|
||||
@@ -2883,11 +3391,43 @@ static int mxl862xx_port_fdb_del(struct
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -750,7 +750,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
u32 entry_port_id;
|
||||
int ret;
|
||||
|
||||
@@ -2885,7 +3425,7 @@ static int mxl862xx_port_fdb_dump(struct
|
||||
@@ -2901,7 +3441,7 @@ static int mxl862xx_port_fdb_dump(struct
|
||||
|
||||
entry_port_id = le32_to_cpu(param.port_id);
|
||||
|
||||
@@ -759,7 +759,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
ret = cb(param.mac, FIELD_GET(MXL862XX_TCI_VLAN_ID,
|
||||
le16_to_cpu(param.tci)),
|
||||
param.static_entry, data);
|
||||
@@ -3556,6 +4096,11 @@ static const struct dsa_switch_ops mxl86
|
||||
@@ -3572,6 +4112,11 @@ static const struct dsa_switch_ops mxl86
|
||||
.port_fdb_dump = mxl862xx_port_fdb_dump,
|
||||
.port_mdb_add = mxl862xx_port_mdb_add,
|
||||
.port_mdb_del = mxl862xx_port_mdb_del,
|
||||
@@ -771,7 +771,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
.port_vlan_filtering = mxl862xx_port_vlan_filtering,
|
||||
.port_vlan_add = mxl862xx_port_vlan_add,
|
||||
.port_vlan_del = mxl862xx_port_vlan_del,
|
||||
@@ -3597,6 +4142,7 @@ static int mxl862xx_probe(struct mdio_de
|
||||
@@ -3612,6 +4157,7 @@ static int mxl862xx_probe(struct mdio_de
|
||||
ds->num_ports = MXL862XX_MAX_PORTS;
|
||||
ds->fdb_isolation = true;
|
||||
ds->max_num_bridges = MXL862XX_MAX_BRIDGES;
|
||||
@@ -781,7 +781,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
|
||||
--- a/drivers/net/dsa/mxl862xx/mxl862xx.h
|
||||
+++ b/drivers/net/dsa/mxl862xx/mxl862xx.h
|
||||
@@ -16,6 +16,19 @@ struct mxl862xx_priv;
|
||||
@@ -19,6 +19,19 @@ struct mxl862xx_priv;
|
||||
#define MXL862XX_MAX_BRIDGE_PORTS 128
|
||||
#define MXL862XX_TOTAL_EVLAN_ENTRIES 1024
|
||||
#define MXL862XX_TOTAL_VF_ENTRIES 1024
|
||||
@@ -801,7 +801,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
|
||||
/* Number of __le16 words in a firmware portmap (128-bit bitmap). */
|
||||
#define MXL862XX_FW_PORTMAP_WORDS (MXL862XX_MAX_BRIDGE_PORTS / 16)
|
||||
@@ -227,6 +240,12 @@ struct mxl862xx_port_stats {
|
||||
@@ -230,6 +243,12 @@ struct mxl862xx_port_stats {
|
||||
* @stats_lock: protects accumulator reads in .get_stats64 against
|
||||
* concurrent updates from the polling work
|
||||
* @tag_8021q_vid: currently assigned tag_8021q management VID
|
||||
@@ -814,7 +814,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
*/
|
||||
struct mxl862xx_port {
|
||||
struct mxl862xx_priv *priv;
|
||||
@@ -246,6 +265,9 @@ struct mxl862xx_port {
|
||||
@@ -249,6 +268,9 @@ struct mxl862xx_port {
|
||||
struct work_struct host_flood_work;
|
||||
u16 tag_8021q_vid;
|
||||
struct mxl862xx_evlan_block cpu_egress_evlan;
|
||||
@@ -824,7 +824,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
struct mxl862xx_port_stats stats;
|
||||
spinlock_t stats_lock; /* protects stats accumulators */
|
||||
};
|
||||
@@ -336,6 +358,15 @@ union mxl862xx_fw_version {
|
||||
@@ -334,6 +356,15 @@ struct mxl862xx_fw_version {
|
||||
* policy. Set once in setup() and referenced by
|
||||
* fill_cpu_trap_action() via bFidEnable. The PCE FID
|
||||
* action field is 6 bits, so this value must be <= 63.
|
||||
@@ -840,7 +840,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
* @stats_work: periodic work item that polls RMON hardware counters
|
||||
* and accumulates them into 64-bit per-port stats
|
||||
*/
|
||||
@@ -355,6 +386,8 @@ struct mxl862xx_priv {
|
||||
@@ -354,6 +385,8 @@ struct mxl862xx_priv {
|
||||
u16 cpu_evlan_ingress_size;
|
||||
u16 vf_block_size;
|
||||
u16 cpu_trap_fid;
|
||||
+15
-15
@@ -1,7 +1,7 @@
|
||||
From d919c2f8da9dbd4dda57ceebb5c8b103805b58d1 Mon Sep 17 00:00:00 2001
|
||||
From 8f7296099da5eaedfe5108a6fe93296bcc0c4b45 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Golle <daniel@makrotopia.org>
|
||||
Date: Tue, 24 Mar 2026 12:05:29 +0000
|
||||
Subject: [PATCH 11/19] net: dsa: mxl862xx: add support for mirror port
|
||||
Subject: [PATCH 10/19] net: dsa: mxl862xx: add support for mirror port
|
||||
|
||||
The MxL862xx hardware supports a single monitor port which can be
|
||||
configured to mirror any other port's ingress and/or egress traffic.
|
||||
@@ -40,17 +40,17 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
* @age_timer: Custom MAC table aging timer in seconds
|
||||
--- a/drivers/net/dsa/mxl862xx/mxl862xx-cmd.h
|
||||
+++ b/drivers/net/dsa/mxl862xx/mxl862xx-cmd.h
|
||||
@@ -30,6 +30,7 @@
|
||||
#define MXL862XX_COMMON_PORTCFGGET (MXL862XX_COMMON_MAGIC + 0x7)
|
||||
@@ -29,6 +29,7 @@
|
||||
|
||||
#define MXL862XX_COMMON_CFGGET (MXL862XX_COMMON_MAGIC + 0x9)
|
||||
#define MXL862XX_COMMON_CFGSET (MXL862XX_COMMON_MAGIC + 0xa)
|
||||
+#define MXL862XX_COMMON_MONITORPORTCFGSET (MXL862XX_COMMON_MAGIC + 0xe)
|
||||
#define MXL862XX_COMMON_REGISTERMOD (MXL862XX_COMMON_MAGIC + 0x11)
|
||||
|
||||
#define MXL862XX_TFLOW_PCERULEWRITE (MXL862XX_TFLOW_MAGIC + 0x2)
|
||||
#define MXL862XX_TFLOW_PCERULEALLOC (MXL862XX_TFLOW_MAGIC + 0x4)
|
||||
--- a/drivers/net/dsa/mxl862xx/mxl862xx.c
|
||||
+++ b/drivers/net/dsa/mxl862xx/mxl862xx.c
|
||||
@@ -1100,6 +1100,8 @@ static int mxl862xx_setup(struct dsa_swi
|
||||
@@ -1116,6 +1116,8 @@ static int mxl862xx_setup(struct dsa_swi
|
||||
(n_user_ports + n_cpu_ports);
|
||||
}
|
||||
|
||||
@@ -59,8 +59,8 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
ret = mxl862xx_setup_drop_meter(ds);
|
||||
if (ret)
|
||||
return ret;
|
||||
@@ -3167,6 +3169,120 @@ static int mxl862xx_fdb_del_per_fid(stru
|
||||
return MXL862XX_API_WRITE(priv, MXL862XX_MAC_TABLEENTRYREMOVE, param);
|
||||
@@ -1960,6 +1962,120 @@ static int mxl862xx_setup_cpu_bridge(str
|
||||
return mxl862xx_set_bridge_port(ds, port);
|
||||
}
|
||||
|
||||
+static int mxl862xx_port_mirror_add(struct dsa_switch *ds, int port,
|
||||
@@ -178,9 +178,9 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
+}
|
||||
+
|
||||
/**
|
||||
* mxl862xx_mac_portmap_add - Set port bits in a MAC table entry's portmap
|
||||
* @priv: driver private data
|
||||
@@ -4096,6 +4212,8 @@ static const struct dsa_switch_ops mxl86
|
||||
* mxl862xx_lag_master_port - Find the LAG master (lowest-numbered member)
|
||||
* @ds: DSA switch
|
||||
@@ -4112,6 +4228,8 @@ static const struct dsa_switch_ops mxl86
|
||||
.port_fdb_dump = mxl862xx_port_fdb_dump,
|
||||
.port_mdb_add = mxl862xx_port_mdb_add,
|
||||
.port_mdb_del = mxl862xx_port_mdb_del,
|
||||
@@ -191,7 +191,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
.port_lag_change = mxl862xx_port_lag_change,
|
||||
--- a/drivers/net/dsa/mxl862xx/mxl862xx.h
|
||||
+++ b/drivers/net/dsa/mxl862xx/mxl862xx.h
|
||||
@@ -240,6 +240,8 @@ struct mxl862xx_port_stats {
|
||||
@@ -243,6 +243,8 @@ struct mxl862xx_port_stats {
|
||||
* @stats_lock: protects accumulator reads in .get_stats64 against
|
||||
* concurrent updates from the polling work
|
||||
* @tag_8021q_vid: currently assigned tag_8021q management VID
|
||||
@@ -200,7 +200,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
* @lag: non-NULL when port is member of a LAG group;
|
||||
* points to the DSA LAG structure
|
||||
* @lag_tx_enabled: true when this port is active for TX in its LAG
|
||||
@@ -265,6 +267,8 @@ struct mxl862xx_port {
|
||||
@@ -268,6 +270,8 @@ struct mxl862xx_port {
|
||||
struct work_struct host_flood_work;
|
||||
u16 tag_8021q_vid;
|
||||
struct mxl862xx_evlan_block cpu_egress_evlan;
|
||||
@@ -209,7 +209,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
struct dsa_lag *lag;
|
||||
bool lag_tx_enabled;
|
||||
u8 lag_hash_bits;
|
||||
@@ -367,6 +371,8 @@ union mxl862xx_fw_version {
|
||||
@@ -365,6 +369,8 @@ struct mxl862xx_fw_version {
|
||||
* @trunk_hash: current global hash field bitmask (6 bits,
|
||||
* MXL862XX_TRUNK_HASH_*); union of all active LAGs'
|
||||
* hash requirements
|
||||
@@ -218,7 +218,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
* @stats_work: periodic work item that polls RMON hardware counters
|
||||
* and accumulates them into 64-bit per-port stats
|
||||
*/
|
||||
@@ -388,6 +394,7 @@ struct mxl862xx_priv {
|
||||
@@ -387,6 +393,7 @@ struct mxl862xx_priv {
|
||||
u16 cpu_trap_fid;
|
||||
u16 lag_bridge_ports[MXL862XX_MAX_LAG_IDS + 1];
|
||||
u8 trunk_hash;
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
From 64269d9d809962a0f7e68e9b618d81e561e3eb6f Mon Sep 17 00:00:00 2001
|
||||
From d11e0b07317e04f347de1b5053bb6720d72fd111 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Golle <daniel@makrotopia.org>
|
||||
Date: Tue, 24 Mar 2026 16:30:08 +0000
|
||||
Subject: [PATCH 12/19] net: dsa: wire flash_update devlink callback to drivers
|
||||
Subject: [PATCH 11/19] net: dsa: wire flash_update devlink callback to drivers
|
||||
|
||||
Add a devlink_flash_update callback to dsa_switch_ops so that DSA
|
||||
drivers can support devlink dev flash without open-coding the devlink
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
From fed4225f75b6fe6898e48f472cbbee0aaa046760 Mon Sep 17 00:00:00 2001
|
||||
From 4dd558c7422fcd2b5c76994928fe3a65e0059fb4 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Golle <daniel@makrotopia.org>
|
||||
Date: Tue, 24 Mar 2026 16:30:17 +0000
|
||||
Subject: [PATCH 13/19] net: dsa: mxl862xx: add SMDIO clause-22 register access
|
||||
Subject: [PATCH 12/19] net: dsa: mxl862xx: add SMDIO clause-22 register access
|
||||
|
||||
Add mxl862xx_smdio_read() and mxl862xx_smdio_write() for clause-22
|
||||
SMDIO register access. MCUboot rescue mode only exposes clause-22
|
||||
+8
-9
@@ -1,7 +1,7 @@
|
||||
From fa186b09e346e0b7f2504232731bc9e4dee0c600 Mon Sep 17 00:00:00 2001
|
||||
From 099e70920b16f5da14d34bc00ac58a5ca95c1e33 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Golle <daniel@makrotopia.org>
|
||||
Date: Tue, 24 Mar 2026 16:30:31 +0000
|
||||
Subject: [PATCH 14/19] net: dsa: mxl862xx: add devlink flash_update and
|
||||
Subject: [PATCH 13/19] net: dsa: mxl862xx: add devlink flash_update and
|
||||
info_get
|
||||
|
||||
Implement runtime firmware upgrade via "devlink dev flash" and version
|
||||
@@ -35,9 +35,9 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
drivers/net/dsa/mxl862xx/mxl862xx-fw.c | 434 +++++++++++++++++++++++
|
||||
drivers/net/dsa/mxl862xx/mxl862xx-fw.h | 15 +
|
||||
drivers/net/dsa/mxl862xx/mxl862xx-host.c | 7 +
|
||||
drivers/net/dsa/mxl862xx/mxl862xx.c | 4 +
|
||||
drivers/net/dsa/mxl862xx/mxl862xx.c | 3 +
|
||||
drivers/net/dsa/mxl862xx/mxl862xx.h | 2 +
|
||||
7 files changed, 464 insertions(+), 1 deletion(-)
|
||||
7 files changed, 463 insertions(+), 1 deletion(-)
|
||||
create mode 100644 drivers/net/dsa/mxl862xx/mxl862xx-fw.c
|
||||
create mode 100644 drivers/net/dsa/mxl862xx/mxl862xx-fw.h
|
||||
|
||||
@@ -57,7 +57,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
+#define SYS_MISC_FW_UPDATE (SYS_MISC_MAGIC + 0x1)
|
||||
#define SYS_MISC_FW_VERSION (SYS_MISC_MAGIC + 0x2)
|
||||
|
||||
#define MXL862XX_XPCS_MAGIC 0x1a00
|
||||
#define MXL862XX_XPCS_PCS_CONFIG (MXL862XX_XPCS_MAGIC + 0x1)
|
||||
--- /dev/null
|
||||
+++ b/drivers/net/dsa/mxl862xx/mxl862xx-fw.c
|
||||
@@ -0,0 +1,434 @@
|
||||
@@ -546,19 +546,18 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
#include "mxl862xx-host.h"
|
||||
#include "mxl862xx-phylink.h"
|
||||
|
||||
@@ -4233,6 +4234,9 @@ static const struct dsa_switch_ops mxl86
|
||||
@@ -4248,6 +4249,8 @@ static const struct dsa_switch_ops mxl86
|
||||
.get_pause_stats = mxl862xx_get_pause_stats,
|
||||
.get_rmon_stats = mxl862xx_get_rmon_stats,
|
||||
.get_stats64 = mxl862xx_get_stats64,
|
||||
.self_test = mxl862xx_serdes_self_test,
|
||||
+ .devlink_info_get = mxl862xx_devlink_info_get,
|
||||
+ .devlink_flash_update = mxl862xx_devlink_flash_update,
|
||||
+
|
||||
};
|
||||
|
||||
static int mxl862xx_probe(struct mdio_device *mdiodev)
|
||||
--- a/drivers/net/dsa/mxl862xx/mxl862xx.h
|
||||
+++ b/drivers/net/dsa/mxl862xx/mxl862xx.h
|
||||
@@ -395,6 +395,8 @@ struct mxl862xx_priv {
|
||||
@@ -394,6 +394,8 @@ struct mxl862xx_priv {
|
||||
u16 lag_bridge_ports[MXL862XX_MAX_LAG_IDS + 1];
|
||||
u8 trunk_hash;
|
||||
int mirror_dest;
|
||||
+6
-6
@@ -1,7 +1,7 @@
|
||||
From 05bc981690d6ef03143a094f28714aa0171ab571 Mon Sep 17 00:00:00 2001
|
||||
From d27d60f42f5188d6cfcb771d2188633f1031646f Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Golle <daniel@makrotopia.org>
|
||||
Date: Wed, 1 Apr 2026 13:43:08 +0100
|
||||
Subject: [PATCH 15/19] net: dsa: mxl862xx: implement port MTU configuration
|
||||
Subject: [PATCH 14/19] net: dsa: mxl862xx: implement port MTU configuration
|
||||
|
||||
The firmware exposes a global max_packet_len register via
|
||||
MXL862XX_COMMON_CFGSET. Since this is switch-wide rather than
|
||||
@@ -25,7 +25,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/of_mdio.h>
|
||||
@@ -3727,6 +3728,53 @@ static int mxl862xx_set_ageing_time(stru
|
||||
@@ -3743,6 +3744,53 @@ static int mxl862xx_set_ageing_time(stru
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -79,7 +79,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
static void mxl862xx_port_stp_state_set(struct dsa_switch *ds, int port,
|
||||
u8 state)
|
||||
{
|
||||
@@ -4202,6 +4250,8 @@ static const struct dsa_switch_ops mxl86
|
||||
@@ -4218,6 +4266,8 @@ static const struct dsa_switch_ops mxl86
|
||||
.port_disable = mxl862xx_port_disable,
|
||||
.port_fast_age = mxl862xx_port_fast_age,
|
||||
.set_ageing_time = mxl862xx_set_ageing_time,
|
||||
@@ -90,7 +90,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
.port_pre_bridge_flags = mxl862xx_port_pre_bridge_flags,
|
||||
--- a/drivers/net/dsa/mxl862xx/mxl862xx.h
|
||||
+++ b/drivers/net/dsa/mxl862xx/mxl862xx.h
|
||||
@@ -248,6 +248,8 @@ struct mxl862xx_port_stats {
|
||||
@@ -251,6 +251,8 @@ struct mxl862xx_port_stats {
|
||||
* @lag_hash_bits: hash field bitmask (MXL862XX_TRUNK_HASH_*) requested
|
||||
* when this port joined its LAG; used to recompute the
|
||||
* global trunk_hash when a LAG is destroyed
|
||||
@@ -99,7 +99,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
*/
|
||||
struct mxl862xx_port {
|
||||
struct mxl862xx_priv *priv;
|
||||
@@ -272,6 +274,7 @@ struct mxl862xx_port {
|
||||
@@ -275,6 +277,7 @@ struct mxl862xx_port {
|
||||
struct dsa_lag *lag;
|
||||
bool lag_tx_enabled;
|
||||
u8 lag_hash_bits;
|
||||
+7
-7
@@ -1,7 +1,7 @@
|
||||
From b723f7484006aadbaa51e16b870f3c98390605b1 Mon Sep 17 00:00:00 2001
|
||||
From ba48edffc80f3dd676a9e8cf63aa4778a4ed0f0d Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Golle <daniel@makrotopia.org>
|
||||
Date: Wed, 1 Apr 2026 13:43:12 +0100
|
||||
Subject: [PATCH 16/19] net: dsa: mxl862xx: support BR_HAIRPIN_MODE bridge flag
|
||||
Subject: [PATCH 15/19] net: dsa: mxl862xx: support BR_HAIRPIN_MODE bridge flag
|
||||
|
||||
Implement hairpin mode by including the port's own bridge port ID in
|
||||
its forwarding portmap. When hairpin is enabled, bridged frames whose
|
||||
@@ -24,7 +24,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
|
||||
--- a/drivers/net/dsa/mxl862xx/mxl862xx.c
|
||||
+++ b/drivers/net/dsa/mxl862xx/mxl862xx.c
|
||||
@@ -759,6 +759,10 @@ static int __mxl862xx_set_bridge_port(st
|
||||
@@ -774,6 +774,10 @@ static int __mxl862xx_set_bridge_port(st
|
||||
}
|
||||
mxl862xx_fw_portmap_set_bit(br_port_cfg.bridge_port_map,
|
||||
mxl862xx_cpu_bridge_port_id(ds, port));
|
||||
@@ -35,7 +35,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
} else {
|
||||
mxl862xx_fw_portmap_set_bit(br_port_cfg.bridge_port_map,
|
||||
mxl862xx_cpu_bridge_port_id(ds, port));
|
||||
@@ -3895,7 +3899,7 @@ static int mxl862xx_port_pre_bridge_flag
|
||||
@@ -3911,7 +3915,7 @@ static int mxl862xx_port_pre_bridge_flag
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
if (flags.mask & ~(BR_FLOOD | BR_MCAST_FLOOD | BR_BCAST_FLOOD |
|
||||
@@ -44,7 +44,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
@@ -3937,7 +3941,11 @@ static int mxl862xx_port_bridge_flags(st
|
||||
@@ -3953,7 +3957,11 @@ static int mxl862xx_port_bridge_flags(st
|
||||
if (flags.mask & BR_LEARNING)
|
||||
priv->ports[port].learning = !!(flags.val & BR_LEARNING);
|
||||
|
||||
@@ -59,7 +59,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
if (ret)
|
||||
--- a/drivers/net/dsa/mxl862xx/mxl862xx.h
|
||||
+++ b/drivers/net/dsa/mxl862xx/mxl862xx.h
|
||||
@@ -240,6 +240,10 @@ struct mxl862xx_port_stats {
|
||||
@@ -243,6 +243,10 @@ struct mxl862xx_port_stats {
|
||||
* @stats_lock: protects accumulator reads in .get_stats64 against
|
||||
* concurrent updates from the polling work
|
||||
* @tag_8021q_vid: currently assigned tag_8021q management VID
|
||||
@@ -70,7 +70,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
* @ingress_mirror: true when ingress mirroring is active on this port
|
||||
* @egress_mirror: true when egress mirroring is active on this port
|
||||
* @lag: non-NULL when port is member of a LAG group;
|
||||
@@ -269,6 +273,7 @@ struct mxl862xx_port {
|
||||
@@ -272,6 +276,7 @@ struct mxl862xx_port {
|
||||
struct work_struct host_flood_work;
|
||||
u16 tag_8021q_vid;
|
||||
struct mxl862xx_evlan_block cpu_egress_evlan;
|
||||
+8
-8
@@ -1,7 +1,7 @@
|
||||
From d8f20ba50ce0f93f34a41a9b833be76a5d1d2714 Mon Sep 17 00:00:00 2001
|
||||
From 45fcd9669da62b27823004480c07854c54574a1a Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Golle <daniel@makrotopia.org>
|
||||
Date: Wed, 25 Mar 2026 01:51:33 +0000
|
||||
Subject: [PATCH 17/19] net: dsa: mxl862xx: support BR_ISOLATED bridge flag
|
||||
Subject: [PATCH 16/19] net: dsa: mxl862xx: support BR_ISOLATED bridge flag
|
||||
|
||||
Implement port isolation by excluding isolated ports from each other's
|
||||
forwarding portmaps in sync_bridge_members. Non-isolated ports can
|
||||
@@ -19,7 +19,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
|
||||
--- a/drivers/net/dsa/mxl862xx/mxl862xx.c
|
||||
+++ b/drivers/net/dsa/mxl862xx/mxl862xx.c
|
||||
@@ -752,6 +752,8 @@ static int __mxl862xx_set_bridge_port(st
|
||||
@@ -767,6 +767,8 @@ static int __mxl862xx_set_bridge_port(st
|
||||
continue;
|
||||
if (!mxl862xx_is_lag_master(priv, member_dp->index))
|
||||
continue;
|
||||
@@ -28,7 +28,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
mxl862xx_fw_portmap_set_bit(
|
||||
br_port_cfg.bridge_port_map,
|
||||
mxl862xx_lag_bridge_port(priv,
|
||||
@@ -3899,7 +3901,7 @@ static int mxl862xx_port_pre_bridge_flag
|
||||
@@ -3915,7 +3917,7 @@ static int mxl862xx_port_pre_bridge_flag
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
if (flags.mask & ~(BR_FLOOD | BR_MCAST_FLOOD | BR_BCAST_FLOOD |
|
||||
@@ -37,7 +37,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
@@ -3912,6 +3914,7 @@ static int mxl862xx_port_bridge_flags(st
|
||||
@@ -3928,6 +3930,7 @@ static int mxl862xx_port_bridge_flags(st
|
||||
struct mxl862xx_priv *priv = ds->priv;
|
||||
unsigned long old_block = priv->ports[port].flood_block;
|
||||
unsigned long block = old_block;
|
||||
@@ -45,7 +45,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
int ret;
|
||||
|
||||
if (flags.mask & BR_FLOOD) {
|
||||
@@ -3952,6 +3955,21 @@ static int mxl862xx_port_bridge_flags(st
|
||||
@@ -3968,6 +3971,21 @@ static int mxl862xx_port_bridge_flags(st
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -69,7 +69,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
|
||||
--- a/drivers/net/dsa/mxl862xx/mxl862xx.h
|
||||
+++ b/drivers/net/dsa/mxl862xx/mxl862xx.h
|
||||
@@ -213,6 +213,9 @@ struct mxl862xx_port_stats {
|
||||
@@ -216,6 +216,9 @@ struct mxl862xx_port_stats {
|
||||
* @flood_block: bitmask of firmware meter indices that are currently
|
||||
* rate-limiting flood traffic on this port (zero-rate
|
||||
* meters used to block flooding)
|
||||
@@ -79,7 +79,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
* @learning: true when address learning is enabled on this port
|
||||
* @setup_done: set at end of port_setup, cleared at start of
|
||||
* port_teardown; guards deferred work against
|
||||
@@ -259,6 +262,7 @@ struct mxl862xx_port {
|
||||
@@ -262,6 +265,7 @@ struct mxl862xx_port {
|
||||
struct mxl862xx_priv *priv;
|
||||
u16 fid;
|
||||
unsigned long flood_block;
|
||||
+134
@@ -0,0 +1,134 @@
|
||||
From 8120b9b88ec47ee41b8350e3e4341839f5fdc28e Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Golle <daniel@makrotopia.org>
|
||||
Date: Tue, 24 Mar 2026 18:17:49 +0000
|
||||
Subject: [PATCH 17/19] DO NOT SUBMIT: net: dsa: mxl862xx: re-introduce PCE
|
||||
workaround for old firmware
|
||||
|
||||
Re-introduce the legacy PCE rule paths needed for firmware versions
|
||||
older than 1.0.83.
|
||||
|
||||
Firmware >= 1.0.83 exposes the new GSW_TFLOW_PCERULELOGICWRITE API
|
||||
which selects the per-CTP block via @region/@logicalportid and grows
|
||||
the hardware block on demand. Older firmware lacks that command and
|
||||
exposes only the legacy GSW_TFLOW_PCERULEWRITE call, where the rule
|
||||
index is a direct offset into a fixed-size pre-allocated CTP block.
|
||||
Add MXL862XX_TFLOW_PCERULEWRITE back to mxl862xx-cmd.h and make
|
||||
mxl862xx_pce_rule_write() pick the right command at runtime based on
|
||||
the cached firmware version.
|
||||
|
||||
In addition, firmware older than 1.0.80 still installs global PCE
|
||||
rules at boot that redirect link-local frames (BPDUs, LLDP, LACP) to
|
||||
port 0 (the on-chip microcontroller) instead of the DSA CPU port.
|
||||
With port 0 disabled under DSA these rules silently drop matching
|
||||
traffic. Re-introduce mxl862xx_disable_fw_global_rules() to clear
|
||||
them out during setup. The upstream submission replaced that call
|
||||
with a dev_warn() since firmware >= 1.0.80 no longer installs the
|
||||
problematic rules.
|
||||
|
||||
This commit is for downstream use only and must not be submitted
|
||||
upstream.
|
||||
|
||||
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
---
|
||||
drivers/net/dsa/mxl862xx/mxl862xx-cmd.h | 1 +
|
||||
drivers/net/dsa/mxl862xx/mxl862xx.c | 61 +++++++++++++++++++++----
|
||||
2 files changed, 53 insertions(+), 9 deletions(-)
|
||||
|
||||
--- a/drivers/net/dsa/mxl862xx/mxl862xx-cmd.h
|
||||
+++ b/drivers/net/dsa/mxl862xx/mxl862xx-cmd.h
|
||||
@@ -32,6 +32,7 @@
|
||||
#define MXL862XX_COMMON_MONITORPORTCFGSET (MXL862XX_COMMON_MAGIC + 0xe)
|
||||
#define MXL862XX_COMMON_REGISTERMOD (MXL862XX_COMMON_MAGIC + 0x11)
|
||||
|
||||
+#define MXL862XX_TFLOW_PCERULEWRITE (MXL862XX_TFLOW_MAGIC + 0x2)
|
||||
#define MXL862XX_TFLOW_PCERULEALLOC (MXL862XX_TFLOW_MAGIC + 0x4)
|
||||
#define MXL862XX_TFLOW_PCERULEFREE (MXL862XX_TFLOW_MAGIC + 0x5)
|
||||
#define MXL862XX_TFLOW_PCERULELOGICWRITE \
|
||||
--- a/drivers/net/dsa/mxl862xx/mxl862xx.c
|
||||
+++ b/drivers/net/dsa/mxl862xx/mxl862xx.c
|
||||
@@ -449,6 +449,43 @@ static int mxl862xx_setup_drop_meter(str
|
||||
return MXL862XX_API_WRITE(priv, MXL862XX_COMMON_REGISTERMOD, reg);
|
||||
}
|
||||
|
||||
+/* Disable firmware global PCE rules that trap various protocols to the
|
||||
+ * on-die microcontroller (port 0) via PORTMAP_CPU. Under DSA, these
|
||||
+ * frames must either reach the host CPU via per-port rules (link-local)
|
||||
+ * or through the normal bridge forwarding path (ARP broadcast), so the
|
||||
+ * global firmware rules are not needed. With the microcontroller port
|
||||
+ * disabled they would silently drop matching traffic.
|
||||
+ *
|
||||
+ * Global rules have lower indices than CTP rules, hence higher priority
|
||||
+ * in the PCE pipeline -- they must be explicitly disabled or they will
|
||||
+ * shadow the per-CTP traps.
|
||||
+ *
|
||||
+ * Indices from gsw_flow_index.h:
|
||||
+ * 1 -- BPDU (STP/RSTP, dst 01:80:c2:00:00:00)
|
||||
+ * 3 -- LLDP (EtherType 0x88cc)
|
||||
+ * 4 -- OAM/LACP (EtherType 0x8809)
|
||||
+ * 6 -- System MAC (dst 02:e0:92:00:00:01, vendor management MAC)
|
||||
+ * 7 -- ARP Request (broadcast + EtherType 0x0806 + TPA 192.0.2.1)
|
||||
+ */
|
||||
+static int mxl862xx_disable_fw_global_rules(struct dsa_switch *ds)
|
||||
+{
|
||||
+ static const u16 indices[] = { 1, 3, 4, 6, 7 };
|
||||
+ struct mxl862xx_pce_rule rule;
|
||||
+ int i, ret;
|
||||
+
|
||||
+ for (i = 0; i < ARRAY_SIZE(indices); i++) {
|
||||
+ memset(&rule, 0, sizeof(rule));
|
||||
+ rule.pattern.index = cpu_to_le16(indices[i]);
|
||||
+ /* pattern.enable == 0 -> rule is disabled */
|
||||
+
|
||||
+ ret = MXL862XX_API_WRITE(ds->priv,
|
||||
+ MXL862XX_TFLOW_PCERULEWRITE, rule);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
|
||||
/* Per-CTP logical indices for protocol trap rules.
|
||||
*
|
||||
@@ -463,16 +500,20 @@ static int mxl862xx_setup_drop_meter(str
|
||||
#define MXL862XX_MLDV1_CTP_INDEX 3
|
||||
#define MXL862XX_MLDV2_CTP_INDEX 4
|
||||
|
||||
-/* Install (or overwrite) a PCE rule via the firmware's logical-index
|
||||
- * API. The firmware translates the logical index in @rule->pattern.index
|
||||
- * to a physical position within the block selected by @rule->region and
|
||||
- * @rule->logicalportid, and expands the hardware block size as needed.
|
||||
+/* Install (or overwrite) a PCE rule. On firmware >= 1.0.83 use the
|
||||
+ * logical-index API (PCERULELOGICWRITE), which grows the per-CTP block
|
||||
+ * on demand. On older firmware that API does not exist, so fall back
|
||||
+ * to the legacy PCERULEWRITE call which uses the rule index as a
|
||||
+ * direct offset into a fixed-size pre-allocated CTP block.
|
||||
*/
|
||||
static int mxl862xx_pce_rule_write(struct mxl862xx_priv *priv,
|
||||
struct mxl862xx_pce_rule *rule)
|
||||
{
|
||||
- return MXL862XX_API_WRITE(priv, MXL862XX_TFLOW_PCERULELOGICWRITE,
|
||||
- *rule);
|
||||
+ u16 cmd = MXL862XX_FW_VER_MIN(priv, 1, 0, 83) ?
|
||||
+ MXL862XX_TFLOW_PCERULELOGICWRITE :
|
||||
+ MXL862XX_TFLOW_PCERULEWRITE;
|
||||
+
|
||||
+ return MXL862XX_API_WRITE(priv, cmd, *rule);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1130,9 +1171,11 @@ static int mxl862xx_setup(struct dsa_swi
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
- if (!MXL862XX_FW_VER_MIN(priv, 1, 0, 80))
|
||||
- dev_warn(ds->dev, "firmware < 1.0.80 installs global PCE rules "
|
||||
- "that interfere with DSA operation, please update\n");
|
||||
+ if (!MXL862XX_FW_VER_MIN(priv, 1, 0, 80)) {
|
||||
+ ret = mxl862xx_disable_fw_global_rules(ds);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+ }
|
||||
|
||||
/* Pre-allocate firmware resources for all ports. The DSA core
|
||||
* calls change_tag_protocol() between setup() and port_setup(),
|
||||
+491
@@ -0,0 +1,491 @@
|
||||
From 494a1eb62219d9ccb97a60e15ea59e7de2f5d9bc Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Golle <daniel@makrotopia.org>
|
||||
Date: Tue, 24 Mar 2026 18:19:56 +0000
|
||||
Subject: [PATCH 18/19] DO NOT SUBMIT: net: dsa: mxl862xx: legacy SFP API
|
||||
fallback for old firmware
|
||||
|
||||
Re-introduce the SYS_MISC_SFP_SET-based PCS implementation as a
|
||||
fallback for firmware versions older than 1.0.84 which lack the
|
||||
XPCS API. mxl862xx_setup_pcs() selects between the XPCS ops and
|
||||
legacy SFP ops based on firmware version.
|
||||
|
||||
This commit is for downstream use only and must not be submitted
|
||||
upstream.
|
||||
|
||||
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
---
|
||||
drivers/net/dsa/mxl862xx/mxl862xx-api.h | 244 ++++++++++++++++++++
|
||||
drivers/net/dsa/mxl862xx/mxl862xx-cmd.h | 3 +
|
||||
drivers/net/dsa/mxl862xx/mxl862xx-phylink.c | 155 ++++++++++++-
|
||||
drivers/net/dsa/mxl862xx/mxl862xx-phylink.h | 3 +
|
||||
4 files changed, 401 insertions(+), 4 deletions(-)
|
||||
|
||||
--- a/drivers/net/dsa/mxl862xx/mxl862xx-api.h
|
||||
+++ b/drivers/net/dsa/mxl862xx/mxl862xx-api.h
|
||||
@@ -2164,6 +2164,18 @@ struct mxl862xx_sys_fw_image_version {
|
||||
} __packed;
|
||||
|
||||
/**
|
||||
+ * enum mxl862xx_port_duplex - Ethernet port duplex status
|
||||
+ * @MXL862XX_DUPLEX_FULL: Port operates in full-duplex mode
|
||||
+ * @MXL862XX_DUPLEX_HALF: Port operates in half-duplex mode
|
||||
+ * @MXL862XX_DUPLEX_AUTO: Port operates in Auto mode
|
||||
+ */
|
||||
+enum mxl862xx_port_duplex {
|
||||
+ MXL862XX_DUPLEX_FULL = 0,
|
||||
+ MXL862XX_DUPLEX_HALF,
|
||||
+ MXL862XX_DUPLEX_AUTO,
|
||||
+};
|
||||
+
|
||||
+/**
|
||||
* enum mxl862xx_port_type - Port Type
|
||||
* @MXL862XX_LOGICAL_PORT: Logical Port
|
||||
* @MXL862XX_PHYSICAL_PORT: Physical Port
|
||||
@@ -2178,6 +2190,238 @@ enum mxl862xx_port_type {
|
||||
};
|
||||
|
||||
/**
|
||||
+ * enum mxl862xx_port_enable - port enable type selection.
|
||||
+ * @MXL862XX_PORT_DISABLE: the port is disabled in both directions
|
||||
+ * @MXL862XX_PORT_ENABLE_RXTX: the port is enabled in both directions
|
||||
+ * @MXL862XX_PORT_ENABLE_RX: the port is enabled in the receive direction
|
||||
+ * @MXL862XX_PORT_ENABLE_TX: the port is enabled in the transmit direction
|
||||
+ */
|
||||
+enum mxl862xx_port_enable {
|
||||
+ MXL862XX_PORT_DISABLE = 0,
|
||||
+ MXL862XX_PORT_ENABLE_RXTX,
|
||||
+ MXL862XX_PORT_ENABLE_RX,
|
||||
+ MXL862XX_PORT_ENABLE_TX,
|
||||
+};
|
||||
+
|
||||
+/**
|
||||
+ * enum mxl862xx_port_flow - ethernet flow control status
|
||||
+ * @MXL862XX_FLOW_AUTO: automatic flow control
|
||||
+ * @MXL862XX_FLOW_RX: receive flow control only
|
||||
+ * @MXL862XX_FLOW_TX: transmit flow control only
|
||||
+ * @MXL862XX_FLOW_RXTX: receive and transmit flow control
|
||||
+ * @MXL862XX_FLOW_OFF: no flow control
|
||||
+ */
|
||||
+enum mxl862xx_port_flow {
|
||||
+ MXL862XX_FLOW_AUTO = 0,
|
||||
+ MXL862XX_FLOW_RX,
|
||||
+ MXL862XX_FLOW_TX,
|
||||
+ MXL862XX_FLOW_RXTX,
|
||||
+ MXL862XX_FLOW_OFF,
|
||||
+};
|
||||
+
|
||||
+/**
|
||||
+ * enum mxl862xx_port_monitor - port mirror options
|
||||
+ * @MXL862XX_PORT_MONITOR_NONE: mirroring is disabled
|
||||
+ * @MXL862XX_PORT_MONITOR_RX: ingress packets are mirrored
|
||||
+ * @MXL862XX_PORT_MONITOR_TX: egress packets are mirrored
|
||||
+ * @MXL862XX_PORT_MONITOR_RXTX: ingress and egress packets are mirrored
|
||||
+ * @MXL862XX_PORT_MONITOR_VLAN_UNKNOWN: mirroring of 'unknown VLAN violation' frames
|
||||
+ * @MXL862XX_PORT_MONITOR_VLAN_MEMBERSHIP: mirroring of 'VLAN ingress or egress membership
|
||||
+ * violation' frames
|
||||
+ * @MXL862XX_PORT_MONITOR_PORT_STATE: mirroring of 'port state violation' frames
|
||||
+ * @MXL862XX_PORT_MONITOR_LEARNING_LIMIT: mirroring of 'MAC learning limit violation' frames
|
||||
+ * @MXL862XX_PORT_MONITOR_PORT_LOCK: mirroring of 'port lock violation' frames
|
||||
+ */
|
||||
+enum mxl862xx_port_monitor {
|
||||
+ MXL862XX_PORT_MONITOR_NONE = 0,
|
||||
+ MXL862XX_PORT_MONITOR_RX,
|
||||
+ MXL862XX_PORT_MONITOR_TX,
|
||||
+ MXL862XX_PORT_MONITOR_RXTX,
|
||||
+ MXL862XX_PORT_MONITOR_VLAN_UNKNOWN,
|
||||
+ MXL862XX_PORT_MONITOR_VLAN_MEMBERSHIP = 16,
|
||||
+ MXL862XX_PORT_MONITOR_PORT_STATE = 32,
|
||||
+ MXL862XX_PORT_MONITOR_LEARNING_LIMIT = 64,
|
||||
+ MXL862XX_PORT_MONITOR_PORT_LOCK = 128,
|
||||
+};
|
||||
+
|
||||
+/**
|
||||
+ * enum mxl862xx_if_rmon_mode - interface RMON counter mode
|
||||
+ * @MXL862XX_IF_RMON_FID: FID based RMON counters
|
||||
+ * @MXL862XX_IF_RMON_SUBID: sub-interface ID based
|
||||
+ * @MXL862XX_IF_RMON_FLOWID_LSB: flow ID based (bits 3:0)
|
||||
+ * @MXL862XX_IF_RMON_FLOWID_MSB: flow ID based (bits 7:4)
|
||||
+ */
|
||||
+enum mxl862xx_if_rmon_mode {
|
||||
+ MXL862XX_IF_RMON_FID = 0,
|
||||
+ MXL862XX_IF_RMON_SUBID,
|
||||
+ MXL862XX_IF_RMON_FLOWID_LSB,
|
||||
+ MXL862XX_IF_RMON_FLOWID_MSB,
|
||||
+};
|
||||
+
|
||||
+/**
|
||||
+ * struct mxl862xx_port_cfg - Port Configuration Parameters
|
||||
+ * @port_type: See &enum mxl862xx_port_type
|
||||
+ * @port_id: Ethernet Port number (zero-based counting)
|
||||
+ * @enable: See &enum mxl862xx_port_enable
|
||||
+ * @unicast_unknown_drop: Drop unknown unicast packets
|
||||
+ * @multicast_unknown_drop: Drop unknown multicast packets
|
||||
+ * @reserved_packet_drop: Drop reserved packet types
|
||||
+ * @broadcast_drop: Drop broadcast packets
|
||||
+ * @aging: Enables MAC address table aging.
|
||||
+ * @learning: MAC address table learning
|
||||
+ * @learning_mac_port_lock: Automatic MAC address table learning locking on the port
|
||||
+ * @learning_limit: Automatic MAC address table learning limitation on this port
|
||||
+ * @mac_spoofing_detection: MAC spoofing detection. Identifies ingress packets that carry
|
||||
+ * a MAC source address which was previously learned on a different ingress port
|
||||
+ * @flow_ctrl: See &enum mxl862xx_port_flow
|
||||
+ * @port_monitor: See &enum mxl862xx_port_monitor
|
||||
+ * @if_counters: Assign Interface RMON Counters for this Port
|
||||
+ * @if_count_start_idx: Interface RMON Counters Start Index
|
||||
+ * @if_rmonmode: See &enum mxl862xx_if_rmon_mode
|
||||
+ */
|
||||
+struct mxl862xx_port_cfg {
|
||||
+ __le32 port_type; /* enum mxl862xx_port_type */
|
||||
+ __le16 port_id;
|
||||
+ __le32 enable; /* enum mxl862xx_port_enable */
|
||||
+ u8 unicast_unknown_drop;
|
||||
+ u8 multicast_unknown_drop;
|
||||
+ u8 reserved_packet_drop;
|
||||
+ u8 broadcast_drop;
|
||||
+ u8 aging;
|
||||
+ u8 learning;
|
||||
+ u8 learning_mac_port_lock;
|
||||
+ __le16 learning_limit;
|
||||
+ u8 mac_spoofing_detection;
|
||||
+ __le32 flow_ctrl; /* enum mxl862xx_port_flow */
|
||||
+ __le32 port_monitor; /* enum mxl862xx_port_monitor */
|
||||
+ u8 if_counters;
|
||||
+ __le32 if_count_start_idx;
|
||||
+ __le32 if_rmonmode; /* enum mxl862xx_if_rmon_mode */
|
||||
+} __packed;
|
||||
+
|
||||
+/**
|
||||
+ * enum mxl862xx_port_speed - Ethernet port speed mode
|
||||
+ * @MXL862XX_PORT_SPEED_10: 10 Mbit/s
|
||||
+ * @MXL862XX_PORT_SPEED_100: 100 Mbit/s
|
||||
+ * @MXL862XX_PORT_SPEED_200: 200 Mbit/s
|
||||
+ * @MXL862XX_PORT_SPEED_1000: 1000 Mbit/s
|
||||
+ * @MXL862XX_PORT_SPEED_2500: 2.5 Gbit/s
|
||||
+ * @MXL862XX_PORT_SPEED_5000: 5 Gbit/s
|
||||
+ * @MXL862XX_PORT_SPEED_10000: 10 Gbit/s
|
||||
+ * @MXL862XX_PORT_SPEED_AUTO: Auto speed for XGMAC
|
||||
+ */
|
||||
+enum mxl862xx_port_speed {
|
||||
+ MXL862XX_PORT_SPEED_10 = 0,
|
||||
+ MXL862XX_PORT_SPEED_100,
|
||||
+ MXL862XX_PORT_SPEED_200,
|
||||
+ MXL862XX_PORT_SPEED_1000,
|
||||
+ MXL862XX_PORT_SPEED_2500,
|
||||
+ MXL862XX_PORT_SPEED_5000,
|
||||
+ MXL862XX_PORT_SPEED_10000,
|
||||
+ MXL862XX_PORT_SPEED_AUTO,
|
||||
+};
|
||||
+
|
||||
+/**
|
||||
+ * enum mxl862xx_port_link - Force the MAC and PHY link modus
|
||||
+ * @MXL862XX_PORT_LINK_UP: Link up
|
||||
+ * @MXL862XX_PORT_LINK_DOWN: Link down
|
||||
+ * @MXL862XX_PORT_LINK_AUTO: Link Auto
|
||||
+ */
|
||||
+enum mxl862xx_port_link {
|
||||
+ MXL862XX_PORT_LINK_UP = 0,
|
||||
+ MXL862XX_PORT_LINK_DOWN,
|
||||
+ MXL862XX_PORT_LINK_AUTO,
|
||||
+};
|
||||
+
|
||||
+/**
|
||||
+ * enum mxl862xx_mii_mode - Ethernet port interface mode
|
||||
+ * @MXL862XX_PORT_HW_MII: Normal PHY interface
|
||||
+ * @MXL862XX_PORT_HW_RMII: Reduced MII interface in normal mode
|
||||
+ * @MXL862XX_PORT_HW_GMII: GMII or MII, depending upon the speed
|
||||
+ * @MXL862XX_PORT_HW_RGMII: RGMII mode
|
||||
+ * @MXL862XX_PORT_HW_XGMII: XGMII mode
|
||||
+ */
|
||||
+enum mxl862xx_mii_mode {
|
||||
+ MXL862XX_PORT_HW_MII = 0,
|
||||
+ MXL862XX_PORT_HW_RMII,
|
||||
+ MXL862XX_PORT_HW_GMII,
|
||||
+ MXL862XX_PORT_HW_RGMII,
|
||||
+ MXL862XX_PORT_HW_XGMII,
|
||||
+};
|
||||
+
|
||||
+/**
|
||||
+ * enum mxl862xx_mii_type - Ethernet port configuration for PHY or MAC mode
|
||||
+ * @MXL862XX_PORT_MAC: The Ethernet port is configured to work in MAC mode
|
||||
+ * @MXL862XX_PORT_PHY: The Ethernet port is configured to work in PHY mode
|
||||
+ */
|
||||
+enum mxl862xx_mii_type {
|
||||
+ MXL862XX_PORT_MAC = 0,
|
||||
+ MXL862XX_PORT_PHY,
|
||||
+};
|
||||
+
|
||||
+/**
|
||||
+ * enum mxl862xx_clk_mode - Ethernet port clock source configuration
|
||||
+ * @MXL862XX_PORT_CLK_NA: Clock Mode not applicable
|
||||
+ * @MXL862XX_PORT_CLK_MASTER: Clock Master Mode.
|
||||
+ * @MXL862XX_PORT_CLK_SLAVE: Clock Slave Mode.
|
||||
+ */
|
||||
+enum mxl862xx_clk_mode {
|
||||
+ MXL862XX_PORT_CLK_NA = 0,
|
||||
+ MXL862XX_PORT_CLK_MASTER,
|
||||
+ MXL862XX_PORT_CLK_SLAVE,
|
||||
+};
|
||||
+
|
||||
+/**
|
||||
+ * struct mxl862xx_port_link_cfg - Ethernet port link, speed status and flow control status
|
||||
+ * @port_id: Ethernet Port number
|
||||
+ * @duplex_force: Force Port Duplex Mode
|
||||
+ * @duplex: See &enum mxl862xx_port_duplex
|
||||
+ * @speed_force: Force Link Speed
|
||||
+ * @speed: See &enum mxl862xx_port_speed
|
||||
+ * @link_force: Force Link
|
||||
+ * @link: See &enum mxl862xx_port_link
|
||||
+ * @mii_mode: See &enum mxl862xx_mii_mode
|
||||
+ * @mii_type: See &enum mxl862xx_mii_type
|
||||
+ * @clk_mode: See &enum mxl862xx_clk_mode
|
||||
+ * @lpi: 'Low Power Idle' Support for 'Energy Efficient Ethernet'
|
||||
+ */
|
||||
+struct mxl862xx_port_link_cfg {
|
||||
+ __le16 port_id;
|
||||
+ u8 duplex_force;
|
||||
+ __le32 duplex; /* enum mxl862xx_port_duplex */
|
||||
+ u8 speed_force;
|
||||
+ __le32 speed; /* enum mxl862xx_port_speed */
|
||||
+ u8 link_force;
|
||||
+ __le32 link; /* enum mxl862xx_port_link */
|
||||
+ __le32 mii_mode; /* enum mxl862xx_mii_mode */
|
||||
+ __le32 mii_type; /* enum mxl862xx_mii_type */
|
||||
+ __le32 clk_mode; /* enum mxl862xx_clk_mode */
|
||||
+ u8 lpi;
|
||||
+} __packed;
|
||||
+
|
||||
+/**
|
||||
+ * struct mxl862xx_sys_sfp_cfg - legacy SFP/SerDes port configuration
|
||||
+ * @port_id: port id (0 or 1)
|
||||
+ * @option: config options (0 - SFP mode/speed/link-status, 1 - flow control)
|
||||
+ * @mode: SFP mode (0 - auto, 1 - fix, 2 - disable)
|
||||
+ * @speed: select speed when mode is 1
|
||||
+ * @link: get link state
|
||||
+ * @fc_en: flow control (0 - disable, 1 - enable)
|
||||
+ */
|
||||
+struct mxl862xx_sys_sfp_cfg {
|
||||
+ u8 port_id:4;
|
||||
+ u8 option:4;
|
||||
+ union {
|
||||
+ struct {
|
||||
+ u8 mode;
|
||||
+ u8 speed;
|
||||
+ u8 link;
|
||||
+ };
|
||||
+ u8 fc_en;
|
||||
+ };
|
||||
+} __packed;
|
||||
+
|
||||
+/**
|
||||
* enum mxl862xx_rmon_port_type - RMON counter table type
|
||||
* @MXL862XX_RMON_CTP_PORT_RX: CTP RX counters
|
||||
* @MXL862XX_RMON_CTP_PORT_TX: CTP TX counters
|
||||
--- a/drivers/net/dsa/mxl862xx/mxl862xx-cmd.h
|
||||
+++ b/drivers/net/dsa/mxl862xx/mxl862xx-cmd.h
|
||||
@@ -27,6 +27,8 @@
|
||||
#define SYS_MISC_MAGIC 0x1900
|
||||
#define MXL862XX_XPCS_MAGIC 0x1a00
|
||||
|
||||
+#define MXL862XX_COMMON_PORTLINKCFGGET (MXL862XX_COMMON_MAGIC + 0x5)
|
||||
+#define MXL862XX_COMMON_PORTCFGGET (MXL862XX_COMMON_MAGIC + 0x7)
|
||||
#define MXL862XX_COMMON_CFGGET (MXL862XX_COMMON_MAGIC + 0x9)
|
||||
#define MXL862XX_COMMON_CFGSET (MXL862XX_COMMON_MAGIC + 0xa)
|
||||
#define MXL862XX_COMMON_MONITORPORTCFGSET (MXL862XX_COMMON_MAGIC + 0xe)
|
||||
@@ -86,6 +88,7 @@
|
||||
|
||||
#define SYS_MISC_FW_UPDATE (SYS_MISC_MAGIC + 0x1)
|
||||
#define SYS_MISC_FW_VERSION (SYS_MISC_MAGIC + 0x2)
|
||||
+#define SYS_MISC_SFP_SET (SYS_MISC_MAGIC + 0xe)
|
||||
|
||||
#define MXL862XX_XPCS_PCS_CONFIG (MXL862XX_XPCS_MAGIC + 0x1)
|
||||
#define MXL862XX_XPCS_PCS_GET_STATE (MXL862XX_XPCS_MAGIC + 0x2)
|
||||
--- a/drivers/net/dsa/mxl862xx/mxl862xx-phylink.c
|
||||
+++ b/drivers/net/dsa/mxl862xx/mxl862xx-phylink.c
|
||||
@@ -62,6 +62,153 @@ static struct mxl862xx_pcs *pcs_to_mxl86
|
||||
return container_of(pcs, struct mxl862xx_pcs, pcs);
|
||||
}
|
||||
|
||||
+/* Legacy SFP-based PCS implementation for firmware < 1.0.84 */
|
||||
+static int mxl862xx_legacy_pcs_config(struct phylink_pcs *pcs,
|
||||
+ unsigned int neg_mode,
|
||||
+ phy_interface_t interface,
|
||||
+ const unsigned long *advertising,
|
||||
+ bool permit_pause_to_mac)
|
||||
+{
|
||||
+ struct mxl862xx_pcs *mpcs = pcs_to_mxl862xx_pcs(pcs);
|
||||
+ struct mxl862xx_priv *priv = mpcs->priv;
|
||||
+ struct mxl862xx_sys_sfp_cfg ser_intf = {
|
||||
+ .option = 0,
|
||||
+ .mode = 1,
|
||||
+ };
|
||||
+
|
||||
+ if (mpcs->slot != 0)
|
||||
+ return 0;
|
||||
+
|
||||
+ ser_intf.port_id = mpcs->serdes_id;
|
||||
+
|
||||
+ switch (interface) {
|
||||
+ case PHY_INTERFACE_MODE_SGMII:
|
||||
+ ser_intf.speed = 8;
|
||||
+ break;
|
||||
+ case PHY_INTERFACE_MODE_1000BASEX:
|
||||
+ ser_intf.speed = (neg_mode & PHYLINK_PCS_NEG_INBAND) ? 1 : 7;
|
||||
+ break;
|
||||
+ case PHY_INTERFACE_MODE_2500BASEX:
|
||||
+ ser_intf.speed = 4;
|
||||
+ break;
|
||||
+ case PHY_INTERFACE_MODE_10GBASER:
|
||||
+ ser_intf.speed = 2;
|
||||
+ break;
|
||||
+ case PHY_INTERFACE_MODE_USXGMII:
|
||||
+ ser_intf.speed = 3;
|
||||
+ break;
|
||||
+ default:
|
||||
+ dev_err(priv->ds->dev, "unsupported interface: %s\n",
|
||||
+ phy_modes(interface));
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ return MXL862XX_API_WRITE(priv, SYS_MISC_SFP_SET, ser_intf);
|
||||
+}
|
||||
+
|
||||
+static void mxl862xx_legacy_pcs_get_state(struct phylink_pcs *pcs,
|
||||
+ unsigned int neg_mode,
|
||||
+ struct phylink_link_state *state)
|
||||
+{
|
||||
+ struct mxl862xx_pcs *mpcs = pcs_to_mxl862xx_pcs(pcs);
|
||||
+ struct mxl862xx_priv *priv = mpcs->priv;
|
||||
+ struct mxl862xx_port_link_cfg port_link_cfg = {
|
||||
+ .port_id = cpu_to_le16(MXL862XX_PCS_PORT(mpcs)),
|
||||
+ };
|
||||
+ struct mxl862xx_port_cfg port_cfg = {
|
||||
+ .port_id = cpu_to_le16(MXL862XX_PCS_PORT(mpcs)),
|
||||
+ };
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = MXL862XX_API_READ(priv, MXL862XX_COMMON_PORTLINKCFGGET,
|
||||
+ port_link_cfg);
|
||||
+ if (ret)
|
||||
+ return;
|
||||
+
|
||||
+ ret = MXL862XX_API_READ(priv, MXL862XX_COMMON_PORTCFGGET, port_cfg);
|
||||
+ if (ret)
|
||||
+ return;
|
||||
+
|
||||
+ state->link = (le32_to_cpu(port_link_cfg.link) == MXL862XX_PORT_LINK_UP);
|
||||
+ state->an_complete = state->link;
|
||||
+
|
||||
+ switch (le32_to_cpu(port_link_cfg.speed)) {
|
||||
+ case MXL862XX_PORT_SPEED_10:
|
||||
+ state->speed = SPEED_10;
|
||||
+ break;
|
||||
+ case MXL862XX_PORT_SPEED_100:
|
||||
+ state->speed = SPEED_100;
|
||||
+ break;
|
||||
+ case MXL862XX_PORT_SPEED_1000:
|
||||
+ state->speed = SPEED_1000;
|
||||
+ break;
|
||||
+ case MXL862XX_PORT_SPEED_2500:
|
||||
+ state->speed = SPEED_2500;
|
||||
+ break;
|
||||
+ case MXL862XX_PORT_SPEED_5000:
|
||||
+ state->speed = SPEED_5000;
|
||||
+ break;
|
||||
+ case MXL862XX_PORT_SPEED_10000:
|
||||
+ state->speed = SPEED_10000;
|
||||
+ break;
|
||||
+ default:
|
||||
+ state->speed = SPEED_UNKNOWN;
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ switch (le32_to_cpu(port_link_cfg.duplex)) {
|
||||
+ case MXL862XX_DUPLEX_HALF:
|
||||
+ state->duplex = DUPLEX_HALF;
|
||||
+ break;
|
||||
+ case MXL862XX_DUPLEX_FULL:
|
||||
+ state->duplex = DUPLEX_FULL;
|
||||
+ break;
|
||||
+ default:
|
||||
+ state->duplex = DUPLEX_UNKNOWN;
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ state->pause &= ~(MLO_PAUSE_RX | MLO_PAUSE_TX);
|
||||
+ switch (le32_to_cpu(port_cfg.flow_ctrl)) {
|
||||
+ case MXL862XX_FLOW_RXTX:
|
||||
+ state->pause |= MLO_PAUSE_TXRX_MASK;
|
||||
+ break;
|
||||
+ case MXL862XX_FLOW_TX:
|
||||
+ state->pause |= MLO_PAUSE_TX;
|
||||
+ break;
|
||||
+ case MXL862XX_FLOW_RX:
|
||||
+ state->pause |= MLO_PAUSE_RX;
|
||||
+ break;
|
||||
+ case MXL862XX_FLOW_OFF:
|
||||
+ default:
|
||||
+ break;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static unsigned int
|
||||
+mxl862xx_legacy_pcs_inband_caps(struct phylink_pcs *pcs,
|
||||
+ phy_interface_t interface)
|
||||
+{
|
||||
+ switch (interface) {
|
||||
+ case PHY_INTERFACE_MODE_SGMII:
|
||||
+ case PHY_INTERFACE_MODE_USXGMII:
|
||||
+ return LINK_INBAND_ENABLE;
|
||||
+ case PHY_INTERFACE_MODE_1000BASEX:
|
||||
+ return LINK_INBAND_DISABLE | LINK_INBAND_ENABLE;
|
||||
+ case PHY_INTERFACE_MODE_10GBASER:
|
||||
+ case PHY_INTERFACE_MODE_2500BASEX:
|
||||
+ return LINK_INBAND_DISABLE;
|
||||
+ default:
|
||||
+ return 0;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static const struct phylink_pcs_ops mxl862xx_legacy_pcs_ops = {
|
||||
+ .pcs_get_state = mxl862xx_legacy_pcs_get_state,
|
||||
+ .pcs_config = mxl862xx_legacy_pcs_config,
|
||||
+ .pcs_inband_caps = mxl862xx_legacy_pcs_inband_caps,
|
||||
+};
|
||||
+
|
||||
static int mxl862xx_xpcs_if_mode(phy_interface_t interface)
|
||||
{
|
||||
switch (interface) {
|
||||
@@ -352,7 +499,10 @@ void mxl862xx_setup_pcs(struct mxl862xx_
|
||||
pcs->slot = MXL862XX_SERDES_SLOT(port);
|
||||
pcs->interface = PHY_INTERFACE_MODE_NA;
|
||||
|
||||
- pcs->pcs.ops = &mxl862xx_pcs_ops;
|
||||
+ if (MXL862XX_FW_VER_MIN(priv, 1, 0, 84))
|
||||
+ pcs->pcs.ops = &mxl862xx_pcs_ops;
|
||||
+ else
|
||||
+ pcs->pcs.ops = &mxl862xx_legacy_pcs_ops;
|
||||
pcs->pcs.poll = true;
|
||||
|
||||
__set_bit(PHY_INTERFACE_MODE_QSGMII, pcs->pcs.supported_interfaces);
|
||||
@@ -376,9 +526,6 @@ mxl862xx_phylink_mac_select_pcs(struct p
|
||||
struct mxl862xx_priv *priv = dp->ds->priv;
|
||||
int port = dp->index;
|
||||
|
||||
- if (!MXL862XX_FW_VER_MIN(priv, 1, 0, 84))
|
||||
- return NULL;
|
||||
-
|
||||
switch (port) {
|
||||
case 9 ... 16:
|
||||
return &priv->serdes_ports[port - 9].pcs;
|
||||
--- a/drivers/net/dsa/mxl862xx/mxl862xx-phylink.h
|
||||
+++ b/drivers/net/dsa/mxl862xx/mxl862xx-phylink.h
|
||||
@@ -11,6 +11,9 @@
|
||||
(((port) - MXL862XX_FIRST_SERDES_PORT) % MXL862XX_SERDES_SLOTS)
|
||||
#define MXL862XX_SERDES_PORT_ID(port) \
|
||||
(((port) - MXL862XX_FIRST_SERDES_PORT) / MXL862XX_SERDES_SLOTS)
|
||||
+#define MXL862XX_PCS_PORT(mpcs) \
|
||||
+ (MXL862XX_FIRST_SERDES_PORT + \
|
||||
+ (mpcs)->serdes_id * MXL862XX_SERDES_SLOTS + (mpcs)->slot)
|
||||
|
||||
extern const struct phylink_mac_ops mxl862xx_phylink_mac_ops;
|
||||
void mxl862xx_phylink_get_caps(struct dsa_switch *ds, int port,
|
||||
-81
@@ -1,81 +0,0 @@
|
||||
From 8856f7610167a3005ecef401c8528111d153b554 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Golle <daniel@makrotopia.org>
|
||||
Date: Tue, 24 Mar 2026 18:17:49 +0000
|
||||
Subject: [PATCH 18/19] DO NOT SUBMIT: net: dsa: mxl862xx: re-introduce PCE
|
||||
workaround for old firmware
|
||||
|
||||
Re-introduce the mxl862xx_disable_fw_global_rules() function that
|
||||
disables firmware default global PCE rules for firmware versions
|
||||
older than 1.0.80. The upstream submission replaced this with a
|
||||
dev_warn() since firmware >= 1.0.80 no longer installs these rules,
|
||||
but downstream deployments may still run older firmware.
|
||||
|
||||
This commit is for downstream use only and must not be submitted
|
||||
upstream.
|
||||
|
||||
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
---
|
||||
drivers/net/dsa/mxl862xx/mxl862xx.c | 45 +++++++++++++++++++++++++++--
|
||||
1 file changed, 42 insertions(+), 3 deletions(-)
|
||||
|
||||
--- a/drivers/net/dsa/mxl862xx/mxl862xx.c
|
||||
+++ b/drivers/net/dsa/mxl862xx/mxl862xx.c
|
||||
@@ -449,6 +449,43 @@ static int mxl862xx_setup_drop_meter(str
|
||||
return MXL862XX_API_WRITE(priv, MXL862XX_COMMON_REGISTERMOD, reg);
|
||||
}
|
||||
|
||||
+/* Disable firmware global PCE rules that trap various protocols to the
|
||||
+ * on-die microcontroller (port 0) via PORTMAP_CPU. Under DSA, these
|
||||
+ * frames must either reach the host CPU via per-port rules (link-local)
|
||||
+ * or through the normal bridge forwarding path (ARP broadcast), so the
|
||||
+ * global firmware rules are not needed. With the microcontroller port
|
||||
+ * disabled they would silently drop matching traffic.
|
||||
+ *
|
||||
+ * Global rules have lower indices than CTP rules, hence higher priority
|
||||
+ * in the PCE pipeline -- they must be explicitly disabled or they will
|
||||
+ * shadow the per-CTP traps.
|
||||
+ *
|
||||
+ * Indices from gsw_flow_index.h:
|
||||
+ * 1 -- BPDU (STP/RSTP, dst 01:80:c2:00:00:00)
|
||||
+ * 3 -- LLDP (EtherType 0x88cc)
|
||||
+ * 4 -- OAM/LACP (EtherType 0x8809)
|
||||
+ * 6 -- System MAC (dst 02:e0:92:00:00:01, vendor management MAC)
|
||||
+ * 7 -- ARP Request (broadcast + EtherType 0x0806 + TPA 192.0.2.1)
|
||||
+ */
|
||||
+static int mxl862xx_disable_fw_global_rules(struct dsa_switch *ds)
|
||||
+{
|
||||
+ static const u16 indices[] = { 1, 3, 4, 6, 7 };
|
||||
+ struct mxl862xx_pce_rule rule;
|
||||
+ int i, ret;
|
||||
+
|
||||
+ for (i = 0; i < ARRAY_SIZE(indices); i++) {
|
||||
+ memset(&rule, 0, sizeof(rule));
|
||||
+ rule.pattern.index = cpu_to_le16(indices[i]);
|
||||
+ /* pattern.enable == 0 -> rule is disabled */
|
||||
+
|
||||
+ ret = MXL862XX_API_WRITE(ds->priv,
|
||||
+ MXL862XX_TFLOW_PCERULEWRITE, rule);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
|
||||
/* Per-CTP offsets for protocol trap rules. Each port's CTP flow-table
|
||||
* block is pre-allocated by the firmware during init (44 entries per
|
||||
@@ -1114,9 +1151,11 @@ static int mxl862xx_setup(struct dsa_swi
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
- if (!MXL862XX_FW_VER_MIN(priv, 1, 0, 80))
|
||||
- dev_warn(ds->dev, "firmware < 1.0.80 installs global PCE rules "
|
||||
- "that interfere with DSA operation, please update\n");
|
||||
+ if (!MXL862XX_FW_VER_MIN(priv, 1, 0, 80)) {
|
||||
+ ret = mxl862xx_disable_fw_global_rules(ds);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+ }
|
||||
|
||||
/* Pre-allocate firmware resources for all ports. The DSA core
|
||||
* calls change_tag_protocol() between setup() and port_setup(),
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
From df0c747216063041ba0d786b01f9b1e2aba5316a Mon Sep 17 00:00:00 2001
|
||||
From 332dd61f50b096256f889ecb4d730d385e58aec2 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Golle <daniel@makrotopia.org>
|
||||
Date: Wed, 22 Apr 2026 15:15:52 +0100
|
||||
Subject: [PATCH] DO NOT SUBMIT: net: dsa: mxl862xx: increase CMD timeout
|
||||
Subject: [PATCH 19/19] DO NOT SUBMIT: net: dsa: mxl862xx: increase CMD timeout
|
||||
|
||||
Lift the command timeout by 10x from 500ms to 5s.
|
||||
This is done because older firmware can be extremely slow to respond
|
||||
-252
@@ -1,252 +0,0 @@
|
||||
From 20be48bbcc89f5ca91e9d6adadeda9bd29d75c53 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Golle <daniel@makrotopia.org>
|
||||
Date: Tue, 24 Mar 2026 18:19:56 +0000
|
||||
Subject: [PATCH 19/19] DO NOT SUBMIT: net: dsa: mxl862xx: legacy SFP API
|
||||
fallback for old firmware
|
||||
|
||||
Re-introduce the SYS_MISC_SFP_SET-based PCS implementation as a
|
||||
fallback for firmware versions older than 1.0.80 which lack the
|
||||
XPCS API. mxl862xx_setup_pcs() selects between the XPCS ops and
|
||||
legacy SFP ops based on firmware version.
|
||||
|
||||
This commit is for downstream use only and must not be submitted
|
||||
upstream.
|
||||
|
||||
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
---
|
||||
drivers/net/dsa/mxl862xx/mxl862xx-api.h | 22 +++
|
||||
drivers/net/dsa/mxl862xx/mxl862xx-cmd.h | 1 +
|
||||
drivers/net/dsa/mxl862xx/mxl862xx-phylink.c | 160 +++++++++++++++++++-
|
||||
3 files changed, 178 insertions(+), 5 deletions(-)
|
||||
|
||||
--- a/drivers/net/dsa/mxl862xx/mxl862xx-api.h
|
||||
+++ b/drivers/net/dsa/mxl862xx/mxl862xx-api.h
|
||||
@@ -2400,6 +2400,28 @@ struct mxl862xx_sys_fw_image_version {
|
||||
} __packed;
|
||||
|
||||
/**
|
||||
+ * struct mxl862xx_sys_sfp_cfg - legacy SFP/SerDes port configuration
|
||||
+ * @port_id: port id (0 or 1)
|
||||
+ * @option: config options (0 - SFP mode/speed/link-status, 1 - flow control)
|
||||
+ * @mode: SFP mode (0 - auto, 1 - fix, 2 - disable)
|
||||
+ * @speed: select speed when mode is 1
|
||||
+ * @link: get link state
|
||||
+ * @fc_en: flow control (0 - disable, 1 - enable)
|
||||
+ */
|
||||
+struct mxl862xx_sys_sfp_cfg {
|
||||
+ u8 port_id:4;
|
||||
+ u8 option:4;
|
||||
+ union {
|
||||
+ struct {
|
||||
+ u8 mode;
|
||||
+ u8 speed;
|
||||
+ u8 link;
|
||||
+ };
|
||||
+ u8 fc_en;
|
||||
+ };
|
||||
+} __packed;
|
||||
+
|
||||
+/**
|
||||
* enum mxl862xx_rmon_port_type - RMON counter table type
|
||||
* @MXL862XX_RMON_CTP_PORT_RX: CTP RX counters
|
||||
* @MXL862XX_RMON_CTP_PORT_TX: CTP TX counters
|
||||
--- a/drivers/net/dsa/mxl862xx/mxl862xx-cmd.h
|
||||
+++ b/drivers/net/dsa/mxl862xx/mxl862xx-cmd.h
|
||||
@@ -85,6 +85,7 @@
|
||||
|
||||
#define SYS_MISC_FW_UPDATE (SYS_MISC_MAGIC + 0x1)
|
||||
#define SYS_MISC_FW_VERSION (SYS_MISC_MAGIC + 0x2)
|
||||
+#define SYS_MISC_SFP_SET (SYS_MISC_MAGIC + 0xe)
|
||||
|
||||
#define MXL862XX_XPCS_MAGIC 0x1a00
|
||||
#define MXL862XX_XPCS_PCS_CONFIG (MXL862XX_XPCS_MAGIC + 0x1)
|
||||
--- a/drivers/net/dsa/mxl862xx/mxl862xx-phylink.c
|
||||
+++ b/drivers/net/dsa/mxl862xx/mxl862xx-phylink.c
|
||||
@@ -52,6 +52,156 @@ static struct mxl862xx_pcs *pcs_to_mxl86
|
||||
return container_of(pcs, struct mxl862xx_pcs, pcs);
|
||||
}
|
||||
|
||||
+/* Legacy SFP-based PCS implementation for firmware < 1.0.80 */
|
||||
+static int mxl862xx_legacy_pcs_config(struct phylink_pcs *pcs,
|
||||
+ unsigned int neg_mode,
|
||||
+ phy_interface_t interface,
|
||||
+ const unsigned long *advertising,
|
||||
+ bool permit_pause_to_mac)
|
||||
+{
|
||||
+ struct mxl862xx_priv *priv = pcs_to_mxl862xx_pcs(pcs)->priv;
|
||||
+ int port = pcs_to_mxl862xx_pcs(pcs)->port;
|
||||
+ struct mxl862xx_sys_sfp_cfg ser_intf = {
|
||||
+ .option = 0,
|
||||
+ .mode = 1,
|
||||
+ };
|
||||
+
|
||||
+ if (port != 9 && port != 13)
|
||||
+ return 0;
|
||||
+
|
||||
+ if (port == 9)
|
||||
+ ser_intf.port_id = 0;
|
||||
+ else
|
||||
+ ser_intf.port_id = 1;
|
||||
+
|
||||
+ switch (interface) {
|
||||
+ case PHY_INTERFACE_MODE_SGMII:
|
||||
+ ser_intf.speed = 8;
|
||||
+ break;
|
||||
+ case PHY_INTERFACE_MODE_1000BASEX:
|
||||
+ ser_intf.speed = (neg_mode & PHYLINK_PCS_NEG_INBAND) ? 1 : 7;
|
||||
+ break;
|
||||
+ case PHY_INTERFACE_MODE_2500BASEX:
|
||||
+ ser_intf.speed = 4;
|
||||
+ break;
|
||||
+ case PHY_INTERFACE_MODE_10GBASER:
|
||||
+ ser_intf.speed = 2;
|
||||
+ break;
|
||||
+ case PHY_INTERFACE_MODE_USXGMII:
|
||||
+ ser_intf.speed = 3;
|
||||
+ break;
|
||||
+ default:
|
||||
+ dev_err(priv->ds->dev, "unsupported interface: %s\n",
|
||||
+ phy_modes(interface));
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ return MXL862XX_API_WRITE(priv, SYS_MISC_SFP_SET, ser_intf);
|
||||
+}
|
||||
+
|
||||
+static void mxl862xx_legacy_pcs_get_state(struct phylink_pcs *pcs,
|
||||
+ unsigned int neg_mode,
|
||||
+ struct phylink_link_state *state)
|
||||
+{
|
||||
+ struct mxl862xx_priv *priv = pcs_to_mxl862xx_pcs(pcs)->priv;
|
||||
+ int port = pcs_to_mxl862xx_pcs(pcs)->port;
|
||||
+ struct mxl862xx_port_link_cfg port_link_cfg = {
|
||||
+ .port_id = port,
|
||||
+ };
|
||||
+ struct mxl862xx_port_cfg port_cfg = {
|
||||
+ .port_id = port,
|
||||
+ };
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = MXL862XX_API_READ(priv, MXL862XX_COMMON_PORTLINKCFGGET,
|
||||
+ port_link_cfg);
|
||||
+ if (ret)
|
||||
+ return;
|
||||
+
|
||||
+ ret = MXL862XX_API_READ(priv, MXL862XX_COMMON_PORTCFGGET, port_cfg);
|
||||
+ if (ret)
|
||||
+ return;
|
||||
+
|
||||
+ state->link = (port_link_cfg.link == MXL862XX_PORT_LINK_UP);
|
||||
+ state->an_complete = state->link;
|
||||
+
|
||||
+ switch (port_link_cfg.speed) {
|
||||
+ case MXL862XX_PORT_SPEED_10:
|
||||
+ state->speed = SPEED_10;
|
||||
+ break;
|
||||
+ case MXL862XX_PORT_SPEED_100:
|
||||
+ state->speed = SPEED_100;
|
||||
+ break;
|
||||
+ case MXL862XX_PORT_SPEED_1000:
|
||||
+ state->speed = SPEED_1000;
|
||||
+ break;
|
||||
+ case MXL862XX_PORT_SPEED_2500:
|
||||
+ state->speed = SPEED_2500;
|
||||
+ break;
|
||||
+ case MXL862XX_PORT_SPEED_5000:
|
||||
+ state->speed = SPEED_5000;
|
||||
+ break;
|
||||
+ case MXL862XX_PORT_SPEED_10000:
|
||||
+ state->speed = SPEED_10000;
|
||||
+ break;
|
||||
+ default:
|
||||
+ state->speed = SPEED_UNKNOWN;
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ switch (port_link_cfg.duplex) {
|
||||
+ case MXL862XX_DUPLEX_HALF:
|
||||
+ state->duplex = DUPLEX_HALF;
|
||||
+ break;
|
||||
+ case MXL862XX_DUPLEX_FULL:
|
||||
+ state->duplex = DUPLEX_FULL;
|
||||
+ break;
|
||||
+ default:
|
||||
+ state->duplex = DUPLEX_UNKNOWN;
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ state->pause &= ~(MLO_PAUSE_RX | MLO_PAUSE_TX);
|
||||
+ switch (port_cfg.flow_ctrl) {
|
||||
+ case MXL862XX_FLOW_RXTX:
|
||||
+ state->pause |= MLO_PAUSE_TXRX_MASK;
|
||||
+ break;
|
||||
+ case MXL862XX_FLOW_TX:
|
||||
+ state->pause |= MLO_PAUSE_TX;
|
||||
+ break;
|
||||
+ case MXL862XX_FLOW_RX:
|
||||
+ state->pause |= MLO_PAUSE_RX;
|
||||
+ break;
|
||||
+ case MXL862XX_FLOW_OFF:
|
||||
+ default:
|
||||
+ break;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static unsigned int
|
||||
+mxl862xx_legacy_pcs_inband_caps(struct phylink_pcs *pcs,
|
||||
+ phy_interface_t interface)
|
||||
+{
|
||||
+ switch (interface) {
|
||||
+ case PHY_INTERFACE_MODE_SGMII:
|
||||
+ case PHY_INTERFACE_MODE_USXGMII:
|
||||
+ return LINK_INBAND_ENABLE;
|
||||
+ case PHY_INTERFACE_MODE_1000BASEX:
|
||||
+ return LINK_INBAND_DISABLE | LINK_INBAND_ENABLE;
|
||||
+ case PHY_INTERFACE_MODE_10GBASER:
|
||||
+ case PHY_INTERFACE_MODE_2500BASEX:
|
||||
+ return LINK_INBAND_DISABLE;
|
||||
+ default:
|
||||
+ return 0;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static const struct phylink_pcs_ops mxl862xx_legacy_pcs_ops = {
|
||||
+ .pcs_get_state = mxl862xx_legacy_pcs_get_state,
|
||||
+ .pcs_config = mxl862xx_legacy_pcs_config,
|
||||
+ .pcs_inband_caps = mxl862xx_legacy_pcs_inband_caps,
|
||||
+};
|
||||
+
|
||||
static int mxl862xx_xpcs_port_id(int port)
|
||||
{
|
||||
return port >= 13;
|
||||
@@ -390,7 +540,10 @@ void mxl862xx_setup_pcs(struct mxl862xx_
|
||||
pcs->priv = priv;
|
||||
pcs->port = port;
|
||||
|
||||
- pcs->pcs.ops = &mxl862xx_pcs_ops;
|
||||
+ if (MXL862XX_FW_VER_MIN(priv, 1, 0, 80))
|
||||
+ pcs->pcs.ops = &mxl862xx_pcs_ops;
|
||||
+ else
|
||||
+ pcs->pcs.ops = &mxl862xx_legacy_pcs_ops;
|
||||
pcs->pcs.poll = true;
|
||||
|
||||
/* Sub-ports only support QSGMII (quad mode with dedicated
|
||||
@@ -418,9 +571,6 @@ mxl862xx_phylink_mac_select_pcs(struct p
|
||||
struct mxl862xx_priv *priv = dp->ds->priv;
|
||||
int port = dp->index;
|
||||
|
||||
- if (!MXL862XX_FW_VER_MIN(priv, 1, 0, 80))
|
||||
- return NULL;
|
||||
-
|
||||
switch (port) {
|
||||
case 9 ... 16:
|
||||
return &priv->serdes_ports[port - 9].pcs;
|
||||
@@ -551,7 +701,7 @@ void mxl862xx_serdes_get_stats(struct ds
|
||||
}
|
||||
|
||||
void mxl862xx_serdes_self_test(struct dsa_switch *ds, int port,
|
||||
- struct ethtool_test *etest, u64 *data)
|
||||
+ struct ethtool_test *etest, u64 *data)
|
||||
{
|
||||
struct mxl862xx_xpcs_prbs_cfg prbs = {};
|
||||
struct mxl862xx_xpcs_bert_cfg bert = {};
|
||||
@@ -18,7 +18,8 @@ gw,imx8mp-gw72xx-2x|\
|
||||
gw,imx8mm-gw73xx-0x|\
|
||||
gw,imx8mp-gw73xx-2x|\
|
||||
gw,imx8mm-gw7902-0x|\
|
||||
gateworks,imx8mp-gw82xx-2x)
|
||||
gateworks,imx8mp-gw82xx-2x|\
|
||||
kontron,imx8mp-bl-osm-s)
|
||||
ucidef_set_interfaces_lan_wan 'eth1' 'eth0'
|
||||
;;
|
||||
gw,imx8mm-gw7901)
|
||||
|
||||
@@ -2,7 +2,8 @@
|
||||
enable_image_metadata_check() {
|
||||
case "$(board_name)" in
|
||||
gateworks,imx8m*|\
|
||||
gw,imx8m*)
|
||||
gw,imx8m*|\
|
||||
kontron,imx8mp-bl-osm-s)
|
||||
REQUIRE_IMAGE_METADATA=1
|
||||
;;
|
||||
esac
|
||||
@@ -14,7 +15,8 @@ platform_check_image() {
|
||||
|
||||
case "$board" in
|
||||
gateworks,imx8m*|\
|
||||
gw,imx8m*)
|
||||
gw,imx8m*|\
|
||||
kontron,imx8mp-bl-osm-s)
|
||||
return 0
|
||||
;;
|
||||
esac
|
||||
@@ -28,7 +30,8 @@ platform_do_upgrade() {
|
||||
|
||||
case "$board" in
|
||||
gateworks,imx8m*|\
|
||||
gw,imx8m*)
|
||||
gw,imx8m*|\
|
||||
kontron,imx8mp-bl-osm-s)
|
||||
export_bootdevice && export_partdevice diskdev 0 || {
|
||||
echo "Unable to find root device."
|
||||
return 1
|
||||
@@ -45,7 +48,8 @@ platform_copy_config() {
|
||||
|
||||
case "$board" in
|
||||
gateworks,imx8m*|\
|
||||
gw,imx8m*)
|
||||
gw,imx8m*|\
|
||||
kontron,imx8mp-bl-osm-s)
|
||||
export_partdevice partdev 1 && {
|
||||
v "Storing $UPGRADE_BACKUP on /dev/$partdev..."
|
||||
mount -o rw,noatime "/dev/$partdev" /mnt
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user