Merge Official Source
Signed-off-by: ZiMing Mo <msylgj@immortalwrt.org>
This commit is contained in:
commit
5dd4ff5cd6
@ -1,2 +1,2 @@
|
|||||||
LINUX_VERSION-5.15 = .35
|
LINUX_VERSION-5.15 = .38
|
||||||
LINUX_KERNEL_HASH-5.15.35 = 0a1a5ae2f30eb2b38215e59077f045aabd7f4e2857a881482f02ea48186105d8
|
LINUX_KERNEL_HASH-5.15.38 = 7e415d420990b88bfec038d56e920b9b28f99d54f31dbbd7aa82e66acca11052
|
||||||
|
@ -30,6 +30,7 @@ ubootenv_mtdinfo () {
|
|||||||
}
|
}
|
||||||
|
|
||||||
case "$board" in
|
case "$board" in
|
||||||
|
arris,tr4400-v2|\
|
||||||
askey,rt4230w-rev6)
|
askey,rt4230w-rev6)
|
||||||
ubootenv_add_uci_config "/dev/mtd9" "0x0" "0x40000" "0x20000"
|
ubootenv_add_uci_config "/dev/mtd9" "0x0" "0x40000" "0x20000"
|
||||||
;;
|
;;
|
||||||
|
@ -15,6 +15,7 @@ zyxel,gs1900-8|\
|
|||||||
zyxel,gs1900-8hp-v1|\
|
zyxel,gs1900-8hp-v1|\
|
||||||
zyxel,gs1900-8hp-v2|\
|
zyxel,gs1900-8hp-v2|\
|
||||||
zyxel,gs1900-10hp|\
|
zyxel,gs1900-10hp|\
|
||||||
|
zyxel,gs1900-16|\
|
||||||
zyxel,gs1900-24-v1|\
|
zyxel,gs1900-24-v1|\
|
||||||
zyxel,gs1900-24hp-v1|\
|
zyxel,gs1900-24hp-v1|\
|
||||||
zyxel,gs1900-24hp-v2)
|
zyxel,gs1900-24hp-v2)
|
||||||
|
@ -1274,71 +1274,24 @@ endef
|
|||||||
$(eval $(call KernelPackage,tpm-i2c-infineon))
|
$(eval $(call KernelPackage,tpm-i2c-infineon))
|
||||||
|
|
||||||
|
|
||||||
define KernelPackage/w83627hf-wdt
|
define KernelPackage/i6300esb-wdt
|
||||||
SUBMENU:=$(OTHER_MENU)
|
SUBMENU:=$(OTHER_MENU)
|
||||||
TITLE:=Winbond 83627HF Watchdog Timer
|
TITLE:=Intel 6300ESB Timer/Watchdog
|
||||||
KCONFIG:=CONFIG_W83627HF_WDT
|
DEPENDS:=@PCI_SUPPORT @!SMALL_FLASH
|
||||||
FILES:=$(LINUX_DIR)/drivers/$(WATCHDOG_DIR)/w83627hf_wdt.ko
|
KCONFIG:=CONFIG_I6300ESB_WDT \
|
||||||
AUTOLOAD:=$(call AutoLoad,50,w83627hf-wdt,1)
|
CONFIG_WATCHDOG_CORE=y
|
||||||
|
FILES:=$(LINUX_DIR)/drivers/$(WATCHDOG_DIR)/i6300esb.ko
|
||||||
|
AUTOLOAD:=$(call AutoLoad,50,i6300esb,1)
|
||||||
endef
|
endef
|
||||||
|
|
||||||
define KernelPackage/w83627hf-wdt/description
|
define KernelPackage/i6300esb-wdt/description
|
||||||
Kernel module for Winbond 83627HF Watchdog Timer
|
Kernel module for the watchdog timer built into the Intel
|
||||||
|
6300ESB controller hub. Also used by QEMU/libvirt.
|
||||||
endef
|
endef
|
||||||
|
|
||||||
$(eval $(call KernelPackage,w83627hf-wdt))
|
$(eval $(call KernelPackage,i6300esb-wdt))
|
||||||
|
|
||||||
|
|
||||||
define KernelPackage/itco-wdt
|
|
||||||
SUBMENU:=$(OTHER_MENU)
|
|
||||||
TITLE:=Intel iTCO Watchdog Timer
|
|
||||||
KCONFIG:=CONFIG_ITCO_WDT \
|
|
||||||
CONFIG_ITCO_VENDOR_SUPPORT=y
|
|
||||||
FILES:=$(LINUX_DIR)/drivers/$(WATCHDOG_DIR)/iTCO_wdt.ko \
|
|
||||||
$(LINUX_DIR)/drivers/$(WATCHDOG_DIR)/iTCO_vendor_support.ko
|
|
||||||
AUTOLOAD:=$(call AutoLoad,50,iTCO_vendor_support iTCO_wdt,1)
|
|
||||||
endef
|
|
||||||
|
|
||||||
define KernelPackage/itco-wdt/description
|
|
||||||
Kernel module for Intel iTCO Watchdog Timer
|
|
||||||
endef
|
|
||||||
|
|
||||||
$(eval $(call KernelPackage,itco-wdt))
|
|
||||||
|
|
||||||
|
|
||||||
define KernelPackage/it87-wdt
|
|
||||||
SUBMENU:=$(OTHER_MENU)
|
|
||||||
TITLE:=ITE IT87 Watchdog Timer
|
|
||||||
KCONFIG:=CONFIG_IT87_WDT
|
|
||||||
FILES:=$(LINUX_DIR)/drivers/$(WATCHDOG_DIR)/it87_wdt.ko
|
|
||||||
AUTOLOAD:=$(call AutoLoad,50,it87-wdt,1)
|
|
||||||
MODPARAMS.it87-wdt:= \
|
|
||||||
nogameport=1 \
|
|
||||||
nocir=1
|
|
||||||
endef
|
|
||||||
|
|
||||||
define KernelPackage/it87-wdt/description
|
|
||||||
Kernel module for ITE IT87 Watchdog Timer
|
|
||||||
endef
|
|
||||||
|
|
||||||
$(eval $(call KernelPackage,it87-wdt))
|
|
||||||
|
|
||||||
|
|
||||||
define KernelPackage/f71808e-wdt
|
|
||||||
SUBMENU:=$(OTHER_MENU)
|
|
||||||
TITLE:=Fintek F718xx/F818xx Watchdog Timer
|
|
||||||
DEPENDS:=@TARGET_x86
|
|
||||||
KCONFIG:=CONFIG_F71808E_WDT
|
|
||||||
FILES:=$(LINUX_DIR)/drivers/$(WATCHDOG_DIR)/f71808e_wdt.ko
|
|
||||||
AUTOLOAD:=$(call AutoProbe,f71808e-wdt,1)
|
|
||||||
endef
|
|
||||||
|
|
||||||
define KernelPackage/f71808e-wdt/description
|
|
||||||
Kernel module for the watchdog timer found on many Fintek Super-IO chips.
|
|
||||||
endef
|
|
||||||
|
|
||||||
$(eval $(call KernelPackage,f71808e-wdt))
|
|
||||||
|
|
||||||
define KernelPackage/mhi-bus
|
define KernelPackage/mhi-bus
|
||||||
SUBMENU:=$(OTHER_MENU)
|
SUBMENU:=$(OTHER_MENU)
|
||||||
TITLE:=MHI bus
|
TITLE:=MHI bus
|
||||||
|
@ -1804,7 +1804,6 @@ $(eval $(call KernelPackage,usb-xhci-mtk))
|
|||||||
|
|
||||||
define KernelPackage/usb-xhci-pci-renesas
|
define KernelPackage/usb-xhci-pci-renesas
|
||||||
TITLE:=Support for additional Renesas xHCI controller with firmware
|
TITLE:=Support for additional Renesas xHCI controller with firmware
|
||||||
DEPENDS:=@LINUX_5_10
|
|
||||||
KCONFIG:=CONFIG_USB_XHCI_PCI_RENESAS
|
KCONFIG:=CONFIG_USB_XHCI_PCI_RENESAS
|
||||||
HIDDEN:=1
|
HIDDEN:=1
|
||||||
FILES:=$(LINUX_DIR)/drivers/usb/host/xhci-pci-renesas.ko
|
FILES:=$(LINUX_DIR)/drivers/usb/host/xhci-pci-renesas.ko
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
include $(TOPDIR)/rules.mk
|
include $(TOPDIR)/rules.mk
|
||||||
|
|
||||||
PKG_NAME:=firewall
|
PKG_NAME:=firewall
|
||||||
PKG_RELEASE:=2
|
PKG_RELEASE:=3
|
||||||
|
|
||||||
PKG_SOURCE_PROTO:=git
|
PKG_SOURCE_PROTO:=git
|
||||||
PKG_SOURCE_URL=$(PROJECT_GIT)/project/firewall3.git
|
PKG_SOURCE_URL=$(PROJECT_GIT)/project/firewall3.git
|
||||||
|
@ -55,13 +55,11 @@ config rule
|
|||||||
option target ACCEPT
|
option target ACCEPT
|
||||||
|
|
||||||
# Allow DHCPv6 replies
|
# Allow DHCPv6 replies
|
||||||
# see https://dev.openwrt.org/ticket/10381
|
# see https://github.com/openwrt/openwrt/issues/5066
|
||||||
config rule
|
config rule
|
||||||
option name Allow-DHCPv6
|
option name Allow-DHCPv6
|
||||||
option src wan
|
option src wan
|
||||||
option proto udp
|
option proto udp
|
||||||
option src_ip fc00::/6
|
|
||||||
option dest_ip fc00::/6
|
|
||||||
option dest_port 546
|
option dest_port 546
|
||||||
option family ipv6
|
option family ipv6
|
||||||
option target ACCEPT
|
option target ACCEPT
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
include $(TOPDIR)/rules.mk
|
include $(TOPDIR)/rules.mk
|
||||||
|
|
||||||
PKG_NAME:=nvram
|
PKG_NAME:=nvram
|
||||||
PKG_RELEASE:=10
|
PKG_RELEASE:=11
|
||||||
|
|
||||||
PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME)
|
PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME)
|
||||||
|
|
||||||
@ -44,7 +44,11 @@ define Package/nvram/install
|
|||||||
$(INSTALL_BIN) $(PKG_BUILD_DIR)/nvram $(1)/usr/sbin/
|
$(INSTALL_BIN) $(PKG_BUILD_DIR)/nvram $(1)/usr/sbin/
|
||||||
ifneq ($(CONFIG_TARGET_bcm47xx),)
|
ifneq ($(CONFIG_TARGET_bcm47xx),)
|
||||||
$(INSTALL_DIR) $(1)/etc/init.d
|
$(INSTALL_DIR) $(1)/etc/init.d
|
||||||
$(INSTALL_BIN) ./files/nvram.init $(1)/etc/init.d/nvram
|
$(INSTALL_BIN) ./files/nvram-bcm47xx.init $(1)/etc/init.d/nvram
|
||||||
|
endif
|
||||||
|
ifneq ($(CONFIG_TARGET_bcm53xx),)
|
||||||
|
$(INSTALL_DIR) $(1)/etc/init.d
|
||||||
|
$(INSTALL_BIN) ./files/nvram-bcm53xx.init $(1)/etc/init.d/nvram
|
||||||
endif
|
endif
|
||||||
endef
|
endef
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#!/bin/sh /etc/rc.common
|
#!/bin/sh /etc/rc.common
|
||||||
# NVRAM setup
|
# NVRAM setup
|
||||||
#
|
#
|
||||||
# This file handles the NVRAM quirks of various hardware.
|
# This file handles the NVRAM quirks of various hardware of the bcm47xx target.
|
||||||
|
|
||||||
START=02
|
START=02
|
||||||
alias debug=${DEBUG:-:}
|
alias debug=${DEBUG:-:}
|
||||||
@ -71,7 +71,7 @@ fixup_linksys() {
|
|||||||
esac
|
esac
|
||||||
}
|
}
|
||||||
|
|
||||||
start() {
|
boot() {
|
||||||
# Don't do any fixups on the WGT634U
|
# Don't do any fixups on the WGT634U
|
||||||
[ "$(cat /proc/diag/model)" = "Netgear WGT634U" ] && return
|
[ "$(cat /proc/diag/model)" = "Netgear WGT634U" ] && return
|
||||||
|
|
40
package/utils/nvram/files/nvram-bcm53xx.init
Executable file
40
package/utils/nvram/files/nvram-bcm53xx.init
Executable file
@ -0,0 +1,40 @@
|
|||||||
|
#!/bin/sh /etc/rc.common
|
||||||
|
# NVRAM setup
|
||||||
|
#
|
||||||
|
# This file handles the NVRAM quirks of various hardware of the bcm53xx target.
|
||||||
|
|
||||||
|
START=02
|
||||||
|
|
||||||
|
clear_partialboots() {
|
||||||
|
# clear partialboots
|
||||||
|
|
||||||
|
case $(board_name) in
|
||||||
|
linksys,panamera)
|
||||||
|
COMMIT=1
|
||||||
|
nvram set partialboots=0
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
set_wireless_led_behaviour() {
|
||||||
|
# set Broadcom wireless LED behaviour for both radios
|
||||||
|
# 0:ledbh9 -> Behaviour of 2.4GHz LED
|
||||||
|
# 1:ledbh9 -> Behaviour of 5GHz LED
|
||||||
|
# 0x7 makes the wireless LEDs on, when radios are enabled, and blink when there's activity
|
||||||
|
|
||||||
|
case $(board_name) in
|
||||||
|
asus,rt-ac88u)
|
||||||
|
COMMIT=1
|
||||||
|
nvram set 0:ledbh9=0x7 set 1:ledbh9=0x7
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
boot() {
|
||||||
|
. /lib/functions.sh
|
||||||
|
|
||||||
|
clear_partialboots
|
||||||
|
set_wireless_led_behaviour
|
||||||
|
|
||||||
|
[ "$COMMIT" = "1" ] && nvram commit
|
||||||
|
}
|
@ -10,6 +10,7 @@ FEATURES:=fpu dt gpio ramdisk squashfs usb
|
|||||||
SUBTARGETS:=nand sata
|
SUBTARGETS:=nand sata
|
||||||
|
|
||||||
KERNEL_PATCHVER:=5.10
|
KERNEL_PATCHVER:=5.10
|
||||||
|
KERNEL_TESTING_PATCHVER:=5.15
|
||||||
|
|
||||||
define Target/Description
|
define Target/Description
|
||||||
Build images for AppliedMicro APM821xx based boards.
|
Build images for AppliedMicro APM821xx based boards.
|
||||||
|
245
target/linux/apm821xx/config-5.15
Normal file
245
target/linux/apm821xx/config-5.15
Normal file
@ -0,0 +1,245 @@
|
|||||||
|
# CONFIG_40x is not set
|
||||||
|
CONFIG_44x=y
|
||||||
|
CONFIG_4xx=y
|
||||||
|
CONFIG_4xx_SOC=y
|
||||||
|
# CONFIG_ADVANCED_OPTIONS is not set
|
||||||
|
CONFIG_APM821xx=y
|
||||||
|
# CONFIG_APOLLO3G is not set
|
||||||
|
# CONFIG_ARCHES is not set
|
||||||
|
CONFIG_ARCH_32BIT_OFF_T=y
|
||||||
|
CONFIG_ARCH_DMA_ADDR_T_64BIT=y
|
||||||
|
CONFIG_ARCH_HIBERNATION_POSSIBLE=y
|
||||||
|
CONFIG_ARCH_KEEP_MEMBLOCK=y
|
||||||
|
CONFIG_ARCH_MAY_HAVE_PC_FDC=y
|
||||||
|
CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y
|
||||||
|
CONFIG_ARCH_MIGHT_HAVE_PC_SERIO=y
|
||||||
|
CONFIG_ARCH_MMAP_RND_BITS=11
|
||||||
|
CONFIG_ARCH_MMAP_RND_BITS_MAX=17
|
||||||
|
CONFIG_ARCH_MMAP_RND_BITS_MIN=11
|
||||||
|
CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MAX=17
|
||||||
|
CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MIN=11
|
||||||
|
CONFIG_ARCH_STACKWALK=y
|
||||||
|
CONFIG_ARCH_SUSPEND_POSSIBLE=y
|
||||||
|
CONFIG_ARCH_WEAK_RELEASE_ACQUIRE=y
|
||||||
|
CONFIG_AUDIT_ARCH=y
|
||||||
|
# CONFIG_BAMBOO is not set
|
||||||
|
# CONFIG_BLK_DEV_INITRD is not set
|
||||||
|
CONFIG_BLK_MQ_PCI=y
|
||||||
|
CONFIG_BLUESTONE=y
|
||||||
|
CONFIG_BOOKE=y
|
||||||
|
CONFIG_BOOKE_WDT=y
|
||||||
|
# CONFIG_CANYONLANDS is not set
|
||||||
|
CONFIG_CLONE_BACKWARDS=y
|
||||||
|
CONFIG_CMDLINE="rootfstype=squashfs noinitrd"
|
||||||
|
CONFIG_CMDLINE_FROM_BOOTLOADER=y
|
||||||
|
CONFIG_COMMON_CLK=y
|
||||||
|
CONFIG_COMPAT_32BIT_TIME=y
|
||||||
|
CONFIG_CPU_BIG_ENDIAN=y
|
||||||
|
CONFIG_CRC16=y
|
||||||
|
# CONFIG_CRC32_SARWATE is not set
|
||||||
|
CONFIG_CRC32_SLICEBY8=y
|
||||||
|
CONFIG_CRYPTO_DEFLATE=y
|
||||||
|
CONFIG_CRYPTO_DEV_PPC4XX=y
|
||||||
|
CONFIG_CRYPTO_HW=y
|
||||||
|
CONFIG_CRYPTO_JITTERENTROPY=y
|
||||||
|
CONFIG_CRYPTO_LIB_POLY1305_RSIZE=1
|
||||||
|
CONFIG_CRYPTO_LZO=y
|
||||||
|
# CONFIG_CRYPTO_MD5_PPC is not set
|
||||||
|
CONFIG_CRYPTO_RNG=y
|
||||||
|
CONFIG_CRYPTO_RNG2=y
|
||||||
|
# CONFIG_CRYPTO_SHA1_PPC is not set
|
||||||
|
CONFIG_DATA_SHIFT=12
|
||||||
|
CONFIG_DMADEVICES=y
|
||||||
|
CONFIG_DMA_DIRECT_REMAP=y
|
||||||
|
CONFIG_DMA_ENGINE=y
|
||||||
|
CONFIG_DMA_OF=y
|
||||||
|
CONFIG_DMA_REMAP=y
|
||||||
|
CONFIG_DTC=y
|
||||||
|
CONFIG_DW_DMAC=y
|
||||||
|
CONFIG_DW_DMAC_CORE=y
|
||||||
|
CONFIG_EARLY_PRINTK=y
|
||||||
|
# CONFIG_EBONY is not set
|
||||||
|
CONFIG_EDAC_ATOMIC_SCRUB=y
|
||||||
|
CONFIG_EDAC_SUPPORT=y
|
||||||
|
# CONFIG_EIGER is not set
|
||||||
|
CONFIG_EXTRA_TARGETS="uImage"
|
||||||
|
CONFIG_FIXED_PHY=y
|
||||||
|
CONFIG_FORCE_PCI=y
|
||||||
|
# CONFIG_FSL_LBC is not set
|
||||||
|
CONFIG_FWNODE_MDIO=y
|
||||||
|
CONFIG_FW_LOADER_PAGED_BUF=y
|
||||||
|
CONFIG_GENERIC_ALLOCATOR=y
|
||||||
|
CONFIG_GENERIC_ATOMIC64=y
|
||||||
|
CONFIG_GENERIC_BUG=y
|
||||||
|
CONFIG_GENERIC_BUG_RELATIVE_POINTERS=y
|
||||||
|
CONFIG_GENERIC_CLOCKEVENTS=y
|
||||||
|
CONFIG_GENERIC_CMOS_UPDATE=y
|
||||||
|
CONFIG_GENERIC_CPU=y
|
||||||
|
CONFIG_GENERIC_CPU_AUTOPROBE=y
|
||||||
|
CONFIG_GENERIC_EARLY_IOREMAP=y
|
||||||
|
CONFIG_GENERIC_GETTIMEOFDAY=y
|
||||||
|
CONFIG_GENERIC_IRQ_SHOW=y
|
||||||
|
CONFIG_GENERIC_IRQ_SHOW_LEVEL=y
|
||||||
|
CONFIG_GENERIC_ISA_DMA=y
|
||||||
|
CONFIG_GENERIC_MSI_IRQ=y
|
||||||
|
CONFIG_GENERIC_MSI_IRQ_DOMAIN=y
|
||||||
|
CONFIG_GENERIC_PCI_IOMAP=y
|
||||||
|
CONFIG_GENERIC_SMP_IDLE_THREAD=y
|
||||||
|
CONFIG_GENERIC_STRNCPY_FROM_USER=y
|
||||||
|
CONFIG_GENERIC_STRNLEN_USER=y
|
||||||
|
CONFIG_GENERIC_TIME_VSYSCALL=y
|
||||||
|
# CONFIG_GEN_RTC is not set
|
||||||
|
# CONFIG_GLACIER is not set
|
||||||
|
CONFIG_GPIOLIB=y
|
||||||
|
CONFIG_GPIO_CDEV=y
|
||||||
|
CONFIG_GPIO_GENERIC=y
|
||||||
|
CONFIG_GPIO_GENERIC_PLATFORM=y
|
||||||
|
CONFIG_HAS_DMA=y
|
||||||
|
CONFIG_HAS_IOMEM=y
|
||||||
|
CONFIG_HAS_IOPORT_MAP=y
|
||||||
|
CONFIG_HW_RANDOM=y
|
||||||
|
CONFIG_HW_RANDOM_PPC4XX=y
|
||||||
|
CONFIG_I2C=y
|
||||||
|
CONFIG_I2C_BOARDINFO=y
|
||||||
|
CONFIG_I2C_CHARDEV=y
|
||||||
|
CONFIG_I2C_IBM_IIC=y
|
||||||
|
CONFIG_IBM_EMAC=y
|
||||||
|
CONFIG_IBM_EMAC_EMAC4=y
|
||||||
|
CONFIG_IBM_EMAC_POLL_WEIGHT=32
|
||||||
|
CONFIG_IBM_EMAC_RGMII=y
|
||||||
|
CONFIG_IBM_EMAC_RXB=128
|
||||||
|
CONFIG_IBM_EMAC_RX_COPY_THRESHOLD=256
|
||||||
|
CONFIG_IBM_EMAC_TAH=y
|
||||||
|
CONFIG_IBM_EMAC_TXB=128
|
||||||
|
# CONFIG_ICON is not set
|
||||||
|
CONFIG_ILLEGAL_POINTER_VALUE=0
|
||||||
|
CONFIG_IRQCHIP=y
|
||||||
|
CONFIG_IRQ_DOMAIN=y
|
||||||
|
CONFIG_IRQ_DOMAIN_HIERARCHY=y
|
||||||
|
CONFIG_IRQ_FORCED_THREADING=y
|
||||||
|
CONFIG_IRQ_WORK=y
|
||||||
|
CONFIG_ISA_DMA_API=y
|
||||||
|
# CONFIG_JFFS2_FS is not set
|
||||||
|
# CONFIG_KATMAI is not set
|
||||||
|
CONFIG_KERNEL_START=0xc0000000
|
||||||
|
CONFIG_LEDS_TRIGGER_MTD=y
|
||||||
|
CONFIG_LEDS_TRIGGER_PATTERN=y
|
||||||
|
CONFIG_LIBFDT=y
|
||||||
|
CONFIG_LOCK_DEBUGGING_SUPPORT=y
|
||||||
|
CONFIG_LOWMEM_SIZE=0x30000000
|
||||||
|
CONFIG_LZO_COMPRESS=y
|
||||||
|
CONFIG_LZO_DECOMPRESS=y
|
||||||
|
# CONFIG_MATH_EMULATION is not set
|
||||||
|
CONFIG_MDIO_BUS=y
|
||||||
|
CONFIG_MDIO_DEVICE=y
|
||||||
|
CONFIG_MDIO_DEVRES=y
|
||||||
|
CONFIG_MEMFD_CREATE=y
|
||||||
|
CONFIG_MIGRATION=y
|
||||||
|
CONFIG_MMU_GATHER_PAGE_SIZE=y
|
||||||
|
CONFIG_MODULES_USE_ELF_RELA=y
|
||||||
|
CONFIG_MODULE_ALLOW_MISSING_NAMESPACE_IMPORTS=y
|
||||||
|
CONFIG_MTD_CFI_ADV_OPTIONS=y
|
||||||
|
# CONFIG_MTD_CFI_GEOMETRY is not set
|
||||||
|
# CONFIG_MTD_SPLIT_SQUASHFS_ROOT is not set
|
||||||
|
CONFIG_NEED_DMA_MAP_STATE=y
|
||||||
|
CONFIG_NEED_PER_CPU_KM=y
|
||||||
|
CONFIG_NEED_SG_DMA_LENGTH=y
|
||||||
|
CONFIG_NET_SELFTESTS=y
|
||||||
|
CONFIG_NOT_COHERENT_CACHE=y
|
||||||
|
CONFIG_NO_HZ=y
|
||||||
|
CONFIG_NO_HZ_COMMON=y
|
||||||
|
CONFIG_NO_HZ_IDLE=y
|
||||||
|
CONFIG_NR_CPUS=1
|
||||||
|
CONFIG_NR_IRQS=512
|
||||||
|
CONFIG_NVMEM=y
|
||||||
|
CONFIG_NVMEM_SYSFS=y
|
||||||
|
CONFIG_OF=y
|
||||||
|
CONFIG_OF_ADDRESS=y
|
||||||
|
CONFIG_OF_EARLY_FLATTREE=y
|
||||||
|
CONFIG_OF_FLATTREE=y
|
||||||
|
CONFIG_OF_GPIO=y
|
||||||
|
CONFIG_OF_IRQ=y
|
||||||
|
CONFIG_OF_KOBJ=y
|
||||||
|
CONFIG_OF_MDIO=y
|
||||||
|
CONFIG_OLD_SIGACTION=y
|
||||||
|
CONFIG_OLD_SIGSUSPEND=y
|
||||||
|
CONFIG_PACKING=y
|
||||||
|
CONFIG_PAGE_OFFSET=0xc0000000
|
||||||
|
CONFIG_PCI=y
|
||||||
|
CONFIG_PCIEAER=y
|
||||||
|
CONFIG_PCIEPORTBUS=y
|
||||||
|
CONFIG_PCI_DISABLE_COMMON_QUIRKS=y
|
||||||
|
CONFIG_PCI_DOMAINS=y
|
||||||
|
CONFIG_PCI_MSI=y
|
||||||
|
CONFIG_PCI_MSI_ARCH_FALLBACKS=y
|
||||||
|
CONFIG_PCI_MSI_IRQ_DOMAIN=y
|
||||||
|
CONFIG_PGTABLE_LEVELS=2
|
||||||
|
CONFIG_PHYLIB=y
|
||||||
|
CONFIG_PHYSICAL_START=0x00000000
|
||||||
|
CONFIG_PHYS_64BIT=y
|
||||||
|
CONFIG_PHYS_ADDR_T_64BIT=y
|
||||||
|
# CONFIG_PMU_SYSFS is not set
|
||||||
|
CONFIG_PPC=y
|
||||||
|
CONFIG_PPC32=y
|
||||||
|
CONFIG_PPC44x_SIMPLE=y
|
||||||
|
CONFIG_PPC4xx_GPIO=y
|
||||||
|
CONFIG_PPC4xx_MSI=y
|
||||||
|
CONFIG_PPC4xx_PCI_EXPRESS=y
|
||||||
|
# CONFIG_PPC64 is not set
|
||||||
|
# CONFIG_PPC_47x is not set
|
||||||
|
# CONFIG_PPC_85xx is not set
|
||||||
|
# CONFIG_PPC_8xx is not set
|
||||||
|
CONFIG_PPC_ADV_DEBUG_DACS=2
|
||||||
|
CONFIG_PPC_ADV_DEBUG_DAC_RANGE=y
|
||||||
|
CONFIG_PPC_ADV_DEBUG_DVCS=2
|
||||||
|
CONFIG_PPC_ADV_DEBUG_IACS=4
|
||||||
|
CONFIG_PPC_ADV_DEBUG_REGS=y
|
||||||
|
# CONFIG_PPC_BOOK3S_32 is not set
|
||||||
|
CONFIG_PPC_DCR=y
|
||||||
|
CONFIG_PPC_DCR_NATIVE=y
|
||||||
|
# CONFIG_PPC_EARLY_DEBUG is not set
|
||||||
|
CONFIG_PPC_FPU=y
|
||||||
|
CONFIG_PPC_FPU_REGS=y
|
||||||
|
CONFIG_PPC_HAVE_KUEP=y
|
||||||
|
CONFIG_PPC_INDIRECT_PCI=y
|
||||||
|
CONFIG_PPC_KUEP=y
|
||||||
|
CONFIG_PPC_MMU_NOHASH=y
|
||||||
|
CONFIG_PPC_MSI_BITMAP=y
|
||||||
|
CONFIG_PPC_PAGE_SHIFT=12
|
||||||
|
CONFIG_PPC_UDBG_16550=y
|
||||||
|
CONFIG_PPC_WERROR=y
|
||||||
|
CONFIG_PTE_64BIT=y
|
||||||
|
CONFIG_PTP_1588_CLOCK_OPTIONAL=y
|
||||||
|
# CONFIG_RAINIER is not set
|
||||||
|
CONFIG_RAS=y
|
||||||
|
CONFIG_RATIONAL=y
|
||||||
|
CONFIG_REGULATOR=y
|
||||||
|
CONFIG_RSEQ=y
|
||||||
|
# CONFIG_SAM440EP is not set
|
||||||
|
# CONFIG_SCOM_DEBUGFS is not set
|
||||||
|
# CONFIG_SEQUOIA is not set
|
||||||
|
CONFIG_SERIAL_8250_FSL=y
|
||||||
|
CONFIG_SERIAL_MCTRL_GPIO=y
|
||||||
|
CONFIG_SERIAL_OF_PLATFORM=y
|
||||||
|
CONFIG_SGL_ALLOC=y
|
||||||
|
CONFIG_SPARSE_IRQ=y
|
||||||
|
CONFIG_SRCU=y
|
||||||
|
CONFIG_SWPHY=y
|
||||||
|
CONFIG_SYSCTL_EXCEPTION_TRACE=y
|
||||||
|
# CONFIG_TAISHAN is not set
|
||||||
|
CONFIG_TASK_SIZE=0xc0000000
|
||||||
|
CONFIG_THREAD_INFO_IN_TASK=y
|
||||||
|
CONFIG_THREAD_SHIFT=13
|
||||||
|
CONFIG_TICK_CPU_ACCOUNTING=y
|
||||||
|
CONFIG_TINY_SRCU=y
|
||||||
|
CONFIG_USB_SUPPORT=y
|
||||||
|
CONFIG_VDSO32=y
|
||||||
|
# CONFIG_VIRTIO_MENU is not set
|
||||||
|
# CONFIG_VIRT_CPU_ACCOUNTING_NATIVE is not set
|
||||||
|
# CONFIG_WARP is not set
|
||||||
|
CONFIG_WATCHDOG_CORE=y
|
||||||
|
CONFIG_XZ_DEC_BCJ=y
|
||||||
|
CONFIG_XZ_DEC_POWERPC=y
|
||||||
|
# CONFIG_YOSEMITE is not set
|
||||||
|
CONFIG_ZLIB_DEFLATE=y
|
||||||
|
CONFIG_ZLIB_INFLATE=y
|
@ -0,0 +1,166 @@
|
|||||||
|
From 4d49367c5303e3ebd17502a45b74de280f6be539 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Christian Lamparter <chunkeey@gmail.com>
|
||||||
|
Date: Sun, 13 Feb 2022 01:47:33 +0100
|
||||||
|
Subject: hwmon: (tc654) Add thermal_cooling device support
|
||||||
|
|
||||||
|
Adds thermal_cooling device support to the tc654/tc655
|
||||||
|
driver. This make it possible to integrate it into a
|
||||||
|
device-tree supported thermal-zone node as a
|
||||||
|
cooling device.
|
||||||
|
|
||||||
|
I have been using this patch as part of the Netgear WNDR4700
|
||||||
|
Centria NAS Router support within OpenWrt since 2016.
|
||||||
|
|
||||||
|
Signed-off-by: Christian Lamparter <chunkeey@gmail.com>
|
||||||
|
Link: https://lore.kernel.org/r/20220213004733.2421193-1-chunkeey@gmail.com
|
||||||
|
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
|
||||||
|
---
|
||||||
|
--- a/drivers/hwmon/tc654.c
|
||||||
|
+++ b/drivers/hwmon/tc654.c
|
||||||
|
@@ -15,6 +15,7 @@
|
||||||
|
#include <linux/module.h>
|
||||||
|
#include <linux/mutex.h>
|
||||||
|
#include <linux/slab.h>
|
||||||
|
+#include <linux/thermal.h>
|
||||||
|
#include <linux/util_macros.h>
|
||||||
|
|
||||||
|
enum tc654_regs {
|
||||||
|
@@ -379,28 +380,20 @@ static ssize_t pwm_show(struct device *d
|
||||||
|
return sprintf(buf, "%d\n", pwm);
|
||||||
|
}
|
||||||
|
|
||||||
|
-static ssize_t pwm_store(struct device *dev, struct device_attribute *da,
|
||||||
|
- const char *buf, size_t count)
|
||||||
|
+static int _set_pwm(struct tc654_data *data, unsigned long val)
|
||||||
|
{
|
||||||
|
- struct tc654_data *data = dev_get_drvdata(dev);
|
||||||
|
struct i2c_client *client = data->client;
|
||||||
|
- unsigned long val;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
- if (kstrtoul(buf, 10, &val))
|
||||||
|
- return -EINVAL;
|
||||||
|
- if (val > 255)
|
||||||
|
- return -EINVAL;
|
||||||
|
-
|
||||||
|
mutex_lock(&data->update_lock);
|
||||||
|
|
||||||
|
- if (val == 0)
|
||||||
|
+ if (val == 0) {
|
||||||
|
data->config |= TC654_REG_CONFIG_SDM;
|
||||||
|
- else
|
||||||
|
+ data->duty_cycle = 0;
|
||||||
|
+ } else {
|
||||||
|
data->config &= ~TC654_REG_CONFIG_SDM;
|
||||||
|
-
|
||||||
|
- data->duty_cycle = find_closest(val, tc654_pwm_map,
|
||||||
|
- ARRAY_SIZE(tc654_pwm_map));
|
||||||
|
+ data->duty_cycle = val - 1;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
ret = i2c_smbus_write_byte_data(client, TC654_REG_CONFIG, data->config);
|
||||||
|
if (ret < 0)
|
||||||
|
@@ -411,6 +404,24 @@ static ssize_t pwm_store(struct device *
|
||||||
|
|
||||||
|
out:
|
||||||
|
mutex_unlock(&data->update_lock);
|
||||||
|
+ return ret;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static ssize_t pwm_store(struct device *dev, struct device_attribute *da,
|
||||||
|
+ const char *buf, size_t count)
|
||||||
|
+{
|
||||||
|
+ struct tc654_data *data = dev_get_drvdata(dev);
|
||||||
|
+ unsigned long val;
|
||||||
|
+ int ret;
|
||||||
|
+
|
||||||
|
+ if (kstrtoul(buf, 10, &val))
|
||||||
|
+ return -EINVAL;
|
||||||
|
+ if (val > 255)
|
||||||
|
+ return -EINVAL;
|
||||||
|
+ if (val > 0)
|
||||||
|
+ val = find_closest(val, tc654_pwm_map, ARRAY_SIZE(tc654_pwm_map)) + 1;
|
||||||
|
+
|
||||||
|
+ ret = _set_pwm(data, val);
|
||||||
|
return ret < 0 ? ret : count;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -443,6 +454,58 @@ static struct attribute *tc654_attrs[] =
|
||||||
|
ATTRIBUTE_GROUPS(tc654);
|
||||||
|
|
||||||
|
/*
|
||||||
|
+ * thermal cooling device functions
|
||||||
|
+ *
|
||||||
|
+ * Account for the "ShutDown Mode (SDM)" state by offsetting
|
||||||
|
+ * the 16 PWM duty cycle states by 1.
|
||||||
|
+ *
|
||||||
|
+ * State 0 = 0% PWM | Shutdown - Fan(s) are off
|
||||||
|
+ * State 1 = 30% PWM | duty_cycle = 0
|
||||||
|
+ * State 2 = ~35% PWM | duty_cycle = 1
|
||||||
|
+ * [...]
|
||||||
|
+ * State 15 = ~95% PWM | duty_cycle = 14
|
||||||
|
+ * State 16 = 100% PWM | duty_cycle = 15
|
||||||
|
+ */
|
||||||
|
+#define TC654_MAX_COOLING_STATE 16
|
||||||
|
+
|
||||||
|
+static int tc654_get_max_state(struct thermal_cooling_device *cdev, unsigned long *state)
|
||||||
|
+{
|
||||||
|
+ *state = TC654_MAX_COOLING_STATE;
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int tc654_get_cur_state(struct thermal_cooling_device *cdev, unsigned long *state)
|
||||||
|
+{
|
||||||
|
+ struct tc654_data *data = tc654_update_client(cdev->devdata);
|
||||||
|
+
|
||||||
|
+ if (IS_ERR(data))
|
||||||
|
+ return PTR_ERR(data);
|
||||||
|
+
|
||||||
|
+ if (data->config & TC654_REG_CONFIG_SDM)
|
||||||
|
+ *state = 0; /* FAN is off */
|
||||||
|
+ else
|
||||||
|
+ *state = data->duty_cycle + 1; /* offset PWM States by 1 */
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int tc654_set_cur_state(struct thermal_cooling_device *cdev, unsigned long state)
|
||||||
|
+{
|
||||||
|
+ struct tc654_data *data = tc654_update_client(cdev->devdata);
|
||||||
|
+
|
||||||
|
+ if (IS_ERR(data))
|
||||||
|
+ return PTR_ERR(data);
|
||||||
|
+
|
||||||
|
+ return _set_pwm(data, clamp_val(state, 0, TC654_MAX_COOLING_STATE));
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static const struct thermal_cooling_device_ops tc654_fan_cool_ops = {
|
||||||
|
+ .get_max_state = tc654_get_max_state,
|
||||||
|
+ .get_cur_state = tc654_get_cur_state,
|
||||||
|
+ .set_cur_state = tc654_set_cur_state,
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
* device probe and removal
|
||||||
|
*/
|
||||||
|
|
||||||
|
@@ -472,7 +535,18 @@ static int tc654_probe(struct i2c_client
|
||||||
|
hwmon_dev =
|
||||||
|
devm_hwmon_device_register_with_groups(dev, client->name, data,
|
||||||
|
tc654_groups);
|
||||||
|
- return PTR_ERR_OR_ZERO(hwmon_dev);
|
||||||
|
+ if (IS_ERR(hwmon_dev))
|
||||||
|
+ return PTR_ERR(hwmon_dev);
|
||||||
|
+
|
||||||
|
+ if (IS_ENABLED(CONFIG_THERMAL)) {
|
||||||
|
+ struct thermal_cooling_device *cdev;
|
||||||
|
+
|
||||||
|
+ cdev = devm_thermal_of_cooling_device_register(dev, dev->of_node, client->name,
|
||||||
|
+ hwmon_dev, &tc654_fan_cool_ops);
|
||||||
|
+ return PTR_ERR_OR_ZERO(cdev);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct i2c_device_id tc654_id[] = {
|
@ -0,0 +1,30 @@
|
|||||||
|
--- a/arch/powerpc/platforms/44x/Kconfig
|
||||||
|
+++ b/arch/powerpc/platforms/44x/Kconfig
|
||||||
|
@@ -121,6 +121,17 @@ config CANYONLANDS
|
||||||
|
help
|
||||||
|
This option enables support for the AMCC PPC460EX evaluation board.
|
||||||
|
|
||||||
|
+config APOLLO3G
|
||||||
|
+ bool "Apollo3G"
|
||||||
|
+ depends on 44x
|
||||||
|
+ default n
|
||||||
|
+ select PPC44x_SIMPLE
|
||||||
|
+ select APM821xx
|
||||||
|
+ select IBM_EMAC_RGMII
|
||||||
|
+ select 460EX
|
||||||
|
+ help
|
||||||
|
+ This option enables support for the AMCC Apollo 3G board.
|
||||||
|
+
|
||||||
|
config GLACIER
|
||||||
|
bool "Glacier"
|
||||||
|
depends on 44x
|
||||||
|
--- a/arch/powerpc/platforms/44x/ppc44x_simple.c
|
||||||
|
+++ b/arch/powerpc/platforms/44x/ppc44x_simple.c
|
||||||
|
@@ -47,6 +47,7 @@ machine_device_initcall(ppc44x_simple, p
|
||||||
|
* board.c file for it rather than adding it to this list.
|
||||||
|
*/
|
||||||
|
static char *board[] __initdata = {
|
||||||
|
+ "amcc,apollo3g",
|
||||||
|
"amcc,arches",
|
||||||
|
"amcc,bamboo",
|
||||||
|
"apm,bluestone",
|
@ -0,0 +1,51 @@
|
|||||||
|
--- a/arch/powerpc/platforms/4xx/pci.c
|
||||||
|
+++ b/arch/powerpc/platforms/4xx/pci.c
|
||||||
|
@@ -1060,15 +1060,24 @@ static int __init apm821xx_pciex_init_po
|
||||||
|
u32 val;
|
||||||
|
|
||||||
|
/*
|
||||||
|
- * Do a software reset on PCIe ports.
|
||||||
|
- * This code is to fix the issue that pci drivers doesn't re-assign
|
||||||
|
- * bus number for PCIE devices after Uboot
|
||||||
|
- * scanned and configured all the buses (eg. PCIE NIC IntelPro/1000
|
||||||
|
- * PT quad port, SAS LSI 1064E)
|
||||||
|
+ * Only reset the PHY when no link is currently established.
|
||||||
|
+ * This is for the Atheros PCIe board which has problems to establish
|
||||||
|
+ * the link (again) after this PHY reset. All other currently tested
|
||||||
|
+ * PCIe boards don't show this problem.
|
||||||
|
*/
|
||||||
|
-
|
||||||
|
- mtdcri(SDR0, PESDR0_460EX_PHY_CTL_RST, 0x0);
|
||||||
|
- mdelay(10);
|
||||||
|
+ val = mfdcri(SDR0, port->sdr_base + PESDRn_LOOP);
|
||||||
|
+ if (!(val & 0x00001000)) {
|
||||||
|
+ /*
|
||||||
|
+ * Do a software reset on PCIe ports.
|
||||||
|
+ * This code is to fix the issue that pci drivers doesn't re-assign
|
||||||
|
+ * bus number for PCIE devices after Uboot
|
||||||
|
+ * scanned and configured all the buses (eg. PCIE NIC IntelPro/1000
|
||||||
|
+ * PT quad port, SAS LSI 1064E)
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+ mtdcri(SDR0, PESDR0_460EX_PHY_CTL_RST, 0x0);
|
||||||
|
+ mdelay(10);
|
||||||
|
+ }
|
||||||
|
|
||||||
|
if (port->endpoint)
|
||||||
|
val = PTYPE_LEGACY_ENDPOINT << 20;
|
||||||
|
@@ -1085,9 +1094,12 @@ static int __init apm821xx_pciex_init_po
|
||||||
|
mtdcri(SDR0, PESDR0_460EX_L0DRV, 0x00000130);
|
||||||
|
mtdcri(SDR0, PESDR0_460EX_L0CLK, 0x00000006);
|
||||||
|
|
||||||
|
- mtdcri(SDR0, PESDR0_460EX_PHY_CTL_RST, 0x10000000);
|
||||||
|
- mdelay(50);
|
||||||
|
- mtdcri(SDR0, PESDR0_460EX_PHY_CTL_RST, 0x30000000);
|
||||||
|
+ val = mfdcri(SDR0, port->sdr_base + PESDRn_LOOP);
|
||||||
|
+ if (!(val & 0x00001000)) {
|
||||||
|
+ mtdcri(SDR0, PESDR0_460EX_PHY_CTL_RST, 0x10000000);
|
||||||
|
+ mdelay(50);
|
||||||
|
+ mtdcri(SDR0, PESDR0_460EX_PHY_CTL_RST, 0x30000000);
|
||||||
|
+ }
|
||||||
|
|
||||||
|
mtdcri(SDR0, port->sdr_base + PESDRn_RCSSET,
|
||||||
|
mfdcri(SDR0, port->sdr_base + PESDRn_RCSSET) |
|
@ -0,0 +1,14 @@
|
|||||||
|
--- a/arch/powerpc/platforms/4xx/pci.c
|
||||||
|
+++ b/arch/powerpc/platforms/4xx/pci.c
|
||||||
|
@@ -1902,9 +1902,9 @@ static void __init ppc4xx_configure_pcie
|
||||||
|
* if it works
|
||||||
|
*/
|
||||||
|
out_le32(mbase + PECFG_PIM0LAL, 0x00000000);
|
||||||
|
- out_le32(mbase + PECFG_PIM0LAH, 0x00000000);
|
||||||
|
+ out_le32(mbase + PECFG_PIM0LAH, 0x00000008);
|
||||||
|
out_le32(mbase + PECFG_PIM1LAL, 0x00000000);
|
||||||
|
- out_le32(mbase + PECFG_PIM1LAH, 0x00000000);
|
||||||
|
+ out_le32(mbase + PECFG_PIM1LAH, 0x0000000c);
|
||||||
|
out_le32(mbase + PECFG_PIM01SAH, 0xffff0000);
|
||||||
|
out_le32(mbase + PECFG_PIM01SAL, 0x00000000);
|
||||||
|
|
@ -0,0 +1,29 @@
|
|||||||
|
From c9395ad54e2cabb87d408becc37566f3d8248933 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Christian Lamparter <chunkeey@gmail.com>
|
||||||
|
Date: Sun, 1 Dec 2019 02:08:23 +0100
|
||||||
|
Subject: [PATCH] powerpc: bootwrapper: force gzip as mkimage's compression
|
||||||
|
method
|
||||||
|
|
||||||
|
Due to CONFIG_KERNEL_XZ symbol, the bootwrapper code tries to
|
||||||
|
instruct the mkimage to use the xz compression, which isn't
|
||||||
|
supported. This patch forces the gzip compression, which is
|
||||||
|
supported and doesn't matter because the generated uImage for
|
||||||
|
the apm821xx target gets ignored as the OpenWrt toolchain will
|
||||||
|
do separate U-Boot kernel images for each device individually.
|
||||||
|
|
||||||
|
Signed-off-by: Christian Lamparter <chunkeey@gmail.com>
|
||||||
|
---
|
||||||
|
arch/powerpc/boot/Makefile | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
--- a/arch/powerpc/boot/Makefile
|
||||||
|
+++ b/arch/powerpc/boot/Makefile
|
||||||
|
@@ -257,7 +257,7 @@ compressor-$(CONFIG_KERNEL_LZO) := lzo
|
||||||
|
|
||||||
|
# args (to if_changed): 1 = (this rule), 2 = platform, 3 = dts 4=dtb 5=initrd
|
||||||
|
quiet_cmd_wrap = WRAP $@
|
||||||
|
- cmd_wrap =$(CONFIG_SHELL) $(wrapper) -Z $(compressor-y) -c -o $@ -p $2 \
|
||||||
|
+ cmd_wrap =$(CONFIG_SHELL) $(wrapper) -Z gzip -c -o $@ -p $2 \
|
||||||
|
$(CROSSWRAP) $(if $3, -s $3)$(if $4, -d $4)$(if $5, -i $5) \
|
||||||
|
vmlinux
|
||||||
|
|
@ -36,6 +36,7 @@ CONFIG_ARM64_WORKAROUND_CLEAN_CACHE=y
|
|||||||
CONFIG_ARM64_WORKAROUND_REPEAT_TLBI=y
|
CONFIG_ARM64_WORKAROUND_REPEAT_TLBI=y
|
||||||
CONFIG_ARM64_WORKAROUND_SPECULATIVE_AT=y
|
CONFIG_ARM64_WORKAROUND_SPECULATIVE_AT=y
|
||||||
CONFIG_ARM_ARCH_TIMER_OOL_WORKAROUND=y
|
CONFIG_ARM_ARCH_TIMER_OOL_WORKAROUND=y
|
||||||
|
CONFIG_ARM_SBSA_WATCHDOG=y
|
||||||
CONFIG_ATOMIC64_SELFTEST=y
|
CONFIG_ATOMIC64_SELFTEST=y
|
||||||
CONFIG_AUDIT_ARCH_COMPAT_GENERIC=y
|
CONFIG_AUDIT_ARCH_COMPAT_GENERIC=y
|
||||||
CONFIG_BACKLIGHT_CLASS_DEVICE=y
|
CONFIG_BACKLIGHT_CLASS_DEVICE=y
|
||||||
@ -147,4 +148,5 @@ CONFIG_VEXPRESS_CONFIG=y
|
|||||||
CONFIG_VIDEOMODE_HELPERS=y
|
CONFIG_VIDEOMODE_HELPERS=y
|
||||||
CONFIG_VIRTIO_DMA_SHARED_BUFFER=y
|
CONFIG_VIRTIO_DMA_SHARED_BUFFER=y
|
||||||
CONFIG_VMAP_STACK=y
|
CONFIG_VMAP_STACK=y
|
||||||
|
CONFIG_WATCHDOG_CORE=y
|
||||||
CONFIG_ZONE_DMA32=y
|
CONFIG_ZONE_DMA32=y
|
||||||
|
@ -38,6 +38,7 @@ CONFIG_ARM64_WORKAROUND_CLEAN_CACHE=y
|
|||||||
CONFIG_ARM64_WORKAROUND_REPEAT_TLBI=y
|
CONFIG_ARM64_WORKAROUND_REPEAT_TLBI=y
|
||||||
CONFIG_ARM64_WORKAROUND_SPECULATIVE_AT=y
|
CONFIG_ARM64_WORKAROUND_SPECULATIVE_AT=y
|
||||||
CONFIG_ARM_ARCH_TIMER_OOL_WORKAROUND=y
|
CONFIG_ARM_ARCH_TIMER_OOL_WORKAROUND=y
|
||||||
|
CONFIG_ARM_SBSA_WATCHDOG=y
|
||||||
CONFIG_ATOMIC64_SELFTEST=y
|
CONFIG_ATOMIC64_SELFTEST=y
|
||||||
CONFIG_AUDIT_ARCH_COMPAT_GENERIC=y
|
CONFIG_AUDIT_ARCH_COMPAT_GENERIC=y
|
||||||
CONFIG_BACKLIGHT_CLASS_DEVICE=y
|
CONFIG_BACKLIGHT_CLASS_DEVICE=y
|
||||||
@ -147,4 +148,5 @@ CONFIG_VEXPRESS_CONFIG=y
|
|||||||
CONFIG_VIDEOMODE_HELPERS=y
|
CONFIG_VIDEOMODE_HELPERS=y
|
||||||
CONFIG_VIRTIO_DMA_SHARED_BUFFER=y
|
CONFIG_VIRTIO_DMA_SHARED_BUFFER=y
|
||||||
CONFIG_VMAP_STACK=y
|
CONFIG_VMAP_STACK=y
|
||||||
|
CONFIG_WATCHDOG_CORE=y
|
||||||
CONFIG_ZONE_DMA32=y
|
CONFIG_ZONE_DMA32=y
|
||||||
|
@ -305,7 +305,7 @@
|
|||||||
list_for_each_entry(p, head, list) {
|
list_for_each_entry(p, head, list) {
|
||||||
--- a/net/ipv4/tcp_output.c
|
--- a/net/ipv4/tcp_output.c
|
||||||
+++ b/net/ipv4/tcp_output.c
|
+++ b/net/ipv4/tcp_output.c
|
||||||
@@ -612,48 +612,53 @@ static void tcp_options_write(__be32 *pt
|
@@ -613,48 +613,53 @@ static void tcp_options_write(__be32 *pt
|
||||||
u16 options = opts->options; /* mungable copy */
|
u16 options = opts->options; /* mungable copy */
|
||||||
|
|
||||||
if (unlikely(OPTION_MD5 & options)) {
|
if (unlikely(OPTION_MD5 & options)) {
|
||||||
@ -382,7 +382,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (unlikely(opts->num_sack_blocks)) {
|
if (unlikely(opts->num_sack_blocks)) {
|
||||||
@@ -661,16 +666,17 @@ static void tcp_options_write(__be32 *pt
|
@@ -662,16 +667,17 @@ static void tcp_options_write(__be32 *pt
|
||||||
tp->duplicate_sack : tp->selective_acks;
|
tp->duplicate_sack : tp->selective_acks;
|
||||||
int this_sack;
|
int this_sack;
|
||||||
|
|
||||||
@ -406,7 +406,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
tp->rx_opt.dsack = 0;
|
tp->rx_opt.dsack = 0;
|
||||||
@@ -683,13 +689,14 @@ static void tcp_options_write(__be32 *pt
|
@@ -684,13 +690,14 @@ static void tcp_options_write(__be32 *pt
|
||||||
|
|
||||||
if (foc->exp) {
|
if (foc->exp) {
|
||||||
len = TCPOLEN_EXP_FASTOPEN_BASE + foc->len;
|
len = TCPOLEN_EXP_FASTOPEN_BASE + foc->len;
|
||||||
@ -706,7 +706,7 @@
|
|||||||
EXPORT_SYMBOL(xfrm_parse_spi);
|
EXPORT_SYMBOL(xfrm_parse_spi);
|
||||||
--- a/net/ipv4/tcp_input.c
|
--- a/net/ipv4/tcp_input.c
|
||||||
+++ b/net/ipv4/tcp_input.c
|
+++ b/net/ipv4/tcp_input.c
|
||||||
@@ -4129,14 +4129,16 @@ static bool tcp_parse_aligned_timestamp(
|
@@ -4130,14 +4130,16 @@ static bool tcp_parse_aligned_timestamp(
|
||||||
{
|
{
|
||||||
const __be32 *ptr = (const __be32 *)(th + 1);
|
const __be32 *ptr = (const __be32 *)(th + 1);
|
||||||
|
|
||||||
@ -785,7 +785,7 @@
|
|||||||
*sum = csum_fold(csum_partial(diff, sizeof(diff),
|
*sum = csum_fold(csum_partial(diff, sizeof(diff),
|
||||||
--- a/include/linux/etherdevice.h
|
--- a/include/linux/etherdevice.h
|
||||||
+++ b/include/linux/etherdevice.h
|
+++ b/include/linux/etherdevice.h
|
||||||
@@ -512,7 +512,7 @@ static inline bool is_etherdev_addr(cons
|
@@ -511,7 +511,7 @@ static inline bool is_etherdev_addr(cons
|
||||||
* @b: Pointer to Ethernet header
|
* @b: Pointer to Ethernet header
|
||||||
*
|
*
|
||||||
* Compare two Ethernet headers, returns 0 if equal.
|
* Compare two Ethernet headers, returns 0 if equal.
|
||||||
@ -794,7 +794,7 @@
|
|||||||
* aligned OR the platform can handle unaligned access. This is the
|
* aligned OR the platform can handle unaligned access. This is the
|
||||||
* case for all packets coming into netif_receive_skb or similar
|
* case for all packets coming into netif_receive_skb or similar
|
||||||
* entry points.
|
* entry points.
|
||||||
@@ -535,11 +535,12 @@ static inline unsigned long compare_ethe
|
@@ -534,11 +534,12 @@ static inline unsigned long compare_ethe
|
||||||
fold |= *(unsigned long *)(a + 6) ^ *(unsigned long *)(b + 6);
|
fold |= *(unsigned long *)(a + 6) ^ *(unsigned long *)(b + 6);
|
||||||
return fold;
|
return fold;
|
||||||
#else
|
#else
|
||||||
|
@ -1,13 +0,0 @@
|
|||||||
#!/bin/sh /etc/rc.common
|
|
||||||
|
|
||||||
START=97
|
|
||||||
boot() {
|
|
||||||
. /lib/functions.sh
|
|
||||||
|
|
||||||
case $(board_name) in
|
|
||||||
linksys,panamera)
|
|
||||||
# clear partialboots
|
|
||||||
nvram set partialboots=0 && nvram commit
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
}
|
|
@ -0,0 +1,27 @@
|
|||||||
|
From: Pablo Neira Ayuso <pablo@netfilter.org>
|
||||||
|
Date: Sat, 17 Jul 2021 10:10:29 +0200
|
||||||
|
Subject: [PATCH] netfilter: flowtable: avoid possible false sharing
|
||||||
|
|
||||||
|
The flowtable follows the same timeout approach as conntrack, use the
|
||||||
|
same idiom as in cc16921351d8 ("netfilter: conntrack: avoid same-timeout
|
||||||
|
update") but also include the fix provided by e37542ba111f ("netfilter:
|
||||||
|
conntrack: avoid possible false sharing").
|
||||||
|
|
||||||
|
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
||||||
|
---
|
||||||
|
|
||||||
|
--- a/net/netfilter/nf_flow_table_core.c
|
||||||
|
+++ b/net/netfilter/nf_flow_table_core.c
|
||||||
|
@@ -328,7 +328,11 @@ EXPORT_SYMBOL_GPL(flow_offload_add);
|
||||||
|
void flow_offload_refresh(struct nf_flowtable *flow_table,
|
||||||
|
struct flow_offload *flow)
|
||||||
|
{
|
||||||
|
- flow->timeout = nf_flowtable_time_stamp + flow_offload_get_timeout(flow);
|
||||||
|
+ u32 timeout;
|
||||||
|
+
|
||||||
|
+ timeout = nf_flowtable_time_stamp + flow_offload_get_timeout(flow);
|
||||||
|
+ if (READ_ONCE(flow->timeout) != timeout)
|
||||||
|
+ WRITE_ONCE(flow->timeout, timeout);
|
||||||
|
|
||||||
|
if (likely(!nf_flowtable_hw_offload(flow_table)))
|
||||||
|
return;
|
@ -0,0 +1,57 @@
|
|||||||
|
From f81d97cb646ab8b90fb181d66fccaf9589990de6 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Matthew Hagan <mnhagan88@gmail.com>
|
||||||
|
Date: Sat, 30 Apr 2022 11:00:49 +0100
|
||||||
|
Subject: [PATCH v2] net: sfp: Add tx-fault workaround for Huawei MA5671A SFP
|
||||||
|
ONT
|
||||||
|
|
||||||
|
As noted elsewhere, various GPON SFP modules exhibit non-standard
|
||||||
|
TX-fault behaviour. In the tested case, the Huawei MA5671A, when used
|
||||||
|
in combination with a Marvell mv88e6085 switch, was found to
|
||||||
|
persistently assert TX-fault, resulting in the module being disabled.
|
||||||
|
|
||||||
|
This patch adds a quirk to ignore the SFP_F_TX_FAULT state, allowing the
|
||||||
|
module to function.
|
||||||
|
|
||||||
|
Change from v1: removal of erroneous return statment (Andrew Lunn)
|
||||||
|
|
||||||
|
Signed-off-by: Matthew Hagan <mnhagan88@gmail.com>
|
||||||
|
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
|
||||||
|
---
|
||||||
|
drivers/net/phy/sfp.c | 12 +++++++++++-
|
||||||
|
1 file changed, 11 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
--- a/drivers/net/phy/sfp.c
|
||||||
|
+++ b/drivers/net/phy/sfp.c
|
||||||
|
@@ -249,6 +249,7 @@ struct sfp {
|
||||||
|
struct sfp_eeprom_id id;
|
||||||
|
unsigned int module_power_mW;
|
||||||
|
unsigned int module_t_start_up;
|
||||||
|
+ bool tx_fault_ignore;
|
||||||
|
|
||||||
|
#if IS_ENABLED(CONFIG_HWMON)
|
||||||
|
struct sfp_diag diag;
|
||||||
|
@@ -1893,6 +1894,12 @@ static int sfp_sm_mod_probe(struct sfp *
|
||||||
|
else
|
||||||
|
sfp->module_t_start_up = T_START_UP;
|
||||||
|
|
||||||
|
+ if (!memcmp(id.base.vendor_name, "HUAWEI ", 16) &&
|
||||||
|
+ !memcmp(id.base.vendor_pn, "MA5671A ", 16))
|
||||||
|
+ sfp->tx_fault_ignore = true;
|
||||||
|
+ else
|
||||||
|
+ sfp->tx_fault_ignore = false;
|
||||||
|
+
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -2320,7 +2327,10 @@ static void sfp_check_state(struct sfp *
|
||||||
|
mutex_lock(&sfp->st_mutex);
|
||||||
|
state = sfp_get_state(sfp);
|
||||||
|
changed = state ^ sfp->state;
|
||||||
|
- changed &= SFP_F_PRESENT | SFP_F_LOS | SFP_F_TX_FAULT;
|
||||||
|
+ if (sfp->tx_fault_ignore)
|
||||||
|
+ changed &= SFP_F_PRESENT | SFP_F_LOS;
|
||||||
|
+ else
|
||||||
|
+ changed &= SFP_F_PRESENT | SFP_F_LOS | SFP_F_TX_FAULT;
|
||||||
|
|
||||||
|
for (i = 0; i < GPIO_MAX; i++)
|
||||||
|
if (changed & BIT(i))
|
@ -0,0 +1,57 @@
|
|||||||
|
From f81d97cb646ab8b90fb181d66fccaf9589990de6 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Matthew Hagan <mnhagan88@gmail.com>
|
||||||
|
Date: Sat, 30 Apr 2022 11:00:49 +0100
|
||||||
|
Subject: [PATCH v2] net: sfp: Add tx-fault workaround for Huawei MA5671A SFP
|
||||||
|
ONT
|
||||||
|
|
||||||
|
As noted elsewhere, various GPON SFP modules exhibit non-standard
|
||||||
|
TX-fault behaviour. In the tested case, the Huawei MA5671A, when used
|
||||||
|
in combination with a Marvell mv88e6085 switch, was found to
|
||||||
|
persistently assert TX-fault, resulting in the module being disabled.
|
||||||
|
|
||||||
|
This patch adds a quirk to ignore the SFP_F_TX_FAULT state, allowing the
|
||||||
|
module to function.
|
||||||
|
|
||||||
|
Change from v1: removal of erroneous return statment (Andrew Lunn)
|
||||||
|
|
||||||
|
Signed-off-by: Matthew Hagan <mnhagan88@gmail.com>
|
||||||
|
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
|
||||||
|
---
|
||||||
|
drivers/net/phy/sfp.c | 12 +++++++++++-
|
||||||
|
1 file changed, 11 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
--- a/drivers/net/phy/sfp.c
|
||||||
|
+++ b/drivers/net/phy/sfp.c
|
||||||
|
@@ -250,6 +250,7 @@ struct sfp {
|
||||||
|
struct sfp_eeprom_id id;
|
||||||
|
unsigned int module_power_mW;
|
||||||
|
unsigned int module_t_start_up;
|
||||||
|
+ bool tx_fault_ignore;
|
||||||
|
|
||||||
|
#if IS_ENABLED(CONFIG_HWMON)
|
||||||
|
struct sfp_diag diag;
|
||||||
|
@@ -1945,6 +1946,12 @@ static int sfp_sm_mod_probe(struct sfp *
|
||||||
|
else
|
||||||
|
sfp->module_t_start_up = T_START_UP;
|
||||||
|
|
||||||
|
+ if (!memcmp(id.base.vendor_name, "HUAWEI ", 16) &&
|
||||||
|
+ !memcmp(id.base.vendor_pn, "MA5671A ", 16))
|
||||||
|
+ sfp->tx_fault_ignore = true;
|
||||||
|
+ else
|
||||||
|
+ sfp->tx_fault_ignore = false;
|
||||||
|
+
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -2397,7 +2404,10 @@ static void sfp_check_state(struct sfp *
|
||||||
|
mutex_lock(&sfp->st_mutex);
|
||||||
|
state = sfp_get_state(sfp);
|
||||||
|
changed = state ^ sfp->state;
|
||||||
|
- changed &= SFP_F_PRESENT | SFP_F_LOS | SFP_F_TX_FAULT;
|
||||||
|
+ if (sfp->tx_fault_ignore)
|
||||||
|
+ changed &= SFP_F_PRESENT | SFP_F_LOS;
|
||||||
|
+ else
|
||||||
|
+ changed &= SFP_F_PRESENT | SFP_F_LOS | SFP_F_TX_FAULT;
|
||||||
|
|
||||||
|
for (i = 0; i < GPIO_MAX; i++)
|
||||||
|
if (changed & BIT(i))
|
@ -4137,6 +4137,7 @@ CONFIG_NET_SCH_FQ_CODEL=y
|
|||||||
# CONFIG_NET_SCH_TBF is not set
|
# CONFIG_NET_SCH_TBF is not set
|
||||||
# CONFIG_NET_SCH_TEQL is not set
|
# CONFIG_NET_SCH_TEQL is not set
|
||||||
# CONFIG_NET_SCTPPROBE is not set
|
# CONFIG_NET_SCTPPROBE is not set
|
||||||
|
# CONFIG_NET_SELFTESTS is not set
|
||||||
CONFIG_NET_SOCK_MSG=y
|
CONFIG_NET_SOCK_MSG=y
|
||||||
# CONFIG_NET_SWITCHDEV is not set
|
# CONFIG_NET_SWITCHDEV is not set
|
||||||
# CONFIG_NET_TCPPROBE is not set
|
# CONFIG_NET_TCPPROBE is not set
|
||||||
|
@ -98,7 +98,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
|||||||
obj-$(CONFIG_NETFILTER_XT_TARGET_LED) += xt_LED.o
|
obj-$(CONFIG_NETFILTER_XT_TARGET_LED) += xt_LED.o
|
||||||
--- /dev/null
|
--- /dev/null
|
||||||
+++ b/net/netfilter/xt_FLOWOFFLOAD.c
|
+++ b/net/netfilter/xt_FLOWOFFLOAD.c
|
||||||
@@ -0,0 +1,657 @@
|
@@ -0,0 +1,712 @@
|
||||||
+/*
|
+/*
|
||||||
+ * Copyright (C) 2018-2021 Felix Fietkau <nbd@nbd.name>
|
+ * Copyright (C) 2018-2021 Felix Fietkau <nbd@nbd.name>
|
||||||
+ *
|
+ *
|
||||||
@ -110,6 +110,9 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
|||||||
+#include <linux/init.h>
|
+#include <linux/init.h>
|
||||||
+#include <linux/netfilter.h>
|
+#include <linux/netfilter.h>
|
||||||
+#include <linux/netfilter/xt_FLOWOFFLOAD.h>
|
+#include <linux/netfilter/xt_FLOWOFFLOAD.h>
|
||||||
|
+#include <linux/if_vlan.h>
|
||||||
|
+#include <linux/if_pppox.h>
|
||||||
|
+#include <linux/ppp_defs.h>
|
||||||
+#include <net/ip.h>
|
+#include <net/ip.h>
|
||||||
+#include <net/netfilter/nf_conntrack.h>
|
+#include <net/netfilter/nf_conntrack.h>
|
||||||
+#include <net/netfilter/nf_conntrack_extend.h>
|
+#include <net/netfilter/nf_conntrack_extend.h>
|
||||||
@ -130,20 +133,62 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
|||||||
+ struct delayed_work work;
|
+ struct delayed_work work;
|
||||||
+};
|
+};
|
||||||
+
|
+
|
||||||
|
+struct nf_forward_info {
|
||||||
|
+ const struct net_device *indev;
|
||||||
|
+ const struct net_device *outdev;
|
||||||
|
+ const struct net_device *hw_outdev;
|
||||||
|
+ struct id {
|
||||||
|
+ __u16 id;
|
||||||
|
+ __be16 proto;
|
||||||
|
+ } encap[NF_FLOW_TABLE_ENCAP_MAX];
|
||||||
|
+ u8 num_encaps;
|
||||||
|
+ u8 ingress_vlans;
|
||||||
|
+ u8 h_source[ETH_ALEN];
|
||||||
|
+ u8 h_dest[ETH_ALEN];
|
||||||
|
+ enum flow_offload_xmit_type xmit_type;
|
||||||
|
+};
|
||||||
|
+
|
||||||
+static DEFINE_SPINLOCK(hooks_lock);
|
+static DEFINE_SPINLOCK(hooks_lock);
|
||||||
+
|
+
|
||||||
+struct xt_flowoffload_table flowtable[2];
|
+struct xt_flowoffload_table flowtable[2];
|
||||||
+
|
+
|
||||||
|
+static inline __be16 nf_flow_pppoe_proto(const struct sk_buff *skb)
|
||||||
|
+{
|
||||||
|
+ __be16 proto;
|
||||||
|
+
|
||||||
|
+ proto = *((__be16 *)(skb_mac_header(skb) + ETH_HLEN +
|
||||||
|
+ sizeof(struct pppoe_hdr)));
|
||||||
|
+ switch (proto) {
|
||||||
|
+ case htons(PPP_IP):
|
||||||
|
+ return htons(ETH_P_IP);
|
||||||
|
+ case htons(PPP_IPV6):
|
||||||
|
+ return htons(ETH_P_IPV6);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
+static unsigned int
|
+static unsigned int
|
||||||
+xt_flowoffload_net_hook(void *priv, struct sk_buff *skb,
|
+xt_flowoffload_net_hook(void *priv, struct sk_buff *skb,
|
||||||
+ const struct nf_hook_state *state)
|
+ const struct nf_hook_state *state)
|
||||||
+{
|
+{
|
||||||
+ struct nf_flowtable *ft = priv;
|
+ struct vlan_ethhdr *veth;
|
||||||
+
|
+ __be16 proto;
|
||||||
+ if (!atomic_read(&ft->rhashtable.nelems))
|
|
||||||
+ return NF_ACCEPT;
|
|
||||||
+
|
+
|
||||||
+ switch (skb->protocol) {
|
+ switch (skb->protocol) {
|
||||||
|
+ case htons(ETH_P_8021Q):
|
||||||
|
+ veth = (struct vlan_ethhdr *)skb_mac_header(skb);
|
||||||
|
+ proto = veth->h_vlan_encapsulated_proto;
|
||||||
|
+ break;
|
||||||
|
+ case htons(ETH_P_PPP_SES):
|
||||||
|
+ proto = nf_flow_pppoe_proto(skb);
|
||||||
|
+ break;
|
||||||
|
+ default:
|
||||||
|
+ proto = skb->protocol;
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ switch (proto) {
|
||||||
+ case htons(ETH_P_IP):
|
+ case htons(ETH_P_IP):
|
||||||
+ return nf_flow_offload_ip_hook(priv, skb, state);
|
+ return nf_flow_offload_ip_hook(priv, skb, state);
|
||||||
+ case htons(ETH_P_IPV6):
|
+ case htons(ETH_P_IPV6):
|
||||||
@ -323,7 +368,26 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
|||||||
+ return false;
|
+ return false;
|
||||||
+}
|
+}
|
||||||
+
|
+
|
||||||
+static bool flow_is_valid_ether_device(const struct net_device *dev)
|
+static enum flow_offload_xmit_type nf_xmit_type(struct dst_entry *dst)
|
||||||
|
+{
|
||||||
|
+ if (dst_xfrm(dst))
|
||||||
|
+ return FLOW_OFFLOAD_XMIT_XFRM;
|
||||||
|
+
|
||||||
|
+ return FLOW_OFFLOAD_XMIT_NEIGH;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void nf_default_forward_path(struct nf_flow_route *route,
|
||||||
|
+ struct dst_entry *dst_cache,
|
||||||
|
+ enum ip_conntrack_dir dir,
|
||||||
|
+ struct net_device **dev)
|
||||||
|
+{
|
||||||
|
+ dev[!dir] = dst_cache->dev;
|
||||||
|
+ route->tuple[!dir].in.ifindex = dst_cache->dev->ifindex;
|
||||||
|
+ route->tuple[dir].dst = dst_cache;
|
||||||
|
+ route->tuple[dir].xmit_type = nf_xmit_type(dst_cache);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static bool nf_is_valid_ether_device(const struct net_device *dev)
|
||||||
+{
|
+{
|
||||||
+ if (!dev || (dev->flags & IFF_LOOPBACK) || dev->type != ARPHRD_ETHER ||
|
+ if (!dev || (dev->flags & IFF_LOOPBACK) || dev->type != ARPHRD_ETHER ||
|
||||||
+ dev->addr_len != ETH_ALEN || !is_valid_ether_addr(dev->dev_addr))
|
+ dev->addr_len != ETH_ALEN || !is_valid_ether_addr(dev->dev_addr))
|
||||||
@ -332,174 +396,181 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
|||||||
+ return true;
|
+ return true;
|
||||||
+}
|
+}
|
||||||
+
|
+
|
||||||
+static void
|
+static void nf_dev_path_info(const struct net_device_path_stack *stack,
|
||||||
+xt_flowoffload_route_check_path(struct nf_flow_route *route,
|
+ struct nf_forward_info *info,
|
||||||
+ const struct nf_conn *ct,
|
+ unsigned char *ha)
|
||||||
+ enum ip_conntrack_dir dir,
|
|
||||||
+ struct net_device **out_dev)
|
|
||||||
+{
|
+{
|
||||||
+ const struct dst_entry *dst = route->tuple[dir].dst;
|
+ const struct net_device_path *path;
|
||||||
+ const void *daddr = &ct->tuplehash[!dir].tuple.src.u3;
|
|
||||||
+ struct net_device_path_stack stack;
|
|
||||||
+ enum net_device_path_type prev_type;
|
|
||||||
+ struct net_device *dev = dst->dev;
|
|
||||||
+ struct neighbour *n;
|
|
||||||
+ bool last = false;
|
|
||||||
+ u8 nud_state;
|
|
||||||
+ int i;
|
+ int i;
|
||||||
+
|
+
|
||||||
+ route->tuple[!dir].in.ifindex = dev->ifindex;
|
+ memcpy(info->h_dest, ha, ETH_ALEN);
|
||||||
+ route->tuple[dir].out.ifindex = dev->ifindex;
|
|
||||||
+
|
|
||||||
+ if (route->tuple[dir].xmit_type == FLOW_OFFLOAD_XMIT_XFRM)
|
|
||||||
+ return;
|
|
||||||
+
|
|
||||||
+ if ((dev->flags & IFF_LOOPBACK) ||
|
|
||||||
+ dev->type != ARPHRD_ETHER || dev->addr_len != ETH_ALEN ||
|
|
||||||
+ !is_valid_ether_addr(dev->dev_addr))
|
|
||||||
+ return;
|
|
||||||
+
|
|
||||||
+ n = dst_neigh_lookup(dst, daddr);
|
|
||||||
+ if (!n)
|
|
||||||
+ return;
|
|
||||||
+
|
|
||||||
+ read_lock_bh(&n->lock);
|
|
||||||
+ nud_state = n->nud_state;
|
|
||||||
+ memcpy(route->tuple[dir].out.h_dest, n->ha, ETH_ALEN);
|
|
||||||
+ read_unlock_bh(&n->lock);
|
|
||||||
+ neigh_release(n);
|
|
||||||
+
|
|
||||||
+ if (!(nud_state & NUD_VALID))
|
|
||||||
+ return;
|
|
||||||
+
|
|
||||||
+ if (dev_fill_forward_path(dev, route->tuple[dir].out.h_dest, &stack) ||
|
|
||||||
+ !stack.num_paths)
|
|
||||||
+ return;
|
|
||||||
+
|
|
||||||
+ prev_type = DEV_PATH_ETHERNET;
|
|
||||||
+ for (i = 0; i <= stack.num_paths; i++) {
|
|
||||||
+ const struct net_device_path *path = &stack.path[i];
|
|
||||||
+ int n_encaps = route->tuple[!dir].in.num_encaps;
|
|
||||||
+
|
|
||||||
+ dev = (struct net_device *)path->dev;
|
|
||||||
+ if (flow_is_valid_ether_device(dev)) {
|
|
||||||
+ if (route->tuple[dir].xmit_type != FLOW_OFFLOAD_XMIT_DIRECT) {
|
|
||||||
+ memcpy(route->tuple[dir].out.h_source,
|
|
||||||
+ dev->dev_addr, ETH_ALEN);
|
|
||||||
+ route->tuple[dir].out.ifindex = dev->ifindex;
|
|
||||||
+ }
|
|
||||||
+ route->tuple[dir].xmit_type = FLOW_OFFLOAD_XMIT_DIRECT;
|
|
||||||
+ }
|
|
||||||
+
|
+
|
||||||
|
+ for (i = 0; i < stack->num_paths; i++) {
|
||||||
|
+ path = &stack->path[i];
|
||||||
+ switch (path->type) {
|
+ switch (path->type) {
|
||||||
+ case DEV_PATH_PPPOE:
|
+ case DEV_PATH_ETHERNET:
|
||||||
|
+ case DEV_PATH_DSA:
|
||||||
+ case DEV_PATH_VLAN:
|
+ case DEV_PATH_VLAN:
|
||||||
+ if (n_encaps >= NF_FLOW_TABLE_ENCAP_MAX ||
|
+ case DEV_PATH_PPPOE:
|
||||||
+ i == stack.num_paths) {
|
+ info->indev = path->dev;
|
||||||
+ last = true;
|
+ if (is_zero_ether_addr(info->h_source))
|
||||||
|
+ memcpy(info->h_source, path->dev->dev_addr, ETH_ALEN);
|
||||||
|
+
|
||||||
|
+ if (path->type == DEV_PATH_ETHERNET)
|
||||||
|
+ break;
|
||||||
|
+ if (path->type == DEV_PATH_DSA) {
|
||||||
|
+ i = stack->num_paths;
|
||||||
+ break;
|
+ break;
|
||||||
+ }
|
+ }
|
||||||
+
|
+
|
||||||
+ route->tuple[!dir].in.num_encaps++;
|
+ /* DEV_PATH_VLAN and DEV_PATH_PPPOE */
|
||||||
+ route->tuple[!dir].in.encap[n_encaps].id = path->encap.id;
|
+ if (info->num_encaps >= NF_FLOW_TABLE_ENCAP_MAX) {
|
||||||
+ route->tuple[!dir].in.encap[n_encaps].proto = path->encap.proto;
|
+ info->indev = NULL;
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ if (!info->outdev)
|
||||||
|
+ info->outdev = path->dev;
|
||||||
|
+ info->encap[info->num_encaps].id = path->encap.id;
|
||||||
|
+ info->encap[info->num_encaps].proto = path->encap.proto;
|
||||||
|
+ info->num_encaps++;
|
||||||
+ if (path->type == DEV_PATH_PPPOE)
|
+ if (path->type == DEV_PATH_PPPOE)
|
||||||
+ memcpy(route->tuple[dir].out.h_dest,
|
+ memcpy(info->h_dest, path->encap.h_dest, ETH_ALEN);
|
||||||
+ path->encap.h_dest, ETH_ALEN);
|
|
||||||
+ break;
|
+ break;
|
||||||
+ case DEV_PATH_BRIDGE:
|
+ case DEV_PATH_BRIDGE:
|
||||||
+ switch (path->bridge.vlan_mode) {
|
+ if (is_zero_ether_addr(info->h_source))
|
||||||
+ case DEV_PATH_BR_VLAN_TAG:
|
+ memcpy(info->h_source, path->dev->dev_addr, ETH_ALEN);
|
||||||
+ if (n_encaps >= NF_FLOW_TABLE_ENCAP_MAX ||
|
|
||||||
+ i == stack.num_paths) {
|
|
||||||
+ last = true;
|
|
||||||
+ break;
|
|
||||||
+ }
|
|
||||||
+
|
+
|
||||||
+ route->tuple[!dir].in.num_encaps++;
|
+ switch (path->bridge.vlan_mode) {
|
||||||
+ route->tuple[!dir].in.encap[n_encaps].id =
|
+ case DEV_PATH_BR_VLAN_UNTAG_HW:
|
||||||
+ path->bridge.vlan_id;
|
+ info->ingress_vlans |= BIT(info->num_encaps - 1);
|
||||||
+ route->tuple[!dir].in.encap[n_encaps].proto =
|
+ break;
|
||||||
+ path->bridge.vlan_proto;
|
+ case DEV_PATH_BR_VLAN_TAG:
|
||||||
|
+ info->encap[info->num_encaps].id = path->bridge.vlan_id;
|
||||||
|
+ info->encap[info->num_encaps].proto = path->bridge.vlan_proto;
|
||||||
|
+ info->num_encaps++;
|
||||||
+ break;
|
+ break;
|
||||||
+ case DEV_PATH_BR_VLAN_UNTAG:
|
+ case DEV_PATH_BR_VLAN_UNTAG:
|
||||||
+ route->tuple[!dir].in.num_encaps--;
|
+ info->num_encaps--;
|
||||||
+ break;
|
|
||||||
+ case DEV_PATH_BR_VLAN_UNTAG_HW:
|
|
||||||
+ route->tuple[!dir].in.ingress_vlans |= BIT(n_encaps - 1);
|
|
||||||
+ break;
|
+ break;
|
||||||
+ case DEV_PATH_BR_VLAN_KEEP:
|
+ case DEV_PATH_BR_VLAN_KEEP:
|
||||||
+ break;
|
+ break;
|
||||||
+ }
|
+ }
|
||||||
+ break;
|
+ break;
|
||||||
+ default:
|
+ default:
|
||||||
+ last = true;
|
+ info->indev = NULL;
|
||||||
+ break;
|
+ break;
|
||||||
+ }
|
+ }
|
||||||
|
+ }
|
||||||
|
+ if (!info->outdev)
|
||||||
|
+ info->outdev = info->indev;
|
||||||
+
|
+
|
||||||
+ if (last)
|
+ info->hw_outdev = info->indev;
|
||||||
+ break;
|
+
|
||||||
|
+ if (nf_is_valid_ether_device(info->indev))
|
||||||
|
+ info->xmit_type = FLOW_OFFLOAD_XMIT_DIRECT;
|
||||||
+}
|
+}
|
||||||
+
|
+
|
||||||
+ *out_dev = dev;
|
+static int nf_dev_fill_forward_path(const struct nf_flow_route *route,
|
||||||
+ route->tuple[dir].out.hw_ifindex = dev->ifindex;
|
+ const struct dst_entry *dst_cache,
|
||||||
+ route->tuple[!dir].in.ifindex = dev->ifindex;
|
+ const struct nf_conn *ct,
|
||||||
+}
|
+ enum ip_conntrack_dir dir, u8 *ha,
|
||||||
+
|
+ struct net_device_path_stack *stack)
|
||||||
+static int
|
|
||||||
+xt_flowoffload_route_dir(struct nf_flow_route *route, const struct nf_conn *ct,
|
|
||||||
+ enum ip_conntrack_dir dir,
|
|
||||||
+ const struct xt_action_param *par, int ifindex)
|
|
||||||
+{
|
+{
|
||||||
+ struct dst_entry *dst = NULL;
|
+ const void *daddr = &ct->tuplehash[!dir].tuple.src.u3;
|
||||||
+ struct flowi fl;
|
+ struct net_device *dev = dst_cache->dev;
|
||||||
|
+ struct neighbour *n;
|
||||||
|
+ u8 nud_state;
|
||||||
+
|
+
|
||||||
+ memset(&fl, 0, sizeof(fl));
|
+ if (!nf_is_valid_ether_device(dev))
|
||||||
+ switch (xt_family(par)) {
|
+ goto out;
|
||||||
+ case NFPROTO_IPV4:
|
+
|
||||||
+ fl.u.ip4.daddr = ct->tuplehash[!dir].tuple.src.u3.ip;
|
+ n = dst_neigh_lookup(dst_cache, daddr);
|
||||||
+ fl.u.ip4.flowi4_oif = ifindex;
|
+ if (!n)
|
||||||
+ break;
|
+ return -1;
|
||||||
+ case NFPROTO_IPV6:
|
+
|
||||||
+ fl.u.ip6.saddr = ct->tuplehash[!dir].tuple.dst.u3.in6;
|
+ read_lock_bh(&n->lock);
|
||||||
+ fl.u.ip6.daddr = ct->tuplehash[!dir].tuple.src.u3.in6;
|
+ nud_state = n->nud_state;
|
||||||
+ fl.u.ip6.flowi6_oif = ifindex;
|
+ ether_addr_copy(ha, n->ha);
|
||||||
+ break;
|
+ read_unlock_bh(&n->lock);
|
||||||
|
+ neigh_release(n);
|
||||||
|
+
|
||||||
|
+ if (!(nud_state & NUD_VALID))
|
||||||
|
+ return -1;
|
||||||
|
+
|
||||||
|
+out:
|
||||||
|
+ return dev_fill_forward_path(dev, ha, stack);
|
||||||
+}
|
+}
|
||||||
+
|
+
|
||||||
+ nf_route(xt_net(par), &dst, &fl, false, xt_family(par));
|
+static void nf_dev_forward_path(struct nf_flow_route *route,
|
||||||
+ if (!dst)
|
+ const struct nf_conn *ct,
|
||||||
+ return -ENOENT;
|
+ enum ip_conntrack_dir dir,
|
||||||
|
+ struct net_device **devs)
|
||||||
|
+{
|
||||||
|
+ const struct dst_entry *dst = route->tuple[dir].dst;
|
||||||
|
+ struct net_device_path_stack stack;
|
||||||
|
+ struct nf_forward_info info = {};
|
||||||
|
+ unsigned char ha[ETH_ALEN];
|
||||||
|
+ int i;
|
||||||
+
|
+
|
||||||
+ route->tuple[dir].dst = dst;
|
+ if (nf_dev_fill_forward_path(route, dst, ct, dir, ha, &stack) >= 0)
|
||||||
+ if (dst_xfrm(dst))
|
+ nf_dev_path_info(&stack, &info, ha);
|
||||||
+ route->tuple[dir].xmit_type = FLOW_OFFLOAD_XMIT_XFRM;
|
|
||||||
+ else
|
|
||||||
+ route->tuple[dir].xmit_type = FLOW_OFFLOAD_XMIT_NEIGH;
|
|
||||||
+
|
+
|
||||||
+ return 0;
|
+ devs[!dir] = (struct net_device *)info.indev;
|
||||||
|
+ if (!info.indev)
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ route->tuple[!dir].in.ifindex = info.indev->ifindex;
|
||||||
|
+ for (i = 0; i < info.num_encaps; i++) {
|
||||||
|
+ route->tuple[!dir].in.encap[i].id = info.encap[i].id;
|
||||||
|
+ route->tuple[!dir].in.encap[i].proto = info.encap[i].proto;
|
||||||
|
+ }
|
||||||
|
+ route->tuple[!dir].in.num_encaps = info.num_encaps;
|
||||||
|
+ route->tuple[!dir].in.ingress_vlans = info.ingress_vlans;
|
||||||
|
+
|
||||||
|
+ if (info.xmit_type == FLOW_OFFLOAD_XMIT_DIRECT) {
|
||||||
|
+ memcpy(route->tuple[dir].out.h_source, info.h_source, ETH_ALEN);
|
||||||
|
+ memcpy(route->tuple[dir].out.h_dest, info.h_dest, ETH_ALEN);
|
||||||
|
+ route->tuple[dir].out.ifindex = info.outdev->ifindex;
|
||||||
|
+ route->tuple[dir].out.hw_ifindex = info.hw_outdev->ifindex;
|
||||||
|
+ route->tuple[dir].xmit_type = info.xmit_type;
|
||||||
|
+ }
|
||||||
+}
|
+}
|
||||||
+
|
+
|
||||||
+static int
|
+static int
|
||||||
+xt_flowoffload_route(struct sk_buff *skb, const struct nf_conn *ct,
|
+xt_flowoffload_route(struct sk_buff *skb, const struct nf_conn *ct,
|
||||||
+ const struct xt_action_param *par,
|
+ const struct xt_action_param *par,
|
||||||
+ struct nf_flow_route *route, enum ip_conntrack_dir dir,
|
+ struct nf_flow_route *route, enum ip_conntrack_dir dir,
|
||||||
+ struct net_device **dev)
|
+ struct net_device **devs)
|
||||||
+{
|
+{
|
||||||
+ int ret;
|
+ struct dst_entry *this_dst = skb_dst(skb);
|
||||||
|
+ struct dst_entry *other_dst = NULL;
|
||||||
|
+ struct flowi fl;
|
||||||
+
|
+
|
||||||
+ ret = xt_flowoffload_route_dir(route, ct, dir, par,
|
+ memset(&fl, 0, sizeof(fl));
|
||||||
+ dev[dir]->ifindex);
|
+ switch (xt_family(par)) {
|
||||||
+ if (ret)
|
+ case NFPROTO_IPV4:
|
||||||
+ return ret;
|
+ fl.u.ip4.daddr = ct->tuplehash[dir].tuple.src.u3.ip;
|
||||||
|
+ fl.u.ip4.flowi4_oif = xt_in(par)->ifindex;
|
||||||
|
+ break;
|
||||||
|
+ case NFPROTO_IPV6:
|
||||||
|
+ fl.u.ip6.saddr = ct->tuplehash[!dir].tuple.dst.u3.in6;
|
||||||
|
+ fl.u.ip6.daddr = ct->tuplehash[dir].tuple.src.u3.in6;
|
||||||
|
+ fl.u.ip6.flowi6_oif = xt_in(par)->ifindex;
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
+
|
+
|
||||||
+ ret = xt_flowoffload_route_dir(route, ct, !dir, par,
|
+ nf_route(xt_net(par), &other_dst, &fl, false, xt_family(par));
|
||||||
+ dev[!dir]->ifindex);
|
+ if (!other_dst)
|
||||||
+ if (ret)
|
+ return -ENOENT;
|
||||||
+ return ret;
|
|
||||||
+
|
+
|
||||||
+ xt_flowoffload_route_check_path(route, ct, dir, &dev[!dir]);
|
+ nf_default_forward_path(route, this_dst, dir, devs);
|
||||||
+ xt_flowoffload_route_check_path(route, ct, !dir, &dev[dir]);
|
+ nf_default_forward_path(route, other_dst, !dir, devs);
|
||||||
|
+
|
||||||
|
+ if (route->tuple[dir].xmit_type == FLOW_OFFLOAD_XMIT_NEIGH &&
|
||||||
|
+ route->tuple[!dir].xmit_type == FLOW_OFFLOAD_XMIT_NEIGH) {
|
||||||
|
+ nf_dev_forward_path(route, ct, dir, devs);
|
||||||
|
+ nf_dev_forward_path(route, ct, !dir, devs);
|
||||||
|
+ }
|
||||||
+
|
+
|
||||||
+ return 0;
|
+ return 0;
|
||||||
+}
|
+}
|
||||||
@ -542,7 +613,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
|||||||
+ }
|
+ }
|
||||||
+
|
+
|
||||||
+ if (nf_ct_ext_exist(ct, NF_CT_EXT_HELPER) ||
|
+ if (nf_ct_ext_exist(ct, NF_CT_EXT_HELPER) ||
|
||||||
+ ct->status & IPS_SEQ_ADJUST)
|
+ ct->status & (IPS_SEQ_ADJUST | IPS_NAT_CLASH))
|
||||||
+ return XT_CONTINUE;
|
+ return XT_CONTINUE;
|
||||||
+
|
+
|
||||||
+ if (!nf_ct_is_confirmed(ct))
|
+ if (!nf_ct_is_confirmed(ct))
|
||||||
@ -586,7 +657,6 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
|||||||
+ xt_flowoffload_check_device(table, devs[0]);
|
+ xt_flowoffload_check_device(table, devs[0]);
|
||||||
+ xt_flowoffload_check_device(table, devs[1]);
|
+ xt_flowoffload_check_device(table, devs[1]);
|
||||||
+
|
+
|
||||||
+ dst_release(route.tuple[dir].dst);
|
|
||||||
+ dst_release(route.tuple[!dir].dst);
|
+ dst_release(route.tuple[!dir].dst);
|
||||||
+
|
+
|
||||||
+ return XT_CONTINUE;
|
+ return XT_CONTINUE;
|
||||||
@ -594,7 +664,6 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
|||||||
+err_flow_add:
|
+err_flow_add:
|
||||||
+ flow_offload_free(flow);
|
+ flow_offload_free(flow);
|
||||||
+err_flow_alloc:
|
+err_flow_alloc:
|
||||||
+ dst_release(route.tuple[dir].dst);
|
|
||||||
+ dst_release(route.tuple[!dir].dst);
|
+ dst_release(route.tuple[!dir].dst);
|
||||||
+err_flow_route:
|
+err_flow_route:
|
||||||
+ clear_bit(IPS_OFFLOAD_BIT, &ct->status);
|
+ clear_bit(IPS_OFFLOAD_BIT, &ct->status);
|
||||||
@ -661,20 +730,6 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
|||||||
+ .notifier_call = flow_offload_netdev_event,
|
+ .notifier_call = flow_offload_netdev_event,
|
||||||
+};
|
+};
|
||||||
+
|
+
|
||||||
+static unsigned int
|
|
||||||
+nf_flow_offload_inet_hook(void *priv, struct sk_buff *skb,
|
|
||||||
+ const struct nf_hook_state *state)
|
|
||||||
+{
|
|
||||||
+ switch (skb->protocol) {
|
|
||||||
+ case htons(ETH_P_IP):
|
|
||||||
+ return nf_flow_offload_ip_hook(priv, skb, state);
|
|
||||||
+ case htons(ETH_P_IPV6):
|
|
||||||
+ return nf_flow_offload_ipv6_hook(priv, skb, state);
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ return NF_ACCEPT;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static int nf_flow_rule_route_inet(struct net *net,
|
+static int nf_flow_rule_route_inet(struct net *net,
|
||||||
+ const struct flow_offload *flow,
|
+ const struct flow_offload *flow,
|
||||||
+ enum flow_offload_tuple_dir dir,
|
+ enum flow_offload_tuple_dir dir,
|
||||||
@ -704,7 +759,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
|||||||
+ .setup = nf_flow_table_offload_setup,
|
+ .setup = nf_flow_table_offload_setup,
|
||||||
+ .action = nf_flow_rule_route_inet,
|
+ .action = nf_flow_rule_route_inet,
|
||||||
+ .free = nf_flow_table_free,
|
+ .free = nf_flow_table_free,
|
||||||
+ .hook = nf_flow_offload_inet_hook,
|
+ .hook = xt_flowoffload_net_hook,
|
||||||
+ .owner = THIS_MODULE,
|
+ .owner = THIS_MODULE,
|
||||||
+};
|
+};
|
||||||
+
|
+
|
||||||
@ -766,7 +821,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
|||||||
#include <net/netfilter/nf_flow_table.h>
|
#include <net/netfilter/nf_flow_table.h>
|
||||||
#include <net/netfilter/nf_conntrack.h>
|
#include <net/netfilter/nf_conntrack.h>
|
||||||
#include <net/netfilter/nf_conntrack_core.h>
|
#include <net/netfilter/nf_conntrack_core.h>
|
||||||
@@ -395,8 +394,7 @@ flow_offload_lookup(struct nf_flowtable
|
@@ -401,8 +400,7 @@ flow_offload_lookup(struct nf_flowtable
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(flow_offload_lookup);
|
EXPORT_SYMBOL_GPL(flow_offload_lookup);
|
||||||
|
|
||||||
@ -776,7 +831,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
|||||||
void (*iter)(struct flow_offload *flow, void *data),
|
void (*iter)(struct flow_offload *flow, void *data),
|
||||||
void *data)
|
void *data)
|
||||||
{
|
{
|
||||||
@@ -428,6 +426,7 @@ nf_flow_table_iterate(struct nf_flowtabl
|
@@ -434,6 +432,7 @@ nf_flow_table_iterate(struct nf_flowtabl
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
@ -98,7 +98,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
|||||||
obj-$(CONFIG_NETFILTER_XT_TARGET_LED) += xt_LED.o
|
obj-$(CONFIG_NETFILTER_XT_TARGET_LED) += xt_LED.o
|
||||||
--- /dev/null
|
--- /dev/null
|
||||||
+++ b/net/netfilter/xt_FLOWOFFLOAD.c
|
+++ b/net/netfilter/xt_FLOWOFFLOAD.c
|
||||||
@@ -0,0 +1,657 @@
|
@@ -0,0 +1,694 @@
|
||||||
+/*
|
+/*
|
||||||
+ * Copyright (C) 2018-2021 Felix Fietkau <nbd@nbd.name>
|
+ * Copyright (C) 2018-2021 Felix Fietkau <nbd@nbd.name>
|
||||||
+ *
|
+ *
|
||||||
@ -110,6 +110,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
|||||||
+#include <linux/init.h>
|
+#include <linux/init.h>
|
||||||
+#include <linux/netfilter.h>
|
+#include <linux/netfilter.h>
|
||||||
+#include <linux/netfilter/xt_FLOWOFFLOAD.h>
|
+#include <linux/netfilter/xt_FLOWOFFLOAD.h>
|
||||||
|
+#include <linux/if_vlan.h>
|
||||||
+#include <net/ip.h>
|
+#include <net/ip.h>
|
||||||
+#include <net/netfilter/nf_conntrack.h>
|
+#include <net/netfilter/nf_conntrack.h>
|
||||||
+#include <net/netfilter/nf_conntrack_extend.h>
|
+#include <net/netfilter/nf_conntrack_extend.h>
|
||||||
@ -130,6 +131,21 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
|||||||
+ struct delayed_work work;
|
+ struct delayed_work work;
|
||||||
+};
|
+};
|
||||||
+
|
+
|
||||||
|
+struct nf_forward_info {
|
||||||
|
+ const struct net_device *indev;
|
||||||
|
+ const struct net_device *outdev;
|
||||||
|
+ const struct net_device *hw_outdev;
|
||||||
|
+ struct id {
|
||||||
|
+ __u16 id;
|
||||||
|
+ __be16 proto;
|
||||||
|
+ } encap[NF_FLOW_TABLE_ENCAP_MAX];
|
||||||
|
+ u8 num_encaps;
|
||||||
|
+ u8 ingress_vlans;
|
||||||
|
+ u8 h_source[ETH_ALEN];
|
||||||
|
+ u8 h_dest[ETH_ALEN];
|
||||||
|
+ enum flow_offload_xmit_type xmit_type;
|
||||||
|
+};
|
||||||
|
+
|
||||||
+static DEFINE_SPINLOCK(hooks_lock);
|
+static DEFINE_SPINLOCK(hooks_lock);
|
||||||
+
|
+
|
||||||
+struct xt_flowoffload_table flowtable[2];
|
+struct xt_flowoffload_table flowtable[2];
|
||||||
@ -138,12 +154,23 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
|||||||
+xt_flowoffload_net_hook(void *priv, struct sk_buff *skb,
|
+xt_flowoffload_net_hook(void *priv, struct sk_buff *skb,
|
||||||
+ const struct nf_hook_state *state)
|
+ const struct nf_hook_state *state)
|
||||||
+{
|
+{
|
||||||
+ struct nf_flowtable *ft = priv;
|
+ struct vlan_ethhdr *veth;
|
||||||
+
|
+ __be16 proto;
|
||||||
+ if (!atomic_read(&ft->rhashtable.nelems))
|
|
||||||
+ return NF_ACCEPT;
|
|
||||||
+
|
+
|
||||||
+ switch (skb->protocol) {
|
+ switch (skb->protocol) {
|
||||||
|
+ case htons(ETH_P_8021Q):
|
||||||
|
+ veth = (struct vlan_ethhdr *)skb_mac_header(skb);
|
||||||
|
+ proto = veth->h_vlan_encapsulated_proto;
|
||||||
|
+ break;
|
||||||
|
+ case htons(ETH_P_PPP_SES):
|
||||||
|
+ proto = nf_flow_pppoe_proto(skb);
|
||||||
|
+ break;
|
||||||
|
+ default:
|
||||||
|
+ proto = skb->protocol;
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ switch (proto) {
|
||||||
+ case htons(ETH_P_IP):
|
+ case htons(ETH_P_IP):
|
||||||
+ return nf_flow_offload_ip_hook(priv, skb, state);
|
+ return nf_flow_offload_ip_hook(priv, skb, state);
|
||||||
+ case htons(ETH_P_IPV6):
|
+ case htons(ETH_P_IPV6):
|
||||||
@ -323,7 +350,26 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
|||||||
+ return false;
|
+ return false;
|
||||||
+}
|
+}
|
||||||
+
|
+
|
||||||
+static bool flow_is_valid_ether_device(const struct net_device *dev)
|
+static enum flow_offload_xmit_type nf_xmit_type(struct dst_entry *dst)
|
||||||
|
+{
|
||||||
|
+ if (dst_xfrm(dst))
|
||||||
|
+ return FLOW_OFFLOAD_XMIT_XFRM;
|
||||||
|
+
|
||||||
|
+ return FLOW_OFFLOAD_XMIT_NEIGH;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void nf_default_forward_path(struct nf_flow_route *route,
|
||||||
|
+ struct dst_entry *dst_cache,
|
||||||
|
+ enum ip_conntrack_dir dir,
|
||||||
|
+ struct net_device **dev)
|
||||||
|
+{
|
||||||
|
+ dev[!dir] = dst_cache->dev;
|
||||||
|
+ route->tuple[!dir].in.ifindex = dst_cache->dev->ifindex;
|
||||||
|
+ route->tuple[dir].dst = dst_cache;
|
||||||
|
+ route->tuple[dir].xmit_type = nf_xmit_type(dst_cache);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static bool nf_is_valid_ether_device(const struct net_device *dev)
|
||||||
+{
|
+{
|
||||||
+ if (!dev || (dev->flags & IFF_LOOPBACK) || dev->type != ARPHRD_ETHER ||
|
+ if (!dev || (dev->flags & IFF_LOOPBACK) || dev->type != ARPHRD_ETHER ||
|
||||||
+ dev->addr_len != ETH_ALEN || !is_valid_ether_addr(dev->dev_addr))
|
+ dev->addr_len != ETH_ALEN || !is_valid_ether_addr(dev->dev_addr))
|
||||||
@ -332,174 +378,181 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
|||||||
+ return true;
|
+ return true;
|
||||||
+}
|
+}
|
||||||
+
|
+
|
||||||
+static void
|
+static void nf_dev_path_info(const struct net_device_path_stack *stack,
|
||||||
+xt_flowoffload_route_check_path(struct nf_flow_route *route,
|
+ struct nf_forward_info *info,
|
||||||
+ const struct nf_conn *ct,
|
+ unsigned char *ha)
|
||||||
+ enum ip_conntrack_dir dir,
|
|
||||||
+ struct net_device **out_dev)
|
|
||||||
+{
|
+{
|
||||||
+ const struct dst_entry *dst = route->tuple[dir].dst;
|
+ const struct net_device_path *path;
|
||||||
+ const void *daddr = &ct->tuplehash[!dir].tuple.src.u3;
|
|
||||||
+ struct net_device_path_stack stack;
|
|
||||||
+ enum net_device_path_type prev_type;
|
|
||||||
+ struct net_device *dev = dst->dev;
|
|
||||||
+ struct neighbour *n;
|
|
||||||
+ bool last = false;
|
|
||||||
+ u8 nud_state;
|
|
||||||
+ int i;
|
+ int i;
|
||||||
+
|
+
|
||||||
+ route->tuple[!dir].in.ifindex = dev->ifindex;
|
+ memcpy(info->h_dest, ha, ETH_ALEN);
|
||||||
+ route->tuple[dir].out.ifindex = dev->ifindex;
|
|
||||||
+
|
|
||||||
+ if (route->tuple[dir].xmit_type == FLOW_OFFLOAD_XMIT_XFRM)
|
|
||||||
+ return;
|
|
||||||
+
|
|
||||||
+ if ((dev->flags & IFF_LOOPBACK) ||
|
|
||||||
+ dev->type != ARPHRD_ETHER || dev->addr_len != ETH_ALEN ||
|
|
||||||
+ !is_valid_ether_addr(dev->dev_addr))
|
|
||||||
+ return;
|
|
||||||
+
|
|
||||||
+ n = dst_neigh_lookup(dst, daddr);
|
|
||||||
+ if (!n)
|
|
||||||
+ return;
|
|
||||||
+
|
|
||||||
+ read_lock_bh(&n->lock);
|
|
||||||
+ nud_state = n->nud_state;
|
|
||||||
+ memcpy(route->tuple[dir].out.h_dest, n->ha, ETH_ALEN);
|
|
||||||
+ read_unlock_bh(&n->lock);
|
|
||||||
+ neigh_release(n);
|
|
||||||
+
|
|
||||||
+ if (!(nud_state & NUD_VALID))
|
|
||||||
+ return;
|
|
||||||
+
|
|
||||||
+ if (dev_fill_forward_path(dev, route->tuple[dir].out.h_dest, &stack) ||
|
|
||||||
+ !stack.num_paths)
|
|
||||||
+ return;
|
|
||||||
+
|
|
||||||
+ prev_type = DEV_PATH_ETHERNET;
|
|
||||||
+ for (i = 0; i <= stack.num_paths; i++) {
|
|
||||||
+ const struct net_device_path *path = &stack.path[i];
|
|
||||||
+ int n_encaps = route->tuple[!dir].in.num_encaps;
|
|
||||||
+
|
|
||||||
+ dev = (struct net_device *)path->dev;
|
|
||||||
+ if (flow_is_valid_ether_device(dev)) {
|
|
||||||
+ if (route->tuple[dir].xmit_type != FLOW_OFFLOAD_XMIT_DIRECT) {
|
|
||||||
+ memcpy(route->tuple[dir].out.h_source,
|
|
||||||
+ dev->dev_addr, ETH_ALEN);
|
|
||||||
+ route->tuple[dir].out.ifindex = dev->ifindex;
|
|
||||||
+ }
|
|
||||||
+ route->tuple[dir].xmit_type = FLOW_OFFLOAD_XMIT_DIRECT;
|
|
||||||
+ }
|
|
||||||
+
|
+
|
||||||
|
+ for (i = 0; i < stack->num_paths; i++) {
|
||||||
|
+ path = &stack->path[i];
|
||||||
+ switch (path->type) {
|
+ switch (path->type) {
|
||||||
+ case DEV_PATH_PPPOE:
|
+ case DEV_PATH_ETHERNET:
|
||||||
|
+ case DEV_PATH_DSA:
|
||||||
+ case DEV_PATH_VLAN:
|
+ case DEV_PATH_VLAN:
|
||||||
+ if (n_encaps >= NF_FLOW_TABLE_ENCAP_MAX ||
|
+ case DEV_PATH_PPPOE:
|
||||||
+ i == stack.num_paths) {
|
+ info->indev = path->dev;
|
||||||
+ last = true;
|
+ if (is_zero_ether_addr(info->h_source))
|
||||||
|
+ memcpy(info->h_source, path->dev->dev_addr, ETH_ALEN);
|
||||||
|
+
|
||||||
|
+ if (path->type == DEV_PATH_ETHERNET)
|
||||||
|
+ break;
|
||||||
|
+ if (path->type == DEV_PATH_DSA) {
|
||||||
|
+ i = stack->num_paths;
|
||||||
+ break;
|
+ break;
|
||||||
+ }
|
+ }
|
||||||
+
|
+
|
||||||
+ route->tuple[!dir].in.num_encaps++;
|
+ /* DEV_PATH_VLAN and DEV_PATH_PPPOE */
|
||||||
+ route->tuple[!dir].in.encap[n_encaps].id = path->encap.id;
|
+ if (info->num_encaps >= NF_FLOW_TABLE_ENCAP_MAX) {
|
||||||
+ route->tuple[!dir].in.encap[n_encaps].proto = path->encap.proto;
|
+ info->indev = NULL;
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ if (!info->outdev)
|
||||||
|
+ info->outdev = path->dev;
|
||||||
|
+ info->encap[info->num_encaps].id = path->encap.id;
|
||||||
|
+ info->encap[info->num_encaps].proto = path->encap.proto;
|
||||||
|
+ info->num_encaps++;
|
||||||
+ if (path->type == DEV_PATH_PPPOE)
|
+ if (path->type == DEV_PATH_PPPOE)
|
||||||
+ memcpy(route->tuple[dir].out.h_dest,
|
+ memcpy(info->h_dest, path->encap.h_dest, ETH_ALEN);
|
||||||
+ path->encap.h_dest, ETH_ALEN);
|
|
||||||
+ break;
|
+ break;
|
||||||
+ case DEV_PATH_BRIDGE:
|
+ case DEV_PATH_BRIDGE:
|
||||||
+ switch (path->bridge.vlan_mode) {
|
+ if (is_zero_ether_addr(info->h_source))
|
||||||
+ case DEV_PATH_BR_VLAN_TAG:
|
+ memcpy(info->h_source, path->dev->dev_addr, ETH_ALEN);
|
||||||
+ if (n_encaps >= NF_FLOW_TABLE_ENCAP_MAX ||
|
|
||||||
+ i == stack.num_paths) {
|
|
||||||
+ last = true;
|
|
||||||
+ break;
|
|
||||||
+ }
|
|
||||||
+
|
+
|
||||||
+ route->tuple[!dir].in.num_encaps++;
|
+ switch (path->bridge.vlan_mode) {
|
||||||
+ route->tuple[!dir].in.encap[n_encaps].id =
|
+ case DEV_PATH_BR_VLAN_UNTAG_HW:
|
||||||
+ path->bridge.vlan_id;
|
+ info->ingress_vlans |= BIT(info->num_encaps - 1);
|
||||||
+ route->tuple[!dir].in.encap[n_encaps].proto =
|
+ break;
|
||||||
+ path->bridge.vlan_proto;
|
+ case DEV_PATH_BR_VLAN_TAG:
|
||||||
|
+ info->encap[info->num_encaps].id = path->bridge.vlan_id;
|
||||||
|
+ info->encap[info->num_encaps].proto = path->bridge.vlan_proto;
|
||||||
|
+ info->num_encaps++;
|
||||||
+ break;
|
+ break;
|
||||||
+ case DEV_PATH_BR_VLAN_UNTAG:
|
+ case DEV_PATH_BR_VLAN_UNTAG:
|
||||||
+ route->tuple[!dir].in.num_encaps--;
|
+ info->num_encaps--;
|
||||||
+ break;
|
|
||||||
+ case DEV_PATH_BR_VLAN_UNTAG_HW:
|
|
||||||
+ route->tuple[!dir].in.ingress_vlans |= BIT(n_encaps - 1);
|
|
||||||
+ break;
|
+ break;
|
||||||
+ case DEV_PATH_BR_VLAN_KEEP:
|
+ case DEV_PATH_BR_VLAN_KEEP:
|
||||||
+ break;
|
+ break;
|
||||||
+ }
|
+ }
|
||||||
+ break;
|
+ break;
|
||||||
+ default:
|
+ default:
|
||||||
+ last = true;
|
+ info->indev = NULL;
|
||||||
+ break;
|
+ break;
|
||||||
+ }
|
+ }
|
||||||
|
+ }
|
||||||
|
+ if (!info->outdev)
|
||||||
|
+ info->outdev = info->indev;
|
||||||
+
|
+
|
||||||
+ if (last)
|
+ info->hw_outdev = info->indev;
|
||||||
+ break;
|
+
|
||||||
|
+ if (nf_is_valid_ether_device(info->indev))
|
||||||
|
+ info->xmit_type = FLOW_OFFLOAD_XMIT_DIRECT;
|
||||||
+}
|
+}
|
||||||
+
|
+
|
||||||
+ *out_dev = dev;
|
+static int nf_dev_fill_forward_path(const struct nf_flow_route *route,
|
||||||
+ route->tuple[dir].out.hw_ifindex = dev->ifindex;
|
+ const struct dst_entry *dst_cache,
|
||||||
+ route->tuple[!dir].in.ifindex = dev->ifindex;
|
+ const struct nf_conn *ct,
|
||||||
+}
|
+ enum ip_conntrack_dir dir, u8 *ha,
|
||||||
+
|
+ struct net_device_path_stack *stack)
|
||||||
+static int
|
|
||||||
+xt_flowoffload_route_dir(struct nf_flow_route *route, const struct nf_conn *ct,
|
|
||||||
+ enum ip_conntrack_dir dir,
|
|
||||||
+ const struct xt_action_param *par, int ifindex)
|
|
||||||
+{
|
+{
|
||||||
+ struct dst_entry *dst = NULL;
|
+ const void *daddr = &ct->tuplehash[!dir].tuple.src.u3;
|
||||||
+ struct flowi fl;
|
+ struct net_device *dev = dst_cache->dev;
|
||||||
|
+ struct neighbour *n;
|
||||||
|
+ u8 nud_state;
|
||||||
+
|
+
|
||||||
+ memset(&fl, 0, sizeof(fl));
|
+ if (!nf_is_valid_ether_device(dev))
|
||||||
+ switch (xt_family(par)) {
|
+ goto out;
|
||||||
+ case NFPROTO_IPV4:
|
+
|
||||||
+ fl.u.ip4.daddr = ct->tuplehash[!dir].tuple.src.u3.ip;
|
+ n = dst_neigh_lookup(dst_cache, daddr);
|
||||||
+ fl.u.ip4.flowi4_oif = ifindex;
|
+ if (!n)
|
||||||
+ break;
|
+ return -1;
|
||||||
+ case NFPROTO_IPV6:
|
+
|
||||||
+ fl.u.ip6.saddr = ct->tuplehash[!dir].tuple.dst.u3.in6;
|
+ read_lock_bh(&n->lock);
|
||||||
+ fl.u.ip6.daddr = ct->tuplehash[!dir].tuple.src.u3.in6;
|
+ nud_state = n->nud_state;
|
||||||
+ fl.u.ip6.flowi6_oif = ifindex;
|
+ ether_addr_copy(ha, n->ha);
|
||||||
+ break;
|
+ read_unlock_bh(&n->lock);
|
||||||
|
+ neigh_release(n);
|
||||||
|
+
|
||||||
|
+ if (!(nud_state & NUD_VALID))
|
||||||
|
+ return -1;
|
||||||
|
+
|
||||||
|
+out:
|
||||||
|
+ return dev_fill_forward_path(dev, ha, stack);
|
||||||
+}
|
+}
|
||||||
+
|
+
|
||||||
+ nf_route(xt_net(par), &dst, &fl, false, xt_family(par));
|
+static void nf_dev_forward_path(struct nf_flow_route *route,
|
||||||
+ if (!dst)
|
+ const struct nf_conn *ct,
|
||||||
+ return -ENOENT;
|
+ enum ip_conntrack_dir dir,
|
||||||
|
+ struct net_device **devs)
|
||||||
|
+{
|
||||||
|
+ const struct dst_entry *dst = route->tuple[dir].dst;
|
||||||
|
+ struct net_device_path_stack stack;
|
||||||
|
+ struct nf_forward_info info = {};
|
||||||
|
+ unsigned char ha[ETH_ALEN];
|
||||||
|
+ int i;
|
||||||
+
|
+
|
||||||
+ route->tuple[dir].dst = dst;
|
+ if (nf_dev_fill_forward_path(route, dst, ct, dir, ha, &stack) >= 0)
|
||||||
+ if (dst_xfrm(dst))
|
+ nf_dev_path_info(&stack, &info, ha);
|
||||||
+ route->tuple[dir].xmit_type = FLOW_OFFLOAD_XMIT_XFRM;
|
|
||||||
+ else
|
|
||||||
+ route->tuple[dir].xmit_type = FLOW_OFFLOAD_XMIT_NEIGH;
|
|
||||||
+
|
+
|
||||||
+ return 0;
|
+ devs[!dir] = (struct net_device *)info.indev;
|
||||||
|
+ if (!info.indev)
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ route->tuple[!dir].in.ifindex = info.indev->ifindex;
|
||||||
|
+ for (i = 0; i < info.num_encaps; i++) {
|
||||||
|
+ route->tuple[!dir].in.encap[i].id = info.encap[i].id;
|
||||||
|
+ route->tuple[!dir].in.encap[i].proto = info.encap[i].proto;
|
||||||
|
+ }
|
||||||
|
+ route->tuple[!dir].in.num_encaps = info.num_encaps;
|
||||||
|
+ route->tuple[!dir].in.ingress_vlans = info.ingress_vlans;
|
||||||
|
+
|
||||||
|
+ if (info.xmit_type == FLOW_OFFLOAD_XMIT_DIRECT) {
|
||||||
|
+ memcpy(route->tuple[dir].out.h_source, info.h_source, ETH_ALEN);
|
||||||
|
+ memcpy(route->tuple[dir].out.h_dest, info.h_dest, ETH_ALEN);
|
||||||
|
+ route->tuple[dir].out.ifindex = info.outdev->ifindex;
|
||||||
|
+ route->tuple[dir].out.hw_ifindex = info.hw_outdev->ifindex;
|
||||||
|
+ route->tuple[dir].xmit_type = info.xmit_type;
|
||||||
|
+ }
|
||||||
+}
|
+}
|
||||||
+
|
+
|
||||||
+static int
|
+static int
|
||||||
+xt_flowoffload_route(struct sk_buff *skb, const struct nf_conn *ct,
|
+xt_flowoffload_route(struct sk_buff *skb, const struct nf_conn *ct,
|
||||||
+ const struct xt_action_param *par,
|
+ const struct xt_action_param *par,
|
||||||
+ struct nf_flow_route *route, enum ip_conntrack_dir dir,
|
+ struct nf_flow_route *route, enum ip_conntrack_dir dir,
|
||||||
+ struct net_device **dev)
|
+ struct net_device **devs)
|
||||||
+{
|
+{
|
||||||
+ int ret;
|
+ struct dst_entry *this_dst = skb_dst(skb);
|
||||||
|
+ struct dst_entry *other_dst = NULL;
|
||||||
|
+ struct flowi fl;
|
||||||
+
|
+
|
||||||
+ ret = xt_flowoffload_route_dir(route, ct, dir, par,
|
+ memset(&fl, 0, sizeof(fl));
|
||||||
+ dev[dir]->ifindex);
|
+ switch (xt_family(par)) {
|
||||||
+ if (ret)
|
+ case NFPROTO_IPV4:
|
||||||
+ return ret;
|
+ fl.u.ip4.daddr = ct->tuplehash[dir].tuple.src.u3.ip;
|
||||||
|
+ fl.u.ip4.flowi4_oif = xt_in(par)->ifindex;
|
||||||
|
+ break;
|
||||||
|
+ case NFPROTO_IPV6:
|
||||||
|
+ fl.u.ip6.saddr = ct->tuplehash[!dir].tuple.dst.u3.in6;
|
||||||
|
+ fl.u.ip6.daddr = ct->tuplehash[dir].tuple.src.u3.in6;
|
||||||
|
+ fl.u.ip6.flowi6_oif = xt_in(par)->ifindex;
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
+
|
+
|
||||||
+ ret = xt_flowoffload_route_dir(route, ct, !dir, par,
|
+ nf_route(xt_net(par), &other_dst, &fl, false, xt_family(par));
|
||||||
+ dev[!dir]->ifindex);
|
+ if (!other_dst)
|
||||||
+ if (ret)
|
+ return -ENOENT;
|
||||||
+ return ret;
|
|
||||||
+
|
+
|
||||||
+ xt_flowoffload_route_check_path(route, ct, dir, &dev[!dir]);
|
+ nf_default_forward_path(route, this_dst, dir, devs);
|
||||||
+ xt_flowoffload_route_check_path(route, ct, !dir, &dev[dir]);
|
+ nf_default_forward_path(route, other_dst, !dir, devs);
|
||||||
|
+
|
||||||
|
+ if (route->tuple[dir].xmit_type == FLOW_OFFLOAD_XMIT_NEIGH &&
|
||||||
|
+ route->tuple[!dir].xmit_type == FLOW_OFFLOAD_XMIT_NEIGH) {
|
||||||
|
+ nf_dev_forward_path(route, ct, dir, devs);
|
||||||
|
+ nf_dev_forward_path(route, ct, !dir, devs);
|
||||||
|
+ }
|
||||||
+
|
+
|
||||||
+ return 0;
|
+ return 0;
|
||||||
+}
|
+}
|
||||||
@ -542,7 +595,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
|||||||
+ }
|
+ }
|
||||||
+
|
+
|
||||||
+ if (nf_ct_ext_exist(ct, NF_CT_EXT_HELPER) ||
|
+ if (nf_ct_ext_exist(ct, NF_CT_EXT_HELPER) ||
|
||||||
+ ct->status & IPS_SEQ_ADJUST)
|
+ ct->status & (IPS_SEQ_ADJUST | IPS_NAT_CLASH))
|
||||||
+ return XT_CONTINUE;
|
+ return XT_CONTINUE;
|
||||||
+
|
+
|
||||||
+ if (!nf_ct_is_confirmed(ct))
|
+ if (!nf_ct_is_confirmed(ct))
|
||||||
@ -586,7 +639,6 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
|||||||
+ xt_flowoffload_check_device(table, devs[0]);
|
+ xt_flowoffload_check_device(table, devs[0]);
|
||||||
+ xt_flowoffload_check_device(table, devs[1]);
|
+ xt_flowoffload_check_device(table, devs[1]);
|
||||||
+
|
+
|
||||||
+ dst_release(route.tuple[dir].dst);
|
|
||||||
+ dst_release(route.tuple[!dir].dst);
|
+ dst_release(route.tuple[!dir].dst);
|
||||||
+
|
+
|
||||||
+ return XT_CONTINUE;
|
+ return XT_CONTINUE;
|
||||||
@ -594,7 +646,6 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
|||||||
+err_flow_add:
|
+err_flow_add:
|
||||||
+ flow_offload_free(flow);
|
+ flow_offload_free(flow);
|
||||||
+err_flow_alloc:
|
+err_flow_alloc:
|
||||||
+ dst_release(route.tuple[dir].dst);
|
|
||||||
+ dst_release(route.tuple[!dir].dst);
|
+ dst_release(route.tuple[!dir].dst);
|
||||||
+err_flow_route:
|
+err_flow_route:
|
||||||
+ clear_bit(IPS_OFFLOAD_BIT, &ct->status);
|
+ clear_bit(IPS_OFFLOAD_BIT, &ct->status);
|
||||||
@ -661,20 +712,6 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
|||||||
+ .notifier_call = flow_offload_netdev_event,
|
+ .notifier_call = flow_offload_netdev_event,
|
||||||
+};
|
+};
|
||||||
+
|
+
|
||||||
+static unsigned int
|
|
||||||
+nf_flow_offload_inet_hook(void *priv, struct sk_buff *skb,
|
|
||||||
+ const struct nf_hook_state *state)
|
|
||||||
+{
|
|
||||||
+ switch (skb->protocol) {
|
|
||||||
+ case htons(ETH_P_IP):
|
|
||||||
+ return nf_flow_offload_ip_hook(priv, skb, state);
|
|
||||||
+ case htons(ETH_P_IPV6):
|
|
||||||
+ return nf_flow_offload_ipv6_hook(priv, skb, state);
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ return NF_ACCEPT;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static int nf_flow_rule_route_inet(struct net *net,
|
+static int nf_flow_rule_route_inet(struct net *net,
|
||||||
+ const struct flow_offload *flow,
|
+ const struct flow_offload *flow,
|
||||||
+ enum flow_offload_tuple_dir dir,
|
+ enum flow_offload_tuple_dir dir,
|
||||||
@ -704,7 +741,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
|||||||
+ .setup = nf_flow_table_offload_setup,
|
+ .setup = nf_flow_table_offload_setup,
|
||||||
+ .action = nf_flow_rule_route_inet,
|
+ .action = nf_flow_rule_route_inet,
|
||||||
+ .free = nf_flow_table_free,
|
+ .free = nf_flow_table_free,
|
||||||
+ .hook = nf_flow_offload_inet_hook,
|
+ .hook = xt_flowoffload_net_hook,
|
||||||
+ .owner = THIS_MODULE,
|
+ .owner = THIS_MODULE,
|
||||||
+};
|
+};
|
||||||
+
|
+
|
||||||
@ -766,7 +803,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
|||||||
#include <net/netfilter/nf_flow_table.h>
|
#include <net/netfilter/nf_flow_table.h>
|
||||||
#include <net/netfilter/nf_conntrack.h>
|
#include <net/netfilter/nf_conntrack.h>
|
||||||
#include <net/netfilter/nf_conntrack_core.h>
|
#include <net/netfilter/nf_conntrack_core.h>
|
||||||
@@ -397,8 +396,7 @@ flow_offload_lookup(struct nf_flowtable
|
@@ -399,8 +398,7 @@ flow_offload_lookup(struct nf_flowtable
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(flow_offload_lookup);
|
EXPORT_SYMBOL_GPL(flow_offload_lookup);
|
||||||
|
|
||||||
@ -776,7 +813,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
|||||||
void (*iter)(struct flow_offload *flow, void *data),
|
void (*iter)(struct flow_offload *flow, void *data),
|
||||||
void *data)
|
void *data)
|
||||||
{
|
{
|
||||||
@@ -430,6 +428,7 @@ nf_flow_table_iterate(struct nf_flowtabl
|
@@ -432,6 +430,7 @@ nf_flow_table_iterate(struct nf_flowtabl
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
|
|
||||||
#define QUECTEL_VENDOR_ID 0x2c7c
|
#define QUECTEL_VENDOR_ID 0x2c7c
|
||||||
/* These Quectel products use Quectel's vendor ID */
|
/* These Quectel products use Quectel's vendor ID */
|
||||||
@@ -1127,6 +1129,11 @@ static const struct usb_device_id option
|
@@ -1129,6 +1131,11 @@ static const struct usb_device_id option
|
||||||
{ USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EG95, 0xff, 0, 0) },
|
{ USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EG95, 0xff, 0, 0) },
|
||||||
{ USB_DEVICE(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_BG96),
|
{ USB_DEVICE(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_BG96),
|
||||||
.driver_info = RSVD(4) },
|
.driver_info = RSVD(4) },
|
||||||
|
@ -0,0 +1,27 @@
|
|||||||
|
From: Felix Fietkau <nbd@nbd.name>
|
||||||
|
Date: Fri, 6 May 2022 12:37:23 +0200
|
||||||
|
Subject: [PATCH] netfilter: flowtable: fix excessive hw offload attempts
|
||||||
|
after failure
|
||||||
|
|
||||||
|
If a flow cannot be offloaded, the code currently repeatedly tries again as
|
||||||
|
quickly as possible, which can significantly increase system load.
|
||||||
|
Fix this by limiting flow timeout update and hardware offload retry to once
|
||||||
|
per second.
|
||||||
|
|
||||||
|
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||||
|
---
|
||||||
|
|
||||||
|
--- a/net/netfilter/nf_flow_table_core.c
|
||||||
|
+++ b/net/netfilter/nf_flow_table_core.c
|
||||||
|
@@ -331,8 +331,10 @@ void flow_offload_refresh(struct nf_flow
|
||||||
|
u32 timeout;
|
||||||
|
|
||||||
|
timeout = nf_flowtable_time_stamp + flow_offload_get_timeout(flow);
|
||||||
|
- if (READ_ONCE(flow->timeout) != timeout)
|
||||||
|
+ if (timeout - READ_ONCE(flow->timeout) > HZ)
|
||||||
|
WRITE_ONCE(flow->timeout, timeout);
|
||||||
|
+ else
|
||||||
|
+ return;
|
||||||
|
|
||||||
|
if (likely(!nf_flowtable_hw_offload(flow_table)))
|
||||||
|
return;
|
@ -0,0 +1,64 @@
|
|||||||
|
From: Felix Fietkau <nbd@nbd.name>
|
||||||
|
Date: Fri, 6 May 2022 12:43:58 +0200
|
||||||
|
Subject: [PATCH] netfilter: nft_flow_offload: skip dst neigh lookup for
|
||||||
|
ppp devices
|
||||||
|
|
||||||
|
The dst entry does not contain a valid hardware address, so skip the lookup
|
||||||
|
in order to avoid running into errors here.
|
||||||
|
The proper hardware address is filled in from nft_dev_path_info
|
||||||
|
|
||||||
|
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||||
|
---
|
||||||
|
|
||||||
|
--- a/net/netfilter/nft_flow_offload.c
|
||||||
|
+++ b/net/netfilter/nft_flow_offload.c
|
||||||
|
@@ -36,6 +36,15 @@ static void nft_default_forward_path(str
|
||||||
|
route->tuple[dir].xmit_type = nft_xmit_type(dst_cache);
|
||||||
|
}
|
||||||
|
|
||||||
|
+static bool nft_is_valid_ether_device(const struct net_device *dev)
|
||||||
|
+{
|
||||||
|
+ if (!dev || (dev->flags & IFF_LOOPBACK) || dev->type != ARPHRD_ETHER ||
|
||||||
|
+ dev->addr_len != ETH_ALEN || !is_valid_ether_addr(dev->dev_addr))
|
||||||
|
+ return false;
|
||||||
|
+
|
||||||
|
+ return true;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static int nft_dev_fill_forward_path(const struct nf_flow_route *route,
|
||||||
|
const struct dst_entry *dst_cache,
|
||||||
|
const struct nf_conn *ct,
|
||||||
|
@@ -47,6 +56,9 @@ static int nft_dev_fill_forward_path(con
|
||||||
|
struct neighbour *n;
|
||||||
|
u8 nud_state;
|
||||||
|
|
||||||
|
+ if (!nft_is_valid_ether_device(dev))
|
||||||
|
+ goto out;
|
||||||
|
+
|
||||||
|
n = dst_neigh_lookup(dst_cache, daddr);
|
||||||
|
if (!n)
|
||||||
|
return -1;
|
||||||
|
@@ -60,6 +72,7 @@ static int nft_dev_fill_forward_path(con
|
||||||
|
if (!(nud_state & NUD_VALID))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
+out:
|
||||||
|
return dev_fill_forward_path(dev, ha, stack);
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -78,15 +91,6 @@ struct nft_forward_info {
|
||||||
|
enum flow_offload_xmit_type xmit_type;
|
||||||
|
};
|
||||||
|
|
||||||
|
-static bool nft_is_valid_ether_device(const struct net_device *dev)
|
||||||
|
-{
|
||||||
|
- if (!dev || (dev->flags & IFF_LOOPBACK) || dev->type != ARPHRD_ETHER ||
|
||||||
|
- dev->addr_len != ETH_ALEN || !is_valid_ether_addr(dev->dev_addr))
|
||||||
|
- return false;
|
||||||
|
-
|
||||||
|
- return true;
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
static void nft_dev_path_info(const struct net_device_path_stack *stack,
|
||||||
|
struct nft_forward_info *info,
|
||||||
|
unsigned char *ha, struct nf_flowtable *flowtable)
|
@ -0,0 +1,66 @@
|
|||||||
|
From: Felix Fietkau <nbd@nbd.name>
|
||||||
|
Date: Fri, 6 May 2022 13:54:44 +0200
|
||||||
|
Subject: [PATCH] net: fix dev_fill_forward_path with pppoe + bridge
|
||||||
|
|
||||||
|
When calling dev_fill_forward_path on a pppoe device, the provided destination
|
||||||
|
address is invalid. In order for the bridge fdb lookup to succeed, the pppoe
|
||||||
|
code needs to update ctx->daddr to the correct value.
|
||||||
|
Fix this by storing the address inside struct net_device_path_ctx
|
||||||
|
|
||||||
|
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||||
|
---
|
||||||
|
|
||||||
|
--- a/drivers/net/ethernet/mediatek/mtk_ppe_offload.c
|
||||||
|
+++ b/drivers/net/ethernet/mediatek/mtk_ppe_offload.c
|
||||||
|
@@ -91,7 +91,6 @@ mtk_flow_get_wdma_info(struct net_device
|
||||||
|
{
|
||||||
|
struct net_device_path_ctx ctx = {
|
||||||
|
.dev = dev,
|
||||||
|
- .daddr = addr,
|
||||||
|
};
|
||||||
|
struct net_device_path path = {};
|
||||||
|
|
||||||
|
@@ -101,6 +100,7 @@ mtk_flow_get_wdma_info(struct net_device
|
||||||
|
if (!dev->netdev_ops->ndo_fill_forward_path)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
+ memcpy(ctx.daddr, addr, sizeof(ctx.daddr));
|
||||||
|
if (dev->netdev_ops->ndo_fill_forward_path(&ctx, &path))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
--- a/drivers/net/ppp/pppoe.c
|
||||||
|
+++ b/drivers/net/ppp/pppoe.c
|
||||||
|
@@ -988,6 +988,7 @@ static int pppoe_fill_forward_path(struc
|
||||||
|
path->encap.proto = htons(ETH_P_PPP_SES);
|
||||||
|
path->encap.id = be16_to_cpu(po->num);
|
||||||
|
memcpy(path->encap.h_dest, po->pppoe_pa.remote, ETH_ALEN);
|
||||||
|
+ memcpy(ctx->daddr, po->pppoe_pa.remote, ETH_ALEN);
|
||||||
|
path->dev = ctx->dev;
|
||||||
|
ctx->dev = dev;
|
||||||
|
|
||||||
|
--- a/include/linux/netdevice.h
|
||||||
|
+++ b/include/linux/netdevice.h
|
||||||
|
@@ -878,7 +878,7 @@ struct net_device_path_stack {
|
||||||
|
|
||||||
|
struct net_device_path_ctx {
|
||||||
|
const struct net_device *dev;
|
||||||
|
- const u8 *daddr;
|
||||||
|
+ u8 daddr[ETH_ALEN];
|
||||||
|
|
||||||
|
int num_vlans;
|
||||||
|
struct {
|
||||||
|
--- a/net/core/dev.c
|
||||||
|
+++ b/net/core/dev.c
|
||||||
|
@@ -863,11 +863,11 @@ int dev_fill_forward_path(const struct n
|
||||||
|
const struct net_device *last_dev;
|
||||||
|
struct net_device_path_ctx ctx = {
|
||||||
|
.dev = dev,
|
||||||
|
- .daddr = daddr,
|
||||||
|
};
|
||||||
|
struct net_device_path *path;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
+ memcpy(ctx.daddr, daddr, sizeof(ctx.daddr));
|
||||||
|
stack->num_paths = 0;
|
||||||
|
while (ctx.dev && ctx.dev->netdev_ops->ndo_fill_forward_path) {
|
||||||
|
last_dev = ctx.dev;
|
@ -0,0 +1,24 @@
|
|||||||
|
From: Felix Fietkau <nbd@nbd.name>
|
||||||
|
Date: Fri, 6 May 2022 15:15:06 +0200
|
||||||
|
Subject: [PATCH] netfilter: nft_flow_offload: fix offload with pppoe +
|
||||||
|
vlan
|
||||||
|
|
||||||
|
When running a combination of PPPoE on top of a VLAN, we need to set
|
||||||
|
info->outdev to the PPPoE device, otherwise PPPoE encap is skipped
|
||||||
|
during software offload.
|
||||||
|
|
||||||
|
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||||
|
---
|
||||||
|
|
||||||
|
--- a/net/netfilter/nft_flow_offload.c
|
||||||
|
+++ b/net/netfilter/nft_flow_offload.c
|
||||||
|
@@ -123,7 +123,8 @@ static void nft_dev_path_info(const stru
|
||||||
|
info->indev = NULL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
- info->outdev = path->dev;
|
||||||
|
+ if (!info->outdev)
|
||||||
|
+ info->outdev = path->dev;
|
||||||
|
info->encap[info->num_encaps].id = path->encap.id;
|
||||||
|
info->encap[info->num_encaps].proto = path->encap.proto;
|
||||||
|
info->num_encaps++;
|
@ -0,0 +1,29 @@
|
|||||||
|
From: Felix Fietkau <nbd@nbd.name>
|
||||||
|
Date: Fri, 6 May 2022 21:38:42 +0200
|
||||||
|
Subject: [PATCH] net: dsa: tag_mtk: add padding for tx packets
|
||||||
|
|
||||||
|
Padding for transmitted packets needs to account for the special tag.
|
||||||
|
With not enough padding, garbage bytes are inserted by the switch at the
|
||||||
|
end of small packets.
|
||||||
|
|
||||||
|
Fixes: 5cd8985a1909 ("net-next: dsa: add Mediatek tag RX/TX handler")
|
||||||
|
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||||
|
---
|
||||||
|
|
||||||
|
--- a/net/dsa/tag_mtk.c
|
||||||
|
+++ b/net/dsa/tag_mtk.c
|
||||||
|
@@ -25,6 +25,14 @@ static struct sk_buff *mtk_tag_xmit(stru
|
||||||
|
u8 xmit_tpid;
|
||||||
|
u8 *mtk_tag;
|
||||||
|
|
||||||
|
+ /* The Ethernet switch we are interfaced with needs packets to be at
|
||||||
|
+ * least 64 bytes (including FCS) otherwise their padding might be
|
||||||
|
+ * corrupted. With tags enabled, we need to make sure that packets are
|
||||||
|
+ * at least 68 bytes (including FCS and tag).
|
||||||
|
+ */
|
||||||
|
+ if (__skb_put_padto(skb, ETH_ZLEN + MTK_HDR_LEN, false))
|
||||||
|
+ return NULL;
|
||||||
|
+
|
||||||
|
/* Build the special tag after the MAC Source Address. If VLAN header
|
||||||
|
* is present, it's required that VLAN header and special tag is
|
||||||
|
* being combined. Only in this way we can allow the switch can parse
|
@ -272,7 +272,7 @@
|
|||||||
obj-$(CONFIG_MTD_BLOCK) += mtdblock.o
|
obj-$(CONFIG_MTD_BLOCK) += mtdblock.o
|
||||||
--- a/include/linux/mtd/mtd.h
|
--- a/include/linux/mtd/mtd.h
|
||||||
+++ b/include/linux/mtd/mtd.h
|
+++ b/include/linux/mtd/mtd.h
|
||||||
@@ -615,6 +615,24 @@ static inline void mtd_align_erase_req(s
|
@@ -613,6 +613,24 @@ static inline void mtd_align_erase_req(s
|
||||||
req->len += mtd->erasesize - mod;
|
req->len += mtd->erasesize - mod;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -297,7 +297,7 @@
|
|||||||
static inline uint32_t mtd_div_by_ws(uint64_t sz, struct mtd_info *mtd)
|
static inline uint32_t mtd_div_by_ws(uint64_t sz, struct mtd_info *mtd)
|
||||||
{
|
{
|
||||||
if (mtd->writesize_shift)
|
if (mtd->writesize_shift)
|
||||||
@@ -687,6 +705,13 @@ extern void __put_mtd_device(struct mtd_
|
@@ -685,6 +703,13 @@ extern void __put_mtd_device(struct mtd_
|
||||||
extern struct mtd_info *get_mtd_device_nm(const char *name);
|
extern struct mtd_info *get_mtd_device_nm(const char *name);
|
||||||
extern void put_mtd_device(struct mtd_info *mtd);
|
extern void put_mtd_device(struct mtd_info *mtd);
|
||||||
|
|
||||||
|
@ -64,7 +64,7 @@ Reviewed-by: Miquel Raynal <miquel.raynal@bootlin.com>
|
|||||||
mutex_lock(&mtd_table_mutex);
|
mutex_lock(&mtd_table_mutex);
|
||||||
--- a/include/linux/mtd/mtd.h
|
--- a/include/linux/mtd/mtd.h
|
||||||
+++ b/include/linux/mtd/mtd.h
|
+++ b/include/linux/mtd/mtd.h
|
||||||
@@ -705,6 +705,8 @@ extern struct mtd_info *get_mtd_device(s
|
@@ -703,6 +703,8 @@ extern struct mtd_info *get_mtd_device(s
|
||||||
extern int __get_mtd_device(struct mtd_info *mtd);
|
extern int __get_mtd_device(struct mtd_info *mtd);
|
||||||
extern void __put_mtd_device(struct mtd_info *mtd);
|
extern void __put_mtd_device(struct mtd_info *mtd);
|
||||||
extern struct mtd_info *get_mtd_device_nm(const char *name);
|
extern struct mtd_info *get_mtd_device_nm(const char *name);
|
||||||
|
@ -87,7 +87,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
|||||||
if (!net_eq(dev_net(dev), sock_net(sk)))
|
if (!net_eq(dev_net(dev), sock_net(sk)))
|
||||||
goto drop;
|
goto drop;
|
||||||
|
|
||||||
@@ -3325,6 +3327,7 @@ static int packet_create(struct net *net
|
@@ -3330,6 +3332,7 @@ static int packet_create(struct net *net
|
||||||
mutex_init(&po->pg_vec_lock);
|
mutex_init(&po->pg_vec_lock);
|
||||||
po->rollover = NULL;
|
po->rollover = NULL;
|
||||||
po->prot_hook.func = packet_rcv;
|
po->prot_hook.func = packet_rcv;
|
||||||
@ -95,7 +95,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
|||||||
|
|
||||||
if (sock->type == SOCK_PACKET)
|
if (sock->type == SOCK_PACKET)
|
||||||
po->prot_hook.func = packet_rcv_spkt;
|
po->prot_hook.func = packet_rcv_spkt;
|
||||||
@@ -3966,6 +3969,16 @@ packet_setsockopt(struct socket *sock, i
|
@@ -3971,6 +3974,16 @@ packet_setsockopt(struct socket *sock, i
|
||||||
po->xmit = val ? packet_direct_xmit : dev_queue_xmit;
|
po->xmit = val ? packet_direct_xmit : dev_queue_xmit;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -112,7 +112,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
|||||||
default:
|
default:
|
||||||
return -ENOPROTOOPT;
|
return -ENOPROTOOPT;
|
||||||
}
|
}
|
||||||
@@ -4022,6 +4035,13 @@ static int packet_getsockopt(struct sock
|
@@ -4027,6 +4040,13 @@ static int packet_getsockopt(struct sock
|
||||||
case PACKET_VNET_HDR:
|
case PACKET_VNET_HDR:
|
||||||
val = po->has_vnet_hdr;
|
val = po->has_vnet_hdr;
|
||||||
break;
|
break;
|
||||||
|
@ -157,7 +157,7 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
|
|||||||
case RTN_THROW:
|
case RTN_THROW:
|
||||||
case RTN_UNREACHABLE:
|
case RTN_UNREACHABLE:
|
||||||
default:
|
default:
|
||||||
@@ -4559,6 +4578,17 @@ static int ip6_pkt_prohibit_out(struct n
|
@@ -4560,6 +4579,17 @@ static int ip6_pkt_prohibit_out(struct n
|
||||||
return ip6_pkt_drop(skb, ICMPV6_ADM_PROHIBITED, IPSTATS_MIB_OUTNOROUTES);
|
return ip6_pkt_drop(skb, ICMPV6_ADM_PROHIBITED, IPSTATS_MIB_OUTNOROUTES);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -175,7 +175,7 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
|
|||||||
/*
|
/*
|
||||||
* Allocate a dst for local (unicast / anycast) address.
|
* Allocate a dst for local (unicast / anycast) address.
|
||||||
*/
|
*/
|
||||||
@@ -5039,7 +5069,8 @@ static int rtm_to_fib6_config(struct sk_
|
@@ -5040,7 +5070,8 @@ static int rtm_to_fib6_config(struct sk_
|
||||||
if (rtm->rtm_type == RTN_UNREACHABLE ||
|
if (rtm->rtm_type == RTN_UNREACHABLE ||
|
||||||
rtm->rtm_type == RTN_BLACKHOLE ||
|
rtm->rtm_type == RTN_BLACKHOLE ||
|
||||||
rtm->rtm_type == RTN_PROHIBIT ||
|
rtm->rtm_type == RTN_PROHIBIT ||
|
||||||
@ -185,7 +185,7 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
|
|||||||
cfg->fc_flags |= RTF_REJECT;
|
cfg->fc_flags |= RTF_REJECT;
|
||||||
|
|
||||||
if (rtm->rtm_type == RTN_LOCAL)
|
if (rtm->rtm_type == RTN_LOCAL)
|
||||||
@@ -6292,6 +6323,8 @@ static int ip6_route_dev_notify(struct n
|
@@ -6293,6 +6324,8 @@ static int ip6_route_dev_notify(struct n
|
||||||
#ifdef CONFIG_IPV6_MULTIPLE_TABLES
|
#ifdef CONFIG_IPV6_MULTIPLE_TABLES
|
||||||
net->ipv6.ip6_prohibit_entry->dst.dev = dev;
|
net->ipv6.ip6_prohibit_entry->dst.dev = dev;
|
||||||
net->ipv6.ip6_prohibit_entry->rt6i_idev = in6_dev_get(dev);
|
net->ipv6.ip6_prohibit_entry->rt6i_idev = in6_dev_get(dev);
|
||||||
@ -194,7 +194,7 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
|
|||||||
net->ipv6.ip6_blk_hole_entry->dst.dev = dev;
|
net->ipv6.ip6_blk_hole_entry->dst.dev = dev;
|
||||||
net->ipv6.ip6_blk_hole_entry->rt6i_idev = in6_dev_get(dev);
|
net->ipv6.ip6_blk_hole_entry->rt6i_idev = in6_dev_get(dev);
|
||||||
#endif
|
#endif
|
||||||
@@ -6303,6 +6336,7 @@ static int ip6_route_dev_notify(struct n
|
@@ -6304,6 +6337,7 @@ static int ip6_route_dev_notify(struct n
|
||||||
in6_dev_put_clear(&net->ipv6.ip6_null_entry->rt6i_idev);
|
in6_dev_put_clear(&net->ipv6.ip6_null_entry->rt6i_idev);
|
||||||
#ifdef CONFIG_IPV6_MULTIPLE_TABLES
|
#ifdef CONFIG_IPV6_MULTIPLE_TABLES
|
||||||
in6_dev_put_clear(&net->ipv6.ip6_prohibit_entry->rt6i_idev);
|
in6_dev_put_clear(&net->ipv6.ip6_prohibit_entry->rt6i_idev);
|
||||||
@ -202,7 +202,7 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
|
|||||||
in6_dev_put_clear(&net->ipv6.ip6_blk_hole_entry->rt6i_idev);
|
in6_dev_put_clear(&net->ipv6.ip6_blk_hole_entry->rt6i_idev);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@@ -6494,6 +6528,8 @@ static int __net_init ip6_route_net_init
|
@@ -6495,6 +6529,8 @@ static int __net_init ip6_route_net_init
|
||||||
|
|
||||||
#ifdef CONFIG_IPV6_MULTIPLE_TABLES
|
#ifdef CONFIG_IPV6_MULTIPLE_TABLES
|
||||||
net->ipv6.fib6_has_custom_rules = false;
|
net->ipv6.fib6_has_custom_rules = false;
|
||||||
@ -211,7 +211,7 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
|
|||||||
net->ipv6.ip6_prohibit_entry = kmemdup(&ip6_prohibit_entry_template,
|
net->ipv6.ip6_prohibit_entry = kmemdup(&ip6_prohibit_entry_template,
|
||||||
sizeof(*net->ipv6.ip6_prohibit_entry),
|
sizeof(*net->ipv6.ip6_prohibit_entry),
|
||||||
GFP_KERNEL);
|
GFP_KERNEL);
|
||||||
@@ -6504,11 +6540,21 @@ static int __net_init ip6_route_net_init
|
@@ -6505,11 +6541,21 @@ static int __net_init ip6_route_net_init
|
||||||
ip6_template_metrics, true);
|
ip6_template_metrics, true);
|
||||||
INIT_LIST_HEAD(&net->ipv6.ip6_prohibit_entry->rt6i_uncached);
|
INIT_LIST_HEAD(&net->ipv6.ip6_prohibit_entry->rt6i_uncached);
|
||||||
|
|
||||||
@ -234,7 +234,7 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
|
|||||||
net->ipv6.ip6_blk_hole_entry->dst.ops = &net->ipv6.ip6_dst_ops;
|
net->ipv6.ip6_blk_hole_entry->dst.ops = &net->ipv6.ip6_dst_ops;
|
||||||
dst_init_metrics(&net->ipv6.ip6_blk_hole_entry->dst,
|
dst_init_metrics(&net->ipv6.ip6_blk_hole_entry->dst,
|
||||||
ip6_template_metrics, true);
|
ip6_template_metrics, true);
|
||||||
@@ -6535,6 +6581,8 @@ out:
|
@@ -6536,6 +6582,8 @@ out:
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
#ifdef CONFIG_IPV6_MULTIPLE_TABLES
|
#ifdef CONFIG_IPV6_MULTIPLE_TABLES
|
||||||
@ -243,7 +243,7 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
|
|||||||
out_ip6_prohibit_entry:
|
out_ip6_prohibit_entry:
|
||||||
kfree(net->ipv6.ip6_prohibit_entry);
|
kfree(net->ipv6.ip6_prohibit_entry);
|
||||||
out_ip6_null_entry:
|
out_ip6_null_entry:
|
||||||
@@ -6554,6 +6602,7 @@ static void __net_exit ip6_route_net_exi
|
@@ -6555,6 +6603,7 @@ static void __net_exit ip6_route_net_exi
|
||||||
kfree(net->ipv6.ip6_null_entry);
|
kfree(net->ipv6.ip6_null_entry);
|
||||||
#ifdef CONFIG_IPV6_MULTIPLE_TABLES
|
#ifdef CONFIG_IPV6_MULTIPLE_TABLES
|
||||||
kfree(net->ipv6.ip6_prohibit_entry);
|
kfree(net->ipv6.ip6_prohibit_entry);
|
||||||
@ -251,7 +251,7 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
|
|||||||
kfree(net->ipv6.ip6_blk_hole_entry);
|
kfree(net->ipv6.ip6_blk_hole_entry);
|
||||||
#endif
|
#endif
|
||||||
dst_entries_destroy(&net->ipv6.ip6_dst_ops);
|
dst_entries_destroy(&net->ipv6.ip6_dst_ops);
|
||||||
@@ -6631,6 +6680,9 @@ void __init ip6_route_init_special_entri
|
@@ -6632,6 +6681,9 @@ void __init ip6_route_init_special_entri
|
||||||
init_net.ipv6.ip6_prohibit_entry->rt6i_idev = in6_dev_get(init_net.loopback_dev);
|
init_net.ipv6.ip6_prohibit_entry->rt6i_idev = in6_dev_get(init_net.loopback_dev);
|
||||||
init_net.ipv6.ip6_blk_hole_entry->dst.dev = init_net.loopback_dev;
|
init_net.ipv6.ip6_blk_hole_entry->dst.dev = init_net.loopback_dev;
|
||||||
init_net.ipv6.ip6_blk_hole_entry->rt6i_idev = in6_dev_get(init_net.loopback_dev);
|
init_net.ipv6.ip6_blk_hole_entry->rt6i_idev = in6_dev_get(init_net.loopback_dev);
|
||||||
|
@ -0,0 +1,27 @@
|
|||||||
|
From: Felix Fietkau <nbd@nbd.name>
|
||||||
|
Date: Fri, 6 May 2022 12:37:23 +0200
|
||||||
|
Subject: [PATCH] netfilter: flowtable: fix excessive hw offload attempts
|
||||||
|
after failure
|
||||||
|
|
||||||
|
If a flow cannot be offloaded, the code currently repeatedly tries again as
|
||||||
|
quickly as possible, which can significantly increase system load.
|
||||||
|
Fix this by limiting flow timeout update and hardware offload retry to once
|
||||||
|
per second.
|
||||||
|
|
||||||
|
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||||
|
---
|
||||||
|
|
||||||
|
--- a/net/netfilter/nf_flow_table_core.c
|
||||||
|
+++ b/net/netfilter/nf_flow_table_core.c
|
||||||
|
@@ -329,8 +329,10 @@ void flow_offload_refresh(struct nf_flow
|
||||||
|
u32 timeout;
|
||||||
|
|
||||||
|
timeout = nf_flowtable_time_stamp + flow_offload_get_timeout(flow);
|
||||||
|
- if (READ_ONCE(flow->timeout) != timeout)
|
||||||
|
+ if (timeout - READ_ONCE(flow->timeout) > HZ)
|
||||||
|
WRITE_ONCE(flow->timeout, timeout);
|
||||||
|
+ else
|
||||||
|
+ return;
|
||||||
|
|
||||||
|
if (likely(!nf_flowtable_hw_offload(flow_table)))
|
||||||
|
return;
|
@ -0,0 +1,64 @@
|
|||||||
|
From: Felix Fietkau <nbd@nbd.name>
|
||||||
|
Date: Fri, 6 May 2022 12:43:58 +0200
|
||||||
|
Subject: [PATCH] netfilter: nft_flow_offload: skip dst neigh lookup for
|
||||||
|
ppp devices
|
||||||
|
|
||||||
|
The dst entry does not contain a valid hardware address, so skip the lookup
|
||||||
|
in order to avoid running into errors here.
|
||||||
|
The proper hardware address is filled in from nft_dev_path_info
|
||||||
|
|
||||||
|
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||||
|
---
|
||||||
|
|
||||||
|
--- a/net/netfilter/nft_flow_offload.c
|
||||||
|
+++ b/net/netfilter/nft_flow_offload.c
|
||||||
|
@@ -36,6 +36,15 @@ static void nft_default_forward_path(str
|
||||||
|
route->tuple[dir].xmit_type = nft_xmit_type(dst_cache);
|
||||||
|
}
|
||||||
|
|
||||||
|
+static bool nft_is_valid_ether_device(const struct net_device *dev)
|
||||||
|
+{
|
||||||
|
+ if (!dev || (dev->flags & IFF_LOOPBACK) || dev->type != ARPHRD_ETHER ||
|
||||||
|
+ dev->addr_len != ETH_ALEN || !is_valid_ether_addr(dev->dev_addr))
|
||||||
|
+ return false;
|
||||||
|
+
|
||||||
|
+ return true;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static int nft_dev_fill_forward_path(const struct nf_flow_route *route,
|
||||||
|
const struct dst_entry *dst_cache,
|
||||||
|
const struct nf_conn *ct,
|
||||||
|
@@ -47,6 +56,9 @@ static int nft_dev_fill_forward_path(con
|
||||||
|
struct neighbour *n;
|
||||||
|
u8 nud_state;
|
||||||
|
|
||||||
|
+ if (!nft_is_valid_ether_device(dev))
|
||||||
|
+ goto out;
|
||||||
|
+
|
||||||
|
n = dst_neigh_lookup(dst_cache, daddr);
|
||||||
|
if (!n)
|
||||||
|
return -1;
|
||||||
|
@@ -60,6 +72,7 @@ static int nft_dev_fill_forward_path(con
|
||||||
|
if (!(nud_state & NUD_VALID))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
+out:
|
||||||
|
return dev_fill_forward_path(dev, ha, stack);
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -78,15 +91,6 @@ struct nft_forward_info {
|
||||||
|
enum flow_offload_xmit_type xmit_type;
|
||||||
|
};
|
||||||
|
|
||||||
|
-static bool nft_is_valid_ether_device(const struct net_device *dev)
|
||||||
|
-{
|
||||||
|
- if (!dev || (dev->flags & IFF_LOOPBACK) || dev->type != ARPHRD_ETHER ||
|
||||||
|
- dev->addr_len != ETH_ALEN || !is_valid_ether_addr(dev->dev_addr))
|
||||||
|
- return false;
|
||||||
|
-
|
||||||
|
- return true;
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
static void nft_dev_path_info(const struct net_device_path_stack *stack,
|
||||||
|
struct nft_forward_info *info,
|
||||||
|
unsigned char *ha, struct nf_flowtable *flowtable)
|
@ -0,0 +1,66 @@
|
|||||||
|
From: Felix Fietkau <nbd@nbd.name>
|
||||||
|
Date: Fri, 6 May 2022 13:54:44 +0200
|
||||||
|
Subject: [PATCH] net: fix dev_fill_forward_path with pppoe + bridge
|
||||||
|
|
||||||
|
When calling dev_fill_forward_path on a pppoe device, the provided destination
|
||||||
|
address is invalid. In order for the bridge fdb lookup to succeed, the pppoe
|
||||||
|
code needs to update ctx->daddr to the correct value.
|
||||||
|
Fix this by storing the address inside struct net_device_path_ctx
|
||||||
|
|
||||||
|
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||||
|
---
|
||||||
|
|
||||||
|
--- a/drivers/net/ethernet/mediatek/mtk_ppe_offload.c
|
||||||
|
+++ b/drivers/net/ethernet/mediatek/mtk_ppe_offload.c
|
||||||
|
@@ -90,7 +90,6 @@ mtk_flow_get_wdma_info(struct net_device
|
||||||
|
{
|
||||||
|
struct net_device_path_ctx ctx = {
|
||||||
|
.dev = dev,
|
||||||
|
- .daddr = addr,
|
||||||
|
};
|
||||||
|
struct net_device_path path = {};
|
||||||
|
|
||||||
|
@@ -100,6 +99,7 @@ mtk_flow_get_wdma_info(struct net_device
|
||||||
|
if (!dev->netdev_ops->ndo_fill_forward_path)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
+ memcpy(ctx.daddr, addr, sizeof(ctx.daddr));
|
||||||
|
if (dev->netdev_ops->ndo_fill_forward_path(&ctx, &path))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
--- a/drivers/net/ppp/pppoe.c
|
||||||
|
+++ b/drivers/net/ppp/pppoe.c
|
||||||
|
@@ -988,6 +988,7 @@ static int pppoe_fill_forward_path(struc
|
||||||
|
path->encap.proto = htons(ETH_P_PPP_SES);
|
||||||
|
path->encap.id = be16_to_cpu(po->num);
|
||||||
|
memcpy(path->encap.h_dest, po->pppoe_pa.remote, ETH_ALEN);
|
||||||
|
+ memcpy(ctx->daddr, po->pppoe_pa.remote, ETH_ALEN);
|
||||||
|
path->dev = ctx->dev;
|
||||||
|
ctx->dev = dev;
|
||||||
|
|
||||||
|
--- a/include/linux/netdevice.h
|
||||||
|
+++ b/include/linux/netdevice.h
|
||||||
|
@@ -894,7 +894,7 @@ struct net_device_path_stack {
|
||||||
|
|
||||||
|
struct net_device_path_ctx {
|
||||||
|
const struct net_device *dev;
|
||||||
|
- const u8 *daddr;
|
||||||
|
+ u8 daddr[ETH_ALEN];
|
||||||
|
|
||||||
|
int num_vlans;
|
||||||
|
struct {
|
||||||
|
--- a/net/core/dev.c
|
||||||
|
+++ b/net/core/dev.c
|
||||||
|
@@ -741,11 +741,11 @@ int dev_fill_forward_path(const struct n
|
||||||
|
const struct net_device *last_dev;
|
||||||
|
struct net_device_path_ctx ctx = {
|
||||||
|
.dev = dev,
|
||||||
|
- .daddr = daddr,
|
||||||
|
};
|
||||||
|
struct net_device_path *path;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
+ memcpy(ctx.daddr, daddr, sizeof(ctx.daddr));
|
||||||
|
stack->num_paths = 0;
|
||||||
|
while (ctx.dev && ctx.dev->netdev_ops->ndo_fill_forward_path) {
|
||||||
|
last_dev = ctx.dev;
|
@ -0,0 +1,24 @@
|
|||||||
|
From: Felix Fietkau <nbd@nbd.name>
|
||||||
|
Date: Fri, 6 May 2022 15:15:06 +0200
|
||||||
|
Subject: [PATCH] netfilter: nft_flow_offload: fix offload with pppoe +
|
||||||
|
vlan
|
||||||
|
|
||||||
|
When running a combination of PPPoE on top of a VLAN, we need to set
|
||||||
|
info->outdev to the PPPoE device, otherwise PPPoE encap is skipped
|
||||||
|
during software offload.
|
||||||
|
|
||||||
|
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||||
|
---
|
||||||
|
|
||||||
|
--- a/net/netfilter/nft_flow_offload.c
|
||||||
|
+++ b/net/netfilter/nft_flow_offload.c
|
||||||
|
@@ -123,7 +123,8 @@ static void nft_dev_path_info(const stru
|
||||||
|
info->indev = NULL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
- info->outdev = path->dev;
|
||||||
|
+ if (!info->outdev)
|
||||||
|
+ info->outdev = path->dev;
|
||||||
|
info->encap[info->num_encaps].id = path->encap.id;
|
||||||
|
info->encap[info->num_encaps].proto = path->encap.proto;
|
||||||
|
info->num_encaps++;
|
@ -0,0 +1,29 @@
|
|||||||
|
From: Felix Fietkau <nbd@nbd.name>
|
||||||
|
Date: Fri, 6 May 2022 21:38:42 +0200
|
||||||
|
Subject: [PATCH] net: dsa: tag_mtk: add padding for tx packets
|
||||||
|
|
||||||
|
Padding for transmitted packets needs to account for the special tag.
|
||||||
|
With not enough padding, garbage bytes are inserted by the switch at the
|
||||||
|
end of small packets.
|
||||||
|
|
||||||
|
Fixes: 5cd8985a1909 ("net-next: dsa: add Mediatek tag RX/TX handler")
|
||||||
|
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||||
|
---
|
||||||
|
|
||||||
|
--- a/net/dsa/tag_mtk.c
|
||||||
|
+++ b/net/dsa/tag_mtk.c
|
||||||
|
@@ -25,6 +25,14 @@ static struct sk_buff *mtk_tag_xmit(stru
|
||||||
|
u8 xmit_tpid;
|
||||||
|
u8 *mtk_tag;
|
||||||
|
|
||||||
|
+ /* The Ethernet switch we are interfaced with needs packets to be at
|
||||||
|
+ * least 64 bytes (including FCS) otherwise their padding might be
|
||||||
|
+ * corrupted. With tags enabled, we need to make sure that packets are
|
||||||
|
+ * at least 68 bytes (including FCS and tag).
|
||||||
|
+ */
|
||||||
|
+ if (__skb_put_padto(skb, ETH_ZLEN + MTK_HDR_LEN, false))
|
||||||
|
+ return NULL;
|
||||||
|
+
|
||||||
|
/* Build the special tag after the MAC Source Address. If VLAN header
|
||||||
|
* is present, it's required that VLAN header and special tag is
|
||||||
|
* being combined. Only in this way we can allow the switch can parse
|
File diff suppressed because it is too large
Load Diff
@ -1,342 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2016, The Linux Foundation. All rights reserved.
|
|
||||||
*
|
|
||||||
* Permission to use, copy, modify, and/or distribute this software for
|
|
||||||
* any purpose with or without fee is hereby granted, provided that the
|
|
||||||
* above copyright notice and this permission notice appear in all copies.
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
||||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
||||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
||||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
|
|
||||||
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __AR40XX_H
|
|
||||||
#define __AR40XX_H
|
|
||||||
|
|
||||||
#define AR40XX_MAX_VLANS 128
|
|
||||||
#define AR40XX_NUM_PORTS 6
|
|
||||||
#define AR40XX_NUM_PHYS 5
|
|
||||||
|
|
||||||
#define BITS(_s, _n) (((1UL << (_n)) - 1) << _s)
|
|
||||||
|
|
||||||
struct ar40xx_priv {
|
|
||||||
struct switch_dev dev;
|
|
||||||
|
|
||||||
u8 __iomem *hw_addr;
|
|
||||||
u8 __iomem *psgmii_hw_addr;
|
|
||||||
u32 mac_mode;
|
|
||||||
struct reset_control *ess_rst;
|
|
||||||
u32 cpu_bmp;
|
|
||||||
u32 lan_bmp;
|
|
||||||
u32 wan_bmp;
|
|
||||||
|
|
||||||
struct mii_bus *mii_bus;
|
|
||||||
struct phy_device *phy;
|
|
||||||
|
|
||||||
/* mutex for qm task */
|
|
||||||
struct mutex qm_lock;
|
|
||||||
struct delayed_work qm_dwork;
|
|
||||||
u32 port_link_up[AR40XX_NUM_PORTS];
|
|
||||||
u32 ar40xx_port_old_link[AR40XX_NUM_PORTS];
|
|
||||||
u32 ar40xx_port_qm_buf[AR40XX_NUM_PORTS];
|
|
||||||
|
|
||||||
u32 phy_t_status;
|
|
||||||
|
|
||||||
/* mutex for switch reg access */
|
|
||||||
struct mutex reg_mutex;
|
|
||||||
|
|
||||||
/* mutex for mib task */
|
|
||||||
struct mutex mib_lock;
|
|
||||||
struct delayed_work mib_work;
|
|
||||||
int mib_next_port;
|
|
||||||
u64 *mib_stats;
|
|
||||||
|
|
||||||
char buf[2048];
|
|
||||||
|
|
||||||
/* all fields below will be cleared on reset */
|
|
||||||
bool vlan;
|
|
||||||
u16 vlan_id[AR40XX_MAX_VLANS];
|
|
||||||
u8 vlan_table[AR40XX_MAX_VLANS];
|
|
||||||
u8 vlan_tagged;
|
|
||||||
u16 pvid[AR40XX_NUM_PORTS];
|
|
||||||
|
|
||||||
/* mirror */
|
|
||||||
bool mirror_rx;
|
|
||||||
bool mirror_tx;
|
|
||||||
int source_port;
|
|
||||||
int monitor_port;
|
|
||||||
};
|
|
||||||
|
|
||||||
#define AR40XX_PORT_LINK_UP 1
|
|
||||||
#define AR40XX_PORT_LINK_DOWN 0
|
|
||||||
#define AR40XX_QM_NOT_EMPTY 1
|
|
||||||
#define AR40XX_QM_EMPTY 0
|
|
||||||
|
|
||||||
#define AR40XX_LAN_VLAN 1
|
|
||||||
#define AR40XX_WAN_VLAN 2
|
|
||||||
|
|
||||||
enum ar40xx_port_wrapper_cfg {
|
|
||||||
PORT_WRAPPER_PSGMII = 0,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ar40xx_mib_desc {
|
|
||||||
u32 size;
|
|
||||||
u32 offset;
|
|
||||||
const char *name;
|
|
||||||
};
|
|
||||||
|
|
||||||
#define AR40XX_PORT_CPU 0
|
|
||||||
|
|
||||||
#define AR40XX_PSGMII_MODE_CONTROL 0x1b4
|
|
||||||
#define AR40XX_PSGMII_ATHR_CSCO_MODE_25M BIT(0)
|
|
||||||
|
|
||||||
#define AR40XX_PSGMIIPHY_TX_CONTROL 0x288
|
|
||||||
|
|
||||||
#define AR40XX_MII_ATH_MMD_ADDR 0x0d
|
|
||||||
#define AR40XX_MII_ATH_MMD_DATA 0x0e
|
|
||||||
#define AR40XX_MII_ATH_DBG_ADDR 0x1d
|
|
||||||
#define AR40XX_MII_ATH_DBG_DATA 0x1e
|
|
||||||
|
|
||||||
#define AR40XX_STATS_RXBROAD 0x00
|
|
||||||
#define AR40XX_STATS_RXPAUSE 0x04
|
|
||||||
#define AR40XX_STATS_RXMULTI 0x08
|
|
||||||
#define AR40XX_STATS_RXFCSERR 0x0c
|
|
||||||
#define AR40XX_STATS_RXALIGNERR 0x10
|
|
||||||
#define AR40XX_STATS_RXRUNT 0x14
|
|
||||||
#define AR40XX_STATS_RXFRAGMENT 0x18
|
|
||||||
#define AR40XX_STATS_RX64BYTE 0x1c
|
|
||||||
#define AR40XX_STATS_RX128BYTE 0x20
|
|
||||||
#define AR40XX_STATS_RX256BYTE 0x24
|
|
||||||
#define AR40XX_STATS_RX512BYTE 0x28
|
|
||||||
#define AR40XX_STATS_RX1024BYTE 0x2c
|
|
||||||
#define AR40XX_STATS_RX1518BYTE 0x30
|
|
||||||
#define AR40XX_STATS_RXMAXBYTE 0x34
|
|
||||||
#define AR40XX_STATS_RXTOOLONG 0x38
|
|
||||||
#define AR40XX_STATS_RXGOODBYTE 0x3c
|
|
||||||
#define AR40XX_STATS_RXBADBYTE 0x44
|
|
||||||
#define AR40XX_STATS_RXOVERFLOW 0x4c
|
|
||||||
#define AR40XX_STATS_FILTERED 0x50
|
|
||||||
#define AR40XX_STATS_TXBROAD 0x54
|
|
||||||
#define AR40XX_STATS_TXPAUSE 0x58
|
|
||||||
#define AR40XX_STATS_TXMULTI 0x5c
|
|
||||||
#define AR40XX_STATS_TXUNDERRUN 0x60
|
|
||||||
#define AR40XX_STATS_TX64BYTE 0x64
|
|
||||||
#define AR40XX_STATS_TX128BYTE 0x68
|
|
||||||
#define AR40XX_STATS_TX256BYTE 0x6c
|
|
||||||
#define AR40XX_STATS_TX512BYTE 0x70
|
|
||||||
#define AR40XX_STATS_TX1024BYTE 0x74
|
|
||||||
#define AR40XX_STATS_TX1518BYTE 0x78
|
|
||||||
#define AR40XX_STATS_TXMAXBYTE 0x7c
|
|
||||||
#define AR40XX_STATS_TXOVERSIZE 0x80
|
|
||||||
#define AR40XX_STATS_TXBYTE 0x84
|
|
||||||
#define AR40XX_STATS_TXCOLLISION 0x8c
|
|
||||||
#define AR40XX_STATS_TXABORTCOL 0x90
|
|
||||||
#define AR40XX_STATS_TXMULTICOL 0x94
|
|
||||||
#define AR40XX_STATS_TXSINGLECOL 0x98
|
|
||||||
#define AR40XX_STATS_TXEXCDEFER 0x9c
|
|
||||||
#define AR40XX_STATS_TXDEFER 0xa0
|
|
||||||
#define AR40XX_STATS_TXLATECOL 0xa4
|
|
||||||
|
|
||||||
#define AR40XX_REG_MODULE_EN 0x030
|
|
||||||
#define AR40XX_MODULE_EN_MIB BIT(0)
|
|
||||||
|
|
||||||
#define AR40XX_REG_MIB_FUNC 0x034
|
|
||||||
#define AR40XX_MIB_BUSY BIT(17)
|
|
||||||
#define AR40XX_MIB_CPU_KEEP BIT(20)
|
|
||||||
#define AR40XX_MIB_FUNC BITS(24, 3)
|
|
||||||
#define AR40XX_MIB_FUNC_S 24
|
|
||||||
#define AR40XX_MIB_FUNC_NO_OP 0x0
|
|
||||||
#define AR40XX_MIB_FUNC_FLUSH 0x1
|
|
||||||
|
|
||||||
#define AR40XX_ESS_SERVICE_TAG 0x48
|
|
||||||
#define AR40XX_ESS_SERVICE_TAG_STAG BIT(17)
|
|
||||||
|
|
||||||
#define AR40XX_REG_PORT_STATUS(_i) (0x07c + (_i) * 4)
|
|
||||||
#define AR40XX_PORT_SPEED BITS(0, 2)
|
|
||||||
#define AR40XX_PORT_STATUS_SPEED_S 0
|
|
||||||
#define AR40XX_PORT_TX_EN BIT(2)
|
|
||||||
#define AR40XX_PORT_RX_EN BIT(3)
|
|
||||||
#define AR40XX_PORT_STATUS_TXFLOW BIT(4)
|
|
||||||
#define AR40XX_PORT_STATUS_RXFLOW BIT(5)
|
|
||||||
#define AR40XX_PORT_DUPLEX BIT(6)
|
|
||||||
#define AR40XX_PORT_TXHALF_FLOW BIT(7)
|
|
||||||
#define AR40XX_PORT_STATUS_LINK_UP BIT(8)
|
|
||||||
#define AR40XX_PORT_AUTO_LINK_EN BIT(9)
|
|
||||||
#define AR40XX_PORT_STATUS_FLOW_CONTROL BIT(12)
|
|
||||||
|
|
||||||
#define AR40XX_REG_MAX_FRAME_SIZE 0x078
|
|
||||||
#define AR40XX_MAX_FRAME_SIZE_MTU BITS(0, 14)
|
|
||||||
|
|
||||||
#define AR40XX_REG_PORT_HEADER(_i) (0x09c + (_i) * 4)
|
|
||||||
|
|
||||||
#define AR40XX_REG_EEE_CTRL 0x100
|
|
||||||
#define AR40XX_EEE_CTRL_DISABLE_PHY(_i) BIT(4 + (_i) * 2)
|
|
||||||
|
|
||||||
#define AR40XX_REG_PORT_VLAN0(_i) (0x420 + (_i) * 0x8)
|
|
||||||
#define AR40XX_PORT_VLAN0_DEF_SVID BITS(0, 12)
|
|
||||||
#define AR40XX_PORT_VLAN0_DEF_SVID_S 0
|
|
||||||
#define AR40XX_PORT_VLAN0_DEF_CVID BITS(16, 12)
|
|
||||||
#define AR40XX_PORT_VLAN0_DEF_CVID_S 16
|
|
||||||
|
|
||||||
#define AR40XX_REG_PORT_VLAN1(_i) (0x424 + (_i) * 0x8)
|
|
||||||
#define AR40XX_PORT_VLAN1_CORE_PORT BIT(9)
|
|
||||||
#define AR40XX_PORT_VLAN1_PORT_TLS_MODE BIT(7)
|
|
||||||
#define AR40XX_PORT_VLAN1_PORT_VLAN_PROP BIT(6)
|
|
||||||
#define AR40XX_PORT_VLAN1_OUT_MODE BITS(12, 2)
|
|
||||||
#define AR40XX_PORT_VLAN1_OUT_MODE_S 12
|
|
||||||
#define AR40XX_PORT_VLAN1_OUT_MODE_UNMOD 0
|
|
||||||
#define AR40XX_PORT_VLAN1_OUT_MODE_UNTAG 1
|
|
||||||
#define AR40XX_PORT_VLAN1_OUT_MODE_TAG 2
|
|
||||||
#define AR40XX_PORT_VLAN1_OUT_MODE_UNTOUCH 3
|
|
||||||
|
|
||||||
#define AR40XX_REG_VTU_FUNC0 0x0610
|
|
||||||
#define AR40XX_VTU_FUNC0_EG_MODE BITS(4, 14)
|
|
||||||
#define AR40XX_VTU_FUNC0_EG_MODE_S(_i) (4 + (_i) * 2)
|
|
||||||
#define AR40XX_VTU_FUNC0_EG_MODE_KEEP 0
|
|
||||||
#define AR40XX_VTU_FUNC0_EG_MODE_UNTAG 1
|
|
||||||
#define AR40XX_VTU_FUNC0_EG_MODE_TAG 2
|
|
||||||
#define AR40XX_VTU_FUNC0_EG_MODE_NOT 3
|
|
||||||
#define AR40XX_VTU_FUNC0_IVL BIT(19)
|
|
||||||
#define AR40XX_VTU_FUNC0_VALID BIT(20)
|
|
||||||
|
|
||||||
#define AR40XX_REG_VTU_FUNC1 0x0614
|
|
||||||
#define AR40XX_VTU_FUNC1_OP BITS(0, 3)
|
|
||||||
#define AR40XX_VTU_FUNC1_OP_NOOP 0
|
|
||||||
#define AR40XX_VTU_FUNC1_OP_FLUSH 1
|
|
||||||
#define AR40XX_VTU_FUNC1_OP_LOAD 2
|
|
||||||
#define AR40XX_VTU_FUNC1_OP_PURGE 3
|
|
||||||
#define AR40XX_VTU_FUNC1_OP_REMOVE_PORT 4
|
|
||||||
#define AR40XX_VTU_FUNC1_OP_GET_NEXT 5
|
|
||||||
#define AR40XX7_VTU_FUNC1_OP_GET_ONE 6
|
|
||||||
#define AR40XX_VTU_FUNC1_FULL BIT(4)
|
|
||||||
#define AR40XX_VTU_FUNC1_PORT BIT(8, 4)
|
|
||||||
#define AR40XX_VTU_FUNC1_PORT_S 8
|
|
||||||
#define AR40XX_VTU_FUNC1_VID BIT(16, 12)
|
|
||||||
#define AR40XX_VTU_FUNC1_VID_S 16
|
|
||||||
#define AR40XX_VTU_FUNC1_BUSY BIT(31)
|
|
||||||
|
|
||||||
#define AR40XX_REG_FWD_CTRL0 0x620
|
|
||||||
#define AR40XX_FWD_CTRL0_CPU_PORT_EN BIT(10)
|
|
||||||
#define AR40XX_FWD_CTRL0_MIRROR_PORT BITS(4, 4)
|
|
||||||
#define AR40XX_FWD_CTRL0_MIRROR_PORT_S 4
|
|
||||||
|
|
||||||
#define AR40XX_REG_FWD_CTRL1 0x624
|
|
||||||
#define AR40XX_FWD_CTRL1_UC_FLOOD BITS(0, 7)
|
|
||||||
#define AR40XX_FWD_CTRL1_UC_FLOOD_S 0
|
|
||||||
#define AR40XX_FWD_CTRL1_MC_FLOOD BITS(8, 7)
|
|
||||||
#define AR40XX_FWD_CTRL1_MC_FLOOD_S 8
|
|
||||||
#define AR40XX_FWD_CTRL1_BC_FLOOD BITS(16, 7)
|
|
||||||
#define AR40XX_FWD_CTRL1_BC_FLOOD_S 16
|
|
||||||
#define AR40XX_FWD_CTRL1_IGMP BITS(24, 7)
|
|
||||||
#define AR40XX_FWD_CTRL1_IGMP_S 24
|
|
||||||
|
|
||||||
#define AR40XX_REG_PORT_LOOKUP(_i) (0x660 + (_i) * 0xc)
|
|
||||||
#define AR40XX_PORT_LOOKUP_MEMBER BITS(0, 7)
|
|
||||||
#define AR40XX_PORT_LOOKUP_IN_MODE BITS(8, 2)
|
|
||||||
#define AR40XX_PORT_LOOKUP_IN_MODE_S 8
|
|
||||||
#define AR40XX_PORT_LOOKUP_STATE BITS(16, 3)
|
|
||||||
#define AR40XX_PORT_LOOKUP_STATE_S 16
|
|
||||||
#define AR40XX_PORT_LOOKUP_LEARN BIT(20)
|
|
||||||
#define AR40XX_PORT_LOOKUP_LOOPBACK BIT(21)
|
|
||||||
#define AR40XX_PORT_LOOKUP_ING_MIRROR_EN BIT(25)
|
|
||||||
|
|
||||||
#define AR40XX_REG_ATU_FUNC 0x60c
|
|
||||||
#define AR40XX_ATU_FUNC_OP BITS(0, 4)
|
|
||||||
#define AR40XX_ATU_FUNC_OP_NOOP 0x0
|
|
||||||
#define AR40XX_ATU_FUNC_OP_FLUSH 0x1
|
|
||||||
#define AR40XX_ATU_FUNC_OP_LOAD 0x2
|
|
||||||
#define AR40XX_ATU_FUNC_OP_PURGE 0x3
|
|
||||||
#define AR40XX_ATU_FUNC_OP_FLUSH_LOCKED 0x4
|
|
||||||
#define AR40XX_ATU_FUNC_OP_FLUSH_UNICAST 0x5
|
|
||||||
#define AR40XX_ATU_FUNC_OP_GET_NEXT 0x6
|
|
||||||
#define AR40XX_ATU_FUNC_OP_SEARCH_MAC 0x7
|
|
||||||
#define AR40XX_ATU_FUNC_OP_CHANGE_TRUNK 0x8
|
|
||||||
#define AR40XX_ATU_FUNC_BUSY BIT(31)
|
|
||||||
|
|
||||||
#define AR40XX_REG_QM_DEBUG_ADDR 0x820
|
|
||||||
#define AR40XX_REG_QM_DEBUG_VALUE 0x824
|
|
||||||
#define AR40XX_REG_QM_PORT0_3_QNUM 0x1d
|
|
||||||
#define AR40XX_REG_QM_PORT4_6_QNUM 0x1e
|
|
||||||
|
|
||||||
#define AR40XX_REG_PORT_HOL_CTRL1(_i) (0x974 + (_i) * 0x8)
|
|
||||||
#define AR40XX_PORT_HOL_CTRL1_EG_MIRROR_EN BIT(16)
|
|
||||||
|
|
||||||
#define AR40XX_REG_PORT_FLOWCTRL_THRESH(_i) (0x9b0 + (_i) * 0x4)
|
|
||||||
#define AR40XX_PORT0_FC_THRESH_ON_DFLT 0x60
|
|
||||||
#define AR40XX_PORT0_FC_THRESH_OFF_DFLT 0x90
|
|
||||||
|
|
||||||
#define AR40XX_PHY_DEBUG_0 0
|
|
||||||
#define AR40XX_PHY_MANU_CTRL_EN BIT(12)
|
|
||||||
|
|
||||||
#define AR40XX_PHY_DEBUG_2 2
|
|
||||||
|
|
||||||
#define AR40XX_PHY_SPEC_STATUS 0x11
|
|
||||||
#define AR40XX_PHY_SPEC_STATUS_LINK BIT(10)
|
|
||||||
#define AR40XX_PHY_SPEC_STATUS_DUPLEX BIT(13)
|
|
||||||
#define AR40XX_PHY_SPEC_STATUS_SPEED BITS(14, 2)
|
|
||||||
|
|
||||||
/* port forwarding state */
|
|
||||||
enum {
|
|
||||||
AR40XX_PORT_STATE_DISABLED = 0,
|
|
||||||
AR40XX_PORT_STATE_BLOCK = 1,
|
|
||||||
AR40XX_PORT_STATE_LISTEN = 2,
|
|
||||||
AR40XX_PORT_STATE_LEARN = 3,
|
|
||||||
AR40XX_PORT_STATE_FORWARD = 4
|
|
||||||
};
|
|
||||||
|
|
||||||
/* ingress 802.1q mode */
|
|
||||||
enum {
|
|
||||||
AR40XX_IN_PORT_ONLY = 0,
|
|
||||||
AR40XX_IN_PORT_FALLBACK = 1,
|
|
||||||
AR40XX_IN_VLAN_ONLY = 2,
|
|
||||||
AR40XX_IN_SECURE = 3
|
|
||||||
};
|
|
||||||
|
|
||||||
/* egress 802.1q mode */
|
|
||||||
enum {
|
|
||||||
AR40XX_OUT_KEEP = 0,
|
|
||||||
AR40XX_OUT_STRIP_VLAN = 1,
|
|
||||||
AR40XX_OUT_ADD_VLAN = 2
|
|
||||||
};
|
|
||||||
|
|
||||||
/* port speed */
|
|
||||||
enum {
|
|
||||||
AR40XX_PORT_SPEED_10M = 0,
|
|
||||||
AR40XX_PORT_SPEED_100M = 1,
|
|
||||||
AR40XX_PORT_SPEED_1000M = 2,
|
|
||||||
AR40XX_PORT_SPEED_ERR = 3,
|
|
||||||
};
|
|
||||||
|
|
||||||
#define AR40XX_MIB_WORK_DELAY 2000 /* msecs */
|
|
||||||
|
|
||||||
#define AR40XX_QM_WORK_DELAY 100
|
|
||||||
|
|
||||||
#define AR40XX_MIB_FUNC_CAPTURE 0x3
|
|
||||||
|
|
||||||
#define AR40XX_REG_PORT_STATS_START 0x1000
|
|
||||||
#define AR40XX_REG_PORT_STATS_LEN 0x100
|
|
||||||
|
|
||||||
#define AR40XX_PORTS_ALL 0x3f
|
|
||||||
|
|
||||||
#define AR40XX_PSGMII_ID 5
|
|
||||||
#define AR40XX_PSGMII_CALB_NUM 100
|
|
||||||
#define AR40XX_MALIBU_PSGMII_MODE_CTRL 0x6d
|
|
||||||
#define AR40XX_MALIBU_PHY_PSGMII_MODE_CTRL_ADJUST_VAL 0x220c
|
|
||||||
#define AR40XX_MALIBU_PHY_MMD7_DAC_CTRL 0x801a
|
|
||||||
#define AR40XX_MALIBU_DAC_CTRL_MASK 0x380
|
|
||||||
#define AR40XX_MALIBU_DAC_CTRL_VALUE 0x280
|
|
||||||
#define AR40XX_MALIBU_PHY_RLP_CTRL 0x805a
|
|
||||||
#define AR40XX_PSGMII_TX_DRIVER_1_CTRL 0xb
|
|
||||||
#define AR40XX_MALIBU_PHY_PSGMII_REDUCE_SERDES_TX_AMP 0x8a
|
|
||||||
#define AR40XX_MALIBU_PHY_LAST_ADDR 4
|
|
||||||
|
|
||||||
static inline struct ar40xx_priv *
|
|
||||||
swdev_to_ar40xx(struct switch_dev *swdev)
|
|
||||||
{
|
|
||||||
return container_of(swdev, struct ar40xx_priv, dev);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
@ -21,7 +21,7 @@
|
|||||||
static void qcom_scm_set_download_mode(bool enable)
|
static void qcom_scm_set_download_mode(bool enable)
|
||||||
{
|
{
|
||||||
bool avail;
|
bool avail;
|
||||||
@@ -1320,6 +1334,13 @@ static int qcom_scm_probe(struct platfor
|
@@ -1314,6 +1328,13 @@ static int qcom_scm_probe(struct platfor
|
||||||
if (download_mode)
|
if (download_mode)
|
||||||
qcom_scm_set_download_mode(true);
|
qcom_scm_set_download_mode(true);
|
||||||
|
|
||||||
|
@ -11,6 +11,11 @@ board_config_update
|
|||||||
board=$(board_name)
|
board=$(board_name)
|
||||||
|
|
||||||
case "$board" in
|
case "$board" in
|
||||||
|
arris,tr4400-v2)
|
||||||
|
ucidef_set_interfaces_lan_wan "eth1" "eth2"
|
||||||
|
ucidef_add_switch "switch0" \
|
||||||
|
"1:lan" "2:lan" "3:lan" "4:lan" "6u@eth1" "0u@eth0"
|
||||||
|
;;
|
||||||
askey,rt4230w-rev6 |\
|
askey,rt4230w-rev6 |\
|
||||||
asrock,g10 |\
|
asrock,g10 |\
|
||||||
nec,wg2600hp)
|
nec,wg2600hp)
|
||||||
|
@ -10,6 +10,7 @@ platform_check_image() {
|
|||||||
|
|
||||||
platform_do_upgrade() {
|
platform_do_upgrade() {
|
||||||
case "$(board_name)" in
|
case "$(board_name)" in
|
||||||
|
arris,tr4400-v2 |\
|
||||||
askey,rt4230w-rev6 |\
|
askey,rt4230w-rev6 |\
|
||||||
compex,wpq864|\
|
compex,wpq864|\
|
||||||
netgear,d7800 |\
|
netgear,d7800 |\
|
||||||
|
@ -0,0 +1,425 @@
|
|||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#include "qcom-ipq8065.dtsi"
|
||||||
|
#include <dt-bindings/input/input.h>
|
||||||
|
|
||||||
|
/ {
|
||||||
|
model = "Arris TR4400 v2";
|
||||||
|
compatible = "arris,tr4400-v2", "qcom,ipq8065", "qcom,ipq8064";
|
||||||
|
|
||||||
|
memory@0 {
|
||||||
|
reg = <0x42000000 0x1e000000>;
|
||||||
|
device_type = "memory";
|
||||||
|
};
|
||||||
|
|
||||||
|
aliases {
|
||||||
|
led-boot = &led_status_blue;
|
||||||
|
led-failsafe = &led_status_red;
|
||||||
|
led-running = &led_status_blue;
|
||||||
|
led-upgrade = &led_status_red;
|
||||||
|
};
|
||||||
|
|
||||||
|
chosen {
|
||||||
|
bootargs = "rootfstype=squashfs noinitrd";
|
||||||
|
};
|
||||||
|
|
||||||
|
keys {
|
||||||
|
compatible = "gpio-keys";
|
||||||
|
pinctrl-0 = <&button_pins>;
|
||||||
|
pinctrl-names = "default";
|
||||||
|
|
||||||
|
reset {
|
||||||
|
label = "reset";
|
||||||
|
gpios = <&qcom_pinmux 6 GPIO_ACTIVE_LOW>;
|
||||||
|
linux,code = <KEY_RESTART>;
|
||||||
|
debounce-interval = <60>;
|
||||||
|
wakeup-source;
|
||||||
|
};
|
||||||
|
|
||||||
|
wps {
|
||||||
|
label = "wps";
|
||||||
|
gpios = <&qcom_pinmux 54 GPIO_ACTIVE_LOW>;
|
||||||
|
linux,code = <KEY_WPS_BUTTON>;
|
||||||
|
debounce-interval = <60>;
|
||||||
|
wakeup-source;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
leds {
|
||||||
|
compatible = "gpio-leds";
|
||||||
|
pinctrl-0 = <&led_pins>;
|
||||||
|
pinctrl-names = "default";
|
||||||
|
|
||||||
|
led_status_red: status_red {
|
||||||
|
label = "red:status";
|
||||||
|
gpios = <&qcom_pinmux 7 GPIO_ACTIVE_HIGH>;
|
||||||
|
};
|
||||||
|
|
||||||
|
led_status_blue: status_blue {
|
||||||
|
label = "blue:status";
|
||||||
|
gpios = <&qcom_pinmux 8 GPIO_ACTIVE_HIGH>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
&qcom_pinmux {
|
||||||
|
button_pins: button_pins {
|
||||||
|
mux {
|
||||||
|
pins = "gpio6", "gpio54";
|
||||||
|
function = "gpio";
|
||||||
|
drive-strength = <2>;
|
||||||
|
bias-pull-up;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
led_pins: led_pins {
|
||||||
|
mux {
|
||||||
|
pins = "gpio7", "gpio8";
|
||||||
|
function = "gpio";
|
||||||
|
drive-strength = <2>;
|
||||||
|
bias-pull-down;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
rgmii2_pins: rgmii2_pins {
|
||||||
|
tx {
|
||||||
|
pins = "gpio27", "gpio28", "gpio29", "gpio30", "gpio31", "gpio32";
|
||||||
|
input-disable;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
spi_pins: spi_pins {
|
||||||
|
cs {
|
||||||
|
pins = "gpio20";
|
||||||
|
drive-strength = <12>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
&gsbi5 {
|
||||||
|
qcom,mode = <GSBI_PROT_SPI>;
|
||||||
|
status = "okay";
|
||||||
|
|
||||||
|
spi@1a280000 {
|
||||||
|
status = "okay";
|
||||||
|
|
||||||
|
pinctrl-0 = <&spi_pins>;
|
||||||
|
pinctrl-names = "default";
|
||||||
|
|
||||||
|
cs-gpios = <&qcom_pinmux 20 GPIO_ACTIVE_HIGH>;
|
||||||
|
|
||||||
|
flash@0 {
|
||||||
|
compatible = "everspin,mr25h256";
|
||||||
|
spi-max-frequency = <40000000>;
|
||||||
|
reg = <0>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
&nand {
|
||||||
|
status = "okay";
|
||||||
|
|
||||||
|
pinctrl-0 = <&nand_pins>;
|
||||||
|
pinctrl-names = "default";
|
||||||
|
|
||||||
|
nand@0 {
|
||||||
|
reg = <0>;
|
||||||
|
compatible = "qcom,nandcs";
|
||||||
|
|
||||||
|
nand-ecc-strength = <4>;
|
||||||
|
nand-bus-width = <8>;
|
||||||
|
nand-ecc-step-size = <512>;
|
||||||
|
|
||||||
|
partitions {
|
||||||
|
compatible = "fixed-partitions";
|
||||||
|
#address-cells = <1>;
|
||||||
|
#size-cells = <1>;
|
||||||
|
|
||||||
|
partition@0 {
|
||||||
|
label = "0:SBL1";
|
||||||
|
reg = <0x0000000 0x0040000>;
|
||||||
|
read-only;
|
||||||
|
};
|
||||||
|
partition@40000 {
|
||||||
|
label = "0:MIBIB";
|
||||||
|
reg = <0x0040000 0x0140000>;
|
||||||
|
read-only;
|
||||||
|
};
|
||||||
|
partition@180000 {
|
||||||
|
label = "0:SBL2";
|
||||||
|
reg = <0x0180000 0x0140000>;
|
||||||
|
read-only;
|
||||||
|
};
|
||||||
|
partition@2c0000 {
|
||||||
|
label = "0:SBL3";
|
||||||
|
reg = <0x02c0000 0x0280000>;
|
||||||
|
read-only;
|
||||||
|
};
|
||||||
|
partition@540000 {
|
||||||
|
label = "0:DDRCONFIG";
|
||||||
|
reg = <0x0540000 0x0120000>;
|
||||||
|
read-only;
|
||||||
|
};
|
||||||
|
partition@660000 {
|
||||||
|
label = "0:SSD";
|
||||||
|
reg = <0x0660000 0x0120000>;
|
||||||
|
read-only;
|
||||||
|
};
|
||||||
|
partition@780000 {
|
||||||
|
label = "0:TZ";
|
||||||
|
reg = <0x0780000 0x0280000>;
|
||||||
|
read-only;
|
||||||
|
};
|
||||||
|
partition@a00000 {
|
||||||
|
label = "0:RPM";
|
||||||
|
reg = <0x0a00000 0x0280000>;
|
||||||
|
read-only;
|
||||||
|
};
|
||||||
|
partition@c80000 {
|
||||||
|
label = "0:APPSBL";
|
||||||
|
reg = <0x0c80000 0x0500000>;
|
||||||
|
read-only;
|
||||||
|
};
|
||||||
|
partition@1180000 {
|
||||||
|
label = "0:APPSBLENV";
|
||||||
|
reg = <0x1180000 0x0080000>;
|
||||||
|
};
|
||||||
|
partition@1200000 {
|
||||||
|
label = "0:ART";
|
||||||
|
reg = <0x1200000 0x0140000>;
|
||||||
|
read-only;
|
||||||
|
|
||||||
|
compatible = "nvmem-cells";
|
||||||
|
#address-cells = <1>;
|
||||||
|
#size-cells = <1>;
|
||||||
|
|
||||||
|
precal_ART_1000: precal@1000 {
|
||||||
|
reg = <0x1000 0x2f20>;
|
||||||
|
};
|
||||||
|
precal_ART_5000: precal@5000 {
|
||||||
|
reg = <0x5000 0x2f20>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
stock_partition@1340000 {
|
||||||
|
label = "stock_rootfs";
|
||||||
|
reg = <0x1340000 0x4000000>;
|
||||||
|
};
|
||||||
|
partition@5340000 {
|
||||||
|
label = "0:BOOTCONFIG";
|
||||||
|
reg = <0x5340000 0x0060000>;
|
||||||
|
read-only;
|
||||||
|
};
|
||||||
|
partition@53a0000 {
|
||||||
|
label = "0:SBL2_1";
|
||||||
|
reg = <0x53a0000 0x0140000>;
|
||||||
|
read-only;
|
||||||
|
};
|
||||||
|
partition@54e0000 {
|
||||||
|
label = "0:SBL3_1";
|
||||||
|
reg = <0x54e0000 0x0280000>;
|
||||||
|
read-only;
|
||||||
|
};
|
||||||
|
partition@5760000 {
|
||||||
|
label = "0:DDRCONFIG_1";
|
||||||
|
reg = <0x5760000 0x0120000>;
|
||||||
|
read-only;
|
||||||
|
};
|
||||||
|
partition@5880000 {
|
||||||
|
label = "0:SSD_1";
|
||||||
|
reg = <0x5880000 0x0120000>;
|
||||||
|
read-only;
|
||||||
|
};
|
||||||
|
partition@59a0000 {
|
||||||
|
label = "0:TZ_1";
|
||||||
|
reg = <0x59a0000 0x0280000>;
|
||||||
|
read-only;
|
||||||
|
};
|
||||||
|
partition@5c20000 {
|
||||||
|
label = "0:RPM_1";
|
||||||
|
reg = <0x5c20000 0x0280000>;
|
||||||
|
read-only;
|
||||||
|
};
|
||||||
|
partition@5ea0000 {
|
||||||
|
label = "0:BOOTCONFIG1";
|
||||||
|
reg = <0x5ea0000 0x0060000>;
|
||||||
|
read-only;
|
||||||
|
};
|
||||||
|
partition@5f00000 {
|
||||||
|
label = "0:APPSBL_1";
|
||||||
|
reg = <0x5f00000 0x0500000>;
|
||||||
|
read-only;
|
||||||
|
};
|
||||||
|
stock_partition@6400000 {
|
||||||
|
label = "stock_rootfs_1";
|
||||||
|
reg = <0x6400000 0x4000000>;
|
||||||
|
};
|
||||||
|
stock_partition@a400000 {
|
||||||
|
label = "stock_fw_env";
|
||||||
|
reg = <0xa400000 0x0100000>;
|
||||||
|
};
|
||||||
|
stock_partition@a500000 {
|
||||||
|
label = "stock_config";
|
||||||
|
reg = <0xa500000 0x0800000>;
|
||||||
|
};
|
||||||
|
stock_partition@ad00000 {
|
||||||
|
label = "stock_PKI";
|
||||||
|
reg = <0xad00000 0x0200000>;
|
||||||
|
};
|
||||||
|
stock_partition@af00000 {
|
||||||
|
label = "stock_scfgmgr";
|
||||||
|
reg = <0xaf00000 0x0100000>;
|
||||||
|
};
|
||||||
|
|
||||||
|
partition@6400000 {
|
||||||
|
label = "fw_env";
|
||||||
|
reg = <0x6400000 0x0100000>;
|
||||||
|
|
||||||
|
compatible = "nvmem-cells";
|
||||||
|
#address-cells = <1>;
|
||||||
|
#size-cells = <1>;
|
||||||
|
|
||||||
|
macaddr_fw_env_0: macaddr@0 {
|
||||||
|
reg = <0x00 0x6>;
|
||||||
|
};
|
||||||
|
macaddr_fw_env_6: macaddr@6 {
|
||||||
|
reg = <0x06 0x6>;
|
||||||
|
};
|
||||||
|
macaddr_fw_env_c: macaddr@c {
|
||||||
|
reg = <0x0c 0x6>;
|
||||||
|
};
|
||||||
|
macaddr_fw_env_12: macaddr@12 {
|
||||||
|
reg = <0x12 0x6>;
|
||||||
|
};
|
||||||
|
macaddr_fw_env_18: macaddr@18 {
|
||||||
|
reg = <0x18 0x6>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
partition@6500000 {
|
||||||
|
label = "ubi";
|
||||||
|
reg = <0x6500000 0x9b00000>;
|
||||||
|
};
|
||||||
|
partition@1340000 {
|
||||||
|
label = "extra";
|
||||||
|
reg = <0x1340000 0x4000000>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
&mdio0 {
|
||||||
|
status = "okay";
|
||||||
|
|
||||||
|
pinctrl-0 = <&mdio0_pins>;
|
||||||
|
pinctrl-names = "default";
|
||||||
|
|
||||||
|
ethernet-phy@0 {
|
||||||
|
reg = <0x0>;
|
||||||
|
qca,ar8327-initvals = <
|
||||||
|
0x00004 0x7600000 /* PAD0_MODE */
|
||||||
|
0x00008 0x1000000 /* PAD5_MODE */
|
||||||
|
0x0000c 0x80 /* PAD6_MODE */
|
||||||
|
0x000e4 0xaa545 /* MAC_POWER_SEL */
|
||||||
|
0x000e0 0xc74164de /* SGMII_CTRL */
|
||||||
|
0x0007c 0x4e /* PORT0_STATUS */
|
||||||
|
0x00094 0x4e /* PORT6_STATUS */
|
||||||
|
>;
|
||||||
|
};
|
||||||
|
|
||||||
|
phy7: ethernet-phy@7 {
|
||||||
|
reg = <7>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
&gmac0 {
|
||||||
|
status = "okay";
|
||||||
|
phy-mode = "rgmii";
|
||||||
|
qcom,id = <0>;
|
||||||
|
|
||||||
|
nvmem-cells = <&macaddr_fw_env_18>;
|
||||||
|
nvmem-cell-names = "mac-address";
|
||||||
|
|
||||||
|
pinctrl-0 = <&rgmii2_pins>;
|
||||||
|
pinctrl-names = "default";
|
||||||
|
|
||||||
|
fixed-link {
|
||||||
|
speed = <1000>;
|
||||||
|
full-duplex;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
&gmac1 {
|
||||||
|
status = "okay";
|
||||||
|
phy-mode = "sgmii";
|
||||||
|
qcom,id = <1>;
|
||||||
|
|
||||||
|
nvmem-cells = <&macaddr_fw_env_0>;
|
||||||
|
nvmem-cell-names = "mac-address";
|
||||||
|
|
||||||
|
fixed-link {
|
||||||
|
speed = <1000>;
|
||||||
|
full-duplex;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
&gmac3 {
|
||||||
|
status = "okay";
|
||||||
|
phy-mode = "sgmii";
|
||||||
|
qcom,id = <3>;
|
||||||
|
phy-handle = <&phy7>;
|
||||||
|
|
||||||
|
nvmem-cells = <&macaddr_fw_env_6>;
|
||||||
|
nvmem-cell-names = "mac-address";
|
||||||
|
};
|
||||||
|
|
||||||
|
&adm_dma {
|
||||||
|
status = "okay";
|
||||||
|
};
|
||||||
|
|
||||||
|
&usb3_1 {
|
||||||
|
status = "okay";
|
||||||
|
};
|
||||||
|
|
||||||
|
&pcie0 {
|
||||||
|
status = "okay";
|
||||||
|
reset-gpio = <&qcom_pinmux 3 GPIO_ACTIVE_HIGH>;
|
||||||
|
pinctrl-0 = <&pcie0_pins>;
|
||||||
|
pinctrl-names = "default";
|
||||||
|
|
||||||
|
bridge@0,0 {
|
||||||
|
reg = <0x00000000 0 0 0 0>;
|
||||||
|
#address-cells = <3>;
|
||||||
|
#size-cells = <2>;
|
||||||
|
ranges;
|
||||||
|
|
||||||
|
wifi0: wifi@1,0 {
|
||||||
|
compatible = "pci168c,0046";
|
||||||
|
reg = <0x00010000 0 0 0 0>;
|
||||||
|
|
||||||
|
nvmem-cells = <&precal_ART_1000>, <&macaddr_fw_env_12>;
|
||||||
|
nvmem-cell-names = "pre-calibration", "mac-address";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
&pcie1 {
|
||||||
|
status = "okay";
|
||||||
|
reset-gpio = <&qcom_pinmux 48 GPIO_ACTIVE_HIGH>;
|
||||||
|
pinctrl-0 = <&pcie1_pins>;
|
||||||
|
pinctrl-names = "default";
|
||||||
|
max-link-speed = <1>;
|
||||||
|
|
||||||
|
bridge@0,0 {
|
||||||
|
reg = <0x00000000 0 0 0 0>;
|
||||||
|
#address-cells = <3>;
|
||||||
|
#size-cells = <2>;
|
||||||
|
ranges;
|
||||||
|
|
||||||
|
wifi1: wifi@1,0 {
|
||||||
|
compatible = "pci168c,0040";
|
||||||
|
reg = <0x00010000 0 0 0 0>;
|
||||||
|
|
||||||
|
nvmem-cells = <&precal_ART_5000>, <&macaddr_fw_env_c>;
|
||||||
|
nvmem-cell-names = "pre-calibration", "mac-address";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
@ -65,6 +65,19 @@ define Device/ZyXELImage
|
|||||||
append-metadata
|
append-metadata
|
||||||
endef
|
endef
|
||||||
|
|
||||||
|
define Device/arris_tr4400-v2
|
||||||
|
$(call Device/LegacyImage)
|
||||||
|
DEVICE_VENDOR := Arris
|
||||||
|
DEVICE_MODEL := TR4400
|
||||||
|
DEVICE_VARIANT := v2
|
||||||
|
SOC := qcom-ipq8065
|
||||||
|
BLOCKSIZE := 128k
|
||||||
|
PAGESIZE := 2048
|
||||||
|
DEVICE_PACKAGES := ath10k-firmware-qca9984-ct ath10k-firmware-qca99x0-ct
|
||||||
|
KERNEL_IN_UBI := 1
|
||||||
|
endef
|
||||||
|
TARGET_DEVICES += arris_tr4400-v2
|
||||||
|
|
||||||
define Device/askey_rt4230w-rev6
|
define Device/askey_rt4230w-rev6
|
||||||
$(call Device/LegacyImage)
|
$(call Device/LegacyImage)
|
||||||
DEVICE_VENDOR := Askey
|
DEVICE_VENDOR := Askey
|
||||||
|
@ -10,7 +10,7 @@ Signed-off-by: John Crispin <john@phrozen.org>
|
|||||||
|
|
||||||
--- a/arch/arm/boot/dts/Makefile
|
--- a/arch/arm/boot/dts/Makefile
|
||||||
+++ b/arch/arm/boot/dts/Makefile
|
+++ b/arch/arm/boot/dts/Makefile
|
||||||
@@ -908,8 +908,29 @@ dtb-$(CONFIG_ARCH_QCOM) += \
|
@@ -908,8 +908,30 @@ dtb-$(CONFIG_ARCH_QCOM) += \
|
||||||
qcom-ipq4019-ap.dk04.1-c3.dtb \
|
qcom-ipq4019-ap.dk04.1-c3.dtb \
|
||||||
qcom-ipq4019-ap.dk07.1-c1.dtb \
|
qcom-ipq4019-ap.dk07.1-c1.dtb \
|
||||||
qcom-ipq4019-ap.dk07.1-c2.dtb \
|
qcom-ipq4019-ap.dk07.1-c2.dtb \
|
||||||
@ -33,6 +33,7 @@ Signed-off-by: John Crispin <john@phrozen.org>
|
|||||||
+ qcom-ipq8065-nbg6817.dtb \
|
+ qcom-ipq8065-nbg6817.dtb \
|
||||||
+ qcom-ipq8065-r7800.dtb \
|
+ qcom-ipq8065-r7800.dtb \
|
||||||
+ qcom-ipq8065-rt4230w-rev6.dtb \
|
+ qcom-ipq8065-rt4230w-rev6.dtb \
|
||||||
|
+ qcom-ipq8065-tr4400-v2.dtb \
|
||||||
+ qcom-ipq8065-xr500.dtb \
|
+ qcom-ipq8065-xr500.dtb \
|
||||||
+ qcom-ipq8068-ecw5410.dtb \
|
+ qcom-ipq8068-ecw5410.dtb \
|
||||||
+ qcom-ipq8068-mr42.dtb \
|
+ qcom-ipq8068-mr42.dtb \
|
||||||
|
@ -10,7 +10,7 @@ Signed-off-by: John Crispin <john@phrozen.org>
|
|||||||
|
|
||||||
--- a/arch/arm/boot/dts/Makefile
|
--- a/arch/arm/boot/dts/Makefile
|
||||||
+++ b/arch/arm/boot/dts/Makefile
|
+++ b/arch/arm/boot/dts/Makefile
|
||||||
@@ -956,8 +956,29 @@ dtb-$(CONFIG_ARCH_QCOM) += \
|
@@ -956,8 +956,30 @@ dtb-$(CONFIG_ARCH_QCOM) += \
|
||||||
qcom-ipq4019-ap.dk04.1-c3.dtb \
|
qcom-ipq4019-ap.dk04.1-c3.dtb \
|
||||||
qcom-ipq4019-ap.dk07.1-c1.dtb \
|
qcom-ipq4019-ap.dk07.1-c1.dtb \
|
||||||
qcom-ipq4019-ap.dk07.1-c2.dtb \
|
qcom-ipq4019-ap.dk07.1-c2.dtb \
|
||||||
@ -32,8 +32,9 @@ Signed-off-by: John Crispin <john@phrozen.org>
|
|||||||
+ qcom-ipq8064-wxr-2533dhp.dtb \
|
+ qcom-ipq8064-wxr-2533dhp.dtb \
|
||||||
+ qcom-ipq8065-nbg6817.dtb \
|
+ qcom-ipq8065-nbg6817.dtb \
|
||||||
+ qcom-ipq8065-r7800.dtb \
|
+ qcom-ipq8065-r7800.dtb \
|
||||||
+ qcom-ipq8065-xr500.dtb \
|
|
||||||
+ qcom-ipq8065-rt4230w-rev6.dtb \
|
+ qcom-ipq8065-rt4230w-rev6.dtb \
|
||||||
|
+ qcom-ipq8065-tr4400-v2.dtb \
|
||||||
|
+ qcom-ipq8065-xr500.dtb \
|
||||||
+ qcom-ipq8068-ecw5410.dtb \
|
+ qcom-ipq8068-ecw5410.dtb \
|
||||||
+ qcom-ipq8068-mr42.dtb \
|
+ qcom-ipq8068-mr42.dtb \
|
||||||
+ qcom-ipq8068-mr52.dtb \
|
+ qcom-ipq8068-mr52.dtb \
|
||||||
|
@ -204,7 +204,7 @@ Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
|
|||||||
host->use_ecc = true;
|
host->use_ecc = true;
|
||||||
clear_bam_transaction(nandc);
|
clear_bam_transaction(nandc);
|
||||||
|
|
||||||
@@ -2899,6 +2958,7 @@ static int qcom_nand_host_init_and_regis
|
@@ -2912,6 +2971,7 @@ static int qcom_nand_host_init_and_regis
|
||||||
struct nand_chip *chip = &host->chip;
|
struct nand_chip *chip = &host->chip;
|
||||||
struct mtd_info *mtd = nand_to_mtd(chip);
|
struct mtd_info *mtd = nand_to_mtd(chip);
|
||||||
struct device *dev = nandc->dev;
|
struct device *dev = nandc->dev;
|
||||||
@ -212,7 +212,7 @@ Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
|
|||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = of_property_read_u32(dn, "reg", &host->cs);
|
ret = of_property_read_u32(dn, "reg", &host->cs);
|
||||||
@@ -2960,6 +3020,17 @@ static int qcom_nand_host_init_and_regis
|
@@ -2962,6 +3022,17 @@ static int qcom_nand_host_init_and_regis
|
||||||
if (ret)
|
if (ret)
|
||||||
nand_cleanup(chip);
|
nand_cleanup(chip);
|
||||||
|
|
||||||
@ -230,7 +230,7 @@ Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3125,6 +3196,7 @@ static int qcom_nandc_remove(struct plat
|
@@ -3127,6 +3198,7 @@ static int qcom_nandc_remove(struct plat
|
||||||
static const struct qcom_nandc_props ipq806x_nandc_props = {
|
static const struct qcom_nandc_props ipq806x_nandc_props = {
|
||||||
.ecc_modes = (ECC_RS_4BIT | ECC_BCH_8BIT),
|
.ecc_modes = (ECC_RS_4BIT | ECC_BCH_8BIT),
|
||||||
.is_bam = false,
|
.is_bam = false,
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
--- a/arch/arm64/boot/dts/mediatek/mt7622.dtsi
|
--- a/arch/arm64/boot/dts/mediatek/mt7622.dtsi
|
||||||
+++ b/arch/arm64/boot/dts/mediatek/mt7622.dtsi
|
+++ b/arch/arm64/boot/dts/mediatek/mt7622.dtsi
|
||||||
@@ -577,6 +577,7 @@
|
@@ -558,6 +558,7 @@
|
||||||
compatible = "mediatek,mt7622-nor",
|
compatible = "mediatek,mt7622-nor",
|
||||||
"mediatek,mt8173-nor";
|
"mediatek,mt8173-nor";
|
||||||
reg = <0 0x11014000 0 0xe0>;
|
reg = <0 0x11014000 0 0xe0>;
|
||||||
|
@ -25,9 +25,9 @@ Link: https://lore.kernel.org/linux-mtd/20220127091808.1043392-6-miquel.raynal@b
|
|||||||
|
|
||||||
--- a/drivers/spi/spi-cadence-quadspi.c
|
--- a/drivers/spi/spi-cadence-quadspi.c
|
||||||
+++ b/drivers/spi/spi-cadence-quadspi.c
|
+++ b/drivers/spi/spi-cadence-quadspi.c
|
||||||
@@ -1230,10 +1230,7 @@ static bool cqspi_supports_mem_op(struct
|
@@ -1249,10 +1249,7 @@ static bool cqspi_supports_mem_op(struct
|
||||||
if (!(all_true || all_false))
|
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
- if (all_true)
|
- if (all_true)
|
||||||
- return spi_mem_dtr_supports_op(mem, op);
|
- return spi_mem_dtr_supports_op(mem, op);
|
||||||
|
@ -1,88 +0,0 @@
|
|||||||
From 41825166744c6e5664281611f5e6d9a2e9333c2b Mon Sep 17 00:00:00 2001
|
|
||||||
From: Chuanhong Guo <gch981213@gmail.com>
|
|
||||||
Date: Sat, 2 Apr 2022 22:31:20 +0800
|
|
||||||
Subject: [PATCH 10/15] mtd: nand: fix ecc parameters for mt7622
|
|
||||||
|
|
||||||
According to the datasheet, mt7622 only has 5 ECC capabilities instead
|
|
||||||
of 7, and the decoding error register is arranged as follows:
|
|
||||||
+------+---------+---------+---------+---------+
|
|
||||||
| Bits | 19:15 | 14:10 | 9:5 | 4:0 |
|
|
||||||
+------+---------+---------+---------+---------+
|
|
||||||
| Name | ERRNUM3 | ERRNUM2 | ERRNUM1 | ERRNUM0 |
|
|
||||||
+------+---------+---------+---------+---------+
|
|
||||||
This means err_mask should be 0x1f instead of 0x3f and the number of
|
|
||||||
bits shifted in mtk_ecc_get_stats should be 5 instead of 8.
|
|
||||||
|
|
||||||
This commit introduces err_shift for the difference in this register
|
|
||||||
and fix other existing parameters.
|
|
||||||
|
|
||||||
Public MT7622 reference manual can be found on [0] and the info this
|
|
||||||
commit is based on is from page 656 and page 660.
|
|
||||||
|
|
||||||
[0]: https://wiki.banana-pi.org/Banana_Pi_BPI-R64#Documents
|
|
||||||
|
|
||||||
Fixes: 98dea8d71931 ("mtd: nand: mtk: Support MT7622 NAND flash controller.")
|
|
||||||
Signed-off-by: Chuanhong Guo <gch981213@gmail.com>
|
|
||||||
(cherry picked from commit 088b769abd1bd21753002b17b696ae1778b16e8c)
|
|
||||||
---
|
|
||||||
drivers/mtd/nand/raw/mtk_ecc.c | 12 ++++++++----
|
|
||||||
1 file changed, 8 insertions(+), 4 deletions(-)
|
|
||||||
|
|
||||||
--- a/drivers/mtd/nand/raw/mtk_ecc.c
|
|
||||||
+++ b/drivers/mtd/nand/raw/mtk_ecc.c
|
|
||||||
@@ -43,6 +43,7 @@
|
|
||||||
|
|
||||||
struct mtk_ecc_caps {
|
|
||||||
u32 err_mask;
|
|
||||||
+ u32 err_shift;
|
|
||||||
const u8 *ecc_strength;
|
|
||||||
const u32 *ecc_regs;
|
|
||||||
u8 num_ecc_strength;
|
|
||||||
@@ -76,7 +77,7 @@ static const u8 ecc_strength_mt2712[] =
|
|
||||||
};
|
|
||||||
|
|
||||||
static const u8 ecc_strength_mt7622[] = {
|
|
||||||
- 4, 6, 8, 10, 12, 14, 16
|
|
||||||
+ 4, 6, 8, 10, 12
|
|
||||||
};
|
|
||||||
|
|
||||||
enum mtk_ecc_regs {
|
|
||||||
@@ -221,7 +222,7 @@ void mtk_ecc_get_stats(struct mtk_ecc *e
|
|
||||||
for (i = 0; i < sectors; i++) {
|
|
||||||
offset = (i >> 2) << 2;
|
|
||||||
err = readl(ecc->regs + ECC_DECENUM0 + offset);
|
|
||||||
- err = err >> ((i % 4) * 8);
|
|
||||||
+ err = err >> ((i % 4) * ecc->caps->err_shift);
|
|
||||||
err &= ecc->caps->err_mask;
|
|
||||||
if (err == ecc->caps->err_mask) {
|
|
||||||
/* uncorrectable errors */
|
|
||||||
@@ -449,6 +450,7 @@ EXPORT_SYMBOL(mtk_ecc_get_parity_bits);
|
|
||||||
|
|
||||||
static const struct mtk_ecc_caps mtk_ecc_caps_mt2701 = {
|
|
||||||
.err_mask = 0x3f,
|
|
||||||
+ .err_shift = 8,
|
|
||||||
.ecc_strength = ecc_strength_mt2701,
|
|
||||||
.ecc_regs = mt2701_ecc_regs,
|
|
||||||
.num_ecc_strength = 20,
|
|
||||||
@@ -459,6 +461,7 @@ static const struct mtk_ecc_caps mtk_ecc
|
|
||||||
|
|
||||||
static const struct mtk_ecc_caps mtk_ecc_caps_mt2712 = {
|
|
||||||
.err_mask = 0x7f,
|
|
||||||
+ .err_shift = 8,
|
|
||||||
.ecc_strength = ecc_strength_mt2712,
|
|
||||||
.ecc_regs = mt2712_ecc_regs,
|
|
||||||
.num_ecc_strength = 23,
|
|
||||||
@@ -468,10 +471,11 @@ static const struct mtk_ecc_caps mtk_ecc
|
|
||||||
};
|
|
||||||
|
|
||||||
static const struct mtk_ecc_caps mtk_ecc_caps_mt7622 = {
|
|
||||||
- .err_mask = 0x3f,
|
|
||||||
+ .err_mask = 0x1f,
|
|
||||||
+ .err_shift = 5,
|
|
||||||
.ecc_strength = ecc_strength_mt7622,
|
|
||||||
.ecc_regs = mt7622_ecc_regs,
|
|
||||||
- .num_ecc_strength = 7,
|
|
||||||
+ .num_ecc_strength = 5,
|
|
||||||
.ecc_mode_shift = 4,
|
|
||||||
.parity_bits = 13,
|
|
||||||
.pg_irq_sel = 0,
|
|
@ -112,7 +112,7 @@ Signed-off-by: Rui Salvaterra <rsalvaterra@gmail.com>
|
|||||||
|
|
||||||
--- a/arch/arm64/boot/dts/mediatek/mt7622.dtsi
|
--- a/arch/arm64/boot/dts/mediatek/mt7622.dtsi
|
||||||
+++ b/arch/arm64/boot/dts/mediatek/mt7622.dtsi
|
+++ b/arch/arm64/boot/dts/mediatek/mt7622.dtsi
|
||||||
@@ -940,6 +940,7 @@
|
@@ -941,6 +941,7 @@
|
||||||
clock-names = "hsdma";
|
clock-names = "hsdma";
|
||||||
power-domains = <&scpsys MT7622_POWER_DOMAIN_ETHSYS>;
|
power-domains = <&scpsys MT7622_POWER_DOMAIN_ETHSYS>;
|
||||||
#dma-cells = <1>;
|
#dma-cells = <1>;
|
||||||
|
@ -194,7 +194,7 @@ Signed-off-by: Matthias Brugger <matthias.bgg@gmail.com>
|
|||||||
&pio {
|
&pio {
|
||||||
--- a/arch/arm64/boot/dts/mediatek/mt7622.dtsi
|
--- a/arch/arm64/boot/dts/mediatek/mt7622.dtsi
|
||||||
+++ b/arch/arm64/boot/dts/mediatek/mt7622.dtsi
|
+++ b/arch/arm64/boot/dts/mediatek/mt7622.dtsi
|
||||||
@@ -807,75 +807,83 @@
|
@@ -808,75 +808,83 @@
|
||||||
#reset-cells = <1>;
|
#reset-cells = <1>;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
--- a/arch/arm64/boot/dts/mediatek/mt7622.dtsi
|
--- a/arch/arm64/boot/dts/mediatek/mt7622.dtsi
|
||||||
+++ b/arch/arm64/boot/dts/mediatek/mt7622.dtsi
|
+++ b/arch/arm64/boot/dts/mediatek/mt7622.dtsi
|
||||||
@@ -847,6 +847,12 @@
|
@@ -848,6 +848,12 @@
|
||||||
#address-cells = <0>;
|
#address-cells = <0>;
|
||||||
#interrupt-cells = <1>;
|
#interrupt-cells = <1>;
|
||||||
};
|
};
|
||||||
@ -13,7 +13,7 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
pcie1: pcie@1a145000 {
|
pcie1: pcie@1a145000 {
|
||||||
@@ -885,6 +891,12 @@
|
@@ -886,6 +892,12 @@
|
||||||
#address-cells = <0>;
|
#address-cells = <0>;
|
||||||
#interrupt-cells = <1>;
|
#interrupt-cells = <1>;
|
||||||
};
|
};
|
||||||
|
@ -10,7 +10,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
|||||||
|
|
||||||
--- a/arch/arm64/boot/dts/mediatek/mt7622.dtsi
|
--- a/arch/arm64/boot/dts/mediatek/mt7622.dtsi
|
||||||
+++ b/arch/arm64/boot/dts/mediatek/mt7622.dtsi
|
+++ b/arch/arm64/boot/dts/mediatek/mt7622.dtsi
|
||||||
@@ -835,6 +835,9 @@
|
@@ -836,6 +836,9 @@
|
||||||
bus-range = <0x00 0xff>;
|
bus-range = <0x00 0xff>;
|
||||||
ranges = <0x82000000 0 0x20000000 0x0 0x20000000 0 0x8000000>;
|
ranges = <0x82000000 0 0x20000000 0x0 0x20000000 0 0x8000000>;
|
||||||
status = "disabled";
|
status = "disabled";
|
||||||
@ -20,7 +20,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
|||||||
|
|
||||||
#interrupt-cells = <1>;
|
#interrupt-cells = <1>;
|
||||||
interrupt-map-mask = <0 0 0 7>;
|
interrupt-map-mask = <0 0 0 7>;
|
||||||
@@ -879,6 +882,9 @@
|
@@ -880,6 +883,9 @@
|
||||||
bus-range = <0x00 0xff>;
|
bus-range = <0x00 0xff>;
|
||||||
ranges = <0x82000000 0 0x28000000 0x0 0x28000000 0 0x8000000>;
|
ranges = <0x82000000 0 0x28000000 0x0 0x28000000 0 0x8000000>;
|
||||||
status = "disabled";
|
status = "disabled";
|
||||||
|
178
target/linux/ramips/dts/mt7621_cudy_x6.dts
Normal file
178
target/linux/ramips/dts/mt7621_cudy_x6.dts
Normal file
@ -0,0 +1,178 @@
|
|||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
|
||||||
|
|
||||||
|
#include "mt7621.dtsi"
|
||||||
|
|
||||||
|
#include <dt-bindings/gpio/gpio.h>
|
||||||
|
#include <dt-bindings/input/input.h>
|
||||||
|
|
||||||
|
/ {
|
||||||
|
compatible = "cudy,x6", "mediatek,mt7621-soc";
|
||||||
|
model = "CUDY X6";
|
||||||
|
|
||||||
|
aliases {
|
||||||
|
led-boot = &led_internet_blue;
|
||||||
|
led-failsafe = &led_internet_blue;
|
||||||
|
led-running = &led_internet_blue;
|
||||||
|
led-upgrade = &led_internet_blue;
|
||||||
|
label-mac-device = &gmac0;
|
||||||
|
};
|
||||||
|
|
||||||
|
chosen {
|
||||||
|
bootargs = "console=ttyS0,115200";
|
||||||
|
};
|
||||||
|
|
||||||
|
keys {
|
||||||
|
compatible = "gpio-keys";
|
||||||
|
|
||||||
|
reset {
|
||||||
|
label = "reset";
|
||||||
|
gpios = <&gpio 8 GPIO_ACTIVE_LOW>;
|
||||||
|
linux,code = <KEY_RESTART>;
|
||||||
|
};
|
||||||
|
|
||||||
|
wps {
|
||||||
|
label = "wps";
|
||||||
|
gpios = <&gpio 7 GPIO_ACTIVE_LOW>;
|
||||||
|
linux,code = <KEY_WPS_BUTTON>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
leds {
|
||||||
|
compatible = "gpio-leds";
|
||||||
|
|
||||||
|
led_internet_blue: internet_blue {
|
||||||
|
label = "blue:internet";
|
||||||
|
gpios = <&gpio 15 GPIO_ACTIVE_LOW>;
|
||||||
|
};
|
||||||
|
|
||||||
|
internet_red {
|
||||||
|
label = "red:internet";
|
||||||
|
gpios = <&gpio 16 GPIO_ACTIVE_LOW>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
&spi0 {
|
||||||
|
status = "okay";
|
||||||
|
|
||||||
|
flash@0 {
|
||||||
|
compatible = "jedec,spi-nor";
|
||||||
|
reg = <0>;
|
||||||
|
spi-max-frequency = <50000000>;
|
||||||
|
|
||||||
|
partitions {
|
||||||
|
compatible = "fixed-partitions";
|
||||||
|
#address-cells = <1>;
|
||||||
|
#size-cells = <1>;
|
||||||
|
|
||||||
|
partition@0 {
|
||||||
|
label = "u-boot";
|
||||||
|
reg = <0x0 0x30000>;
|
||||||
|
read-only;
|
||||||
|
};
|
||||||
|
|
||||||
|
partition@30000 {
|
||||||
|
label = "u-boot-env";
|
||||||
|
reg = <0x30000 0x10000>;
|
||||||
|
read-only;
|
||||||
|
};
|
||||||
|
|
||||||
|
factory: partition@40000 {
|
||||||
|
label = "factory";
|
||||||
|
reg = <0x40000 0x10000>;
|
||||||
|
read-only;
|
||||||
|
};
|
||||||
|
|
||||||
|
partition@50000 {
|
||||||
|
compatible = "denx,uimage";
|
||||||
|
label = "firmware";
|
||||||
|
reg = <0x50000 0x1f80000>;
|
||||||
|
};
|
||||||
|
|
||||||
|
partition@1fd0000 {
|
||||||
|
label = "debug";
|
||||||
|
reg = <0x1fd0000 0x10000>;
|
||||||
|
read-only;
|
||||||
|
};
|
||||||
|
|
||||||
|
partition@1fe0000 {
|
||||||
|
label = "backup";
|
||||||
|
reg = <0x1fe0000 0x10000>;
|
||||||
|
read-only;
|
||||||
|
};
|
||||||
|
|
||||||
|
bdinfo: partition@1ff0000 {
|
||||||
|
label = "bdinfo";
|
||||||
|
reg = <0x1ff0000 0x10000>;
|
||||||
|
read-only;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
&pcie {
|
||||||
|
status = "okay";
|
||||||
|
};
|
||||||
|
|
||||||
|
&pcie1 {
|
||||||
|
wifi@0,0 {
|
||||||
|
compatible = "mediatek,mt76";
|
||||||
|
reg = <0x0000 0 0 0 0>;
|
||||||
|
mediatek,mtd-eeprom = <&factory 0x0000>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
&gmac0 {
|
||||||
|
nvmem-cells = <&macaddr_bdinfo_de00>;
|
||||||
|
nvmem-cell-names = "mac-address";
|
||||||
|
};
|
||||||
|
|
||||||
|
&switch0 {
|
||||||
|
ports {
|
||||||
|
port@0 {
|
||||||
|
status = "okay";
|
||||||
|
label = "lan1";
|
||||||
|
};
|
||||||
|
|
||||||
|
port@1 {
|
||||||
|
status = "okay";
|
||||||
|
label = "lan2";
|
||||||
|
};
|
||||||
|
|
||||||
|
port@2 {
|
||||||
|
status = "okay";
|
||||||
|
label = "lan3";
|
||||||
|
};
|
||||||
|
|
||||||
|
port@3 {
|
||||||
|
status = "okay";
|
||||||
|
label = "lan4";
|
||||||
|
};
|
||||||
|
|
||||||
|
port@4 {
|
||||||
|
status = "okay";
|
||||||
|
label = "wan";
|
||||||
|
nvmem-cells = <&macaddr_bdinfo_de00>;
|
||||||
|
nvmem-cell-names = "mac-address";
|
||||||
|
mac-address-increment = <1>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
&state_default {
|
||||||
|
gpio {
|
||||||
|
groups = "uart3", "jtag";
|
||||||
|
function = "gpio";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
&bdinfo {
|
||||||
|
compatible = "nvmem-cells";
|
||||||
|
#address-cells = <1>;
|
||||||
|
#size-cells = <1>;
|
||||||
|
|
||||||
|
macaddr_bdinfo_de00: macaddr@de00 {
|
||||||
|
reg = <0xde00 0x6>;
|
||||||
|
};
|
||||||
|
};
|
@ -131,6 +131,10 @@
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
&i2c {
|
||||||
|
status = "okay";
|
||||||
|
};
|
||||||
|
|
||||||
&uart1 {
|
&uart1 {
|
||||||
status = "okay";
|
status = "okay";
|
||||||
};
|
};
|
||||||
|
@ -319,6 +319,16 @@ define Device/cudy_wr2100
|
|||||||
endef
|
endef
|
||||||
TARGET_DEVICES += cudy_wr2100
|
TARGET_DEVICES += cudy_wr2100
|
||||||
|
|
||||||
|
define Device/cudy_x6
|
||||||
|
$(Device/dsa-migration)
|
||||||
|
IMAGE_SIZE := 32256k
|
||||||
|
DEVICE_VENDOR := Cudy
|
||||||
|
DEVICE_MODEL := X6
|
||||||
|
UIMAGE_NAME := R13
|
||||||
|
DEVICE_PACKAGES := kmod-mt7915e
|
||||||
|
endef
|
||||||
|
TARGET_DEVICES += cudy_x6
|
||||||
|
|
||||||
define Device/dlink_dir-8xx-a1
|
define Device/dlink_dir-8xx-a1
|
||||||
$(Device/dsa-migration)
|
$(Device/dsa-migration)
|
||||||
IMAGE_SIZE := 16000k
|
IMAGE_SIZE := 16000k
|
||||||
|
@ -16,6 +16,10 @@ case "$board" in
|
|||||||
[ "$PHYNBR" = "0" ] && echo -n $hw_mac_addr_ra0 > /sys${DEVPATH}/macaddress
|
[ "$PHYNBR" = "0" ] && echo -n $hw_mac_addr_ra0 > /sys${DEVPATH}/macaddress
|
||||||
[ "$PHYNBR" = "1" ] && echo -n $hw_mac_addr_rax0 > /sys${DEVPATH}/macaddress
|
[ "$PHYNBR" = "1" ] && echo -n $hw_mac_addr_rax0 > /sys${DEVPATH}/macaddress
|
||||||
;;
|
;;
|
||||||
|
cudy,x6)
|
||||||
|
hw_mac_addr="$(mtd_get_mac_binary factory 0x4)"
|
||||||
|
macaddr_add $hw_mac_addr "$PHYNBR" > /sys${DEVPATH}/macaddress
|
||||||
|
;;
|
||||||
dlink,dir-853-a3)
|
dlink,dir-853-a3)
|
||||||
[ "$PHYNBR" = "0" ] && \
|
[ "$PHYNBR" = "0" ] && \
|
||||||
macaddr_setbit_la "$(mtd_get_mac_binary factory 0xe000)" \
|
macaddr_setbit_la "$(mtd_get_mac_binary factory 0xe000)" \
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
--- a/drivers/net/ethernet/Kconfig
|
--- a/drivers/net/ethernet/Kconfig
|
||||||
+++ b/drivers/net/ethernet/Kconfig
|
+++ b/drivers/net/ethernet/Kconfig
|
||||||
@@ -162,6 +162,7 @@ source "drivers/net/ethernet/pasemi/Kcon
|
@@ -162,6 +162,7 @@ source "drivers/net/ethernet/pensando/Kc
|
||||||
source "drivers/net/ethernet/pensando/Kconfig"
|
|
||||||
source "drivers/net/ethernet/qlogic/Kconfig"
|
source "drivers/net/ethernet/qlogic/Kconfig"
|
||||||
|
source "drivers/net/ethernet/brocade/Kconfig"
|
||||||
source "drivers/net/ethernet/qualcomm/Kconfig"
|
source "drivers/net/ethernet/qualcomm/Kconfig"
|
||||||
+source "drivers/net/ethernet/ralink/Kconfig"
|
+source "drivers/net/ethernet/ralink/Kconfig"
|
||||||
source "drivers/net/ethernet/rdc/Kconfig"
|
source "drivers/net/ethernet/rdc/Kconfig"
|
||||||
|
36
target/linux/realtek/dts-5.10/rtl8382_zyxel_gs1900-16.dts
Normal file
36
target/linux/realtek/dts-5.10/rtl8382_zyxel_gs1900-16.dts
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#include "rtl8380_zyxel_gs1900.dtsi"
|
||||||
|
|
||||||
|
/ {
|
||||||
|
compatible = "zyxel,gs1900-16", "realtek,rtl838x-soc";
|
||||||
|
model = "ZyXEL GS1900-16";
|
||||||
|
};
|
||||||
|
|
||||||
|
&mdio {
|
||||||
|
EXTERNAL_PHY(16)
|
||||||
|
EXTERNAL_PHY(17)
|
||||||
|
EXTERNAL_PHY(18)
|
||||||
|
EXTERNAL_PHY(19)
|
||||||
|
EXTERNAL_PHY(20)
|
||||||
|
EXTERNAL_PHY(21)
|
||||||
|
EXTERNAL_PHY(22)
|
||||||
|
EXTERNAL_PHY(23)
|
||||||
|
};
|
||||||
|
|
||||||
|
&switch0 {
|
||||||
|
ports {
|
||||||
|
SWITCH_PORT(16, 9, qsgmii)
|
||||||
|
SWITCH_PORT(17, 10, qsgmii)
|
||||||
|
SWITCH_PORT(18, 11, qsgmii)
|
||||||
|
SWITCH_PORT(19, 12, qsgmii)
|
||||||
|
SWITCH_PORT(20, 13, qsgmii)
|
||||||
|
SWITCH_PORT(21, 14, qsgmii)
|
||||||
|
SWITCH_PORT(22, 15, qsgmii)
|
||||||
|
SWITCH_PORT(23, 16, qsgmii)
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
&gpio1 {
|
||||||
|
/delete-node/ poe_enable;
|
||||||
|
};
|
@ -205,6 +205,15 @@ static int rtl83xx_setup(struct dsa_switch *ds)
|
|||||||
|
|
||||||
priv->r->l2_learning_setup();
|
priv->r->l2_learning_setup();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Make sure all frames sent to the switch's MAC are trapped to the CPU-port
|
||||||
|
* 0: FWD, 1: DROP, 2: TRAP2CPU
|
||||||
|
*/
|
||||||
|
if (priv->family_id == RTL8380_FAMILY_ID)
|
||||||
|
sw_w32(0x2, RTL838X_SPCL_TRAP_SWITCH_MAC_CTRL);
|
||||||
|
else
|
||||||
|
sw_w32(0x2, RTL839X_SPCL_TRAP_SWITCH_MAC_CTRL);
|
||||||
|
|
||||||
/* Enable MAC Polling PHY again */
|
/* Enable MAC Polling PHY again */
|
||||||
rtl83xx_enable_phy_polling(priv);
|
rtl83xx_enable_phy_polling(priv);
|
||||||
pr_debug("Please wait until PHY is settled\n");
|
pr_debug("Please wait until PHY is settled\n");
|
||||||
|
@ -111,6 +111,14 @@ define Device/zyxel_gs1900-10hp
|
|||||||
endef
|
endef
|
||||||
TARGET_DEVICES += zyxel_gs1900-10hp
|
TARGET_DEVICES += zyxel_gs1900-10hp
|
||||||
|
|
||||||
|
define Device/zyxel_gs1900-16
|
||||||
|
$(Device/zyxel_gs1900)
|
||||||
|
SOC := rtl8382
|
||||||
|
DEVICE_MODEL := GS1900-16
|
||||||
|
ZYXEL_VERS := AAHJ
|
||||||
|
endef
|
||||||
|
TARGET_DEVICES += zyxel_gs1900-16
|
||||||
|
|
||||||
define Device/zyxel_gs1900-8
|
define Device/zyxel_gs1900-8
|
||||||
$(Device/zyxel_gs1900)
|
$(Device/zyxel_gs1900)
|
||||||
DEVICE_MODEL := GS1900-8
|
DEVICE_MODEL := GS1900-8
|
||||||
|
@ -35,6 +35,22 @@ endef
|
|||||||
$(eval $(call KernelPackage,amd-xgbe))
|
$(eval $(call KernelPackage,amd-xgbe))
|
||||||
|
|
||||||
|
|
||||||
|
define KernelPackage/f71808e-wdt
|
||||||
|
SUBMENU:=$(OTHER_MENU)
|
||||||
|
TITLE:=Fintek F718xx/F818xx Watchdog Timer
|
||||||
|
DEPENDS:=@TARGET_x86
|
||||||
|
KCONFIG:=CONFIG_F71808E_WDT
|
||||||
|
FILES:=$(LINUX_DIR)/drivers/watchdog/f71808e_wdt.ko
|
||||||
|
AUTOLOAD:=$(call AutoProbe,f71808e-wdt,1)
|
||||||
|
endef
|
||||||
|
|
||||||
|
define KernelPackage/f71808e-wdt/description
|
||||||
|
Kernel module for the watchdog timer found on many Fintek Super-IO chips.
|
||||||
|
endef
|
||||||
|
|
||||||
|
$(eval $(call KernelPackage,f71808e-wdt))
|
||||||
|
|
||||||
|
|
||||||
define KernelPackage/sound-cs5535audio
|
define KernelPackage/sound-cs5535audio
|
||||||
TITLE:=CS5535/CS5536 Audio Controller
|
TITLE:=CS5535/CS5536 Audio Controller
|
||||||
DEPENDS:=@TARGET_x86_geode +kmod-ac97
|
DEPENDS:=@TARGET_x86_geode +kmod-ac97
|
||||||
@ -67,6 +83,60 @@ endef
|
|||||||
$(eval $(call KernelPackage,sp5100-tco))
|
$(eval $(call KernelPackage,sp5100-tco))
|
||||||
|
|
||||||
|
|
||||||
|
define KernelPackage/ib700-wdt
|
||||||
|
SUBMENU:=$(OTHER_MENU)
|
||||||
|
TITLE:=IB700 SBC Watchdog Timer
|
||||||
|
DEPENDS:=@TARGET_x86
|
||||||
|
KCONFIG:=CONFIG_IB700_WDT
|
||||||
|
FILES:=$(LINUX_DIR)/drivers/watchdog/ib700wdt.ko
|
||||||
|
AUTOLOAD:=$(call AutoLoad,50,ib700wdt,1)
|
||||||
|
endef
|
||||||
|
|
||||||
|
define KernelPackage/ib700-wdt/description
|
||||||
|
Kernel module for the hardware watchdog on the IB700 Single
|
||||||
|
Board Computer produced by TMC Technology (www.tmc-uk.com).
|
||||||
|
Also used by QEMU/libvirt.
|
||||||
|
endef
|
||||||
|
|
||||||
|
$(eval $(call KernelPackage,ib700-wdt))
|
||||||
|
|
||||||
|
define KernelPackage/it87-wdt
|
||||||
|
SUBMENU:=$(OTHER_MENU)
|
||||||
|
TITLE:=ITE IT87 Watchdog Timer
|
||||||
|
DEPENDS:=@TARGET_x86
|
||||||
|
KCONFIG:=CONFIG_IT87_WDT
|
||||||
|
FILES:=$(LINUX_DIR)/drivers/watchdog/it87_wdt.ko
|
||||||
|
AUTOLOAD:=$(call AutoLoad,50,it87-wdt,1)
|
||||||
|
MODPARAMS.it87-wdt:= \
|
||||||
|
nogameport=1 \
|
||||||
|
nocir=1
|
||||||
|
endef
|
||||||
|
|
||||||
|
define KernelPackage/it87-wdt/description
|
||||||
|
Kernel module for ITE IT87 Watchdog Timer
|
||||||
|
endef
|
||||||
|
|
||||||
|
$(eval $(call KernelPackage,it87-wdt))
|
||||||
|
|
||||||
|
|
||||||
|
define KernelPackage/itco-wdt
|
||||||
|
SUBMENU:=$(OTHER_MENU)
|
||||||
|
TITLE:=Intel iTCO Watchdog Timer
|
||||||
|
DEPENDS:=@TARGET_x86
|
||||||
|
KCONFIG:=CONFIG_ITCO_WDT \
|
||||||
|
CONFIG_ITCO_VENDOR_SUPPORT=y
|
||||||
|
FILES:=$(LINUX_DIR)/drivers/watchdog/iTCO_wdt.ko \
|
||||||
|
$(LINUX_DIR)/drivers/watchdog/iTCO_vendor_support.ko
|
||||||
|
AUTOLOAD:=$(call AutoLoad,50,iTCO_vendor_support iTCO_wdt,1)
|
||||||
|
endef
|
||||||
|
|
||||||
|
define KernelPackage/itco-wdt/description
|
||||||
|
Kernel module for Intel iTCO Watchdog Timer
|
||||||
|
endef
|
||||||
|
|
||||||
|
$(eval $(call KernelPackage,itco-wdt))
|
||||||
|
|
||||||
|
|
||||||
define KernelPackage/pcengines-apuv2
|
define KernelPackage/pcengines-apuv2
|
||||||
SUBMENU:=$(OTHER_MENU)
|
SUBMENU:=$(OTHER_MENU)
|
||||||
TITLE:=PC Engines APUv2/3 front button and LEDs driver
|
TITLE:=PC Engines APUv2/3 front button and LEDs driver
|
||||||
@ -88,7 +158,8 @@ define KernelPackage/meraki-mx100
|
|||||||
SUBMENU:=$(OTHER_MENU)
|
SUBMENU:=$(OTHER_MENU)
|
||||||
TITLE:=Cisco Meraki MX100 Platform Driver
|
TITLE:=Cisco Meraki MX100 Platform Driver
|
||||||
DEPENDS:=@TARGET_x86 +kmod-tg3 +kmod-gpio-button-hotplug +kmod-leds-gpio \
|
DEPENDS:=@TARGET_x86 +kmod-tg3 +kmod-gpio-button-hotplug +kmod-leds-gpio \
|
||||||
+kmod-usb-ledtrig-usbport +nu801 +kmod-itco-wdt +kmod-leds-uleds
|
+kmod-usb-ledtrig-usbport +PACKAGE_kmod-meraki-mx100:nu801 +kmod-itco-wdt \
|
||||||
|
+kmod-leds-uleds
|
||||||
KCONFIG:=CONFIG_MERAKI_MX100
|
KCONFIG:=CONFIG_MERAKI_MX100
|
||||||
FILES:=$(LINUX_DIR)/drivers/platform/x86/meraki-mx100.ko
|
FILES:=$(LINUX_DIR)/drivers/platform/x86/meraki-mx100.ko
|
||||||
AUTOLOAD:=$(call AutoLoad,60,meraki-mx100,1)
|
AUTOLOAD:=$(call AutoLoad,60,meraki-mx100,1)
|
||||||
@ -102,3 +173,18 @@ define KernelPackage/meraki-mx100/description
|
|||||||
endef
|
endef
|
||||||
|
|
||||||
$(eval $(call KernelPackage,meraki-mx100))
|
$(eval $(call KernelPackage,meraki-mx100))
|
||||||
|
|
||||||
|
define KernelPackage/w83627hf-wdt
|
||||||
|
SUBMENU:=$(OTHER_MENU)
|
||||||
|
TITLE:=Winbond 83627HF Watchdog Timer
|
||||||
|
DEPENDS:=@TARGET_x86
|
||||||
|
KCONFIG:=CONFIG_W83627HF_WDT
|
||||||
|
FILES:=$(LINUX_DIR)/drivers/watchdog/w83627hf_wdt.ko
|
||||||
|
AUTOLOAD:=$(call AutoLoad,50,w83627hf-wdt,1)
|
||||||
|
endef
|
||||||
|
|
||||||
|
define KernelPackage/w83627hf-wdt/description
|
||||||
|
Kernel module for Winbond 83627HF Watchdog Timer
|
||||||
|
endef
|
||||||
|
|
||||||
|
$(eval $(call KernelPackage,w83627hf-wdt))
|
||||||
|
Loading…
x
Reference in New Issue
Block a user